201 lines
5.7 KiB
C
201 lines
5.7 KiB
C
|
// 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);
|
||
|
}
|