1. Add detailed layer/layer_state definitions
2. Add d71_layer_init to report layer features and capabilities according
   to D71 layer block.
3. Add d71_layer_updat/disable

Signed-off-by: James (Qian) Wang <james.qian.w...@arm.com>
---
 .../drm/arm/display/include/malidp_utils.h    |  17 ++
 .../arm/display/komeda/d71/d71_component.c    | 162 +++++++++++++++++-
 .../drm/arm/display/komeda/komeda_pipeline.c  |   2 +-
 .../drm/arm/display/komeda/komeda_pipeline.h  |  10 +-
 4 files changed, 186 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/include/malidp_utils.h 
b/drivers/gpu/drm/arm/display/include/malidp_utils.h
index b7bf8db39a64..e97df5fbc9ea 100644
--- a/drivers/gpu/drm/arm/display/include/malidp_utils.h
+++ b/drivers/gpu/drm/arm/display/include/malidp_utils.h
@@ -25,4 +25,21 @@
        num_tries;                                      \
 })
 
+/* the restriction of range is [start, end] */
+struct malidp_range {
+       u32 start;
+       u32 end;
+};
+
+static inline void set_range(struct malidp_range *rg, u32 start, u32 end)
+{
+       rg->start = start;
+       rg->end   = end;
+}
+
+static inline bool in_range(struct malidp_range *rg, u32 v)
+{
+       return (v >= rg->start) && (v <= rg->end);
+}
+
 #endif /* _MALIDP_UTILS_ */
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 a43a2410159f..0e8ae7b00d14 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -7,11 +7,171 @@
 #include "d71_dev.h"
 #include "komeda_kms.h"
 #include "malidp_io.h"
