Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 71 additions & 8 deletions drivers/gpu/drm/vc4/vc4_hvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1845,9 +1845,71 @@ static const struct vc6_csc_coeff_entry csc_coeffs[2][3] = {
}
};

/*
* GEN_6D has a 3x3 matrix of signed 3p12 fixed point values, signed 13bit
* offset, and high and low clamp values. The offset can be applied before or
* after the multiply - for use here for YUV to RGB conversion it is easier to
* put it before.
* Clamp values are always set to max 0xfff and min 0, and the conversion always
* has the offset before the multiply.
*/
struct vc6_d0_csc_coeff_entry {
u32 csc[3][2];
};

static const struct vc6_d0_csc_coeff_entry vc6_d0_csc_coeffs[2][3] = {
[DRM_COLOR_YCBCR_LIMITED_RANGE] = {
[DRM_COLOR_YCBCR_BT601] = {
.csc = {
{ 0x1f002543, 0x00003313 },
{ 0x18002543, 0xf377e5fc },
{ 0x18002543, 0x408d0000 }
}
},
[DRM_COLOR_YCBCR_BT709] = {
.csc = {
{ 0x1f002543, 0x0000395e },
{ 0x18002543, 0xf92deef2 },
{ 0x18002543, 0x43990000 }
}
},
[DRM_COLOR_YCBCR_BT2020] = {
.csc = {
{ 0x1f002543, 0x000035a0 },
{ 0x18002543, 0xfa00eb20 },
{ 0x18002543, 0x44800000 }
}
}
},
[DRM_COLOR_YCBCR_FULL_RANGE] = {
[DRM_COLOR_YCBCR_BT601] = {
.csc = {
{ 0x00002000, 0x00002cdd },
{ 0x18002000, 0xf4fde926 },
{ 0x18002000, 0x38b40000 }
}
},
[DRM_COLOR_YCBCR_BT709] = {
.csc = {
{ 0x00002000, 0x00003265 },
{ 0x18002000, 0xfa01f105 },
{ 0x18002000, 0x3b610000 }
}
},
[DRM_COLOR_YCBCR_BT2020] = {
.csc = {
{ 0x00002000, 0x00002f30 },
{ 0x18002000, 0xfabcedb7 },
{ 0x18002000, 0x3c340000 }
}
}
}
};

static int vc6_hvs_hw_init(struct vc4_hvs *hvs)
{
const struct vc6_csc_coeff_entry *coeffs;
const struct vc6_d0_csc_coeff_entry *d0_coeffs;
unsigned int i;

HVS_WRITE(SCALER6_CONTROL,
Expand Down Expand Up @@ -1884,16 +1946,17 @@ static int vc6_hvs_hw_init(struct vc4_hvs *hvs)
HVS_WRITE(CFC1_N_NL_CSC_CTRL(i), BIT(15));
}
} else {
for (i = 0; i < 8; i++) {
HVS_WRITE(SCALER_PI_CMP_CSC_RED0(i), 0x1f002566);
HVS_WRITE(SCALER_PI_CMP_CSC_RED1(i), 0x3994);
for (i = 0; i < 6; i++) {
d0_coeffs = &vc6_d0_csc_coeffs[i / 3][i % 3];
HVS_WRITE(SCALER_PI_CMP_CSC_RED0(i), d0_coeffs->csc[0][0]);
HVS_WRITE(SCALER_PI_CMP_CSC_RED1(i), d0_coeffs->csc[0][1]);
HVS_WRITE(SCALER_PI_CMP_CSC_RED_CLAMP(i), 0xfff00000);
HVS_WRITE(SCALER_PI_CMP_CSC_CFG(i), 0x1);
HVS_WRITE(SCALER_PI_CMP_CSC_GREEN0(i), 0x18002566);
HVS_WRITE(SCALER_PI_CMP_CSC_GREEN1(i), 0xf927eee2);
HVS_WRITE(SCALER_PI_CMP_CSC_CFG(i), 1);
HVS_WRITE(SCALER_PI_CMP_CSC_GREEN0(i), d0_coeffs->csc[1][0]);
HVS_WRITE(SCALER_PI_CMP_CSC_GREEN1(i), d0_coeffs->csc[1][1]);
HVS_WRITE(SCALER_PI_CMP_CSC_GREEN_CLAMP(i), 0xfff00000);
HVS_WRITE(SCALER_PI_CMP_CSC_BLUE0(i), 0x18002566);
HVS_WRITE(SCALER_PI_CMP_CSC_BLUE1(i), 0x43d80000);
HVS_WRITE(SCALER_PI_CMP_CSC_BLUE0(i), d0_coeffs->csc[2][0]);
HVS_WRITE(SCALER_PI_CMP_CSC_BLUE1(i), d0_coeffs->csc[2][1]);
HVS_WRITE(SCALER_PI_CMP_CSC_BLUE_CLAMP(i), 0xfff00000);
}
}
Expand Down