208 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#include <drm/drm_drv.h>4#include <drm/drm_kunit_helpers.h>5 6#include <kunit/test.h>7 8#include "vc4_mock.h"9 10struct vc4_mock_output_desc {11 enum vc4_encoder_type vc4_encoder_type;12 unsigned int encoder_type;13 unsigned int connector_type;14};15 16#define VC4_MOCK_OUTPUT_DESC(_vc4_type, _etype, _ctype) \17 { \18 .vc4_encoder_type = _vc4_type, \19 .encoder_type = _etype, \20 .connector_type = _ctype, \21 }22 23struct vc4_mock_pipe_desc {24 const struct vc4_crtc_data *data;25 const struct vc4_mock_output_desc *outputs;26 unsigned int noutputs;27};28 29#define VC4_MOCK_CRTC_DESC(_data, ...) \30 { \31 .data = _data, \32 .outputs = (struct vc4_mock_output_desc[]) { __VA_ARGS__ }, \33 .noutputs = sizeof((struct vc4_mock_output_desc[]) { __VA_ARGS__ }) / \34 sizeof(struct vc4_mock_output_desc), \35 }36 37#define VC4_MOCK_PIXELVALVE_DESC(_data, ...) \38 VC4_MOCK_CRTC_DESC(&(_data)->base, __VA_ARGS__)39 40struct vc4_mock_desc {41 const struct vc4_mock_pipe_desc *pipes;42 unsigned int npipes;43};44 45#define VC4_MOCK_DESC(...) \46 { \47 .pipes = (struct vc4_mock_pipe_desc[]) { __VA_ARGS__ }, \48 .npipes = sizeof((struct vc4_mock_pipe_desc[]) { __VA_ARGS__ }) / \49 sizeof(struct vc4_mock_pipe_desc), \50 }51 52static const struct vc4_mock_desc vc4_mock =53 VC4_MOCK_DESC(54 VC4_MOCK_CRTC_DESC(&vc4_txp_crtc_data,55 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_TXP,56 DRM_MODE_ENCODER_VIRTUAL,57 DRM_MODE_CONNECTOR_WRITEBACK)),58 VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv0_data,59 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI0,60 DRM_MODE_ENCODER_DSI,61 DRM_MODE_CONNECTOR_DSI),62 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DPI,63 DRM_MODE_ENCODER_DPI,64 DRM_MODE_CONNECTOR_DPI)),65 VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv1_data,66 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI1,67 DRM_MODE_ENCODER_DSI,68 DRM_MODE_CONNECTOR_DSI)),69 VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv2_data,70 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_HDMI0,71 DRM_MODE_ENCODER_TMDS,72 DRM_MODE_CONNECTOR_HDMIA),73 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_VEC,74 DRM_MODE_ENCODER_TVDAC,75 DRM_MODE_CONNECTOR_Composite)),76);77 78static const struct vc4_mock_desc vc5_mock =79 VC4_MOCK_DESC(80 VC4_MOCK_CRTC_DESC(&vc4_txp_crtc_data,81 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_TXP,82 DRM_MODE_ENCODER_VIRTUAL,83 DRM_MODE_CONNECTOR_WRITEBACK)),84 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv0_data,85 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI0,86 DRM_MODE_ENCODER_DSI,87 DRM_MODE_CONNECTOR_DSI),88 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DPI,89 DRM_MODE_ENCODER_DPI,90 DRM_MODE_CONNECTOR_DPI)),91 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv1_data,92 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI1,93 DRM_MODE_ENCODER_DSI,94 DRM_MODE_CONNECTOR_DSI)),95 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv2_data,96 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_HDMI0,97 DRM_MODE_ENCODER_TMDS,98 DRM_MODE_CONNECTOR_HDMIA)),99 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv3_data,100 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_VEC,101 DRM_MODE_ENCODER_TVDAC,102 DRM_MODE_CONNECTOR_Composite)),103 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv4_data,104 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_HDMI1,105 DRM_MODE_ENCODER_TMDS,106 DRM_MODE_CONNECTOR_HDMIA)),107);108 109static int __build_one_pipe(struct kunit *test, struct drm_device *drm,110 const struct vc4_mock_pipe_desc *pipe)111{112 struct drm_plane *plane;113 struct vc4_dummy_crtc *dummy_crtc;114 struct drm_crtc *crtc;115 unsigned int i;116 117 plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);118 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);119 120 dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data);121 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc);122 123 crtc = &dummy_crtc->crtc.base;124 for (i = 0; i < pipe->noutputs; i++) {125 const struct vc4_mock_output_desc *mock_output = &pipe->outputs[i];126 struct vc4_dummy_output *dummy_output;127 128 dummy_output = vc4_dummy_output(test, drm, crtc,129 mock_output->vc4_encoder_type,130 mock_output->encoder_type,131 mock_output->connector_type);132 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_output);133 }134 135 return 0;136}137 138static int __build_mock(struct kunit *test, struct drm_device *drm,139 const struct vc4_mock_desc *mock)140{141 unsigned int i;142 143 for (i = 0; i < mock->npipes; i++) {144 const struct vc4_mock_pipe_desc *pipe = &mock->pipes[i];145 int ret;146 147 ret = __build_one_pipe(test, drm, pipe);148 KUNIT_ASSERT_EQ(test, ret, 0);149 }150 151 return 0;152}153 154KUNIT_DEFINE_ACTION_WRAPPER(kunit_action_drm_dev_unregister,155 drm_dev_unregister,156 struct drm_device *);157 158static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5)159{160 struct drm_device *drm;161 const struct drm_driver *drv = is_vc5 ? &vc5_drm_driver : &vc4_drm_driver;162 const struct vc4_mock_desc *desc = is_vc5 ? &vc5_mock : &vc4_mock;163 struct vc4_dev *vc4;164 struct device *dev;165 int ret;166 167 dev = drm_kunit_helper_alloc_device(test);168 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);169 170 vc4 = drm_kunit_helper_alloc_drm_device_with_driver(test, dev,171 struct vc4_dev, base,172 drv);173 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);174 175 vc4->dev = dev;176 vc4->is_vc5 = is_vc5;177 178 vc4->hvs = __vc4_hvs_alloc(vc4, NULL);179 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4->hvs);180 181 drm = &vc4->base;182 ret = __build_mock(test, drm, desc);183 KUNIT_ASSERT_EQ(test, ret, 0);184 185 ret = vc4_kms_load(drm);186 KUNIT_ASSERT_EQ(test, ret, 0);187 188 ret = drm_dev_register(drm, 0);189 KUNIT_ASSERT_EQ(test, ret, 0);190 191 ret = kunit_add_action_or_reset(test,192 kunit_action_drm_dev_unregister,193 drm);194 KUNIT_ASSERT_EQ(test, ret, 0);195 196 return vc4;197}198 199struct vc4_dev *vc4_mock_device(struct kunit *test)200{201 return __mock_device(test, false);202}203 204struct vc4_dev *vc5_mock_device(struct kunit *test)205{206 return __mock_device(test, true);207}208