+#include "komeda_framebuffer.h"
+
+static void get_resources_id(u32 hw_id, u32 *pipe_id, u32 *comp_id)
+{
+       u32 id = BLOCK_INFO_BLK_ID(hw_id);
+       u32 pipe = id;
+
+       switch (BLOCK_INFO_BLK_TYPE(hw_id)) {
+       case D71_BLK_TYPE_LPU_WB_LAYER:
+               id = KOMEDA_COMPONENT_WB_LAYER;
+               break;
+       case D71_BLK_TYPE_CU_SPLITTER:
+               id = KOMEDA_COMPONENT_SPLITTER;
+               break;
+       case D71_BLK_TYPE_CU_SCALER:
+               pipe = id / D71_PIPELINE_MAX_SCALERS;
+               id %= D71_PIPELINE_MAX_SCALERS;
+               id += KOMEDA_COMPONENT_SCALER0;
+               break;
+       case D71_BLK_TYPE_CU:
+               id += KOMEDA_COMPONENT_COMPIZ0;
+               break;
+       case D71_BLK_TYPE_LPU_LAYER:
+               pipe = id / D71_PIPELINE_MAX_LAYERS;
+               id %= D71_PIPELINE_MAX_LAYERS;
+               id += KOMEDA_COMPONENT_LAYER0;
+               break;
+       case D71_BLK_TYPE_DOU_IPS:
+               id += KOMEDA_COMPONENT_IPS0;
+               break;
+       case D71_BLK_TYPE_CU_MERGER:
+               id = KOMEDA_COMPONENT_MERGER;
+               break;
+       case D71_BLK_TYPE_DOU:
+               id = KOMEDA_COMPONENT_TIMING_CTRLR;
+               break;
+       default:
+               id = 0xFFFFFFFF;
+       }
+
+       if (comp_id)
+               *comp_id = id;
+
+       if (pipe_id)
+               *pipe_id = pipe;
+}
+
+static u32 get_valid_inputs(struct block_header *blk)
+{
+       u32 valid_inputs = 0, comp_id;
+       int i;
+
+       for (i = 0; i < PIPELINE_INFO_N_VALID_INPUTS(blk->pipeline_info); i++) {
+               get_resources_id(blk->input_ids[i], NULL, &comp_id);
+               if (comp_id == 0xFFFFFFFF)
+                       continue;
+               valid_inputs |= BIT(comp_id);
+       }
+
+       return valid_inputs;
+}
+
+static u32 to_rot_ctrl(u32 rot)
+{
+       u32 lr_ctrl = 0;
+
+       switch (rot & DRM_MODE_ROTATE_MASK) {
+       case DRM_MODE_ROTATE_0:
+               lr_ctrl |= L_ROT(L_ROT_R0);
+               break;
+       case DRM_MODE_ROTATE_90:
+               lr_ctrl |= L_ROT(L_ROT_R90);
+               break;
+       case DRM_MODE_ROTATE_180:
+               lr_ctrl |= L_ROT(L_ROT_R180);
+               break;
+       case DRM_MODE_ROTATE_270:
+               lr_ctrl |= L_ROT(L_ROT_R270);
+               break;
+       }
+
+       if (rot & DRM_MODE_REFLECT_X)
+               lr_ctrl |= L_HFLIP;
+       if (rot & DRM_MODE_REFLECT_Y)
+               lr_ctrl |= L_VFLIP;
+
+       return lr_ctrl;
+}
+
+static void d71_layer_disable(struct komeda_component *c)
+{
+       malidp_write32_mask(c->reg, BLK_CONTROL, L_EN, 0);
+}
+
+static void d71_layer_update(struct komeda_component *c,
+                            struct komeda_component_state *state)
+{
+       struct komeda_layer_state *st = to_layer_st(state);
+       struct drm_plane_state *plane_st = state->plane->state;
+       struct drm_framebuffer *fb = plane_st->fb;
+       struct komeda_fb *kfb = to_kfb(fb);
+       u32 __iomem *reg = c->reg;
+       u32 ctrl_mask = L_EN | L_ROT(L_ROT_R270) | L_HFLIP | L_VFLIP | L_TBU_EN;
+       u32 ctrl = L_EN | to_rot_ctrl(st->rot);
+       int i;
+
+       for (i = 0; i < fb->format->num_planes; i++) {
+               malidp_write32(reg,
+                              BLK_P0_PTR_LOW + i * LAYER_PER_PLANE_REGS * 4,
+                              lower_32_bits(st->addr[i]));
+               malidp_write32(reg,
+                              BLK_P0_PTR_HIGH + i * LAYER_PER_PLANE_REGS * 4,
+                              upper_32_bits(st->addr[i]));
+               if (i >= 2)
+                       break;
+
+               malidp_write32(reg,
+                              BLK_P0_STRIDE + i * LAYER_PER_PLANE_REGS * 4,
+                              fb->pitches[i] & 0xFFFF);
+       }
+
+       malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
+       malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
+
+       malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
+}
+
+struct komeda_component_funcs d71_layer_funcs = {
+       .update         = d71_layer_update,
+       .disable        = d71_layer_disable,
+};
 
 static int d71_layer_init(struct d71_dev *d71,
                          struct block_header *blk, u32 __iomem *reg)
 {
-       DRM_INFO("Detect D71_Layer.\n");
+       struct komeda_component *c;
+       struct komeda_layer *layer;
+       u32 pipe_id, layer_id, layer_info;
+
+       get_resources_id(blk->block_info, &pipe_id, &layer_id);
+       c = komeda_component_add(&d71->pipes[pipe_id]->base, sizeof(*layer),
+                                layer_id,
+                                BLOCK_INFO_INPUT_ID(blk->block_info),
+                                &d71_layer_funcs, 0,
+                                get_valid_inputs(blk),
+                                1, reg, "LPU%d_LAYER%d", pipe_id, layer_id);
+       if (!c) {
+               DRM_ERROR("Failed to add layer component\n");
+               return -EINVAL;
+       }
+
+       layer = to_layer(c);
+       layer_info = malidp_read32(reg, LAYER_INFO);
+
+       if (layer_info & L_INFO_RF)
+               layer->layer_type = KOMEDA_FMT_RICH_LAYER;
+       else
+               layer->layer_type = KOMEDA_FMT_SIMPLE_LAYER;
+
+       set_range(&layer->hsize_in, 4, d71->max_line_size);
+       set_range(&layer->vsize_in, 4, d71->max_vsize);
+
+       malidp_write32(reg, LAYER_PALPHA, D71_PALPHA_DEF_MAP);
+
+       layer->supported_rots = DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK;
 
        return 0;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
index e731b2a85c3a..65b35495d3b7 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
@@ -146,7 +146,7 @@ komeda_component_add(struct komeda_pipeline *pipe,
        }
 
        pos = komeda_pipeline_get_component_pos(pipe, id);
-       if (!pos || !(*pos))
+       if (!pos || (*pos))
                return NULL;
 
        if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) {
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 114129d96851..b8cf502982fb 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -209,16 +209,20 @@ static inline u16 component_changed_inputs(struct 
komeda_component_state *st)
 #define to_comp(__c)   (((__c) == NULL) ? NULL : &((__c)->base))
 #define to_cpos(__c)   ((struct komeda_component **)&(__c))
 
-/* these structures are going to be filled in in uture patches */
 struct komeda_layer {
        struct komeda_component base;
-       /* layer specific features and caps */
-       int layer_type; /* RICH, SIMPLE or WB */
+       /* accepted h/v input range before rotation */
+       struct malidp_range hsize_in, vsize_in;
+       u32 layer_type; /* RICH, SIMPLE or WB */
+       u32 supported_rots;
 };
 
 struct komeda_layer_state {
        struct komeda_component_state base;
        /* layer specific configuration state */
+       u16 hsize, vsize;
+       u32 rot;
+       dma_addr_t addr[3];
 };
 
 struct komeda_compiz {
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to