/* 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;
#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,
.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);
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);
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);
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];
}
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),
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);
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);
return 0;
err_destroy_encoder:
- drm_encoder_cleanup(vec->encoder);
+ drm_encoder_cleanup(&vec->encoder.base);
pm_runtime_disable(dev);
return ret;
{
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);
}