Commit 24c5ed3d authored by Maxime Ripard's avatar Maxime Ripard Committed by Dave Stevenson
Browse files

drm/vc4: Introduce generation number enum



With the introduction of the BCM2712 support, we will get yet another
generation of display engine to support.

The binary check of whether it's VC5 or not thus doesn't work anymore,
especially since some parts of the driver will have changed with BCM2711,
and some others with BCM2712.

Let's introduce an enum to store the generation the driver is running
on, which should provide more flexibility.

Signed-off-by: default avatarMaxime Ripard <mripard@kernel.org>
Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-21-dave.stevenson@raspberrypi.com


Signed-off-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
parent 1330d28d
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -155,11 +155,11 @@ KUNIT_DEFINE_ACTION_WRAPPER(kunit_action_drm_dev_unregister,
			    drm_dev_unregister,
			    struct drm_device *);

static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5)
static struct vc4_dev *__mock_device(struct kunit *test, enum vc4_gen gen)
{
	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;
	const struct drm_driver *drv = (gen == VC4_GEN_5) ? &vc5_drm_driver : &vc4_drm_driver;
	const struct vc4_mock_desc *desc = (gen == VC4_GEN_5) ? &vc5_mock : &vc4_mock;
	struct vc4_dev *vc4;
	struct device *dev;
	int ret;
@@ -173,7 +173,7 @@ static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5)
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);

	vc4->dev = dev;
	vc4->is_vc5 = is_vc5;
	vc4->gen = gen;

	vc4->hvs = __vc4_hvs_alloc(vc4, NULL);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4->hvs);
@@ -198,10 +198,10 @@ static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5)

struct vc4_dev *vc4_mock_device(struct kunit *test)
{
	return __mock_device(test, false);
	return __mock_device(test, VC4_GEN_4);
}

struct vc4_dev *vc5_mock_device(struct kunit *test)
{
	return __mock_device(test, true);
	return __mock_device(test, VC4_GEN_5);
}
+14 −14
Original line number Diff line number Diff line
@@ -251,7 +251,7 @@ void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo)
{
	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return;

	mutex_lock(&vc4->purgeable.lock);
@@ -265,7 +265,7 @@ static void vc4_bo_remove_from_purgeable_pool_locked(struct vc4_bo *bo)
{
	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return;

	/* list_del_init() is used here because the caller might release
@@ -396,7 +396,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_bo *bo;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return ERR_PTR(-ENODEV);

	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
@@ -427,7 +427,7 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
	struct drm_gem_dma_object *dma_obj;
	struct vc4_bo *bo;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return ERR_PTR(-ENODEV);

	if (size == 0)
@@ -496,7 +496,7 @@ int vc4_bo_dumb_create(struct drm_file *file_priv,
	struct vc4_bo *bo = NULL;
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	ret = vc4_dumb_fixup_args(args);
@@ -622,7 +622,7 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo)
	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	/* Fast path: if the BO is already retained by someone, no need to
@@ -661,7 +661,7 @@ void vc4_bo_dec_usecnt(struct vc4_bo *bo)
{
	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return;

	/* Fast path: if the BO is still retained by someone, no need to test
@@ -783,7 +783,7 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
	struct vc4_bo *bo = NULL;
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	ret = vc4_grab_bin_bo(vc4, vc4file);
@@ -813,7 +813,7 @@ int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
	struct drm_vc4_mmap_bo *args = data;
	struct drm_gem_object *gem_obj;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	gem_obj = drm_gem_object_lookup(file_priv, args->handle);
@@ -839,7 +839,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
	struct vc4_bo *bo = NULL;
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	if (args->size == 0)
@@ -918,7 +918,7 @@ int vc4_set_tiling_ioctl(struct drm_device *dev, void *data,
	struct vc4_bo *bo;
	bool t_format;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	if (args->flags != 0)
@@ -964,7 +964,7 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
	struct drm_gem_object *gem_obj;
	struct vc4_bo *bo;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	if (args->flags != 0 || args->modifier != 0)
@@ -1007,7 +1007,7 @@ int vc4_bo_cache_init(struct drm_device *dev)
	int ret;
	int i;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	/* Create the initial set of BO labels that the kernel will
@@ -1071,7 +1071,7 @@ int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
	struct drm_gem_object *gem_obj;
	int ret = 0, label;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	if (!args->len)
+6 −7
Original line number Diff line number Diff line
@@ -264,7 +264,7 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format)
		 * Removing 1 from the FIFO full level however
		 * seems to completely remove that issue.
		 */
		if (!vc4->is_vc5)
		if (vc4->gen == VC4_GEN_4)
			return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1;

		return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX;
@@ -429,7 +429,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
	if (is_dsi)
		CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);

	if (vc4->is_vc5)
	if (vc4->gen == VC4_GEN_5)
		CRTC_WRITE(PV_MUX_CFG,
			   VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP,
					 PV_MUX_CFG_RGB_PIXEL_MUX_MODE));
