diff options
Diffstat (limited to 'drivers/gpu/drm/vc4/tests/vc4_mock.c')
-rw-r--r-- | drivers/gpu/drm/vc4/tests/vc4_mock.c | 200 |
1 files changed, 200 insertions, 0 deletions
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); +} |