|
32 | 32 | #include "intel_display_utils.h" |
33 | 33 | #include "intel_dsb.h" |
34 | 34 | #include "intel_vrr.h" |
| 35 | +#include "skl_universal_plane.h" |
| 36 | +#include "skl_universal_plane_regs.h" |
35 | 37 |
|
36 | 38 | struct intel_color_funcs { |
37 | 39 | int (*color_check)(struct intel_atomic_state *state, |
@@ -3842,6 +3844,101 @@ static void icl_read_luts(struct intel_crtc_state *crtc_state) |
3842 | 3844 | } |
3843 | 3845 | } |
3844 | 3846 |
|
| 3847 | +static void |
| 3848 | +xelpd_load_plane_csc_matrix(struct intel_dsb *dsb, |
| 3849 | + const struct intel_plane_state *plane_state) |
| 3850 | +{ |
| 3851 | + struct intel_display *display = to_intel_display(plane_state); |
| 3852 | + const struct drm_plane_state *state = &plane_state->uapi; |
| 3853 | + enum pipe pipe = to_intel_plane(state->plane)->pipe; |
| 3854 | + enum plane_id plane = to_intel_plane(state->plane)->id; |
| 3855 | + const struct drm_property_blob *blob = plane_state->hw.ctm; |
| 3856 | + struct drm_color_ctm_3x4 *ctm; |
| 3857 | + const u64 *input; |
| 3858 | + u16 coeffs[9] = {}; |
| 3859 | + int i, j; |
| 3860 | + |
| 3861 | + if (!icl_is_hdr_plane(display, plane) || !blob) |
| 3862 | + return; |
| 3863 | + |
| 3864 | + ctm = blob->data; |
| 3865 | + input = ctm->matrix; |
| 3866 | + |
| 3867 | + /* |
| 3868 | + * Convert fixed point S31.32 input to format supported by the |
| 3869 | + * hardware. |
| 3870 | + */ |
| 3871 | + for (i = 0, j = 0; i < ARRAY_SIZE(coeffs); i++) { |
| 3872 | + u64 abs_coeff = ((1ULL << 63) - 1) & input[j]; |
| 3873 | + |
| 3874 | + /* |
| 3875 | + * Clamp input value to min/max supported by |
| 3876 | + * hardware. |
| 3877 | + */ |
| 3878 | + abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1); |
| 3879 | + |
| 3880 | + /* sign bit */ |
| 3881 | + if (CTM_COEFF_NEGATIVE(input[j])) |
| 3882 | + coeffs[i] |= 1 << 15; |
| 3883 | + |
| 3884 | + if (abs_coeff < CTM_COEFF_0_125) |
| 3885 | + coeffs[i] |= (3 << 12) | |
| 3886 | + ILK_CSC_COEFF_FP(abs_coeff, 12); |
| 3887 | + else if (abs_coeff < CTM_COEFF_0_25) |
| 3888 | + coeffs[i] |= (2 << 12) | |
| 3889 | + ILK_CSC_COEFF_FP(abs_coeff, 11); |
| 3890 | + else if (abs_coeff < CTM_COEFF_0_5) |
| 3891 | + coeffs[i] |= (1 << 12) | |
| 3892 | + ILK_CSC_COEFF_FP(abs_coeff, 10); |
| 3893 | + else if (abs_coeff < CTM_COEFF_1_0) |
| 3894 | + coeffs[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9); |
| 3895 | + else if (abs_coeff < CTM_COEFF_2_0) |
| 3896 | + coeffs[i] |= (7 << 12) | |
| 3897 | + ILK_CSC_COEFF_FP(abs_coeff, 8); |
| 3898 | + else |
| 3899 | + coeffs[i] |= (6 << 12) | |
| 3900 | + ILK_CSC_COEFF_FP(abs_coeff, 7); |
| 3901 | + |
| 3902 | + /* Skip postoffs */ |
| 3903 | + if (!((j + 2) % 4)) |
| 3904 | + j += 2; |
| 3905 | + else |
| 3906 | + j++; |
| 3907 | + } |
| 3908 | + |
| 3909 | + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 0), |
| 3910 | + coeffs[0] << 16 | coeffs[1]); |
| 3911 | + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 1), |
| 3912 | + coeffs[2] << 16); |
| 3913 | + |
| 3914 | + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 2), |
| 3915 | + coeffs[3] << 16 | coeffs[4]); |
| 3916 | + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 3), |
| 3917 | + coeffs[5] << 16); |
| 3918 | + |
| 3919 | + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 4), |
| 3920 | + coeffs[6] << 16 | coeffs[7]); |
| 3921 | + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 5), |
| 3922 | + coeffs[8] << 16); |
| 3923 | + |
| 3924 | + intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane, 0), 0); |
| 3925 | + intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane, 1), 0); |
| 3926 | + intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane, 2), 0); |
| 3927 | + |
| 3928 | + /* |
| 3929 | + * Conversion from S31.32 to S0.12. BIT[12] is the signed bit |
| 3930 | + */ |
| 3931 | + intel_de_write_dsb(display, dsb, |
| 3932 | + PLANE_CSC_POSTOFF(pipe, plane, 0), |
| 3933 | + ctm_to_twos_complement(input[3], 0, 12)); |
| 3934 | + intel_de_write_dsb(display, dsb, |
| 3935 | + PLANE_CSC_POSTOFF(pipe, plane, 1), |
| 3936 | + ctm_to_twos_complement(input[7], 0, 12)); |
| 3937 | + intel_de_write_dsb(display, dsb, |
| 3938 | + PLANE_CSC_POSTOFF(pipe, plane, 2), |
| 3939 | + ctm_to_twos_complement(input[11], 0, 12)); |
| 3940 | +} |
| 3941 | + |
3845 | 3942 | static const struct intel_color_funcs chv_color_funcs = { |
3846 | 3943 | .color_check = chv_color_check, |
3847 | 3944 | .color_commit_arm = i9xx_color_commit_arm, |
@@ -3889,6 +3986,7 @@ static const struct intel_color_funcs tgl_color_funcs = { |
3889 | 3986 | .lut_equal = icl_lut_equal, |
3890 | 3987 | .read_csc = icl_read_csc, |
3891 | 3988 | .get_config = skl_get_config, |
| 3989 | + .load_plane_csc_matrix = xelpd_load_plane_csc_matrix, |
3892 | 3990 | }; |
3893 | 3991 |
|
3894 | 3992 | static const struct intel_color_funcs icl_color_funcs = { |
|
0 commit comments