summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/arm/display/komeda/d71/d71_component.c')
-rw-r--r--drivers/gpu/drm/arm/display/komeda/d71/d71_component.c47
1 files changed, 42 insertions, 5 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 2e9789ac7be1..ad6a716a0d30 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -642,23 +642,58 @@ static void d71_scaler_update(struct komeda_component *c,
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize_in, st->vsize_in));
malidp_write32(reg, SC_OUT_SIZE, HV_SIZE(st->hsize_out, st->vsize_out));
+ malidp_write32(reg, SC_H_CROP, HV_CROP(st->left_crop, st->right_crop));
+
+ /* for right part, HW only sample the valid pixel which means the pixels
+ * in left_crop will be jumpped, and the first sample pixel is:
+ *
+ * dst_a = st->total_hsize_out - st->hsize_out + st->left_crop + 0.5;
+ *
+ * Then the corresponding texel in src is:
+ *
+ * h_delta_phase = st->total_hsize_in / st->total_hsize_out;
+ * src_a = dst_A * h_delta_phase;
+ *
+ * and h_init_phase is src_a deduct the real source start src_S;
+ *
+ * src_S = st->total_hsize_in - st->hsize_in;
+ * h_init_phase = src_a - src_S;
+ *
+ * And HW precision for the initial/delta_phase is 16:16 fixed point,
+ * the following is the simplified formula
+ */
+ if (st->right_part) {
+ u32 dst_a = st->total_hsize_out - st->hsize_out + st->left_crop;
+
+ if (st->en_img_enhancement)
+ dst_a -= 1;
+
+ init_ph = ((st->total_hsize_in * (2 * dst_a + 1) -
+ 2 * st->total_hsize_out * (st->total_hsize_in -
+ st->hsize_in)) << 15) / st->total_hsize_out;
+ } else {
+ init_ph = (st->total_hsize_in << 15) / st->total_hsize_out;
+ }
- init_ph = (st->hsize_in << 15) / st->hsize_out;
malidp_write32(reg, SC_H_INIT_PH, init_ph);
- delta_ph = (st->hsize_in << 16) / st->hsize_out;
+ delta_ph = (st->total_hsize_in << 16) / st->total_hsize_out;
malidp_write32(reg, SC_H_DELTA_PH, delta_ph);
- init_ph = (st->vsize_in << 15) / st->vsize_out;
+ init_ph = (st->total_vsize_in << 15) / st->vsize_out;
malidp_write32(reg, SC_V_INIT_PH, init_ph);
- delta_ph = (st->vsize_in << 16) / st->vsize_out;
+ delta_ph = (st->total_vsize_in << 16) / st->vsize_out;
malidp_write32(reg, SC_V_DELTA_PH, delta_ph);
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;
+ /* If we use the hardware splitter we shouldn't set SC_CTRL_LS */
+ if (st->en_split &&
+ state->inputs[0].component->id != KOMEDA_COMPONENT_SPLITTER)
+ ctrl |= SC_CTRL_LS;
malidp_write32(reg, BLK_CONTROL, ctrl);
malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));
@@ -716,10 +751,12 @@ static int d71_scaler_init(struct d71_dev *d71,
}
scaler = to_scaler(c);
- set_range(&scaler->hsize, 4, d71->max_line_size);
+ set_range(&scaler->hsize, 4, 2048);
set_range(&scaler->vsize, 4, 4096);
scaler->max_downscaling = 6;
scaler->max_upscaling = 64;
+ scaler->scaling_split_overlap = 8;
+ scaler->enh_split_overlap = 1;
malidp_write32(c->reg, BLK_CONTROL, 0);