mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
drm: pq: G12A DRM support gamma and ctm setting [1/1]
PD#165492 Problem: G12A DRM add gamma and ctm setting support Solution: 1. amvecm: add gamma apis for drm 2. drm: add gamma and ctm setting Verify: Verified on customer platfor Change-Id: Iff5204ae7f719542463ac15140e471cd762c9c27 Signed-off-by: Bencheng Jing <bencheng.jing@amlogic.com>
This commit is contained in:
committed by
Dongjin Kim
parent
3ca49d987b
commit
c59e70f644
@@ -14175,6 +14175,7 @@ F: driver/amlogic/drm/am_meson_drv.c
|
||||
F: driver/amlogic/drm/am_meson_drv.h
|
||||
F: driver/amlogic/drm/am_meson_vpu.c
|
||||
F: driver/amlogic/drm/am_meson_vpu.h
|
||||
F: drivers/amlogic/media/enhancement/amvecm/amvecm_drm.c
|
||||
|
||||
AMLOGIC ADD S400EMMC DTS
|
||||
M: Yue Gui <yuegui.he@amlogic.com>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
/* Amlogic Headers */
|
||||
#include <linux/amlogic/media/vout/vout_notify.h>
|
||||
#include <linux/amlogic/media/amvecm/amvecm.h>
|
||||
|
||||
#include "osd.h"
|
||||
#include "osd_drm.h"
|
||||
@@ -255,7 +256,6 @@ int am_meson_crtc_dts_info_set(const void *dt_match_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct drm_plane_funcs am_osd_plane_funs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
@@ -667,6 +667,26 @@ void am_meson_crtc_atomic_begin(struct drm_crtc *crtc,
|
||||
void am_meson_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct drm_color_ctm *ctm;
|
||||
struct drm_color_lut *lut;
|
||||
int gamma_lut_size = 0;
|
||||
|
||||
if (crtc->state->color_mgmt_changed) {
|
||||
DRM_INFO("%s color_mgmt_changed!\n", __func__);
|
||||
if (crtc->state->ctm) {
|
||||
DRM_INFO("%s color_mgmt_changed 1!\n", __func__);
|
||||
ctm = (struct drm_color_ctm *)
|
||||
crtc->state->ctm->data;
|
||||
am_meson_ctm_set(0, ctm);
|
||||
}
|
||||
if (crtc->state->gamma_lut) {
|
||||
DRM_INFO("%s color_mgmt_changed 2!\n", __func__);
|
||||
lut = (struct drm_color_lut *)
|
||||
crtc->state->gamma_lut->data;
|
||||
gamma_lut_size = amvecm_drm_get_gamma_size(0);
|
||||
amvecm_drm_gamma_set(0, lut, gamma_lut_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs am_crtc_helper_funcs = {
|
||||
@@ -682,6 +702,7 @@ int am_meson_crtc_create(struct am_meson_crtc *amcrtc)
|
||||
{
|
||||
struct meson_drm *priv = amcrtc->priv;
|
||||
struct drm_crtc *crtc = &amcrtc->base;
|
||||
int gamma_lut_size = 0;
|
||||
int ret;
|
||||
|
||||
DRM_INFO("%s\n", __func__);
|
||||
@@ -696,6 +717,12 @@ int am_meson_crtc_create(struct am_meson_crtc *amcrtc)
|
||||
drm_crtc_helper_add(crtc, &am_crtc_helper_funcs);
|
||||
osd_drm_init(&osd_meson_dev);
|
||||
|
||||
amvecm_drm_init(0);
|
||||
amvecm_drm_gamma_enable(0);
|
||||
gamma_lut_size = amvecm_drm_get_gamma_size(0);
|
||||
drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size);
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, true, gamma_lut_size);
|
||||
|
||||
priv->crtc = crtc;
|
||||
return 0;
|
||||
}
|
||||
@@ -830,6 +857,8 @@ static void am_meson_vpu_unbind(struct device *dev,
|
||||
struct meson_drm *private = drm_dev->dev_private;
|
||||
|
||||
am_meson_unregister_crtc_funcs(private->crtc);
|
||||
amvecm_drm_gamma_disable(0);
|
||||
am_meson_ctm_disable();
|
||||
osd_drm_debugfs_exit();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,3 +15,4 @@ am_vecm-objs += cm2_adj.o
|
||||
am_vecm-objs += vlock.o
|
||||
am_vecm-objs += hdr/am_hdr10_plus.o
|
||||
am_vecm-objs += local_contrast.o
|
||||
am_vecm-objs += amvecm_drm.o
|
||||
|
||||
@@ -338,12 +338,12 @@ void ve_on_vs(struct vframe_s *vf)
|
||||
|
||||
void vpp_enable_lcd_gamma_table(void)
|
||||
{
|
||||
WRITE_VPP_REG_BITS(L_GAMMA_CNTL_PORT, 1, GAMMA_EN, 1);
|
||||
VSYNC_WR_MPEG_REG_BITS(L_GAMMA_CNTL_PORT, 1, GAMMA_EN, 1);
|
||||
}
|
||||
|
||||
void vpp_disable_lcd_gamma_table(void)
|
||||
{
|
||||
WRITE_VPP_REG_BITS(L_GAMMA_CNTL_PORT, 0, GAMMA_EN, 1);
|
||||
VSYNC_WR_MPEG_REG_BITS(L_GAMMA_CNTL_PORT, 0, GAMMA_EN, 1);
|
||||
}
|
||||
|
||||
void vpp_set_lcd_gamma_table(u16 *data, u32 rgb_mask)
|
||||
@@ -387,7 +387,7 @@ void vpp_set_lcd_gamma_table(u16 *data, u32 rgb_mask)
|
||||
(0x1 << rgb_mask) |
|
||||
(0x23 << HADR));
|
||||
|
||||
WRITE_VPP_REG_BITS(L_GAMMA_CNTL_PORT,
|
||||
VSYNC_WR_MPEG_REG_BITS(L_GAMMA_CNTL_PORT,
|
||||
gamma_en, GAMMA_EN, 1);
|
||||
|
||||
spin_unlock_irqrestore(&vpp_lcd_gamma_lock, flags);
|
||||
|
||||
@@ -143,6 +143,9 @@ extern int VSYNC_WR_MPEG_REG(u32 adr, u32 val);
|
||||
/* unsigned long long ve_get_vs_cnt(void); */
|
||||
/* #endif */
|
||||
extern int video_rgb_ogo_xvy_mtx;
|
||||
|
||||
#define GAMMA_SIZE 256
|
||||
|
||||
extern unsigned int dnlp_sel;
|
||||
extern void ve_dnlp_load_reg(void);
|
||||
|
||||
@@ -161,5 +164,8 @@ extern int vpp_set_lut3d(int enable, int bLut3DLoad,
|
||||
extern void vpp_lut3d_table_init(int *pLut3D, int bitdepth);
|
||||
extern void dump_plut3d_table(void);
|
||||
extern void dump_plut3d_reg_table(void);
|
||||
|
||||
extern void amvecm_gamma_init(bool en);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5198,7 +5198,7 @@ void init_pq_setting(void)
|
||||
}
|
||||
/* #endif*/
|
||||
|
||||
static void amvecm_gamma_init(bool en)
|
||||
void amvecm_gamma_init(bool en)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned short data[256];
|
||||
|
||||
133
drivers/amlogic/media/enhancement/amvecm/amvecm_drm.c
Normal file
133
drivers/amlogic/media/enhancement/amvecm/amvecm_drm.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* drivers/amlogic/media/enhancement/amvecm/amvecm_drm.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <uapi/drm/drm_mode.h>
|
||||
#include <linux/amlogic/media/utils/amstream.h>
|
||||
#include <linux/amlogic/media/amvecm/amvecm.h>
|
||||
#include "arch/ve_regs.h"
|
||||
#include "arch/vpp_regs.h"
|
||||
#include "amve.h"
|
||||
|
||||
void amvecm_drm_init(u32 index)
|
||||
{
|
||||
amvecm_gamma_init(1);
|
||||
}
|
||||
EXPORT_SYMBOL(amvecm_drm_init);
|
||||
|
||||
/*gamam size*/
|
||||
int amvecm_drm_get_gamma_size(u32 index)
|
||||
{
|
||||
return GAMMA_SIZE;
|
||||
}
|
||||
EXPORT_SYMBOL(amvecm_drm_get_gamma_size);
|
||||
|
||||
/*get gamma table*/
|
||||
int amvecm_drm_gamma_get(u32 index, u16 *red, u16 *green, u16 *blue)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < GAMMA_SIZE; i++) {
|
||||
red[i] = video_gamma_table_r.data[i] << 6;
|
||||
green[i] = video_gamma_table_g.data[i] << 6;
|
||||
blue[i] = video_gamma_table_b.data[i] << 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(amvecm_drm_gamma_get);
|
||||
|
||||
/*set gamma table*/
|
||||
int amvecm_drm_gamma_set(u32 index, struct drm_color_lut *lut, int lut_size)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
|
||||
if (lut_size != GAMMA_SIZE) {
|
||||
pr_info("AMGAMMA_DRM: %s: lutsize is unsuitable\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < GAMMA_SIZE; i++) {
|
||||
video_gamma_table_r.data[i] = ((lut[i].red >> 6) & 0x3ff);
|
||||
video_gamma_table_g.data[i] = ((lut[i].green >> 6) & 0x3ff);
|
||||
video_gamma_table_b.data[i] = ((lut[i].blue >> 6) & 0x3ff);
|
||||
}
|
||||
|
||||
vecm_latch_flag |= FLAG_GAMMA_TABLE_R;
|
||||
vecm_latch_flag |= FLAG_GAMMA_TABLE_G;
|
||||
vecm_latch_flag |= FLAG_GAMMA_TABLE_B;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(amvecm_drm_gamma_set);
|
||||
|
||||
/*gamma enable*/
|
||||
int amvecm_drm_gamma_enable(u32 index)
|
||||
{
|
||||
vecm_latch_flag |= FLAG_GAMMA_TABLE_EN;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(amvecm_drm_gamma_enable);
|
||||
|
||||
/*gamma disable*/
|
||||
int amvecm_drm_gamma_disable(u32 index)
|
||||
{
|
||||
vecm_latch_flag |= FLAG_GAMMA_TABLE_DIS;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(amvecm_drm_gamma_disable);
|
||||
|
||||
int am_meson_ctm_set(u32 index, struct drm_color_ctm *ctm)
|
||||
{
|
||||
int64_t m[9];
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < 9; i++) {
|
||||
m[i] = ctm->matrix[i];
|
||||
// DRM uses signed 32.32 fixed point while Meson expects signed
|
||||
// 3.10 fixed point. The following operations are performed to
|
||||
// transform the numbers:
|
||||
// - shift the sign bit from bit 63 to bit 12,
|
||||
// - shift the 2 integer bits from from starting bit 21 to 10,
|
||||
// - shift the fractional part and take the 10 significant bits.
|
||||
m[i] = ((m[i] >> 51) & 0x1000) | ((m[i] >> 22) & 0xfff);
|
||||
}
|
||||
VSYNC_WR_MPEG_REG_BITS(VPP_POST_MATRIX_EN_CTRL, 1, 0, 1);
|
||||
|
||||
VSYNC_WR_MPEG_REG(VPP_POST_MATRIX_COEF00_01, ((m[0] & 0xfff) << 16)
|
||||
| (m[1] & 0xfff));
|
||||
VSYNC_WR_MPEG_REG(VPP_POST_MATRIX_COEF02_10, ((m[2] & 0xfff) << 16)
|
||||
| (m[3] & 0xfff));
|
||||
VSYNC_WR_MPEG_REG(VPP_POST_MATRIX_COEF11_12, ((m[4] & 0xfff) << 16)
|
||||
| (m[5] & 0xfff));
|
||||
VSYNC_WR_MPEG_REG(VPP_POST_MATRIX_COEF20_21, ((m[6] & 0xfff) << 16)
|
||||
| (m[7] & 0xfff));
|
||||
VSYNC_WR_MPEG_REG(VPP_POST_MATRIX_COEF22, (m[8] & 0xfff));
|
||||
VSYNC_WR_MPEG_REG(VPP_POST_MATRIX_OFFSET0_1, 0x0);
|
||||
VSYNC_WR_MPEG_REG(VPP_POST_MATRIX_OFFSET2, 0x0);
|
||||
VSYNC_WR_MPEG_REG(VPP_POST_MATRIX_PRE_OFFSET0_1, 0x0);
|
||||
VSYNC_WR_MPEG_REG(VPP_POST_MATRIX_PRE_OFFSET2, 0x0);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(am_meson_ctm_set);
|
||||
|
||||
int am_meson_ctm_disable(void)
|
||||
{
|
||||
VSYNC_WR_MPEG_REG_BITS(VPP_POST_MATRIX_EN_CTRL, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(am_meson_ctm_disable);
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <linux/amlogic/media/vfm/vframe.h>
|
||||
#include <linux/amlogic/media/utils/amstream.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
#include <drm/drmP.h>
|
||||
|
||||
|
||||
/* struct ve_dnlp_s video_ve_dnlp; */
|
||||
|
||||
@@ -429,5 +431,15 @@ extern int VSYNC_WR_MPEG_REG_BITS(u32 adr, u32 val, u32 start, u32 len);
|
||||
extern u32 VSYNC_RD_MPEG_REG(u32 adr);
|
||||
extern int VSYNC_WR_MPEG_REG(u32 adr, u32 val);
|
||||
#endif
|
||||
extern int amvecm_drm_get_gamma_size(u32 index);
|
||||
extern void amvecm_drm_init(u32 index);
|
||||
extern int amvecm_drm_gamma_set(u32 index,
|
||||
struct drm_color_lut *lut, int lut_size);
|
||||
extern int amvecm_drm_gamma_get(u32 index, u16 *red, u16 *green, u16 *blue);
|
||||
extern int amvecm_drm_gamma_enable(u32 index);
|
||||
extern int amvecm_drm_gamma_disable(u32 index);
|
||||
extern int am_meson_ctm_set(u32 index, struct drm_color_ctm *ctm);
|
||||
extern int am_meson_ctm_disable(void);
|
||||
|
||||
#endif /* AMVECM_H */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user