]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
drm/komeda: Rename main engine clk name "mclk" to "aclk"
[linux.git] / drivers / gpu / drm / arm / display / komeda / d71 / d71_component.c
index 2ea282c6a156774197365fb763403c52a04ad4d5..5212988c438c42904d44d70068254b31ad39d650 100644 (file)
@@ -10,6 +10,7 @@
 #include "komeda_kms.h"
 #include "malidp_io.h"
 #include "komeda_framebuffer.h"
+#include "komeda_color_mgmt.h"
 
 static void get_resources_id(u32 hw_id, u32 *pipe_id, u32 *comp_id)
 {
@@ -162,6 +163,30 @@ static inline u32 to_d71_input_id(struct komeda_component_output *output)
        return comp ? (comp->hw_id + output->output_port) : 0;
 }
 
+static void d71_layer_update_fb(struct komeda_component *c,
+                               struct komeda_fb *kfb,
+                               dma_addr_t *addr)
+{
+       struct drm_framebuffer *fb = &kfb->base;
+       const struct drm_format_info *info = fb->format;
+       u32 __iomem *reg = c->reg;
+       int block_h;
+
+       if (info->num_planes > 2)
+               malidp_write64(reg, BLK_P2_PTR_LOW, addr[2]);
+
+       if (info->num_planes > 1) {
+               block_h = drm_format_info_block_height(info, 1);
+               malidp_write32(reg, BLK_P1_STRIDE, fb->pitches[1] * block_h);
+               malidp_write64(reg, BLK_P1_PTR_LOW, addr[1]);
+       }
+
+       block_h = drm_format_info_block_height(info, 0);
+       malidp_write32(reg, BLK_P0_STRIDE, fb->pitches[0] * block_h);
+       malidp_write64(reg, BLK_P0_PTR_LOW, addr[0]);
+       malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
+}
+
 static void d71_layer_disable(struct komeda_component *c)
 {
        malidp_write32_mask(c->reg, BLK_CONTROL, L_EN, 0);
@@ -177,22 +202,8 @@ static void d71_layer_update(struct komeda_component *c,
        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);
-       }
+       d71_layer_update_fb(c, kfb, st->addr);
 
        malidp_write32(reg, AD_CONTROL, to_ad_ctrl(fb->modifier));
        if (fb->modifier) {
@@ -212,9 +223,44 @@ static void d71_layer_update(struct komeda_component *c,
                malidp_write32(reg, BLK_P1_PTR_HIGH, upper_32_bits(addr));
        }
 
-       malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
+       if (fb->format->is_yuv) {
+               u32 upsampling = 0;
+
+               switch (kfb->format_caps->fourcc) {
+               case DRM_FORMAT_YUYV:
+                       upsampling = fb->modifier ? LR_CHI422_BILINEAR :
+                                    LR_CHI422_REPLICATION;
+                       break;
+               case DRM_FORMAT_UYVY:
+                       upsampling = LR_CHI422_REPLICATION;
+                       break;
+               case DRM_FORMAT_NV12:
+               case DRM_FORMAT_YUV420_8BIT:
+               case DRM_FORMAT_YUV420_10BIT:
+               case DRM_FORMAT_YUV420:
+               case DRM_FORMAT_P010:
+               /* these fmt support MPGE/JPEG both, here perfer JPEG*/
+                       upsampling = LR_CHI420_JPEG;
+                       break;
+               case DRM_FORMAT_X0L2:
+                       upsampling = LR_CHI420_JPEG;
+                       break;
+               default:
+                       break;
+               }
+
+               malidp_write32(reg, LAYER_R_CONTROL, upsampling);
+               malidp_write_group(reg, LAYER_YUV_RGB_COEFF0,
+                                  KOMEDA_N_YUV2RGB_COEFFS,
+                                  komeda_select_yuv2rgb_coeffs(
+                                       plane_st->color_encoding,
+                                       plane_st->color_range));
+       }
+
        malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
 
+       if (kfb->is_va)
+               ctrl |= L_TBU_EN;
        malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
 }
 
