drm: mali-dp: Add plane upscaling support
Enable the scaling engine for upscaling a single plane using the polyphase scaler. No image enhancement support or downscaling yet*, and composition result scaling is not implemented. * Downscaling a plane requires mclk > pxlclk. Signed-off-by: Mihail Atanassov <mihail.atanassov@arm.com> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
This commit is contained in:

committad av
Liviu Dudau

förälder
50c7512fd7
incheckning
28ce675b74
@@ -86,6 +86,80 @@ static const struct malidp_layer malidp550_layers[] = {
|
||||
{ DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE },
|
||||
};
|
||||
|
||||
#define SE_N_SCALING_COEFFS 96
|
||||
static const u16 dp500_se_scaling_coeffs[][SE_N_SCALING_COEFFS] = {
|
||||
[MALIDP_UPSCALING_COEFFS - 1] = {
|
||||
0x0000, 0x0001, 0x0007, 0x0011, 0x001e, 0x002e, 0x003f, 0x0052,
|
||||
0x0064, 0x0073, 0x007d, 0x0080, 0x007a, 0x006c, 0x0053, 0x002f,
|
||||
0x0000, 0x3fc6, 0x3f83, 0x3f39, 0x3eea, 0x3e9b, 0x3e4f, 0x3e0a,
|
||||
0x3dd4, 0x3db0, 0x3da2, 0x3db1, 0x3dde, 0x3e2f, 0x3ea5, 0x3f40,
|
||||
0x0000, 0x00e5, 0x01ee, 0x0315, 0x0456, 0x05aa, 0x0709, 0x086c,
|
||||
0x09c9, 0x0b15, 0x0c4a, 0x0d5d, 0x0e4a, 0x0f06, 0x0f91, 0x0fe5,
|
||||
0x1000, 0x0fe5, 0x0f91, 0x0f06, 0x0e4a, 0x0d5d, 0x0c4a, 0x0b15,
|
||||
0x09c9, 0x086c, 0x0709, 0x05aa, 0x0456, 0x0315, 0x01ee, 0x00e5,
|
||||
0x0000, 0x3f40, 0x3ea5, 0x3e2f, 0x3dde, 0x3db1, 0x3da2, 0x3db0,
|
||||
0x3dd4, 0x3e0a, 0x3e4f, 0x3e9b, 0x3eea, 0x3f39, 0x3f83, 0x3fc6,
|
||||
0x0000, 0x002f, 0x0053, 0x006c, 0x007a, 0x0080, 0x007d, 0x0073,
|
||||
0x0064, 0x0052, 0x003f, 0x002e, 0x001e, 0x0011, 0x0007, 0x0001
|
||||
},
|
||||
[MALIDP_DOWNSCALING_1_5_COEFFS - 1] = {
|
||||
0x0059, 0x004f, 0x0041, 0x002e, 0x0016, 0x3ffb, 0x3fd9, 0x3fb4,
|
||||
0x3f8c, 0x3f62, 0x3f36, 0x3f09, 0x3edd, 0x3eb3, 0x3e8d, 0x3e6c,
|
||||
0x3e52, 0x3e3f, 0x3e35, 0x3e37, 0x3e46, 0x3e61, 0x3e8c, 0x3ec5,
|
||||
0x3f0f, 0x3f68, 0x3fd1, 0x004a, 0x00d3, 0x0169, 0x020b, 0x02b8,
|
||||
0x036e, 0x042d, 0x04f2, 0x05b9, 0x0681, 0x0745, 0x0803, 0x08ba,
|
||||
0x0965, 0x0a03, 0x0a91, 0x0b0d, 0x0b75, 0x0bc6, 0x0c00, 0x0c20,
|
||||
0x0c28, 0x0c20, 0x0c00, 0x0bc6, 0x0b75, 0x0b0d, 0x0a91, 0x0a03,
|
||||
0x0965, 0x08ba, 0x0803, 0x0745, 0x0681, 0x05b9, 0x04f2, 0x042d,
|
||||
0x036e, 0x02b8, 0x020b, 0x0169, 0x00d3, 0x004a, 0x3fd1, 0x3f68,
|
||||
0x3f0f, 0x3ec5, 0x3e8c, 0x3e61, 0x3e46, 0x3e37, 0x3e35, 0x3e3f,
|
||||
0x3e52, 0x3e6c, 0x3e8d, 0x3eb3, 0x3edd, 0x3f09, 0x3f36, 0x3f62,
|
||||
0x3f8c, 0x3fb4, 0x3fd9, 0x3ffb, 0x0016, 0x002e, 0x0041, 0x004f
|
||||
},
|
||||
[MALIDP_DOWNSCALING_2_COEFFS - 1] = {
|
||||
0x3f19, 0x3f03, 0x3ef0, 0x3edf, 0x3ed0, 0x3ec5, 0x3ebd, 0x3eb9,
|
||||
0x3eb9, 0x3ebf, 0x3eca, 0x3ed9, 0x3eef, 0x3f0a, 0x3f2c, 0x3f52,
|
||||
0x3f7f, 0x3fb0, 0x3fe8, 0x0026, 0x006a, 0x00b4, 0x0103, 0x0158,
|
||||
0x01b1, 0x020d, 0x026c, 0x02cd, 0x032f, 0x0392, 0x03f4, 0x0455,
|
||||
0x04b4, 0x051e, 0x0585, 0x05eb, 0x064c, 0x06a8, 0x06fe, 0x074e,
|
||||
0x0796, 0x07d5, 0x080c, 0x0839, 0x085c, 0x0875, 0x0882, 0x0887,
|
||||
0x0881, 0x0887, 0x0882, 0x0875, 0x085c, 0x0839, 0x080c, 0x07d5,
|
||||
0x0796, 0x074e, 0x06fe, 0x06a8, 0x064c, 0x05eb, 0x0585, 0x051e,
|
||||
0x04b4, 0x0455, 0x03f4, 0x0392, 0x032f, 0x02cd, 0x026c, 0x020d,
|
||||
0x01b1, 0x0158, 0x0103, 0x00b4, 0x006a, 0x0026, 0x3fe8, 0x3fb0,
|
||||
0x3f7f, 0x3f52, 0x3f2c, 0x3f0a, 0x3eef, 0x3ed9, 0x3eca, 0x3ebf,
|
||||
0x3eb9, 0x3eb9, 0x3ebd, 0x3ec5, 0x3ed0, 0x3edf, 0x3ef0, 0x3f03
|
||||
},
|
||||
[MALIDP_DOWNSCALING_2_75_COEFFS - 1] = {
|
||||
0x3f51, 0x3f60, 0x3f71, 0x3f84, 0x3f98, 0x3faf, 0x3fc8, 0x3fe3,
|
||||
0x0000, 0x001f, 0x0040, 0x0064, 0x008a, 0x00b1, 0x00da, 0x0106,
|
||||
0x0133, 0x0160, 0x018e, 0x01bd, 0x01ec, 0x021d, 0x024e, 0x0280,
|
||||
0x02b2, 0x02e4, 0x0317, 0x0349, 0x037c, 0x03ad, 0x03df, 0x0410,
|
||||
0x0440, 0x0468, 0x048f, 0x04b3, 0x04d6, 0x04f8, 0x0516, 0x0533,
|
||||
0x054e, 0x0566, 0x057c, 0x0590, 0x05a0, 0x05ae, 0x05ba, 0x05c3,
|
||||
0x05c9, 0x05c3, 0x05ba, 0x05ae, 0x05a0, 0x0590, 0x057c, 0x0566,
|
||||
0x054e, 0x0533, 0x0516, 0x04f8, 0x04d6, 0x04b3, 0x048f, 0x0468,
|
||||
0x0440, 0x0410, 0x03df, 0x03ad, 0x037c, 0x0349, 0x0317, 0x02e4,
|
||||
0x02b2, 0x0280, 0x024e, 0x021d, 0x01ec, 0x01bd, 0x018e, 0x0160,
|
||||
0x0133, 0x0106, 0x00da, 0x00b1, 0x008a, 0x0064, 0x0040, 0x001f,
|
||||
0x0000, 0x3fe3, 0x3fc8, 0x3faf, 0x3f98, 0x3f84, 0x3f71, 0x3f60
|
||||
},
|
||||
[MALIDP_DOWNSCALING_4_COEFFS - 1] = {
|
||||
0x0094, 0x00a9, 0x00be, 0x00d4, 0x00ea, 0x0101, 0x0118, 0x012f,
|
||||
0x0148, 0x0160, 0x017a, 0x0193, 0x01ae, 0x01c8, 0x01e4, 0x01ff,
|
||||
0x021c, 0x0233, 0x024a, 0x0261, 0x0278, 0x028f, 0x02a6, 0x02bd,
|
||||
0x02d4, 0x02eb, 0x0302, 0x0319, 0x032f, 0x0346, 0x035d, 0x0374,
|
||||
0x038a, 0x0397, 0x03a3, 0x03af, 0x03bb, 0x03c6, 0x03d1, 0x03db,
|
||||
0x03e4, 0x03ed, 0x03f6, 0x03fe, 0x0406, 0x040d, 0x0414, 0x041a,
|
||||
0x0420, 0x041a, 0x0414, 0x040d, 0x0406, 0x03fe, 0x03f6, 0x03ed,
|
||||
0x03e4, 0x03db, 0x03d1, 0x03c6, 0x03bb, 0x03af, 0x03a3, 0x0397,
|
||||
0x038a, 0x0374, 0x035d, 0x0346, 0x032f, 0x0319, 0x0302, 0x02eb,
|
||||
0x02d4, 0x02bd, 0x02a6, 0x028f, 0x0278, 0x0261, 0x024a, 0x0233,
|
||||
0x021c, 0x01ff, 0x01e4, 0x01c8, 0x01ae, 0x0193, 0x017a, 0x0160,
|
||||
0x0148, 0x012f, 0x0118, 0x0101, 0x00ea, 0x00d4, 0x00be, 0x00a9
|
||||
},
|
||||
};
|
||||
|
||||
#define MALIDP_DE_DEFAULT_PREFETCH_START 5
|
||||
|
||||
static int malidp500_query_hw(struct malidp_hw_device *hwdev)
|
||||
@@ -211,6 +285,55 @@ static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
|
||||
return w * drm_format_plane_cpp(fmt, 0) * 8;
|
||||
}
|
||||
|
||||
static void malidp500_se_write_pp_coefftab(struct malidp_hw_device *hwdev,
|
||||
u32 direction,
|
||||
u16 addr,
|
||||
u8 coeffs_id)
|
||||
{
|
||||
int i;
|
||||
u16 scaling_control = MALIDP500_SE_CONTROL + MALIDP_SE_SCALING_CONTROL;
|
||||
|
||||
malidp_hw_write(hwdev,
|
||||
direction | (addr & MALIDP_SE_COEFFTAB_ADDR_MASK),
|
||||
scaling_control + MALIDP_SE_COEFFTAB_ADDR);
|
||||
for (i = 0; i < ARRAY_SIZE(dp500_se_scaling_coeffs); ++i)
|
||||
malidp_hw_write(hwdev, MALIDP_SE_SET_COEFFTAB_DATA(
|
||||
dp500_se_scaling_coeffs[coeffs_id][i]),
|
||||
scaling_control + MALIDP_SE_COEFFTAB_DATA);
|
||||
}
|
||||
|
||||
static int malidp500_se_set_scaling_coeffs(struct malidp_hw_device *hwdev,
|
||||
struct malidp_se_config *se_config,
|
||||
struct malidp_se_config *old_config)
|
||||
{
|
||||
/* Get array indices into dp500_se_scaling_coeffs. */
|
||||
u8 h = (u8)se_config->hcoeff - 1;
|
||||
u8 v = (u8)se_config->vcoeff - 1;
|
||||
|
||||
if (WARN_ON(h >= ARRAY_SIZE(dp500_se_scaling_coeffs) ||
|
||||
v >= ARRAY_SIZE(dp500_se_scaling_coeffs)))
|
||||
return -EINVAL;
|
||||
|
||||
if ((h == v) && (se_config->hcoeff != old_config->hcoeff ||
|
||||
se_config->vcoeff != old_config->vcoeff)) {
|
||||
malidp500_se_write_pp_coefftab(hwdev,
|
||||
(MALIDP_SE_V_COEFFTAB |
|
||||
MALIDP_SE_H_COEFFTAB),
|
||||
0, v);
|
||||
} else {
|
||||
if (se_config->vcoeff != old_config->vcoeff)
|
||||
malidp500_se_write_pp_coefftab(hwdev,
|
||||
MALIDP_SE_V_COEFFTAB,
|
||||
0, v);
|
||||
if (se_config->hcoeff != old_config->hcoeff)
|
||||
malidp500_se_write_pp_coefftab(hwdev,
|
||||
MALIDP_SE_H_COEFFTAB,
|
||||
0, h);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int malidp550_query_hw(struct malidp_hw_device *hwdev)
|
||||
{
|
||||
u32 conf = malidp_hw_read(hwdev, MALIDP550_CONFIG_ID);
|
||||
@@ -384,6 +507,20 @@ static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
|
||||
return w * bytes_per_col;
|
||||
}
|
||||
|
||||
static int malidp550_se_set_scaling_coeffs(struct malidp_hw_device *hwdev,
|
||||
struct malidp_se_config *se_config,
|
||||
struct malidp_se_config *old_config)
|
||||
{
|
||||
u32 mask = MALIDP550_SE_CTL_VCSEL(MALIDP550_SE_CTL_SEL_MASK) |
|
||||
MALIDP550_SE_CTL_HCSEL(MALIDP550_SE_CTL_SEL_MASK);
|
||||
u32 new_value = MALIDP550_SE_CTL_VCSEL(se_config->vcoeff) |
|
||||
MALIDP550_SE_CTL_HCSEL(se_config->hcoeff);
|
||||
|
||||
malidp_hw_clearbits(hwdev, mask, MALIDP550_SE_CONTROL);
|
||||
malidp_hw_setbits(hwdev, new_value, MALIDP550_SE_CONTROL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int malidp650_query_hw(struct malidp_hw_device *hwdev)
|
||||
{
|
||||
u32 conf = malidp_hw_read(hwdev, MALIDP550_CONFIG_ID);
|
||||
@@ -448,6 +585,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = {
|
||||
.set_config_valid = malidp500_set_config_valid,
|
||||
.modeset = malidp500_modeset,
|
||||
.rotmem_required = malidp500_rotmem_required,
|
||||
.se_set_scaling_coeffs = malidp500_se_set_scaling_coeffs,
|
||||
.features = MALIDP_DEVICE_LV_HAS_3_STRIDES,
|
||||
},
|
||||
[MALIDP_550] = {
|
||||
@@ -483,6 +621,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = {
|
||||
.set_config_valid = malidp550_set_config_valid,
|
||||
.modeset = malidp550_modeset,
|
||||
.rotmem_required = malidp550_rotmem_required,
|
||||
.se_set_scaling_coeffs = malidp550_se_set_scaling_coeffs,
|
||||
.features = 0,
|
||||
},
|
||||
[MALIDP_650] = {
|
||||
@@ -519,6 +658,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = {
|
||||
.set_config_valid = malidp550_set_config_valid,
|
||||
.modeset = malidp550_modeset,
|
||||
.rotmem_required = malidp550_rotmem_required,
|
||||
.se_set_scaling_coeffs = malidp550_se_set_scaling_coeffs,
|
||||
.features = 0,
|
||||
},
|
||||
};
|
||||
|
Referens i nytt ärende
Block a user