Skip to content

Commit 3368e8d

Browse files
Mark YaoCK Zhang
authored andcommitted
drm/rockchip: vop: support overscan setting
Change-Id: I2213c7da45fd625d154a9bf11c79ec5608b06a0e Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
1 parent 0fce7eb commit 3368e8d

4 files changed

Lines changed: 147 additions & 7 deletions

File tree

drivers/gpu/drm/rockchip/rockchip_drm_drv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ struct rockchip_atomic_commit {
6767

6868
struct rockchip_crtc_state {
6969
struct drm_crtc_state base;
70+
int left_margin;
71+
int right_margin;
72+
int top_margin;
73+
int bottom_margin;
7074
int afbdc_win_format;
7175
int afbdc_win_width;
7276
int afbdc_win_height;

drivers/gpu/drm/rockchip/rockchip_drm_vop.c

Lines changed: 138 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,6 +1868,44 @@ static int vop_crtc_atomic_check(struct drm_crtc *crtc,
18681868
return ret;
18691869
}
18701870

1871+
static void vop_post_config(struct drm_crtc *crtc)
1872+
{
1873+
struct vop *vop = to_vop(crtc);
1874+
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
1875+
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
1876+
u16 vtotal = mode->crtc_vtotal;
1877+
u16 hdisplay = mode->crtc_hdisplay;
1878+
u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1879+
u16 vdisplay = mode->crtc_vdisplay;
1880+
u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1881+
u16 hsize = hdisplay * (s->left_margin + s->right_margin) / 200;
1882+
u16 vsize = vdisplay * (s->top_margin + s->bottom_margin) / 200;
1883+
u16 hact_end, vact_end;
1884+
u32 val;
1885+
1886+
hact_st += hdisplay * (100 - s->left_margin) / 200;
1887+
hact_end = hact_st + hsize;
1888+
val = hact_st << 16;
1889+
val |= hact_end;
1890+
VOP_CTRL_SET(vop, hpost_st_end, val);
1891+
vact_st += vdisplay * (100 - s->top_margin) / 200;
1892+
vact_end = vact_st + vsize;
1893+
val = vact_st << 16;
1894+
val |= vact_end;
1895+
VOP_CTRL_SET(vop, vpost_st_end, val);
1896+
val = scl_cal_scale2(vdisplay, vsize) << 16;
1897+
val |= scl_cal_scale2(hdisplay, hsize);
1898+
VOP_CTRL_SET(vop, post_scl_factor, val);
1899+
VOP_CTRL_SET(vop, post_scl_ctrl, 0x3);
1900+
if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1901+
u16 vact_st_f1 = vtotal + vact_st + 1;
1902+
u16 vact_end_f1 = vact_st_f1 + vsize;
1903+
1904+
val = vact_st_f1 << 16 | vact_end_f1;
1905+
VOP_CTRL_SET(vop, vpost_st_end_f1, val);
1906+
}
1907+
}
1908+
18711909
static void vop_cfg_update(struct drm_crtc *crtc,
18721910
struct drm_crtc_state *old_crtc_state)
18731911
{
@@ -1891,6 +1929,7 @@ static void vop_cfg_update(struct drm_crtc *crtc,
18911929

18921930
VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en);
18931931
VOP_CTRL_SET(vop, dsp_layer_sel, s->dsp_layer_sel);
1932+
vop_post_config(crtc);
18941933

18951934
spin_unlock(&vop->reg_lock);
18961935
}
@@ -1975,20 +2014,30 @@ static void vop_crtc_destroy(struct drm_crtc *crtc)
19752014

19762015
static void vop_crtc_reset(struct drm_crtc *crtc)
19772016
{
1978-
if (crtc->state)
2017+
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
2018+
2019+
if (crtc->state) {
19792020
__drm_atomic_helper_crtc_destroy_state(crtc, crtc->state);
1980-
kfree(crtc->state);
2021+
kfree(s);
2022+
}
19812023

1982-
crtc->state = kzalloc(sizeof(struct rockchip_crtc_state), GFP_KERNEL);
1983-
if (crtc->state)
1984-
crtc->state->crtc = crtc;
2024+
s = kzalloc(sizeof(*s), GFP_KERNEL);
2025+
if (!s)
2026+
return;
2027+
crtc->state = &s->base;
2028+
crtc->state->crtc = crtc;
2029+
s->left_margin = 100;
2030+
s->right_margin = 100;
2031+
s->top_margin = 100;
2032+
s->bottom_margin = 100;
19852033
}
19862034

19872035
static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
19882036
{
1989-
struct rockchip_crtc_state *rockchip_state;
2037+
struct rockchip_crtc_state *rockchip_state, *old_state;
19902038

1991-
rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
2039+
old_state = to_rockchip_crtc_state(crtc->state);
2040+
rockchip_state = kmemdup(old_state, sizeof(*old_state), GFP_KERNEL);
19922041
if (!rockchip_state)
19932042
return NULL;
19942043

@@ -2005,11 +2054,79 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc,
20052054
kfree(s);
20062055
}
20072056

2057+
static int vop_crtc_atomic_get_property(struct drm_crtc *crtc,
2058+
const struct drm_crtc_state *state,
2059+
struct drm_property *property,
2060+
uint64_t *val)
2061+
{
2062+
struct drm_device *drm_dev = crtc->dev;
2063+
struct drm_mode_config *mode_config = &drm_dev->mode_config;
2064+
struct rockchip_crtc_state *s = to_rockchip_crtc_state(state);
2065+
2066+
if (property == mode_config->tv_left_margin_property) {
2067+
*val = s->left_margin;
2068+
return 0;
2069+
}
2070+
2071+
if (property == mode_config->tv_right_margin_property) {
2072+
*val = s->right_margin;
2073+
return 0;
2074+
}
2075+
2076+
if (property == mode_config->tv_top_margin_property) {
2077+
*val = s->top_margin;
2078+
return 0;
2079+
}
2080+
2081+
if (property == mode_config->tv_bottom_margin_property) {
2082+
*val = s->bottom_margin;
2083+
return 0;
2084+
}
2085+
2086+
DRM_ERROR("failed to get vop crtc property\n");
2087+
return -EINVAL;
2088+
}
2089+
2090+
static int vop_crtc_atomic_set_property(struct drm_crtc *crtc,
2091+
struct drm_crtc_state *state,
2092+
struct drm_property *property,
2093+
uint64_t val)
2094+
{
2095+
struct drm_device *drm_dev = crtc->dev;
2096+
struct drm_mode_config *mode_config = &drm_dev->mode_config;
2097+
struct rockchip_crtc_state *s = to_rockchip_crtc_state(state);
2098+
2099+
if (property == mode_config->tv_left_margin_property) {
2100+
s->left_margin = val;
2101+
return 0;
2102+
}
2103+
2104+
if (property == mode_config->tv_right_margin_property) {
2105+
s->right_margin = val;
2106+
return 0;
2107+
}
2108+
2109+
if (property == mode_config->tv_top_margin_property) {
2110+
s->top_margin = val;
2111+
return 0;
2112+
}
2113+
2114+
if (property == mode_config->tv_bottom_margin_property) {
2115+
s->bottom_margin = val;
2116+
return 0;
2117+
}
2118+
2119+
DRM_ERROR("failed to set vop crtc property\n");
2120+
return -EINVAL;
2121+
}
2122+
20082123
static const struct drm_crtc_funcs vop_crtc_funcs = {
20092124
.set_config = drm_atomic_helper_set_config,
20102125
.page_flip = drm_atomic_helper_page_flip,
20112126
.destroy = vop_crtc_destroy,
20122127
.reset = vop_crtc_reset,
2128+
.atomic_get_property = vop_crtc_atomic_get_property,
2129+
.atomic_set_property = vop_crtc_atomic_set_property,
20132130
.atomic_duplicate_state = vop_crtc_duplicate_state,
20142131
.atomic_destroy_state = vop_crtc_destroy_state,
20152132
};
@@ -2228,13 +2345,27 @@ static int vop_create_crtc(struct vop *vop)
22282345
crtc->port = port;
22292346
rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);
22302347

