mirror of
https://github.com/torvalds/linux.git
synced 2026-06-09 15:12:59 +02:00
drm/rockchip: vop: add BCSH support for full vops
The full name of BCSH is Brightness, Contrast, Saturation and Hue. BCSH is supported on all full vop designed. Change-Id: I17bcd5a07b93b3c68aa892606f886bcd3a7673a0 Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
This commit is contained in:
parent
2272eb5d62
commit
e268caad71
|
|
@ -213,6 +213,7 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
|
|||
s->output_type = DRM_MODE_CONNECTOR_eDP;
|
||||
if (info->num_bus_formats)
|
||||
s->bus_format = info->bus_formats[0];
|
||||
s->tv_state = &conn_state->tv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -743,6 +743,7 @@ static int cdn_dp_encoder_atomic_check(struct drm_encoder *encoder,
|
|||
|
||||
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
||||
s->output_type = DRM_MODE_CONNECTOR_DisplayPort;
|
||||
s->tv_state = &conn_state->tv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1220,6 +1220,7 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
|
|||
s->output_type = DRM_MODE_CONNECTOR_DSI;
|
||||
if (info->num_bus_formats)
|
||||
s->bus_format = info->bus_formats[0];
|
||||
s->tv_state = &conn_state->tv;
|
||||
|
||||
if (dsi->slave)
|
||||
s->output_flags = ROCKCHIP_OUTPUT_DSI_DUAL_CHANNEL;
|
||||
|
|
|
|||
|
|
@ -543,6 +543,7 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
|
|||
s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
}
|
||||
s->output_type = DRM_MODE_CONNECTOR_HDMIA;
|
||||
s->tv_state = &conn_state->tv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1122,6 +1122,26 @@ static void rockchip_gem_pool_destroy(struct drm_device *drm)
|
|||
gen_pool_destroy(private->secure_buffer_pool);
|
||||
}
|
||||
|
||||
static void rockchip_attach_connector_property(struct drm_device *drm)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct drm_mode_config *conf = &drm->mode_config;
|
||||
|
||||
mutex_lock(&drm->mode_config.mutex);
|
||||
|
||||
drm_for_each_connector(connector, drm) {
|
||||
#define ROCKCHIP_PROP_ATTACH(prop, v) \
|
||||
drm_object_attach_property(&connector->base, prop, v)
|
||||
|
||||
ROCKCHIP_PROP_ATTACH(conf->tv_brightness_property, 100);
|
||||
ROCKCHIP_PROP_ATTACH(conf->tv_contrast_property, 100);
|
||||
ROCKCHIP_PROP_ATTACH(conf->tv_saturation_property, 100);
|
||||
ROCKCHIP_PROP_ATTACH(conf->tv_hue_property, 100);
|
||||
}
|
||||
|
||||
mutex_unlock(&drm->mode_config.mutex);
|
||||
}
|
||||
|
||||
static int rockchip_drm_bind(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev;
|
||||
|
|
@ -1192,6 +1212,8 @@ static int rockchip_drm_bind(struct device *dev)
|
|||
if (ret)
|
||||
goto err_mode_config_cleanup;
|
||||
|
||||
rockchip_attach_connector_property(drm_dev);
|
||||
|
||||
ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
|
||||
if (ret)
|
||||
goto err_unbind_all;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ struct rockchip_dclk_pll {
|
|||
struct rockchip_crtc_state {
|
||||
struct drm_crtc_state base;
|
||||
struct drm_property_blob *cabc_lut;
|
||||
struct drm_tv_connector_state *tv_state;
|
||||
int left_margin;
|
||||
int right_margin;
|
||||
int top_margin;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <drm/drm_plane_helper.h>
|
||||
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/fixp-arith.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
|
@ -2192,6 +2193,67 @@ static void vop_update_cabc(struct drm_crtc *crtc,
|
|||
}
|
||||
}
|
||||
|
||||
static void vop_tv_config_update(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct rockchip_crtc_state *s =
|
||||
to_rockchip_crtc_state(crtc->state);
|
||||
struct rockchip_crtc_state *old_s =
|
||||
to_rockchip_crtc_state(old_crtc_state);
|
||||
int brightness, contrast, saturation, hue, sin_hue, cos_hue;
|
||||
struct vop *vop = to_vop(crtc);
|
||||
const struct vop_data *vop_data = vop->data;
|
||||
|
||||
if (!s->tv_state)
|
||||
return;
|
||||
|
||||
if (old_s->tv_state &&
|
||||
!memcmp(s->tv_state, old_s->tv_state, sizeof(*s->tv_state)))
|
||||
return;
|
||||
|
||||
if (s->tv_state->brightness == 50 &&
|
||||
s->tv_state->contrast == 50 &&
|
||||
s->tv_state->saturation == 50 &&
|
||||
s->tv_state->hue == 50) {
|
||||
VOP_CTRL_SET(vop, bcsh_en, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vop_data->feature & VOP_FEATURE_OUTPUT_10BIT)
|
||||
brightness = interpolate(0, -128, 100, 127,
|
||||
s->tv_state->brightness);
|
||||
else
|
||||
brightness = interpolate(0, -32, 100, 31,
|
||||
s->tv_state->brightness);
|
||||
contrast = interpolate(0, 0, 100, 511, s->tv_state->contrast);
|
||||
saturation = interpolate(0, 0, 100, 511, s->tv_state->saturation);
|
||||
hue = interpolate(0, -30, 100, 30, s->tv_state->hue);
|
||||
|
||||
/*
|
||||
* a:[-30~0]:
|
||||
* sin_hue = 0x100 - sin(a)*256;
|
||||
* cos_hue = cos(a)*256;
|
||||
* a:[0~30]
|
||||
* sin_hue = sin(a)*256;
|
||||
* cos_hue = cos(a)*256;
|
||||
*/
|
||||
sin_hue = fixp_sin32(hue) >> 23;
|
||||
cos_hue = fixp_cos32(hue) >> 23;
|
||||
VOP_CTRL_SET(vop, bcsh_brightness, brightness);
|
||||
VOP_CTRL_SET(vop, bcsh_contrast, contrast);
|
||||
VOP_CTRL_SET(vop, bcsh_sat_con, saturation * contrast / 0x100);
|
||||
VOP_CTRL_SET(vop, bcsh_sin_hue, sin_hue);
|
||||
VOP_CTRL_SET(vop, bcsh_cos_hue, cos_hue);
|
||||
VOP_CTRL_SET(vop, bcsh_en, 1);
|
||||
if (!is_yuv_output(s->bus_format)) {
|
||||
VOP_CTRL_SET(vop, bcsh_r2y_en, 1);
|
||||
VOP_CTRL_SET(vop, bcsh_y2r_en, 1);
|
||||
} else {
|
||||
VOP_CTRL_SET(vop, bcsh_r2y_en, 0);
|
||||
VOP_CTRL_SET(vop, bcsh_y2r_en, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void vop_cfg_update(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
|
|
@ -2201,6 +2263,8 @@ static void vop_cfg_update(struct drm_crtc *crtc,
|
|||
|
||||
spin_lock(&vop->reg_lock);
|
||||
|
||||
vop_tv_config_update(crtc, old_crtc_state);
|
||||
|
||||
if (s->afbdc_en) {
|
||||
uint32_t pic_size;
|
||||
|
||||
|
|
|
|||
|
|
@ -179,6 +179,20 @@ struct vop_ctrl {
|
|||
struct vop_reg cabc_global_dn;
|
||||
struct vop_reg cabc_calc_pixel_num;
|
||||
|
||||
/* BCSH */
|
||||
struct vop_reg bcsh_brightness;
|
||||
struct vop_reg bcsh_contrast;
|
||||
struct vop_reg bcsh_sat_con;
|
||||
struct vop_reg bcsh_sin_hue;
|
||||
struct vop_reg bcsh_cos_hue;
|
||||
struct vop_reg bcsh_r2y_csc_mode;
|
||||
struct vop_reg bcsh_r2y_en;
|
||||
struct vop_reg bcsh_y2r_csc_mode;
|
||||
struct vop_reg bcsh_y2r_en;
|
||||
struct vop_reg bcsh_color_bar;
|
||||
struct vop_reg bcsh_out_mode;
|
||||
struct vop_reg bcsh_en;
|
||||
|
||||
struct vop_reg cfg_done;
|
||||
};
|
||||
|
||||
|
|
@ -544,5 +558,10 @@ static inline int us_to_vertical_line(struct drm_display_mode *mode, int us)
|
|||
return us * mode->clock / mode->htotal / 1000;
|
||||
}
|
||||
|
||||
static inline int interpolate(int x1, int y1, int x2, int y2, int x)
|
||||
{
|
||||
return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
|
||||
}
|
||||
|
||||
extern const struct component_ops vop_component_ops;
|
||||
#endif /* _ROCKCHIP_DRM_VOP_H */
|
||||
|
|
|
|||
|
|
@ -621,6 +621,7 @@ rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder,
|
|||
s->output_type = DRM_MODE_CONNECTOR_LVDS;
|
||||
if (info->num_bus_formats)
|
||||
s->bus_format = info->bus_formats[0];
|
||||
s->tv_state = &conn_state->tv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,6 +247,19 @@ static const struct vop_ctrl rk3288_ctrl_data = {
|
|||
.cabc_global_dn_limit_en = VOP_REG_VER(RK3399_CABC_CTRL3, 0x1, 8,
|
||||
3, 5, -1),
|
||||
|
||||
.bcsh_brightness = VOP_REG(RK3288_BCSH_BCS, 0xff, 0),
|
||||
.bcsh_contrast = VOP_REG(RK3288_BCSH_BCS, 0x1ff, 8),
|
||||
.bcsh_sat_con = VOP_REG(RK3288_BCSH_BCS, 0x3ff, 20),
|
||||
.bcsh_out_mode = VOP_REG(RK3288_BCSH_BCS, 0x3, 0),
|
||||
.bcsh_sin_hue = VOP_REG(RK3288_BCSH_H, 0x1ff, 0),
|
||||
.bcsh_cos_hue = VOP_REG(RK3288_BCSH_H, 0x1ff, 16),
|
||||
.bcsh_r2y_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 6, 3, 2, -1),
|
||||
.bcsh_r2y_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 4, 3, 2, -1),
|
||||
.bcsh_y2r_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x3, 2, 3, 2, -1),
|
||||
.bcsh_y2r_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 0, 3, 2, -1),
|
||||
.bcsh_color_bar = VOP_REG(RK3288_BCSH_COLOR_BAR, 0xffffff, 8),
|
||||
.bcsh_en = VOP_REG(RK3288_BCSH_COLOR_BAR, 0x1, 0),
|
||||
|
||||
.xmirror = VOP_REG(RK3288_DSP_CTRL0, 0x1, 22),
|
||||
.ymirror = VOP_REG(RK3288_DSP_CTRL0, 0x1, 23),
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,10 @@
|
|||
#define RK3288_DSP_VACT_ST_END 0x0194
|
||||
#define RK3288_DSP_VS_ST_END_F1 0x0198
|
||||
#define RK3288_DSP_VACT_ST_END_F1 0x019c
|
||||
|
||||
#define RK3288_BCSH_COLOR_BAR 0x01b0
|
||||
#define RK3288_BCSH_BCS 0x01b4
|
||||
#define RK3288_BCSH_H 0x01b8
|
||||
/* register definition end */
|
||||
|
||||
/* rk3368 register definition */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user