Commit 9780315b authored by Maxime Ripard's avatar Maxime Ripard

drm/vc4: vec: Embed DRM structures into the private structure

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: default avatarThomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Link: https://lore.kernel.org/r/20220711173939.1132294-56-maxime@cerno.tech
parent a0883e4d
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment