@@ -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+
18711909static 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
19762015static 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
19872035static 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+
20082123static 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 );
22382369err_cleanup_crtc :
22392370 drm_crtc_cleanup (crtc );
22402371err_cleanup_planes :
0 commit comments