@@ -332,23 +378,15 @@ static void d71_wb_layer_update(struct komeda_component *c,
 {
        struct komeda_layer_state *st = to_layer_st(state);
        struct drm_connector_state *conn_st = state->wb_conn->state;
-       struct drm_framebuffer *fb = conn_st->writeback_job->fb;
-       struct komeda_fb *kfb = to_kfb(fb);
-       u32 __iomem *reg = c->reg;
+       struct komeda_fb *kfb = to_kfb(conn_st->writeback_job->fb);
        u32 ctrl = L_EN | LW_OFM, mask = L_EN | LW_OFM | LW_TBU_EN;
-       int i;
+       u32 __iomem *reg = c->reg;
 
-       for (i = 0; i < fb->format->num_planes; i++) {
-               malidp_write32(reg + i * LAYER_PER_PLANE_REGS, BLK_P0_PTR_LOW,
-                              lower_32_bits(st->addr[i]));
-               malidp_write32(reg + i * LAYER_PER_PLANE_REGS, BLK_P0_PTR_HIGH,
-                              upper_32_bits(st->addr[i]));
+       d71_layer_update_fb(c, kfb, st->addr);
 
-               malidp_write32(reg + i * LAYER_PER_PLANE_REGS, BLK_P0_STRIDE,
-                              fb->pitches[i] & 0xFFFF);
-       }
+       if (kfb->is_va)
+               ctrl |= LW_TBU_EN;
 
-       malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
        malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
        malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));
        malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
@@ -430,8 +468,18 @@ static void d71_component_disable(struct komeda_component *c)
 
        malidp_write32(reg, BLK_CONTROL, 0);
 
-       for (i = 0; i < c->max_active_inputs; i++)
+       for (i = 0; i < c->max_active_inputs; i++) {
                malidp_write32(reg, BLK_INPUT_ID0 + (i << 2), 0);
+
+               /* Besides clearing the input ID to zero, D71 compiz also has
+                * input enable bit in CU_INPUTx_CONTROL which need to be
+                * cleared.
+                */
+               if (has_bit(c->id, KOMEDA_PIPELINE_COMPIZS))
+                       malidp_write32(reg, CU_INPUT0_CONTROL +
+                                      i * CU_PER_INPUT_REGS * 4,
+                                      CU_INPUT_CTRL_ALPHA(0xFF));
+       }
 }
 
 static void compiz_enable_input(u32 __iomem *id_reg,
@@ -610,6 +658,7 @@ static void d71_scaler_update(struct komeda_component *c,
        ctrl = 0;
        ctrl |= st->en_scaling ? SC_CTRL_SCL : 0;
        ctrl |= st->en_alpha ? SC_CTRL_AP : 0;
+       ctrl |= st->en_img_enhancement ? SC_CTRL_IENH : 0;
 
        malidp_write32(reg, BLK_CONTROL, ctrl);
        malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));
@@ -679,7 +728,7 @@ static int d71_scaler_init(struct d71_dev *d71,
 
 static int d71_downscaling_clk_check(struct komeda_pipeline *pipe,
                                     struct drm_display_mode *mode,
-                                    unsigned long mclk_rate,
+                                    unsigned long aclk_rate,
                                     struct komeda_data_flow_cfg *dflow)
 {
        u32 h_in = dflow->in_w;
@@ -689,20 +738,20 @@ static int d71_downscaling_clk_check(struct komeda_pipeline *pipe,
 
        /* D71 downscaling must satisfy the following equation
         *
-        *   MCLK                   h_in * v_in
+        *   ACLK                   h_in * v_in
         * ------- >= ---------------------------------------------
         *  PXLCLK     (h_total - (1 + 2 * v_in / v_out)) * v_out
         *
         * In only horizontal downscaling situation, the right side should be
         * multiplied by (h_total - 3) / (h_active - 3), then equation becomes
         *
-        *   MCLK          h_in
+        *   ACLK          h_in
         * ------- >= ----------------
         *  PXLCLK     (h_active - 3)
         *
         * To avoid precision lost the equation 1 will be convert to:
         *
-        *   MCLK             h_in * v_in
+        *   ACLK             h_in * v_in
         * ------- >= -----------------------------------
         *  PXLCLK     (h_total -1 ) * v_out -  2 * v_in
         */
@@ -714,7 +763,7 @@ static int d71_downscaling_clk_check(struct komeda_pipeline *pipe,
                denominator = (mode->htotal - 1) * v_out -  2 * v_in;
        }
 
-       return mclk_rate * denominator >= mode->clock * 1000 * fraction ?
+       return aclk_rate * denominator >= mode->clock * 1000 * fraction ?
               0 : -EINVAL;
 }