@@ -921,7 +921,7 @@ static int vc4_async_set_fence_cb(struct drm_device *dev,
	struct dma_fence *fence;
	int ret;

	if (!vc4->is_vc5) {
	if (vc4->gen == VC4_GEN_4) {
		struct vc4_bo *bo = to_vc4_bo(&dma_bo->base);

		return vc4_queue_seqno_cb(dev, &flip_state->cb.seqno, bo->seqno,
@@ -1008,7 +1008,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
	struct vc4_bo *bo = to_vc4_bo(&dma_bo->base);
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	/*
@@ -1051,7 +1051,7 @@ int vc4_page_flip(struct drm_crtc *crtc,
		struct drm_device *dev = crtc->dev;
		struct vc4_dev *vc4 = to_vc4_dev(dev);

		if (vc4->is_vc5)
		if (vc4->gen == VC4_GEN_5)
			return vc5_async_page_flip(crtc, fb, event, flags);
		else
			return vc4_async_page_flip(crtc, fb, event, flags);
@@ -1346,9 +1346,8 @@ int __vc4_crtc_init(struct drm_device *drm,

	drm_crtc_helper_add(crtc, crtc_helper_funcs);

	if (!vc4->is_vc5) {
	if (vc4->gen == VC4_GEN_4) {
		drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));

		drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);

		/* We support CTM, but only for one CRTC at a time. It's therefore
+13 −9
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
	if (args->pad != 0)
		return -EINVAL;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	if (!vc4->v3d)
@@ -147,7 +147,7 @@ static int vc4_open(struct drm_device *dev, struct drm_file *file)
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_file *vc4file;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return -ENODEV;

	vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL);
@@ -165,7 +165,7 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file)
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_file *vc4file = file->driver_priv;

	if (WARN_ON_ONCE(vc4->is_vc5))
	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
		return;

	if (vc4file->bin_bo_used)
@@ -291,13 +291,17 @@ static int vc4_drm_bind(struct device *dev)
	struct vc4_dev *vc4;
	struct device_node *node;
	struct drm_crtc *crtc;
	bool is_vc5;
	enum vc4_gen gen;
	int ret = 0;

	dev->coherent_dma_mask = DMA_BIT_MASK(32);

	is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5");
	if (is_vc5)
	if (of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5"))
		gen = VC4_GEN_5;
	else
		gen = VC4_GEN_4;

	if (gen == VC4_GEN_5)
		driver = &vc5_drm_driver;
	else
		driver = &vc4_drm_driver;
@@ -315,13 +319,13 @@ static int vc4_drm_bind(struct device *dev)
	vc4 = devm_drm_dev_alloc(dev, driver, struct vc4_dev, base);
	if (IS_ERR(vc4))
		return PTR_ERR(vc4);
	vc4->is_vc5 = is_vc5;
	vc4->gen = gen;
	vc4->dev = dev;

	drm = &vc4->base;
	platform_set_drvdata(pdev, drm);

	if (!is_vc5) {
	if (gen == VC4_GEN_4) {
		ret = drmm_mutex_init(drm, &vc4->bin_bo_lock);
		if (ret)
			goto err;
@@ -335,7 +339,7 @@ static int vc4_drm_bind(struct device *dev)
	if (ret)
		goto err;

	if (!is_vc5) {
	if (gen == VC4_GEN_4) {
		ret = vc4_gem_init(drm);
		if (ret)
			goto err;
+6 −1
Original line number Diff line number Diff line
@@ -80,11 +80,16 @@ struct vc4_perfmon {
	u64 counters[] __counted_by(ncounters);
};

enum vc4_gen {
	VC4_GEN_4,
	VC4_GEN_5,
};

struct vc4_dev {
	struct drm_device base;
	struct device *dev;

	bool is_vc5;
	enum vc4_gen gen;

	unsigned int irq;

Loading