mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
drm/omapdrm: Implement gamma_lut atomic crtc properties
Implement gamma_lut atomic crtc properties, set crtc gamma size to 256 for all crtcs and use drm_atomic_helper_legacy_gamma_set() as gamma_set func. The tv-out crtc has 1024 element gamma table (with 10bit precision) in HW, but current Xorg server does not accept anything else but 256 elements so that is used for all CRTCs. The dss dispc API converts table of any length for HW and uses linear interpolation in the process. The default gamma table is restored if gamma_lut property is deleted. Signed-off-by: Jyri Sarha <jsarha@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
parent
fbff010bd0
commit
492a426a2f
1 changed files with 56 additions and 0 deletions
|
@ -372,6 +372,20 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
|||
copy_timings_drm_to_omap(&omap_crtc->timings, mode);
|
||||
}
|
||||
|
||||
static int omap_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state)
|
||||
{
|
||||
if (state->color_mgmt_changed && state->gamma_lut) {
|
||||
uint length = state->gamma_lut->length /
|
||||
sizeof(struct drm_color_lut);
|
||||
|
||||
if (length < 2)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap_crtc_atomic_begin(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
|
@ -384,6 +398,32 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
|
|||
|
||||
WARN_ON(omap_crtc->vblank_irq.registered);
|
||||
|
||||
if (crtc->state->color_mgmt_changed) {
|
||||
struct drm_color_lut *lut = NULL;
|
||||
uint length = 0;
|
||||
|
||||
if (crtc->state->gamma_lut) {
|
||||
lut = (struct drm_color_lut *)
|
||||
crtc->state->gamma_lut->data;
|
||||
length = crtc->state->gamma_lut->length /
|
||||
sizeof(*lut);
|
||||
}
|
||||
dispc_mgr_set_gamma(omap_crtc->channel, lut, length);
|
||||
}
|
||||
|
||||
if (crtc->state->color_mgmt_changed) {
|
||||
struct drm_color_lut *lut = NULL;
|
||||
uint length = 0;
|
||||
|
||||
if (crtc->state->gamma_lut) {
|
||||
lut = (struct drm_color_lut *)
|
||||
crtc->state->gamma_lut->data;
|
||||
length = crtc->state->gamma_lut->length /
|
||||
sizeof(*lut);
|
||||
}
|
||||
dispc_mgr_set_gamma(omap_crtc->channel, lut, length);
|
||||
}
|
||||
|
||||
if (dispc_mgr_is_enabled(omap_crtc->channel)) {
|
||||
|
||||
DBG("%s: GO", omap_crtc->name);
|
||||
|
@ -460,6 +500,7 @@ static const struct drm_crtc_funcs omap_crtc_funcs = {
|
|||
.set_config = drm_atomic_helper_set_config,
|
||||
.destroy = omap_crtc_destroy,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.gamma_set = drm_atomic_helper_legacy_gamma_set,
|
||||
.set_property = drm_atomic_helper_crtc_set_property,
|
||||
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
|
||||
|
@ -471,6 +512,7 @@ static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
|
|||
.mode_set_nofb = omap_crtc_mode_set_nofb,
|
||||
.disable = omap_crtc_disable,
|
||||
.enable = omap_crtc_enable,
|
||||
.atomic_check = omap_crtc_atomic_check,
|
||||
.atomic_begin = omap_crtc_atomic_begin,
|
||||
.atomic_flush = omap_crtc_atomic_flush,
|
||||
};
|
||||
|
@ -534,6 +576,20 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
|||
|
||||
drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
|
||||
|
||||
/* The dispc API adapts to what ever size, but the HW supports
|
||||
* 256 element gamma table for LCDs and 1024 element table for
|
||||
* OMAP_DSS_CHANNEL_DIGIT. X server assumes 256 element gamma
|
||||
* tables so lets use that. Size of HW gamma table can be
|
||||
* extracted with dispc_mgr_gamma_size(). If it returns 0
|
||||
* gamma table is not supprted.
|
||||
*/
|
||||
if (dispc_mgr_gamma_size(channel)) {
|
||||
uint gamma_lut_size = 256;
|
||||
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size);
|
||||
drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size);
|
||||
}
|
||||
|
||||
omap_plane_install_properties(crtc->primary, &crtc->base);
|
||||
|
||||
omap_crtcs[channel] = omap_crtc;
|
||||
|
|
Loading…
Reference in a new issue