drm: mali-dp: Add CTM support
All DPs have a COLORADJ matrix which is applied prior to output gamma. Attach that to the CTM property. Also, ensure the input CTM's coefficients can fit in the DP registers' Q3.12 format. Signed-off-by: Mihail Atanassov <mihail.atanassov@arm.com> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
This commit is contained in:
parent
02725d3137
commit
6954f24588
|
@ -195,6 +195,58 @@ static int malidp_crtc_atomic_check_gamma(struct drm_crtc *crtc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if there is a new CTM and if it contains valid input. Valid here means
|
||||
* that the number is inside the representable range for a Q3.12 number,
|
||||
* excluding truncating the fractional part of the input data.
|
||||
*
|
||||
* The COLORADJ registers can be changed atomically.
|
||||
*/
|
||||
static int malidp_crtc_atomic_check_ctm(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state)
|
||||
{
|
||||
struct malidp_crtc_state *mc = to_malidp_crtc_state(state);
|
||||
struct drm_color_ctm *ctm;
|
||||
int i;
|
||||
|
||||
if (!state->color_mgmt_changed)
|
||||
return 0;
|
||||
|
||||
if (!state->ctm)
|
||||
return 0;
|
||||
|
||||
if (crtc->state->ctm && (crtc->state->ctm->base.id ==
|
||||
state->ctm->base.id))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The size of the ctm is checked in
|
||||
* drm_atomic_replace_property_blob_from_id.
|
||||
*/
|
||||
ctm = (struct drm_color_ctm *)state->ctm->data;
|
||||
for (i = 0; i < ARRAY_SIZE(ctm->matrix); ++i) {
|
||||
/* Convert from S31.32 to Q3.12. */
|
||||
s64 val = ctm->matrix[i];
|
||||
u32 mag = ((((u64)val) & ~BIT_ULL(63)) >> 20) &
|
||||
GENMASK_ULL(14, 0);
|
||||
|
||||
/*
|
||||
* Convert to 2s complement and check the destination's top bit
|
||||
* for overflow. NB: Can't check before converting or it'd
|
||||
* incorrectly reject the case:
|
||||
* sign == 1
|
||||
* mag == 0x2000
|
||||
*/
|
||||
if (val & BIT_ULL(63))
|
||||
mag = ~mag + 1;
|
||||
if (!!(val & BIT_ULL(63)) != !!(mag & BIT(14)))
|
||||
return -EINVAL;
|
||||
mc->coloradj_coeffs[i] = mag;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state)
|
||||
{
|
||||
|
@ -204,6 +256,7 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
|
|||
const struct drm_plane_state *pstate;
|
||||
u32 rot_mem_free, rot_mem_usable;
|
||||
int rotated_planes = 0;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* check if there is enough rotation memory available for planes
|
||||
|
@ -270,7 +323,10 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
|
|||
}
|
||||
}
|
||||
|
||||
return malidp_crtc_atomic_check_gamma(crtc, state);
|
||||
ret = malidp_crtc_atomic_check_gamma(crtc, state);
|
||||
ret = ret ? ret : malidp_crtc_atomic_check_ctm(crtc, state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = {
|
||||
|
@ -295,6 +351,8 @@ static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc)
|
|||
__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
|
||||
memcpy(state->gamma_coeffs, old_state->gamma_coeffs,
|
||||
sizeof(state->gamma_coeffs));
|
||||
memcpy(state->coloradj_coeffs, old_state->coloradj_coeffs,
|
||||
sizeof(state->coloradj_coeffs));
|
||||
|
||||
return &state->base;
|
||||
}
|
||||
|
@ -392,8 +450,8 @@ int malidp_crtc_init(struct drm_device *drm)
|
|||
|
||||
drm_crtc_helper_add(&malidp->crtc, &malidp_crtc_helper_funcs);
|
||||
drm_mode_crtc_set_gamma_size(&malidp->crtc, MALIDP_GAMMA_LUT_SIZE);
|
||||
/* No inverse-gamma and color adjustments yet. */
|
||||
drm_crtc_enable_color_mgmt(&malidp->crtc, 0, false, MALIDP_GAMMA_LUT_SIZE);
|
||||
/* No inverse-gamma: it is per-plane */
|
||||
drm_crtc_enable_color_mgmt(&malidp->crtc, 0, true, MALIDP_GAMMA_LUT_SIZE);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -79,6 +79,37 @@ static void malidp_atomic_commit_update_gamma(struct drm_crtc *crtc,
|
|||
}
|
||||
}
|
||||
|
||||
static
|
||||
void malidp_atomic_commit_update_coloradj(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_state)
|
||||
{
|
||||
struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
|
||||
struct malidp_hw_device *hwdev = malidp->dev;
|
||||
int i;
|
||||
|
||||
if (!crtc->state->color_mgmt_changed)
|
||||
return;
|
||||
|
||||
if (!crtc->state->ctm) {
|
||||
malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_CADJ,
|
||||
MALIDP_DE_DISPLAY_FUNC);
|
||||
} else {
|
||||
struct malidp_crtc_state *mc =
|
||||
to_malidp_crtc_state(crtc->state);
|
||||
|
||||
if (!old_state->ctm || (crtc->state->ctm->base.id !=
|
||||
old_state->ctm->base.id))
|
||||
for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; ++i)
|
||||
malidp_hw_write(hwdev,
|
||||
mc->coloradj_coeffs[i],
|
||||
hwdev->map.coeffs_base +
|
||||
MALIDP_COLOR_ADJ_COEF + 4 * i);
|
||||
|
||||
malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_CADJ,
|
||||
MALIDP_DE_DISPLAY_FUNC);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* set the "config valid" bit and wait until the hardware acts on it
|
||||
*/
|
||||
|
@ -145,8 +176,10 @@ static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
|
||||
drm_atomic_helper_commit_modeset_disables(drm, state);
|
||||
|
||||
for_each_crtc_in_state(state, crtc, old_crtc_state, i)
|
||||
for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
|
||||
malidp_atomic_commit_update_gamma(crtc, old_crtc_state);
|
||||
malidp_atomic_commit_update_coloradj(crtc, old_crtc_state);
|
||||
}
|
||||
|
||||
drm_atomic_helper_commit_planes(drm, state, 0);
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ struct malidp_plane_state {
|
|||
struct malidp_crtc_state {
|
||||
struct drm_crtc_state base;
|
||||
u32 gamma_coeffs[MALIDP_COEFFTAB_NUM_COEFFS];
|
||||
u32 coloradj_coeffs[MALIDP_COLORADJ_NUM_COEFFS];
|
||||
};
|
||||
|
||||
#define to_malidp_crtc_state(x) container_of(x, struct malidp_crtc_state, base)
|
||||
|
|
|
@ -259,6 +259,7 @@ static inline bool malidp_hw_pitch_valid(struct malidp_hw_device *hwdev,
|
|||
#define MALIDP_BGND_COLOR_G 0x000
|
||||
#define MALIDP_BGND_COLOR_B 0x000
|
||||
|
||||
#define MALIDP_COLORADJ_NUM_COEFFS 12
|
||||
#define MALIDP_COEFFTAB_NUM_COEFFS 64
|
||||
|
||||
#define MALIDP_GAMMA_LUT_SIZE 4096
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
/* bit masks that are common between products */
|
||||
#define MALIDP_CFG_VALID (1 << 0)
|
||||
#define MALIDP_DISP_FUNC_GAMMA (1 << 0)
|
||||
#define MALIDP_DISP_FUNC_CADJ (1 << 4)
|
||||
#define MALIDP_DISP_FUNC_ILACED (1 << 8)
|
||||
|
||||
/* register offsets for IRQ management */
|
||||
|
|
Loading…
Reference in New Issue