@@ -807,6 +807,16 @@ static int rcar_du_crtc_verify_crc_source(struct drm_crtc *crtc,
return 0;
}
+const char *const *rcar_du_crtc_get_crc_sources(struct drm_crtc *crtc,
+ size_t *count)
+{
+ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+ struct rcar_du_device *rcdu = rcrtc->group->dev;
+
+ *count = rcdu->sources_count;
+ return (const char * const*)rcdu->sources;
+}
+
static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
const char *source_name)
{
@@ -898,6 +908,7 @@ static const struct drm_crtc_funcs crtc_funcs_gen3 = {
.disable_vblank = rcar_du_crtc_disable_vblank,
.set_crc_source = rcar_du_crtc_set_crc_source,
.verify_crc_source = rcar_du_crtc_verify_crc_source,
+ .get_crc_sources = rcar_du_crtc_get_crc_sources,
};
/* -----------------------------------------------------------------------------
@@ -401,6 +401,8 @@ static int rcar_du_remove(struct platform_device *pdev)
drm_dev_unregister(ddev);
+ rcar_du_crc_sources_list_uninit(rcdu);
+
if (rcdu->fbdev)
drm_fbdev_cma_fini(rcdu->fbdev);
@@ -92,6 +92,8 @@ struct rcar_du_device {
unsigned int dpad0_source;
unsigned int vspd1_sink;
+ char **sources;
+ size_t sources_count;
};
static inline bool rcar_du_has(struct rcar_du_device *rcdu,
@@ -421,6 +421,70 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
return 0;
}
+static void rcar_du_crc_sources_list_init(struct rcar_du_device *rcdu)
+{
+ struct drm_device *dev = rcdu->ddev;
+ struct drm_plane *plane;
+ char **sources;
+ size_t count;
+ int i = 0;
+
+ /* reserve 1 for "auto" source */
+ count = 1;
+
+ drm_for_each_plane(plane, dev)
+ count++;
+
+ sources = kmalloc_array(count, sizeof(char *), GFP_KERNEL);
+ if (!sources)
+ goto fail;
+
+ sources[i] = kstrdup("auto", GFP_KERNEL);
+ if (!sources[i])
+ goto fail_no_mem;
+
+ i++;
+ drm_for_each_plane(plane, dev) {
+ char name[16];
+
+ sprintf(name, "plane%d", plane->base.id);
+ sources[i] = kstrdup(name, GFP_KERNEL);
+ if (!sources[i])
+ goto fail_no_mem;
+ i++;
+ }
+
+ rcdu->sources = sources;
+ rcdu->sources_count = count;
+ return;
+
+fail_no_mem:
+ while (i > 0) {
+ i--;
+ kfree(sources[i]);
+ }
+ kfree(sources);
+fail:
+ rcdu->sources = NULL;
+ rcdu->sources_count = 0;
+}
+
+void rcar_du_crc_sources_list_uninit(struct rcar_du_device *rcdu)
+{
+ int i = rcdu->sources_count;
+
+ if (!rcdu->sources)
+ return;
+
+ while (i > 0) {
+ i--;
+ kfree(rcdu->sources[i]);
+ }
+ kfree(rcdu->sources);
+ rcdu->sources = NULL;
+ rcdu->sources_count = 0;
+}
+
static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
{
const struct device_node *np = rcdu->dev->of_node;
@@ -591,6 +655,9 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
return ret;
}
+ /* Initialize CRC-sources list */
+ rcar_du_crc_sources_list_init(rcdu);
+
/* Initialize the encoders. */
ret = rcar_du_encoders_init(rcdu);
if (ret < 0)
@@ -32,6 +32,7 @@ struct rcar_du_format_info {
const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc);
int rcar_du_modeset_init(struct rcar_du_device *rcdu);
+void rcar_du_crc_sources_list_uninit(struct rcar_du_device *rcdu);
int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
struct drm_mode_create_dumb *args);
This patch implements get_crc_sources callback, which returns list of all the crc sources supported by driver in current platform. Signed-off-by: Mahesh Kumar <mahesh1.kumar@intel.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 11 ++++++ drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 67 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/rcar-du/rcar_du_kms.h | 1 + 5 files changed, 83 insertions(+)