1
0
Fork 0

drm/sun4i: Implement gamma correction

Add support for gamma corretion to sun4i TCON driver. Its LUT has 256
entries and can be updated only when gamma correction is disabled.

Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
alistair/sunxi64-5.5-dsi
Vasily Khoruzhick 2019-03-13 19:50:17 -07:00 committed by Alistair Francis
parent 678e645eb1
commit b02e15455c
3 changed files with 59 additions and 1 deletions

View File

@ -98,6 +98,20 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
drm_crtc_send_vblank_event(crtc, event);
spin_unlock_irq(&crtc->dev->event_lock);
}
if (crtc->state->color_mgmt_changed) {
if (crtc->state->gamma_lut) {
/* LUT can be only updated when gamma correction is
* disabled
*/
sun4i_tcon_enable_gamma(scrtc->tcon, false);
sun4i_tcon_load_gamma_lut(scrtc->tcon,
crtc->state->gamma_lut->data);
sun4i_tcon_enable_gamma(scrtc->tcon, true);
} else
sun4i_tcon_enable_gamma(scrtc->tcon, false);
}
}
static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc,
@ -181,6 +195,7 @@ static const struct drm_crtc_funcs sun4i_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.enable_vblank = sun4i_crtc_enable_vblank,
.disable_vblank = sun4i_crtc_disable_vblank,
.gamma_set = drm_atomic_helper_legacy_gamma_set,
};
struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm,

View File

@ -214,6 +214,34 @@ void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable)
}
EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
void sun4i_tcon_load_gamma_lut(struct sun4i_tcon *tcon,
struct drm_color_lut *lut)
{
int i;
for (i = 0; i < SUN4I_TCON_GAMMA_LUT_SIZE; i++) {
u32 r, g, b;
r = drm_color_lut_extract(lut[i].red, 8);
g = drm_color_lut_extract(lut[i].green, 8);
b = drm_color_lut_extract(lut[i].blue, 8);
regmap_write(tcon->regs, SUN4I_TCON_GAMMA_TABLE_REG + 4 * i,
SUN4I_TCON_GAMMA_TABLE_R(r) |
SUN4I_TCON_GAMMA_TABLE_G(g) |
SUN4I_TCON_GAMMA_TABLE_B(b));
}
}
EXPORT_SYMBOL(sun4i_tcon_load_gamma_lut);
void sun4i_tcon_enable_gamma(struct sun4i_tcon *tcon, bool enable)
{
regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
SUN4I_TCON_GCTL_GAMMA_ENABLE,
enable ? SUN4I_TCON_GCTL_GAMMA_ENABLE : 0);
}
EXPORT_SYMBOL(sun4i_tcon_enable_gamma);
/*
* This function is a helper for TCON output muxing. The TCON output
* muxing control register in earlier SoCs (without the TCON TOP block)
@ -1261,6 +1289,11 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
list_add_tail(&tcon->list, &drv->tcon_list);
drm_mode_crtc_set_gamma_size(&tcon->crtc->crtc,
SUN4I_TCON_GAMMA_LUT_SIZE);
drm_crtc_enable_color_mgmt(&tcon->crtc->crtc, 0, false,
tcon->crtc->crtc.gamma_size);
return 0;
err_free_dotclock:

View File

@ -18,6 +18,7 @@
#define SUN4I_TCON_GCTL_REG 0x0
#define SUN4I_TCON_GCTL_TCON_ENABLE BIT(31)
#define SUN4I_TCON_GCTL_GAMMA_ENABLE BIT(30)
#define SUN4I_TCON_GCTL_IOMAP_MASK BIT(0)
#define SUN4I_TCON_GCTL_IOMAP_TCON1 (1 << 0)
#define SUN4I_TCON_GCTL_IOMAP_TCON0 (0 << 0)
@ -211,7 +212,13 @@
#define SUN4I_TCON1_FILL_BEG2_REG 0x31c
#define SUN4I_TCON1_FILL_END2_REG 0x320
#define SUN4I_TCON1_FILL_DATA2_REG 0x324
#define SUN4I_TCON1_GAMMA_TABLE_REG 0x400
#define SUN4I_TCON_GAMMA_TABLE_REG 0x400
#define SUN4I_TCON_GAMMA_TABLE_B(x) ((x) & 0xff)
#define SUN4I_TCON_GAMMA_TABLE_G(x) (((x) & 0xff) << 8)
#define SUN4I_TCON_GAMMA_TABLE_R(x) (((x) & 0xff) << 16)
#define SUN4I_TCON_GAMMA_LUT_SIZE 256
#define SUN4I_TCON_MAX_CHANNELS 2
@ -275,6 +282,9 @@ void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
const struct drm_display_mode *mode);
void sun4i_tcon_set_status(struct sun4i_tcon *crtc,
const struct drm_encoder *encoder, bool enable);
void sun4i_tcon_load_gamma_lut(struct sun4i_tcon *tcon,
struct drm_color_lut *lut);
void sun4i_tcon_enable_gamma(struct sun4i_tcon *tcon, bool enable);
extern const struct of_device_id sun4i_tcon_of_table[];