Add and initialize improc and timing_ctrlr according to D71 capablitites

Signed-off-by: James (Qian) Wang <james.qian.w...@arm.com>
---
 .../arm/display/komeda/d71/d71_component.c    | 108 +++++++++++++++++-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |   2 +
 .../drm/arm/display/komeda/komeda_pipeline.h  |   7 ++
 3 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 5458df726b08..811634ec1193 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -285,18 +285,122 @@ static int d71_compiz_init(struct d71_dev *d71,
        return 0;
 }
 
+static void d71_improc_update(struct komeda_component *c,
+                             struct komeda_component_state *state)
+{
+       struct komeda_improc_state *st = to_improc_st(state);
+       u32 __iomem *reg = c->reg;
+       u32 index, input_hw_id;
+
+       for_each_changed_input(state, index) {
+               input_hw_id = state->active_inputs & BIT(index) ?
+                             to_d71_input_id(&state->inputs[index]) : 0;
+               malidp_write32(reg, BLK_INPUT_ID0 + index * 4, input_hw_id);
+       }
+
+       malidp_write32(reg, BLK_SIZE, HV_SIZE(st->hsize, st->vsize));
+}
+
+struct komeda_component_funcs d71_improc_funcs = {
+       .update         = d71_improc_update,
+       .disable        = d71_component_disable,
+};
+
 static int d71_improc_init(struct d71_dev *d71,
                           struct block_header *blk, u32 __iomem *reg)
 {
-       DRM_INFO("Detect D71_improc.\n");
+       struct komeda_component *c;
+       struct komeda_improc *improc;
+       u32 blk_id = BLOCK_INFO_BLK_ID(blk->block_info);
+       u32 value;
+
+       c = komeda_component_add(&d71->pipes[blk_id]->base, sizeof(*improc),
+                                KOMEDA_COMPONENT_IPS0 + blk_id,
+                                BLOCK_INFO_INPUT_ID(blk->block_info),
+                                &d71_improc_funcs, IPS_NUM_INPUT_IDS,
+                                get_valid_inputs(blk),
+                                IPS_NUM_OUTPUT_IDS, reg, "DOU%d_IPS", blk_id);
+       if (!c) {
+               DRM_ERROR("Failed to add improc component\n");
+               return -EINVAL;
+       }
+
+       improc = to_improc(c);
+       improc->supported_color_depths = BIT(8) | BIT(10);
+       improc->supported_color_formats = DRM_COLOR_FORMAT_RGB444 |
+                                         DRM_COLOR_FORMAT_YCRCB444 |
+                                         DRM_COLOR_FORMAT_YCRCB422;
+       value = malidp_read32(reg, BLK_INFO);
+       if (value & IPS_INFO_CHD420)
+               improc->supported_color_formats |= DRM_COLOR_FORMAT_YCRCB420;
+
+       improc->supports_csc = true;
+       improc->supports_gamma = true;
 
        return 0;
 }
 
+static void d71_timing_ctrlr_disable(struct komeda_component *c)
+{
+       malidp_write32_mask(c->reg, BLK_CONTROL, BS_CTRL_EN, 0);
+}
+
+static void d71_timing_ctrlr_update(struct komeda_component *c,
+                                   struct komeda_component_state *state)
+{
+       struct drm_crtc_state *crtc_st = state->crtc->state;
+       u32 __iomem *reg = c->reg;
+       struct videomode vm;
+       u32 value;
+
+       drm_display_mode_to_videomode(&crtc_st->adjusted_mode, &vm);
+
+       malidp_write32(reg, BS_ACTIVESIZE, HV_SIZE(vm.hactive, vm.vactive));
+       malidp_write32(reg, BS_HINTERVALS, BS_H_INTVALS(vm.hfront_porch,
+                                                       vm.hback_porch));
+       malidp_write32(reg, BS_VINTERVALS, BS_V_INTVALS(vm.vfront_porch,
+                                                       vm.vback_porch));
+
+       value = BS_SYNC_VSW(vm.vsync_len) | BS_SYNC_HSW(vm.hsync_len);
+       value |= vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ? BS_SYNC_VSP : 0;
+       value |= vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ? BS_SYNC_HSP : 0;
+       malidp_write32(reg, BS_SYNC, value);
+
+       malidp_write32(reg, BS_PROG_LINE, D71_DEFAULT_PREPRETCH_LINE - 1);
+       malidp_write32(reg, BS_PREFETCH_LINE, D71_DEFAULT_PREPRETCH_LINE);
+
+       /* configure bs control register */
+       value = BS_CTRL_EN | BS_CTRL_VM;
+
+       malidp_write32(reg, BLK_CONTROL, value);
+}
+
+struct komeda_component_funcs d71_timing_ctrlr_funcs = {
+       .update         = d71_timing_ctrlr_update,
+       .disable        = d71_timing_ctrlr_disable,
+};
+
 static int d71_timing_ctrlr_init(struct d71_dev *d71,
                                 struct block_header *blk, u32 __iomem *reg)
 {
-       DRM_INFO("Detect D71_timing_ctrlr.\n");
+       struct komeda_component *c;
+       struct komeda_timing_ctrlr *ctrlr;
+       u32 blk_id = BLOCK_INFO_BLK_ID(blk->block_info);
+
+       c = komeda_component_add(&d71->pipes[blk_id]->base, sizeof(*ctrlr),
+                                KOMEDA_COMPONENT_TIMING_CTRLR,
+                                BLOCK_INFO_INPUT_ID(blk->block_info),
+                                &d71_timing_ctrlr_funcs,
+                                1, BIT(KOMEDA_COMPONENT_IPS0 + blk_id),
+                                BS_NUM_OUTPUT_IDS, reg, "DOU%d_BS", blk_id);
+       if (!c) {
+               DRM_ERROR("Failed to add display_ctrl component\n");
+               return -EINVAL;
+       }
+
+       ctrlr = to_ctrlr(c);
+
+       ctrlr->supports_dual_link = true;
 
        return 0;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index f13666004a42..f519a4c587e6 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -11,6 +11,8 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_writeback.h>
+#include <video/videomode.h>
+#include <video/display_timing.h>
 
 /** struct komeda_plane - komeda instance of drm_plane */
 struct komeda_plane {
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 22baeb5e1b61..b2bd6ab282cb 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -258,15 +258,22 @@ struct komeda_compiz_state {
 
 struct komeda_improc {
        struct komeda_component base;
+       u32 supported_color_formats;  /* DRM_RGB/YUV444/YUV420*/
+       u32 supported_color_depths; /* BIT(8) | BIT(10)*/
+       u8 supports_degamma : 1;
+       u8 supports_csc : 1;
+       u8 supports_gamma : 1;
 };
 
 struct komeda_improc_state {
        struct komeda_component_state base;
+       u16 hsize, vsize;
 };
 
 /* display timing controller */
 struct komeda_timing_ctrlr {
        struct komeda_component base;
+       u8 supports_dual_link : 1;
 };
 
 struct komeda_timing_ctrlr_state {
-- 
2.17.1

Reply via email to