lists.linaro.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
July
June
May
April
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
List overview
Download
Linux-kselftest-mirror
----- 2025 -----
July 2025
June 2025
May 2025
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
linux-kselftest-mirror@lists.linaro.org
49 participants
12795 discussions
Start a n
N
ew thread
Re: [PATCH v2 03/17] drm/tests: helpers: Rename the device init helper
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > The name doesn't really fit the conventions for the other helpers in > DRM/KMS, so let's rename it to make it obvious that we allocate a new > DRM device. > > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> Reviewed-by: Maíra Canal <mcanal(a)igalia.com> Best Regards, - Maíra Canal > --- > drivers/gpu/drm/tests/drm_client_modeset_test.c | 3 ++- > drivers/gpu/drm/tests/drm_kunit_helpers.c | 8 +++++--- > drivers/gpu/drm/tests/drm_modes_test.c | 3 ++- > drivers/gpu/drm/tests/drm_probe_helper_test.c | 5 +++-- > include/drm/drm_kunit_helpers.h | 5 ++++- > 5 files changed, 16 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/tests/drm_client_modeset_test.c b/drivers/gpu/drm/tests/drm_client_modeset_test.c > index ed2f62e92fea..6cdf08f582ce 100644 > --- a/drivers/gpu/drm/tests/drm_client_modeset_test.c > +++ b/drivers/gpu/drm/tests/drm_client_modeset_test.c > @@ -59,7 +59,8 @@ static int drm_client_modeset_test_init(struct kunit *test) > > test->priv = priv; > > - priv->drm = drm_kunit_device_init(test, DRIVER_MODESET, "drm-client-modeset-test"); > + priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET, > + "drm-client-modeset-test"); > KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > > ret = drmm_connector_init(priv->drm, &priv->connector, > diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c > index 46a68c2fd80c..2f67f6cf78d0 100644 > --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c > +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c > @@ -36,7 +36,7 @@ static void dev_free(struct kunit_resource *res) > } > > /** > - * drm_kunit_device_init - Allocates a mock DRM device for Kunit tests > + * drm_kunit_helper_alloc_drm_device - Allocates a mock DRM device for Kunit tests > * @test: The test context object > * @features: Mocked DRM device driver features > * @name: Name of the struct &device to allocate > @@ -52,7 +52,9 @@ static void dev_free(struct kunit_resource *res) > * Returns: > * A pointer to the new drm_device, or an ERR_PTR() otherwise. > */ > -struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, char *name) > +struct drm_device * > +drm_kunit_helper_alloc_drm_device(struct kunit *test, > + u32 features, char *name) > { > struct kunit_dev *kdev; > struct drm_device *drm; > @@ -82,7 +84,7 @@ struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, char > > return drm; > } > -EXPORT_SYMBOL(drm_kunit_device_init); > +EXPORT_SYMBOL(drm_kunit_helper_alloc_drm_device); > > MODULE_AUTHOR("Maxime Ripard <maxime(a)cerno.tech>"); > MODULE_LICENSE("GPL"); > diff --git a/drivers/gpu/drm/tests/drm_modes_test.c b/drivers/gpu/drm/tests/drm_modes_test.c > index 3953e478c4d0..6723089dff9f 100644 > --- a/drivers/gpu/drm/tests/drm_modes_test.c > +++ b/drivers/gpu/drm/tests/drm_modes_test.c > @@ -22,7 +22,8 @@ static int drm_test_modes_init(struct kunit *test) > priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); > KUNIT_ASSERT_NOT_NULL(test, priv); > > - priv->drm = drm_kunit_device_init(test, DRIVER_MODESET, "drm-modes-test"); > + priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET, > + "drm-modes-test"); > KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > > test->priv = priv; > diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c b/drivers/gpu/drm/tests/drm_probe_helper_test.c > index 1f3941c150ae..85236ff4744f 100644 > --- a/drivers/gpu/drm/tests/drm_probe_helper_test.c > +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c > @@ -39,8 +39,9 @@ static int drm_probe_helper_test_init(struct kunit *test) > KUNIT_ASSERT_NOT_NULL(test, priv); > test->priv = priv; > > - priv->drm = drm_kunit_device_init(test, DRIVER_MODESET | DRIVER_ATOMIC, > - "drm-probe-helper-test"); > + priv->drm = drm_kunit_helper_alloc_drm_device(test, > + DRIVER_MODESET | DRIVER_ATOMIC, > + "drm-probe-helper-test"); > KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > > connector = &priv->connector; > diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h > index 20ab6eec4c89..e9870c7911fe 100644 > --- a/include/drm/drm_kunit_helpers.h > +++ b/include/drm/drm_kunit_helpers.h > @@ -6,6 +6,9 @@ > struct drm_device; > struct kunit; > > -struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, char *name); > +struct drm_device * > +drm_kunit_helper_alloc_drm_device(struct kunit *test, > + u32 features, > + char *name); > > #endif // DRM_KUNIT_HELPERS_H_ >
2 years, 7 months
1
0
0
0
Re: [PATCH v2 15/17] drm/vc4: tests: Introduce a mocking infrastructure
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > In order to test the current atomic_check hooks we need to have a DRM > device that has roughly the same capabilities and layout that the actual > hardware. We'll also need a bunch of functions to create arbitrary > atomic states. > > Let's create some helpers to create a device that behaves like the real > one, and some helpers to maintain the atomic state we want to check. > > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> > --- > drivers/gpu/drm/vc4/Kconfig | 15 +++ > drivers/gpu/drm/vc4/Makefile | 6 + > drivers/gpu/drm/vc4/tests/.kunitconfig | 14 ++ > drivers/gpu/drm/vc4/tests/vc4_mock.c | 200 ++++++++++++++++++++++++++++ > drivers/gpu/drm/vc4/tests/vc4_mock.h | 60 +++++++++ > drivers/gpu/drm/vc4/tests/vc4_mock_crtc.c | 41 ++++++ > drivers/gpu/drm/vc4/tests/vc4_mock_output.c | 99 ++++++++++++++ > drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 47 +++++++ > drivers/gpu/drm/vc4/vc4_crtc.c | 20 +-- > drivers/gpu/drm/vc4/vc4_drv.c | 4 +- > drivers/gpu/drm/vc4/vc4_drv.h | 16 +++ > drivers/gpu/drm/vc4/vc4_txp.c | 2 +- > 12 files changed, 511 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig > index 246305d17a52..dcdcc9e5cac4 100644 > --- a/drivers/gpu/drm/vc4/Kconfig > +++ b/drivers/gpu/drm/vc4/Kconfig > @@ -34,3 +34,18 @@ config DRM_VC4_HDMI_CEC > help > Choose this option if you have a Broadcom VC4 GPU > and want to use CEC. > + > +config DRM_VC4_KUNIT_TEST > + bool "KUnit tests for VC4" if !KUNIT_ALL_TESTS > + depends on DRM_VC4 && KUNIT > + default KUNIT_ALL_TESTS > + help > + This builds unit tests for the VC4 DRM/KMS driver. This option is > + not useful for distributions or general kernels, but only for kernel > + developers working on the VC4 driver. > + > + For more information on KUnit and unit tests in general, > + please refer to the KUnit documentation in > + Documentation/dev-tools/kunit/. > + > + If in doubt, say "N". > diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile > index d0163e18e9ca..f974a8c80e2f 100644 > --- a/drivers/gpu/drm/vc4/Makefile > +++ b/drivers/gpu/drm/vc4/Makefile > @@ -25,6 +25,12 @@ vc4-y := \ > vc4_validate.o \ > vc4_validate_shaders.o > > +vc4-$(CONFIG_DRM_VC4_KUNIT_TEST) += \ > + tests/vc4_mock.o \ > + tests/vc4_mock_crtc.o \ > + tests/vc4_mock_output.o \ > + tests/vc4_mock_plane.o > + > vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o > > obj-$(CONFIG_DRM_VC4) += vc4.o > diff --git a/drivers/gpu/drm/vc4/tests/.kunitconfig b/drivers/gpu/drm/vc4/tests/.kunitconfig > new file mode 100644 > index 000000000000..bfd9899ed6e0 > --- /dev/null > +++ b/drivers/gpu/drm/vc4/tests/.kunitconfig > @@ -0,0 +1,14 @@ > +CONFIG_ARCH_BCM=y > +CONFIG_ARCH_BCM2835=y > +CONFIG_BCM2835_MBOX=y > +CONFIG_KUNIT=y > +CONFIG_DRM=y > +CONFIG_DRM_KUNIT_TEST=y I'm not sure if it makes sense to run the DRM tests here as well. Maybe it would be better to separate the compilation of the drm_kunit_helpers from the compilation of the rest of the DRM tests. This way, this Kconfig entry could be dropped and only the vc4 tests would run. Moreover, it would allow to run the vc4 tests with --arch=arm. Best Regards, - Maíra Canal > +CONFIG_DRM_VC4=y > +CONFIG_DRM_VC4_KUNIT_TEST=y > +CONFIG_MAILBOX=y > +CONFIG_RASPBERRYPI_FIRMWARE=y > +CONFIG_SND=y > +CONFIG_SND_SOC=y > +CONFIG_SOUND=y > +CONFIG_COMMON_CLK=y > diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c b/drivers/gpu/drm/vc4/tests/vc4_mock.c > new file mode 100644 > index 000000000000..a4bed26af32f > --- /dev/null > +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c > @@ -0,0 +1,200 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <drm/drm_drv.h> > +#include <drm/drm_kunit_helpers.h> > + > +#include <kunit/test.h> > + > +#include "vc4_mock.h" > + > +struct vc4_mock_output_desc { > + enum vc4_encoder_type vc4_encoder_type; > + unsigned int encoder_type; > + unsigned int connector_type; > +}; > + > +#define VC4_MOCK_OUTPUT_DESC(_vc4_type, _etype, _ctype) \ > + { \ > + .vc4_encoder_type = _vc4_type, \ > + .encoder_type = _etype, \ > + .connector_type = _ctype, \ > + } > + > +struct vc4_mock_pipe_desc { > + const struct vc4_crtc_data *data; > + const struct vc4_mock_output_desc *outputs; > + unsigned int noutputs; > +}; > + > +#define VC4_MOCK_CRTC_DESC(_data, ...) \ > + { \ > + .data = _data, \ > + .outputs = (struct vc4_mock_output_desc[]) { __VA_ARGS__ }, \ > + .noutputs = sizeof((struct vc4_mock_output_desc[]) { __VA_ARGS__ }) / \ > + sizeof(struct vc4_mock_output_desc), \ > + } > + > +#define VC4_MOCK_PIXELVALVE_DESC(_data, ...) \ > + VC4_MOCK_CRTC_DESC(&(_data)->base, __VA_ARGS__) > + > +struct vc4_mock_desc { > + const struct vc4_mock_pipe_desc *pipes; > + unsigned int npipes; > +}; > + > +#define VC4_MOCK_DESC(...) \ > + { \ > + .pipes = (struct vc4_mock_pipe_desc[]) { __VA_ARGS__ }, \ > + .npipes = sizeof((struct vc4_mock_pipe_desc[]) { __VA_ARGS__ }) / \ > + sizeof(struct vc4_mock_pipe_desc), \ > + } > + > +static const struct vc4_mock_desc vc4_mock = > + VC4_MOCK_DESC( > + VC4_MOCK_CRTC_DESC(&vc4_txp_crtc_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_TXP, > + DRM_MODE_ENCODER_VIRTUAL, > + DRM_MODE_CONNECTOR_WRITEBACK)), > + VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv0_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI0, > + DRM_MODE_ENCODER_DSI, > + DRM_MODE_CONNECTOR_DSI), > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DPI, > + DRM_MODE_ENCODER_DPI, > + DRM_MODE_CONNECTOR_DPI)), > + VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv1_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI1, > + DRM_MODE_ENCODER_DSI, > + DRM_MODE_CONNECTOR_DSI)), > + VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv2_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_HDMI0, > + DRM_MODE_ENCODER_TMDS, > + DRM_MODE_CONNECTOR_HDMIA), > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_VEC, > + DRM_MODE_ENCODER_TVDAC, > + DRM_MODE_CONNECTOR_Composite)), > +); > + > +static const struct vc4_mock_desc vc5_mock = > + VC4_MOCK_DESC( > + VC4_MOCK_CRTC_DESC(&vc4_txp_crtc_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_TXP, > + DRM_MODE_ENCODER_VIRTUAL, > + DRM_MODE_CONNECTOR_WRITEBACK)), > + VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv0_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI0, > + DRM_MODE_ENCODER_DSI, > + DRM_MODE_CONNECTOR_DSI), > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DPI, > + DRM_MODE_ENCODER_DPI, > + DRM_MODE_CONNECTOR_DPI)), > + VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv1_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI1, > + DRM_MODE_ENCODER_DSI, > + DRM_MODE_CONNECTOR_DSI)), > + VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv2_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_HDMI0, > + DRM_MODE_ENCODER_TMDS, > + DRM_MODE_CONNECTOR_HDMIA)), > + VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv3_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_VEC, > + DRM_MODE_ENCODER_TVDAC, > + DRM_MODE_CONNECTOR_Composite)), > + VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv4_data, > + VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_HDMI1, > + DRM_MODE_ENCODER_TMDS, > + DRM_MODE_CONNECTOR_HDMIA)), > +); > + > +static int __build_one_pipe(struct kunit *test, struct drm_device *drm, > + const struct vc4_mock_pipe_desc *pipe) > +{ > + struct vc4_dummy_plane *dummy_plane; > + struct drm_plane *plane; > + struct vc4_dummy_crtc *dummy_crtc; > + struct drm_crtc *crtc; > + unsigned int i; > + > + dummy_plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane); > + > + plane = &dummy_plane->plane.base; > + dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc); > + > + crtc = &dummy_crtc->crtc.base; > + for (i = 0; i < pipe->noutputs; i++) { > + const struct vc4_mock_output_desc *mock_output = &pipe->outputs[i]; > + struct vc4_dummy_output *dummy_output; > + > + dummy_output = vc4_dummy_output(test, drm, crtc, > + mock_output->vc4_encoder_type, > + mock_output->encoder_type, > + mock_output->connector_type); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_output); > + } > + > + return 0; > +} > + > +static int __build_mock(struct kunit *test, struct drm_device *drm, > + const struct vc4_mock_desc *mock) > +{ > + unsigned int i; > + > + for (i = 0; i < mock->npipes; i++) { > + const struct vc4_mock_pipe_desc *pipe = &mock->pipes[i]; > + int ret; > + > + ret = __build_one_pipe(test, drm, pipe); > + KUNIT_ASSERT_EQ(test, ret, 0); > + } > + > + return 0; > +} > + > +static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5) > +{ > + struct drm_device *drm; > + const struct drm_driver *drv = is_vc5 ? &vc5_drm_driver : &vc4_drm_driver; > + const struct vc4_mock_desc *desc = is_vc5 ? &vc5_mock : &vc4_mock; > + struct vc4_dev *vc4; > + struct device *dev; > + int ret; > + > + dev = drm_kunit_helper_alloc_device(test); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); > + > + vc4 = drm_kunit_helper_alloc_drm_device_with_driver(test, dev, > + struct vc4_dev, base, > + drv); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4); > + > + vc4->dev = dev; > + vc4->is_vc5 = is_vc5; > + > + vc4->hvs = __vc4_hvs_alloc(vc4, NULL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4->hvs); > + > + drm = &vc4->base; > + ret = __build_mock(test, drm, desc); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + ret = vc4_kms_load(drm); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + ret = drm_dev_register(drm, 0); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + return vc4; > +} > + > +struct vc4_dev *vc4_mock_device(struct kunit *test) > +{ > + return __mock_device(test, false); > +} > + > +struct vc4_dev *vc5_mock_device(struct kunit *test) > +{ > + return __mock_device(test, true); > +} > diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.h b/drivers/gpu/drm/vc4/tests/vc4_mock.h > new file mode 100644 > index 000000000000..ace5b2e00f4a > --- /dev/null > +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.h > @@ -0,0 +1,60 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > + > +#ifndef VC4_MOCK_H_ > +#define VC4_MOCK_H_ > + > +#include "../vc4_drv.h" > + > +static inline > +struct drm_crtc *vc4_find_crtc_for_encoder(struct kunit *test, > + struct drm_device *drm, > + struct drm_encoder *encoder) > +{ > + struct drm_crtc *crtc; > + > + KUNIT_ASSERT_EQ(test, hweight32(encoder->possible_crtcs), 1); > + > + drm_for_each_crtc(crtc, drm) > + if (encoder->possible_crtcs & drm_crtc_mask(crtc)) > + return crtc; > + > + return NULL; > +} > + > +struct vc4_dummy_plane { > + struct vc4_plane plane; > +}; > + > +struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test, > + struct drm_device *drm, > + enum drm_plane_type type); > + > +struct vc4_dummy_crtc { > + struct vc4_crtc crtc; > +}; > + > +struct vc4_dummy_crtc *vc4_mock_pv(struct kunit *test, > + struct drm_device *drm, > + struct drm_plane *plane, > + const struct vc4_crtc_data *data); > + > +struct vc4_dummy_output { > + struct vc4_encoder encoder; > + struct drm_connector connector; > +}; > + > +struct vc4_dummy_output *vc4_dummy_output(struct kunit *test, > + struct drm_device *drm, > + struct drm_crtc *crtc, > + enum vc4_encoder_type vc4_encoder_type, > + unsigned int kms_encoder_type, > + unsigned int connector_type); > + > +struct vc4_dev *vc4_mock_device(struct kunit *test); > +struct vc4_dev *vc5_mock_device(struct kunit *test); > + > +int vc4_mock_atomic_add_output(struct kunit *test, struct drm_device *drm, > + enum vc4_encoder_type type, > + struct drm_atomic_state *state); > + > +#endif // VC4_MOCK_H_ > diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_crtc.c b/drivers/gpu/drm/vc4/tests/vc4_mock_crtc.c > new file mode 100644 > index 000000000000..5d12d7beef0e > --- /dev/null > +++ b/drivers/gpu/drm/vc4/tests/vc4_mock_crtc.c > @@ -0,0 +1,41 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <drm/drm_atomic_state_helper.h> > +#include <drm/drm_modeset_helper_vtables.h> > + > +#include <kunit/test.h> > + > +#include "vc4_mock.h" > + > +static const struct drm_crtc_helper_funcs vc4_dummy_crtc_helper_funcs = { > + .atomic_check = vc4_crtc_atomic_check, > +}; > + > +static const struct drm_crtc_funcs vc4_dummy_crtc_funcs = { > + .atomic_destroy_state = vc4_crtc_destroy_state, > + .atomic_duplicate_state = vc4_crtc_duplicate_state, > + .reset = vc4_crtc_reset, > +}; > + > +struct vc4_dummy_crtc *vc4_mock_pv(struct kunit *test, > + struct drm_device *drm, > + struct drm_plane *plane, > + const struct vc4_crtc_data *data) > +{ > + struct vc4_dummy_crtc *dummy_crtc; > + struct vc4_crtc *vc4_crtc; > + int ret; > + > + dummy_crtc = kunit_kzalloc(test, sizeof(*dummy_crtc), GFP_KERNEL); > + KUNIT_ASSERT_NOT_NULL(test, dummy_crtc); > + > + vc4_crtc = &dummy_crtc->crtc; > + ret = __vc4_crtc_init(drm, NULL, > + vc4_crtc, data, plane, > + &vc4_dummy_crtc_funcs, > + &vc4_dummy_crtc_helper_funcs, > + false); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + return dummy_crtc; > +} > diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c > new file mode 100644 > index 000000000000..cb16ab4451f7 > --- /dev/null > +++ b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c > @@ -0,0 +1,99 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <drm/drm_atomic_state_helper.h> > +#include <drm/drm_atomic_uapi.h> > +#include <drm/drm_connector.h> > +#include <drm/drm_crtc.h> > +#include <drm/drm_encoder.h> > +#include <drm/drm_modeset_helper_vtables.h> > + > +#include <kunit/test.h> > + > +#include "vc4_mock.h" > + > +static const struct drm_connector_helper_funcs vc4_dummy_connector_helper_funcs = { > +}; > + > +static const struct drm_connector_funcs vc4_dummy_connector_funcs = { > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .reset = drm_atomic_helper_connector_reset, > +}; > + > +struct vc4_dummy_output *vc4_dummy_output(struct kunit *test, > + struct drm_device *drm, > + struct drm_crtc *crtc, > + enum vc4_encoder_type vc4_encoder_type, > + unsigned int kms_encoder_type, > + unsigned int connector_type) > +{ > + struct vc4_dummy_output *dummy_output; > + struct drm_connector *conn; > + struct drm_encoder *enc; > + int ret; > + > + dummy_output = kunit_kzalloc(test, sizeof(*dummy_output), GFP_KERNEL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_output); > + dummy_output->encoder.type = vc4_encoder_type; > + > + enc = &dummy_output->encoder.base; > + ret = drmm_encoder_init(drm, enc, > + NULL, > + kms_encoder_type, > + NULL); > + KUNIT_ASSERT_EQ(test, ret, 0); > + enc->possible_crtcs = drm_crtc_mask(crtc); > + > + conn = &dummy_output->connector; > + ret = drmm_connector_init(drm, conn, > + &vc4_dummy_connector_funcs, > + connector_type, > + NULL); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_connector_helper_add(conn, &vc4_dummy_connector_helper_funcs); > + drm_connector_attach_encoder(conn, enc); > + > + return dummy_output; > +} > + > +static const struct drm_display_mode default_mode = { > + DRM_SIMPLE_MODE(640, 480, 64, 48) > +}; > + > +int vc4_mock_atomic_add_output(struct kunit *test, struct drm_device *drm, > + enum vc4_encoder_type type, > + struct drm_atomic_state *state) > +{ > + struct vc4_dummy_output *output; > + struct drm_connector *conn; > + struct drm_connector_state *conn_state; > + struct drm_encoder *encoder; > + struct drm_crtc *crtc; > + struct drm_crtc_state *crtc_state; > + int ret; > + > + encoder = vc4_find_encoder_by_type(drm, type); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder); > + > + crtc = vc4_find_crtc_for_encoder(test, drm, encoder); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc); > + > + output = container_of(encoder, struct vc4_dummy_output, encoder.base); > + conn = &output->connector; > + conn_state = drm_atomic_get_connector_state(state, conn); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); > + > + ret = drm_atomic_set_crtc_for_connector(conn_state, crtc); > + KUNIT_EXPECT_EQ(test, ret, 0); > + > + crtc_state = drm_atomic_get_crtc_state(state, crtc); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); > + > + ret = drm_atomic_set_mode_for_crtc(crtc_state, &default_mode); > + KUNIT_EXPECT_EQ(test, ret, 0); > + > + crtc_state->active = true; > + > + return 0; > +} > diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c > new file mode 100644 > index 000000000000..62b18f5f41db > --- /dev/null > +++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c > @@ -0,0 +1,47 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <drm/drm_atomic_state_helper.h> > +#include <drm/drm_fourcc.h> > +#include <drm/drm_modeset_helper_vtables.h> > +#include <drm/drm_plane.h> > + > +#include <kunit/test.h> > + > +#include "vc4_mock.h" > + > +static const struct drm_plane_helper_funcs vc4_dummy_plane_helper_funcs = { > +}; > + > +static const struct drm_plane_funcs vc4_dummy_plane_funcs = { > + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, > + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, > + .reset = drm_atomic_helper_plane_reset, > +}; > + > +static const uint32_t vc4_dummy_plane_formats[] = { > + DRM_FORMAT_XRGB8888, > +}; > + > +struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test, > + struct drm_device *drm, > + enum drm_plane_type type) > +{ > + struct vc4_dummy_plane *dummy_plane; > + struct drm_plane *plane; > + > + dummy_plane = drmm_universal_plane_alloc(drm, > + struct vc4_dummy_plane, plane.base, > + 0, > + &vc4_dummy_plane_funcs, > + vc4_dummy_plane_formats, > + ARRAY_SIZE(vc4_dummy_plane_formats), > + NULL, > + DRM_PLANE_TYPE_PRIMARY, > + NULL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane); > + > + plane = &dummy_plane->plane.base; > + drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs); > + > + return dummy_plane; > +} > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > index 59e473059fa2..21b40d644ace 100644 > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > @@ -675,8 +675,8 @@ void vc4_crtc_get_margins(struct drm_crtc_state *state, > } > } > > -static int vc4_crtc_atomic_check(struct drm_crtc *crtc, > - struct drm_atomic_state *state) > +int vc4_crtc_atomic_check(struct drm_crtc *crtc, > + struct drm_atomic_state *state) > { > struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, > crtc); > @@ -1116,7 +1116,7 @@ static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { > .get_scanout_position = vc4_crtc_get_scanout_position, > }; > > -static const struct vc4_pv_data bcm2835_pv0_data = { > +const struct vc4_pv_data bcm2835_pv0_data = { > .base = { > .name = "pixelvalve-0", > .debugfs_name = "crtc0_regs", > @@ -1131,7 +1131,7 @@ static const struct vc4_pv_data bcm2835_pv0_data = { > }, > }; > > -static const struct vc4_pv_data bcm2835_pv1_data = { > +const struct vc4_pv_data bcm2835_pv1_data = { > .base = { > .name = "pixelvalve-1", > .debugfs_name = "crtc1_regs", > @@ -1146,7 +1146,7 @@ static const struct vc4_pv_data bcm2835_pv1_data = { > }, > }; > > -static const struct vc4_pv_data bcm2835_pv2_data = { > +const struct vc4_pv_data bcm2835_pv2_data = { > .base = { > .name = "pixelvalve-2", > .debugfs_name = "crtc2_regs", > @@ -1161,7 +1161,7 @@ static const struct vc4_pv_data bcm2835_pv2_data = { > }, > }; > > -static const struct vc4_pv_data bcm2711_pv0_data = { > +const struct vc4_pv_data bcm2711_pv0_data = { > .base = { > .name = "pixelvalve-0", > .debugfs_name = "crtc0_regs", > @@ -1176,7 +1176,7 @@ static const struct vc4_pv_data bcm2711_pv0_data = { > }, > }; > > -static const struct vc4_pv_data bcm2711_pv1_data = { > +const struct vc4_pv_data bcm2711_pv1_data = { > .base = { > .name = "pixelvalve-1", > .debugfs_name = "crtc1_regs", > @@ -1191,7 +1191,7 @@ static const struct vc4_pv_data bcm2711_pv1_data = { > }, > }; > > -static const struct vc4_pv_data bcm2711_pv2_data = { > +const struct vc4_pv_data bcm2711_pv2_data = { > .base = { > .name = "pixelvalve-2", > .debugfs_name = "crtc2_regs", > @@ -1205,7 +1205,7 @@ static const struct vc4_pv_data bcm2711_pv2_data = { > }, > }; > > -static const struct vc4_pv_data bcm2711_pv3_data = { > +const struct vc4_pv_data bcm2711_pv3_data = { > .base = { > .name = "pixelvalve-3", > .debugfs_name = "crtc3_regs", > @@ -1219,7 +1219,7 @@ static const struct vc4_pv_data bcm2711_pv3_data = { > }, > }; > > -static const struct vc4_pv_data bcm2711_pv4_data = { > +const struct vc4_pv_data bcm2711_pv4_data = { > .base = { > .name = "pixelvalve-4", > .debugfs_name = "crtc4_regs", > diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c > index 5990d8f8c363..3b0ae2c3e33c 100644 > --- a/drivers/gpu/drm/vc4/vc4_drv.c > +++ b/drivers/gpu/drm/vc4/vc4_drv.c > @@ -196,7 +196,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = { > DRM_IOCTL_DEF_DRV(VC4_PERFMON_GET_VALUES, vc4_perfmon_get_values_ioctl, DRM_RENDER_ALLOW), > }; > > -static const struct drm_driver vc4_drm_driver = { > +const struct drm_driver vc4_drm_driver = { > .driver_features = (DRIVER_MODESET | > DRIVER_ATOMIC | > DRIVER_GEM | > @@ -225,7 +225,7 @@ static const struct drm_driver vc4_drm_driver = { > .patchlevel = DRIVER_PATCHLEVEL, > }; > > -static const struct drm_driver vc5_drm_driver = { > +const struct drm_driver vc5_drm_driver = { > .driver_features = (DRIVER_MODESET | > DRIVER_ATOMIC | > DRIVER_GEM), > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h > index e0be7a81a24a..418f4f308e36 100644 > --- a/drivers/gpu/drm/vc4/vc4_drv.h > +++ b/drivers/gpu/drm/vc4/vc4_drv.h > @@ -24,6 +24,9 @@ > struct drm_device; > struct drm_gem_object; > > +extern const struct drm_driver vc4_drm_driver; > +extern const struct drm_driver vc5_drm_driver; > + > /* Don't forget to update vc4_bo.c: bo_type_names[] when adding to > * this. > */ > @@ -523,6 +526,8 @@ struct vc4_crtc_data { > int hvs_output; > }; > > +extern const struct vc4_crtc_data vc4_txp_crtc_data; > + > struct vc4_pv_data { > struct vc4_crtc_data base; > > @@ -535,6 +540,15 @@ struct vc4_pv_data { > enum vc4_encoder_type encoder_types[4]; > }; > > +extern const struct vc4_pv_data bcm2835_pv0_data; > +extern const struct vc4_pv_data bcm2835_pv1_data; > +extern const struct vc4_pv_data bcm2835_pv2_data; > +extern const struct vc4_pv_data bcm2711_pv0_data; > +extern const struct vc4_pv_data bcm2711_pv1_data; > +extern const struct vc4_pv_data bcm2711_pv2_data; > +extern const struct vc4_pv_data bcm2711_pv3_data; > +extern const struct vc4_pv_data bcm2711_pv4_data; > + > struct vc4_crtc { > struct drm_crtc base; > struct platform_device *pdev; > @@ -920,6 +934,8 @@ int vc4_page_flip(struct drm_crtc *crtc, > struct drm_pending_vblank_event *event, > uint32_t flags, > struct drm_modeset_acquire_ctx *ctx); > +int vc4_crtc_atomic_check(struct drm_crtc *crtc, > + struct drm_atomic_state *state); > struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc); > void vc4_crtc_destroy_state(struct drm_crtc *crtc, > struct drm_crtc_state *state); > diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c > index 4f7ce5d3e8ad..2b69454b8534 100644 > --- a/drivers/gpu/drm/vc4/vc4_txp.c > +++ b/drivers/gpu/drm/vc4/vc4_txp.c > @@ -479,7 +479,7 @@ static irqreturn_t vc4_txp_interrupt(int irq, void *data) > return IRQ_HANDLED; > } > > -static const struct vc4_crtc_data vc4_txp_crtc_data = { > +const struct vc4_crtc_data vc4_txp_crtc_data = { > .name = "txp", > .debugfs_name = "txp_regs", > .hvs_available_channels = BIT(2), >
2 years, 7 months
1
0
0
0
Re: [PATCH v2 13/17] drm/vc4: crtc: Make encoder lookup helper public
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > We'll need a function that looks up an encoder by its vc4_encoder_type. > Such a function is already present in the CRTC code, so let's make it > public so that we can reuse it in the unit tests. > > Reviewed-by: Javier Martinez Canillas <javierm(a)redhat.com> > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> Reviewed-by: Maíra Canal <mcanal(a)igalia.com> Best Regards, - Maíra Canal > --- > drivers/gpu/drm/vc4/vc4_crtc.c | 17 +---------------- > drivers/gpu/drm/vc4/vc4_drv.h | 16 ++++++++++++++++ > 2 files changed, 17 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > index 7a2c54efecb0..59e473059fa2 100644 > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > @@ -486,21 +486,6 @@ static int vc4_crtc_disable(struct drm_crtc *crtc, > return 0; > } > > -static struct drm_encoder *vc4_crtc_get_encoder_by_type(struct drm_crtc *crtc, > - enum vc4_encoder_type type) > -{ > - struct drm_encoder *encoder; > - > - drm_for_each_encoder(encoder, crtc->dev) { > - struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); > - > - if (vc4_encoder->type == type) > - return encoder; > - } > - > - return NULL; > -} > - > int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) > { > struct drm_device *drm = crtc->dev; > @@ -536,7 +521,7 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) > > pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc); > encoder_type = pv_data->encoder_types[encoder_sel]; > - encoder = vc4_crtc_get_encoder_by_type(crtc, encoder_type); > + encoder = vc4_find_encoder_by_type(drm, encoder_type); > if (WARN_ON(!encoder)) > return 0; > > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h > index cd2002fff115..54352db48476 100644 > --- a/drivers/gpu/drm/vc4/vc4_drv.h > +++ b/drivers/gpu/drm/vc4/vc4_drv.h > @@ -495,6 +495,22 @@ to_vc4_encoder(const struct drm_encoder *encoder) > return container_of(encoder, struct vc4_encoder, base); > } > > +static inline > +struct drm_encoder *vc4_find_encoder_by_type(struct drm_device *drm, > + enum vc4_encoder_type type) > +{ > + struct drm_encoder *encoder; > + > + drm_for_each_encoder(encoder, drm) { > + struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); > + > + if (vc4_encoder->type == type) > + return encoder; > + } > + > + return NULL; > +} > + > struct vc4_crtc_data { > const char *name; > >
2 years, 7 months
1
0
0
0
Re: [PATCH v2 12/17] drm/vc4: crtc: Introduce a lower-level crtc init helper
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > The current vc4_crtc_init() helper assumes that we will be using > hardware planes and calls vc4_plane_init(). > > While it's a reasonable assumption, we'll want to mock the plane and > thus provide our own. Let's create a helper that will take the plane as > an argument. > > Reviewed-by: Javier Martinez Canillas <javierm(a)redhat.com> > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> Although the commit message explains a bit about why __vc4_crtc_init is being created, it would be nice to add a comment in the code explaining that __vc4_crtc_init can be used for tests as it allows mocking the plane. This way the distinction between vc4_crtc_init and __vc4_crtc_init will be cleaner to the reader. Reviewed-by: Maíra Canal <mcanal(a)igalia.com> Best Regards, - Maíra Canal > --- > drivers/gpu/drm/vc4/vc4_crtc.c | 52 +++++++++++++++++++++++++++--------------- > drivers/gpu/drm/vc4/vc4_drv.h | 6 +++++ > 2 files changed, 39 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > index 333529ed3a0d..7a2c54efecb0 100644 > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > @@ -1286,31 +1286,20 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm, > } > } > > -int vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev, > - struct vc4_crtc *vc4_crtc, > - const struct vc4_crtc_data *data, > - const struct drm_crtc_funcs *crtc_funcs, > - const struct drm_crtc_helper_funcs *crtc_helper_funcs, > - bool feeds_txp) > +int __vc4_crtc_init(struct drm_device *drm, > + struct platform_device *pdev, > + struct vc4_crtc *vc4_crtc, > + const struct vc4_crtc_data *data, > + struct drm_plane *primary_plane, > + const struct drm_crtc_funcs *crtc_funcs, > + const struct drm_crtc_helper_funcs *crtc_helper_funcs, > + bool feeds_txp) > { > struct vc4_dev *vc4 = to_vc4_dev(drm); > struct drm_crtc *crtc = &vc4_crtc->base; > - struct drm_plane *primary_plane; > unsigned int i; > int ret; > > - /* For now, we create just the primary and the legacy cursor > - * planes. We should be able to stack more planes on easily, > - * but to do that we would need to compute the bandwidth > - * requirement of the plane configuration, and reject ones > - * that will take too much. > - */ > - primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, 0); > - if (IS_ERR(primary_plane)) { > - dev_err(drm->dev, "failed to construct primary plane\n"); > - return PTR_ERR(primary_plane); > - } > - > vc4_crtc->data = data; > vc4_crtc->pdev = pdev; > vc4_crtc->feeds_txp = feeds_txp; > @@ -1342,6 +1331,31 @@ int vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev, > return 0; > } > > +int vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev, > + struct vc4_crtc *vc4_crtc, > + const struct vc4_crtc_data *data, > + const struct drm_crtc_funcs *crtc_funcs, > + const struct drm_crtc_helper_funcs *crtc_helper_funcs, > + bool feeds_txp) > +{ > + struct drm_plane *primary_plane; > + > + /* For now, we create just the primary and the legacy cursor > + * planes. We should be able to stack more planes on easily, > + * but to do that we would need to compute the bandwidth > + * requirement of the plane configuration, and reject ones > + * that will take too much. > + */ > + primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, 0); > + if (IS_ERR(primary_plane)) { > + dev_err(drm->dev, "failed to construct primary plane\n"); > + return PTR_ERR(primary_plane); > + } > + > + return __vc4_crtc_init(drm, pdev, vc4_crtc, data, primary_plane, > + crtc_funcs, crtc_helper_funcs, feeds_txp); > +} > + > static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) > { > struct platform_device *pdev = to_platform_device(dev); > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h > index 051c2e3b6d43..cd2002fff115 100644 > --- a/drivers/gpu/drm/vc4/vc4_drv.h > +++ b/drivers/gpu/drm/vc4/vc4_drv.h > @@ -888,6 +888,12 @@ int vc4_bo_debugfs_init(struct drm_minor *minor); > /* vc4_crtc.c */ > extern struct platform_driver vc4_crtc_driver; > int vc4_crtc_disable_at_boot(struct drm_crtc *crtc); > +int __vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev, > + struct vc4_crtc *vc4_crtc, const struct vc4_crtc_data *data, > + struct drm_plane *primary_plane, > + const struct drm_crtc_funcs *crtc_funcs, > + const struct drm_crtc_helper_funcs *crtc_helper_funcs, > + bool feeds_txp); > int vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev, > struct vc4_crtc *vc4_crtc, const struct vc4_crtc_data *data, > const struct drm_crtc_funcs *crtc_funcs, >
2 years, 7 months
1
0
0
0
Re: [PATCH v2 11/17] drm/vc4: Move HVS state to main header
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > In order to introduce unit tests for the HVS state computation, we'll > need access to the vc4_hvs_state struct definition and its associated > helpers. > > Let's move them in our driver header. > > Reviewed-by: Javier Martinez Canillas <javierm(a)redhat.com> > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> Reviewed-by: Maíra Canal <mcanal(a)igalia.com> Best Regards, - Maíra Canal > --- > drivers/gpu/drm/vc4/vc4_drv.h | 23 +++++++++++++++++++++++ > drivers/gpu/drm/vc4/vc4_kms.c | 25 +++---------------------- > 2 files changed, 26 insertions(+), 22 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h > index 6af615c2eb65..051c2e3b6d43 100644 > --- a/drivers/gpu/drm/vc4/vc4_drv.h > +++ b/drivers/gpu/drm/vc4/vc4_drv.h > @@ -355,6 +355,29 @@ struct vc4_hvs { > bool vc5_hdmi_enable_4096by2160; > }; > > +#define HVS_NUM_CHANNELS 3 > + > +struct vc4_hvs_state { > + struct drm_private_state base; > + unsigned long core_clock_rate; > + > + struct { > + unsigned in_use: 1; > + unsigned long fifo_load; > + struct drm_crtc_commit *pending_commit; > + } fifo_state[HVS_NUM_CHANNELS]; > +}; > + > +static inline struct vc4_hvs_state * > +to_vc4_hvs_state(const struct drm_private_state *priv) > +{ > + return container_of(priv, struct vc4_hvs_state, base); > +} > + > +struct vc4_hvs_state *vc4_hvs_get_global_state(struct drm_atomic_state *state); > +struct vc4_hvs_state *vc4_hvs_get_old_global_state(const struct drm_atomic_state *state); > +struct vc4_hvs_state *vc4_hvs_get_new_global_state(const struct drm_atomic_state *state); > + > struct vc4_plane { > struct drm_plane base; > }; > diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c > index 7282545c54a1..53d9f30460cf 100644 > --- a/drivers/gpu/drm/vc4/vc4_kms.c > +++ b/drivers/gpu/drm/vc4/vc4_kms.c > @@ -25,8 +25,6 @@ > #include "vc4_drv.h" > #include "vc4_regs.h" > > -#define HVS_NUM_CHANNELS 3 > - > struct vc4_ctm_state { > struct drm_private_state base; > struct drm_color_ctm *ctm; > @@ -39,23 +37,6 @@ to_vc4_ctm_state(const struct drm_private_state *priv) > return container_of(priv, struct vc4_ctm_state, base); > } > > -struct vc4_hvs_state { > - struct drm_private_state base; > - unsigned long core_clock_rate; > - > - struct { > - unsigned in_use: 1; > - unsigned long fifo_load; > - struct drm_crtc_commit *pending_commit; > - } fifo_state[HVS_NUM_CHANNELS]; > -}; > - > -static struct vc4_hvs_state * > -to_vc4_hvs_state(const struct drm_private_state *priv) > -{ > - return container_of(priv, struct vc4_hvs_state, base); > -} > - > struct vc4_load_tracker_state { > struct drm_private_state base; > u64 hvs_load; > @@ -191,7 +172,7 @@ vc4_ctm_commit(struct vc4_dev *vc4, struct drm_atomic_state *state) > VC4_SET_FIELD(ctm_state->fifo, SCALER_OLEDOFFS_DISPFIFO)); > } > > -static struct vc4_hvs_state * > +struct vc4_hvs_state * > vc4_hvs_get_new_global_state(const struct drm_atomic_state *state) > { > struct vc4_dev *vc4 = to_vc4_dev(state->dev); > @@ -204,7 +185,7 @@ vc4_hvs_get_new_global_state(const struct drm_atomic_state *state) > return to_vc4_hvs_state(priv_state); > } > > -static struct vc4_hvs_state * > +struct vc4_hvs_state * > vc4_hvs_get_old_global_state(const struct drm_atomic_state *state) > { > struct vc4_dev *vc4 = to_vc4_dev(state->dev); > @@ -217,7 +198,7 @@ vc4_hvs_get_old_global_state(const struct drm_atomic_state *state) > return to_vc4_hvs_state(priv_state); > } > > -static struct vc4_hvs_state * > +struct vc4_hvs_state * > vc4_hvs_get_global_state(struct drm_atomic_state *state) > { > struct vc4_dev *vc4 = to_vc4_dev(state->dev); >
2 years, 7 months
1
0
0
0
Re: [PATCH v2 10/17] drm/tests: Add a test for DRM managed actions
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > DRM-managed actions are supposed to be ran whenever the device is > released. Let's introduce a basic unit test to make sure it happens. > > Reviewed-by: Javier Martinez Canillas <javierm(a)redhat.com> > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> Reviewed-by: Maíra Canal <mcanal(a)igalia.com> Best Regards, - Maíra Canal > --- > drivers/gpu/drm/tests/Makefile | 1 + > drivers/gpu/drm/tests/drm_managed_test.c | 71 ++++++++++++++++++++++++++++++++ > 2 files changed, 72 insertions(+) > > diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile > index 94fe546d937d..486053052ba9 100644 > --- a/drivers/gpu/drm/tests/Makefile > +++ b/drivers/gpu/drm/tests/Makefile > @@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST) += \ > drm_format_test.o \ > drm_framebuffer_test.o \ > drm_kunit_helpers.o \ > + drm_managed_test.o \ > drm_mm_test.o \ > drm_modes_test.o \ > drm_plane_helper_test.o \ > diff --git a/drivers/gpu/drm/tests/drm_managed_test.c b/drivers/gpu/drm/tests/drm_managed_test.c > new file mode 100644 > index 000000000000..1652dca11d30 > --- /dev/null > +++ b/drivers/gpu/drm/tests/drm_managed_test.c > @@ -0,0 +1,71 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <drm/drm_drv.h> > +#include <drm/drm_kunit_helpers.h> > +#include <drm/drm_managed.h> > + > +#include <kunit/resource.h> > + > +#include <linux/device.h> > + > +/* Ought to be enough for anybody */ > +#define TEST_TIMEOUT_MS 100 > + > +struct managed_test_priv { > + bool action_done; > + wait_queue_head_t action_wq; > +}; > + > +static void drm_action(struct drm_device *drm, void *ptr) > +{ > + struct managed_test_priv *priv = ptr; > + > + priv->action_done = true; > + wake_up_interruptible(&priv->action_wq); > +} > + > +static void drm_test_managed_run_action(struct kunit *test) > +{ > + struct managed_test_priv *priv; > + struct drm_device *drm; > + struct device *dev; > + int ret; > + > + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); > + init_waitqueue_head(&priv->action_wq); > + > + dev = drm_kunit_helper_alloc_device(test); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); > + > + drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm); > + > + ret = drmm_add_action_or_reset(drm, drm_action, priv); > + KUNIT_EXPECT_EQ(test, ret, 0); > + > + ret = drm_dev_register(drm, 0); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_dev_unregister(drm); > + drm_kunit_helper_free_device(test, dev); > + > + ret = wait_event_interruptible_timeout(priv->action_wq, priv->action_done, > + msecs_to_jiffies(TEST_TIMEOUT_MS)); > + KUNIT_EXPECT_GT(test, ret, 0); > +} > + > +static struct kunit_case drm_managed_tests[] = { > + KUNIT_CASE(drm_test_managed_run_action), > + {} > +}; > + > +static struct kunit_suite drm_managed_test_suite = { > + .name = "drm-test-managed", > + .test_cases = drm_managed_tests > +}; > + > +kunit_test_suite(drm_managed_test_suite); > + > +MODULE_AUTHOR("Maxime Ripard <maxime(a)cerno.tech>"); > +MODULE_LICENSE("GPL"); >
2 years, 7 months
1
0
0
0
Re: [PATCH v2 07/17] drm/tests: helpers: Make sure the device is bound
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > The device managed resources are freed when the device is detached, so > it has to be bound in the first place. > > Let's create a fake driver that we will bind to our fake device to > benefit from the device managed cleanups in our tests. > > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> Reviewed-by: Maíra Canal <mcanal(a)igalia.com> Best Regards, - Maíra Canal > --- > drivers/gpu/drm/tests/drm_kunit_helpers.c | 26 +++++++++++++++++++++++++- > 1 file changed, 25 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c > index 15678ab823b0..5d3e29353d1a 100644 > --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c > +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c > @@ -18,12 +18,32 @@ struct kunit_dev { > static const struct drm_mode_config_funcs drm_mode_config_funcs = { > }; > > +static int fake_probe(struct platform_device *pdev) > +{ > + return 0; > +} > + > +static int fake_remove(struct platform_device *pdev) > +{ > + return 0; > +} > + > +static struct platform_driver fake_platform_driver = { > + .probe = fake_probe, > + .remove = fake_remove, > + .driver = { > + .name = KUNIT_DEVICE_NAME, > + }, > +}; > + > /** > * drm_kunit_helper_alloc_device - Allocate a mock device for a KUnit test > * @test: The test context object > * > * This allocates a fake struct &device to create a mock for a Kunit > - * test. > + * test. The device will also be bound to a fake driver. It will thus be > + * able to leverage the usual infrastructure and most notably the > + * device-managed resources just like a "real" device. > * > * Callers need to make sure drm_kunit_helper_free_device() on the > * device when done. > @@ -36,6 +56,9 @@ struct device *drm_kunit_helper_alloc_device(struct kunit *test) > struct platform_device *pdev; > int ret; > > + ret = platform_driver_register(&fake_platform_driver); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > pdev = platform_device_alloc(KUNIT_DEVICE_NAME, PLATFORM_DEVID_NONE); > KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); > > @@ -58,6 +81,7 @@ void drm_kunit_helper_free_device(struct kunit *test, struct device *dev) > struct platform_device *pdev = to_platform_device(dev); > > platform_device_unregister(pdev); > + platform_driver_unregister(&fake_platform_driver); > } > EXPORT_SYMBOL(drm_kunit_helper_free_device); > >
2 years, 7 months
1
0
0
0
Re: [PATCH v2 06/17] drm/tests: helpers: Switch to a platform_device
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > The device managed resources are ran if the device has bus, which is not > the case of a root_device. > > Let's use a platform_device instead. > > Reviewed-by: Javier Martinez Canillas <javierm(a)redhat.com> > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> Reviewed-by: Maíra Canal <mcanal(a)igalia.com> Best Regards, - Maíra Canal > --- > drivers/gpu/drm/tests/drm_kunit_helpers.c | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c > index 9fb045fa685f..15678ab823b0 100644 > --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c > +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c > @@ -7,6 +7,7 @@ > #include <kunit/resource.h> > > #include <linux/device.h> > +#include <linux/platform_device.h> > > #define KUNIT_DEVICE_NAME "drm-kunit-mock-device" > > @@ -32,7 +33,16 @@ static const struct drm_mode_config_funcs drm_mode_config_funcs = { > */ > struct device *drm_kunit_helper_alloc_device(struct kunit *test) > { > - return root_device_register(KUNIT_DEVICE_NAME); > + struct platform_device *pdev; > + int ret; > + > + pdev = platform_device_alloc(KUNIT_DEVICE_NAME, PLATFORM_DEVID_NONE); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); > + > + ret = platform_device_add(pdev); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + return &pdev->dev; > } > EXPORT_SYMBOL(drm_kunit_helper_alloc_device); > > @@ -45,7 +55,9 @@ EXPORT_SYMBOL(drm_kunit_helper_alloc_device); > */ > void drm_kunit_helper_free_device(struct kunit *test, struct device *dev) > { > - root_device_unregister(dev); > + struct platform_device *pdev = to_platform_device(dev); > + > + platform_device_unregister(pdev); > } > EXPORT_SYMBOL(drm_kunit_helper_free_device); > >
2 years, 7 months
1
0
0
0
Re: [PATCH v2 05/17] drm/tests: helpers: Create the device in another function
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > We'll need in some tests to control when the device needs to be added > and removed, so let's split the device creation from the DRM device > creation function. > > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> Just a small nit below, Reviewed-by: Maíra Canal <mcanal(a)igalia.com> > > diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c b/drivers/gpu/drm/tests/drm_probe_helper_test.c > index be61a92b79d2..438b1d42b843 100644 > --- a/drivers/gpu/drm/tests/drm_probe_helper_test.c > +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c > @@ -17,6 +17,7 @@ > > struct drm_probe_helper_test_priv { > struct drm_device *drm; > + struct device *dev; > struct drm_connector connector; > }; > > @@ -39,7 +40,10 @@ static int drm_probe_helper_test_init(struct kunit *test) > KUNIT_ASSERT_NOT_NULL(test, priv); > test->priv = priv; > > - priv->drm = drm_kunit_helper_alloc_drm_device(test, > + priv->dev = drm_kunit_helper_alloc_device(test); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev); > + > + priv->drm = drm_kunit_helper_alloc_drm_device(test, priv->dev, > DRIVER_MODESET | DRIVER_ATOMIC); > KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > > @@ -55,6 +59,13 @@ static int drm_probe_helper_test_init(struct kunit *test) > return 0; > } > > +static void drm_probe_helper_test_exit(struct kunit *test) > +{ > + struct drm_probe_helper_test_priv *priv = test->priv;; There are two semicolons by the end of this statement. Best Regards, - Maíra Canal > + > + drm_kunit_helper_free_device(test, priv->dev); > +} > + > typedef struct drm_display_mode *(*expected_mode_func_t)(struct drm_device *); > > struct drm_connector_helper_tv_get_modes_test { > @@ -195,6 +206,7 @@ static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = { > static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = { > .name = "drm_connector_helper_tv_get_modes", > .init = drm_probe_helper_test_init, > + .exit = drm_probe_helper_test_exit, > .test_cases = drm_test_connector_helper_tv_get_modes_tests, > }; > > diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h > index 6c12b1426ba0..b4277fe92c38 100644 > --- a/include/drm/drm_kunit_helpers.h > +++ b/include/drm/drm_kunit_helpers.h > @@ -6,8 +6,11 @@ > struct drm_device; > struct kunit; > > +struct device *drm_kunit_helper_alloc_device(struct kunit *test); > +void drm_kunit_helper_free_device(struct kunit *test, struct device *dev); > + > struct drm_device * > -drm_kunit_helper_alloc_drm_device(struct kunit *test, > +drm_kunit_helper_alloc_drm_device(struct kunit *test, struct device *dev, > u32 features); > > #endif // DRM_KUNIT_HELPERS_H_ >
2 years, 7 months
1
0
0
0
Re: [PATCH v2 04/17] drm/tests: helpers: Remove the name parameter
by Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote: > The device name isn't really useful, we can just define it instead of > exposing it in the API. > > Signed-off-by: Maxime Ripard <maxime(a)cerno.tech> Reviewed-by: Maíra Canal <mcanal(a)igalia.com> Best Regards - Maíra Canal > --- > drivers/gpu/drm/tests/drm_client_modeset_test.c | 3 +-- > drivers/gpu/drm/tests/drm_kunit_helpers.c | 7 ++++--- > drivers/gpu/drm/tests/drm_modes_test.c | 3 +-- > drivers/gpu/drm/tests/drm_probe_helper_test.c | 3 +-- > include/drm/drm_kunit_helpers.h | 3 +-- > 5 files changed, 8 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/tests/drm_client_modeset_test.c b/drivers/gpu/drm/tests/drm_client_modeset_test.c > index 6cdf08f582ce..4d475ae6dbb6 100644 > --- a/drivers/gpu/drm/tests/drm_client_modeset_test.c > +++ b/drivers/gpu/drm/tests/drm_client_modeset_test.c > @@ -59,8 +59,7 @@ static int drm_client_modeset_test_init(struct kunit *test) > > test->priv = priv; > > - priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET, > - "drm-client-modeset-test"); > + priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET); > KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > > ret = drmm_connector_init(priv->drm, &priv->connector, > diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c > index 2f67f6cf78d0..16c7926d83c2 100644 > --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c > +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c > @@ -8,6 +8,8 @@ > > #include <linux/device.h> > > +#define KUNIT_DEVICE_NAME "drm-kunit-mock-device" > + > struct kunit_dev { > struct drm_device base; > }; > @@ -39,7 +41,6 @@ static void dev_free(struct kunit_resource *res) > * drm_kunit_helper_alloc_drm_device - Allocates a mock DRM device for Kunit tests > * @test: The test context object > * @features: Mocked DRM device driver features > - * @name: Name of the struct &device to allocate > * > * This function allocates a new struct &device, creates a struct > * &drm_driver and will create a struct &drm_device using both. > @@ -54,7 +55,7 @@ static void dev_free(struct kunit_resource *res) > */ > struct drm_device * > drm_kunit_helper_alloc_drm_device(struct kunit *test, > - u32 features, char *name) > + u32 features) > { > struct kunit_dev *kdev; > struct drm_device *drm; > @@ -62,7 +63,7 @@ drm_kunit_helper_alloc_drm_device(struct kunit *test, > struct device *dev; > int ret; > > - dev = kunit_alloc_resource(test, dev_init, dev_free, GFP_KERNEL, name); > + dev = kunit_alloc_resource(test, dev_init, dev_free, GFP_KERNEL, KUNIT_DEVICE_NAME); > if (!dev) > return ERR_PTR(-ENOMEM); > > diff --git a/drivers/gpu/drm/tests/drm_modes_test.c b/drivers/gpu/drm/tests/drm_modes_test.c > index 6723089dff9f..35965ad86188 100644 > --- a/drivers/gpu/drm/tests/drm_modes_test.c > +++ b/drivers/gpu/drm/tests/drm_modes_test.c > @@ -22,8 +22,7 @@ static int drm_test_modes_init(struct kunit *test) > priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); > KUNIT_ASSERT_NOT_NULL(test, priv); > > - priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET, > - "drm-modes-test"); > + priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET); > KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > > test->priv = priv; > diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c b/drivers/gpu/drm/tests/drm_probe_helper_test.c > index 85236ff4744f..be61a92b79d2 100644 > --- a/drivers/gpu/drm/tests/drm_probe_helper_test.c > +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c > @@ -40,8 +40,7 @@ static int drm_probe_helper_test_init(struct kunit *test) > test->priv = priv; > > priv->drm = drm_kunit_helper_alloc_drm_device(test, > - DRIVER_MODESET | DRIVER_ATOMIC, > - "drm-probe-helper-test"); > + DRIVER_MODESET | DRIVER_ATOMIC); > KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > > connector = &priv->connector; > diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h > index e9870c7911fe..6c12b1426ba0 100644 > --- a/include/drm/drm_kunit_helpers.h > +++ b/include/drm/drm_kunit_helpers.h > @@ -8,7 +8,6 @@ struct kunit; > > struct drm_device * > drm_kunit_helper_alloc_drm_device(struct kunit *test, > - u32 features, > - char *name); > + u32 features); > > #endif // DRM_KUNIT_HELPERS_H_ >
2 years, 7 months
1
0
0
0
← Newer
1
...
680
681
682
683
684
685
686
...
1280
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
Results per page:
10
25
50
100
200