drm/vc4: vec: Embed DRM structures into the private structure
authorMaxime Ripard <maxime@cerno.tech>
Mon, 11 Jul 2022 17:39:25 +0000 (19:39 +0200)
committerMaxime Ripard <maxime@cerno.tech>
Wed, 13 Jul 2022 08:46:11 +0000 (10:46 +0200)
The VC4 VEC driver private structure contains only a pointer to the
encoder and connector it implements. This makes the overall structure
somewhat inconsistent with the rest of the driver, and complicates its
initialisation without any apparent gain.

Let's embed the drm_encoder structure (through the vc4_encoder one) and
drm_connector into struct vc4_vec to fix both issues.

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://lore.kernel.org/r/20220711173939.1132294-56-maxime@cerno.tech
drivers/gpu/drm/vc4/vc4_vec.c

index 99fe40c8cf81fc704ac93145c0992a5d13b82b8c..2c96d5adcf499939cca46f8d30fda9332f2cf666 100644 (file)
@@ -160,12 +160,12 @@ struct vc4_vec_variant {
 
 /* General VEC hardware state. */
 struct vc4_vec {
+       struct vc4_encoder encoder;
+       struct drm_connector connector;
+
        struct platform_device *pdev;
        const struct vc4_vec_variant *variant;
 
-       struct drm_encoder *encoder;
-       struct drm_connector *connector;
-
        void __iomem *regs;
 
        struct clk *clock;
@@ -178,30 +178,12 @@ struct vc4_vec {
 #define VEC_READ(offset) readl(vec->regs + (offset))
 #define VEC_WRITE(offset, val) writel(val, vec->regs + (offset))
 
-/* VC4 VEC encoder KMS struct */
-struct vc4_vec_encoder {
-       struct vc4_encoder base;
-       struct vc4_vec *vec;
-};
-
-static inline struct vc4_vec_encoder *
-to_vc4_vec_encoder(struct drm_encoder *encoder)
+static inline struct vc4_vec *
+encoder_to_vc4_vec(struct drm_encoder *encoder)
 {
-       return container_of(encoder, struct vc4_vec_encoder, base.base);
+       return container_of(encoder, struct vc4_vec, encoder.base);
 }
 
-/* VC4 VEC connector KMS struct */
-struct vc4_vec_connector {
-       struct drm_connector base;
-       struct vc4_vec *vec;
-
-       /* Since the connector is attached to just the one encoder,
-        * this is the reference to it so we can do the best_encoder()
-        * hook.
-        */
-       struct drm_encoder *encoder;
-};
-
 enum vc4_vec_tv_mode_id {
        VC4_VEC_TV_MODE_NTSC,
        VC4_VEC_TV_MODE_NTSC_J,
@@ -343,22 +325,12 @@ static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs =
        .get_modes = vc4_vec_connector_get_modes,
 };
 
-static struct drm_connector *vc4_vec_connector_init(struct drm_device *dev,
-                                                   struct vc4_vec *vec)
+static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec)
 {
-       struct drm_connector *connector = NULL;
-       struct vc4_vec_connector *vec_connector;
+       struct drm_connector *connector = &vec->connector;
 
-       vec_connector = devm_kzalloc(dev->dev, sizeof(*vec_connector),
-                                    GFP_KERNEL);
-       if (!vec_connector)
-               return ERR_PTR(-ENOMEM);
-
-       connector = &vec_connector->base;
        connector->interlace_allowed = true;
 
-       vec_connector->encoder = vec->encoder;
-       vec_connector->vec = vec;
 
        drm_connector_init(dev, connector, &vc4_vec_connector_funcs,
                           DRM_MODE_CONNECTOR_Composite);
@@ -369,15 +341,14 @@ static struct drm_connector *vc4_vec_connector_init(struct drm_device *dev,
                                   VC4_VEC_TV_MODE_NTSC);
        vec->tv_mode = &vc4_vec_tv_modes[VC4_VEC_TV_MODE_NTSC];
 
-       drm_connector_attach_encoder(connector, vec->encoder);
+       drm_connector_attach_encoder(connector, &vec->encoder.base);
 
-       return connector;
+       return 0;
 }
 
 static void vc4_vec_encoder_disable(struct drm_encoder *encoder)
 {
-       struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder);
-       struct vc4_vec *vec = vc4_vec_encoder->vec;
+       struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
        int ret;
 
        VEC_WRITE(VEC_CFG, 0);
@@ -398,8 +369,7 @@ static void vc4_vec_encoder_disable(struct drm_encoder *encoder)
 
 static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
 {
-       struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder);
-       struct vc4_vec *vec = vc4_vec_encoder->vec;
+       struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
        int ret;
 
        ret = pm_runtime_get_sync(&vec->pdev->dev);
@@ -474,8 +444,7 @@ static void vc4_vec_encoder_atomic_mode_set(struct drm_encoder *encoder,
                                        struct drm_crtc_state *crtc_state,
                                        struct drm_connector_state *conn_state)
 {
-       struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder);
-       struct vc4_vec *vec = vc4_vec_encoder->vec;
+       struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
 
        vec->tv_mode = &vc4_vec_tv_modes[conn_state->tv.mode];
 }
@@ -533,7 +502,6 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
        struct platform_device *pdev = to_platform_device(dev);
        struct drm_device *drm = dev_get_drvdata(master);
        struct vc4_vec *vec;
-       struct vc4_vec_encoder *vc4_vec_encoder;
        int ret;
 
        ret = drm_mode_create_tv_properties(drm, ARRAY_SIZE(tv_mode_names),
@@ -545,14 +513,7 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
        if (!vec)
                return -ENOMEM;
 
-       vc4_vec_encoder = devm_kzalloc(dev, sizeof(*vc4_vec_encoder),
-                                      GFP_KERNEL);
-       if (!vc4_vec_encoder)
-               return -ENOMEM;
-       vc4_vec_encoder->base.type = VC4_ENCODER_TYPE_VEC;
-       vc4_vec_encoder->vec = vec;
-       vec->encoder = &vc4_vec_encoder->base.base;
-
+       vec->encoder.type = VC4_ENCODER_TYPE_VEC;
        vec->pdev = pdev;
        vec->variant = (const struct vc4_vec_variant *)
                of_device_get_match_data(dev);
@@ -573,14 +534,12 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
 
        pm_runtime_enable(dev);
 
-       drm_simple_encoder_init(drm, vec->encoder, DRM_MODE_ENCODER_TVDAC);
-       drm_encoder_helper_add(vec->encoder, &vc4_vec_encoder_helper_funcs);
+       drm_simple_encoder_init(drm, &vec->encoder.base, DRM_MODE_ENCODER_TVDAC);
+       drm_encoder_helper_add(&vec->encoder.base, &vc4_vec_encoder_helper_funcs);
 
-       vec->connector = vc4_vec_connector_init(drm, vec);
-       if (IS_ERR(vec->connector)) {
-               ret = PTR_ERR(vec->connector);
+       ret = vc4_vec_connector_init(drm, vec);
+       if (ret)
                goto err_destroy_encoder;
-       }
 
        dev_set_drvdata(dev, vec);
 
@@ -589,7 +548,7 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
        return 0;
 
 err_destroy_encoder:
-       drm_encoder_cleanup(vec->encoder);
+       drm_encoder_cleanup(&vec->encoder.base);
        pm_runtime_disable(dev);
 
        return ret;
@@ -600,8 +559,8 @@ static void vc4_vec_unbind(struct device *dev, struct device *master,
 {
        struct vc4_vec *vec = dev_get_drvdata(dev);
 
-       vc4_vec_connector_destroy(vec->connector);
-       drm_encoder_cleanup(vec->encoder);
+       vc4_vec_connector_destroy(&vec->connector);
+       drm_encoder_cleanup(&vec->encoder.base);
        pm_runtime_disable(dev);
 }