2348+
ret = drm_mode_create_tv_properties(drm_dev, 0, NULL);
2349+
if (ret)
2350+
goto err_unregister_crtc_funcs;
2351+
#define VOP_ATTACH_MODE_CONFIG_PROP(prop, v) \
2352+
drm_object_attach_property(&crtc->base, drm_dev->mode_config.prop, v)
2353+
2354+
VOP_ATTACH_MODE_CONFIG_PROP(tv_left_margin_property, 100);
2355+
VOP_ATTACH_MODE_CONFIG_PROP(tv_right_margin_property, 100);
2356+
VOP_ATTACH_MODE_CONFIG_PROP(tv_top_margin_property, 100);
2357+
VOP_ATTACH_MODE_CONFIG_PROP(tv_bottom_margin_property, 100);
2358+
#undef VOP_ATTACH_MODE_CONFIG_PROP
2359+
22312360
if (VOP_CTRL_SUPPORT(vop, afbdc_en))
22322361
feature |= BIT(ROCKCHIP_DRM_CRTC_FEATURE_AFBDC);
22332362
drm_object_attach_property(&crtc->base, vop->feature_prop,
22342363
feature);
22352364

22362365
return 0;
22372366

2367+
err_unregister_crtc_funcs:
2368+
rockchip_unregister_crtc_funcs(crtc);
22382369
err_cleanup_crtc:
22392370
drm_crtc_cleanup(crtc);
22402371
err_cleanup_planes:

drivers/gpu/drm/rockchip/rockchip_drm_vop.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ struct vop_ctrl {
8383
struct vop_reg hpost_st_end;
8484
struct vop_reg vpost_st_end;
8585
struct vop_reg vpost_st_end_f1;
86+
struct vop_reg post_scl_factor;
87+
struct vop_reg post_scl_ctrl;
8688
struct vop_reg dsp_interlace;
8789
struct vop_reg global_regdone_en;
8890
struct vop_reg auto_gate_en;

drivers/gpu/drm/rockchip/rockchip_vop_reg.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ static const struct vop_ctrl rk3288_ctrl_data = {
178178
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
179179
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
180180
.vpost_st_end_f1 = VOP_REG(RK3288_POST_DSP_VACT_INFO_F1, 0x1fff1fff, 0),
181+
.post_scl_factor = VOP_REG(RK3288_POST_SCL_FACTOR_YRGB, 0xffffffff, 0),
182+
.post_scl_ctrl = VOP_REG(RK3288_POST_SCL_CTRL, 0x3, 0),
183+
181184
.dsp_interlace = VOP_REG(RK3288_DSP_CTRL0, 0x1, 10),
182185
.auto_gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
183186
.dsp_layer_sel = VOP_REG(RK3288_DSP_CTRL1, 0xff, 8),

0 commit comments

Comments
 (0)