misc: rk628: provides multiple hsync and vsync polarity configuration methods

// example:
&rk628 {
    // case 1:
    mode-hsync-pol = <1>;
    mode-vsync-pol = <1>;
    // case 2:
    mode-sync-pol = <1>;
    // case 3:
    display-timings {
        src-timing {
            ...
            hsync-active = <1>;
            vsync-active = <1>;
            ...
        }
        dst-timing {
            ...
        }
    }
}

Priority: case 3 > case 2 > case 1
-- case 1: the hsync and vsync polarities are configured by parsing
the values of the "mode-hsync-pol" and "mode-vsync-pol" properties
(if no property is configured, the corresponding polarity defaults to
positive polarity.
-- case 2: hsync and vsync polarity equal to "mode-sync-pol"
-- case 3: the "hsync-active" and "vsync-active" properties values in
the "display-timings"-"src-timings" node are prioritized to configure
the hsync and vsync polarity.

Signed-off-by: Zhibin Huang <zhibin.huang@rock-chips.com>
Change-Id: I595651f0761ed77e5582e297977359ab7ddc1743
This commit is contained in:
Zhibin Huang
2024-08-09 08:35:34 +08:00
committed by Tao Huang
parent 60a6e19c71
commit cd5901c83f
3 changed files with 40 additions and 28 deletions

View File

@@ -736,7 +736,6 @@ static int rk628_display_route_info_parse(struct rk628 *rk628)
{
struct device_node *np;
int ret = 0;
u32 val;
if (of_property_read_bool(rk628->dev->of_node, "rk628-hdmi-in") ||
of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-in")) {
@@ -786,11 +785,6 @@ static int rk628_display_route_info_parse(struct rk628 *rk628)
ret = rk628_rgb_parse(rk628, NULL);
}
if (of_property_read_u32(rk628->dev->of_node, "mode-sync-pol", &val) < 0)
rk628->sync_pol = MODE_FLAG_PSYNC;
else
rk628->sync_pol = (!val ? MODE_FLAG_NSYNC : MODE_FLAG_PSYNC);
return ret;
}
@@ -812,6 +806,29 @@ rk628_display_mode_from_videomode(const struct rk628_videomode *vm,
dmode->flags = vm->flags;
}
static void of_parse_rk628_display_sync_pol(struct rk628 *rk628)
{
u32 val;
rk628->src_mode.flags = 0;
if (!of_property_read_u32(rk628->dev->of_node, "mode-sync-pol", &val)) {
if (val)
rk628->src_mode.flags |= DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC;
else
rk628->src_mode.flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC;
} else {
if (of_property_read_u32(rk628->dev->of_node, "mode-hsync-pol", &val) || val)
rk628->src_mode.flags |= DRM_MODE_FLAG_PHSYNC;
else
rk628->src_mode.flags |= DRM_MODE_FLAG_NHSYNC;
if (of_property_read_u32(rk628->dev->of_node, "mode-vsync-pol", &val) || val)
rk628->src_mode.flags |= DRM_MODE_FLAG_PVSYNC;
else
rk628->src_mode.flags |= DRM_MODE_FLAG_NVSYNC;
}
}
static void
of_parse_rk628_display_timing(struct device_node *np, struct rk628_videomode *vm)
{
@@ -838,10 +855,11 @@ of_parse_rk628_display_timing(struct device_node *np, struct rk628_videomode *vm
static int rk628_get_video_mode(struct rk628 *rk628)
{
struct device_node *timings_np, *src_np, *dst_np;
struct rk628_videomode vm;
of_parse_rk628_display_sync_pol(rk628);
timings_np = of_get_child_by_name(rk628->dev->of_node, "display-timings");
if (!timings_np) {
dev_info(rk628->dev, "failed to found display timings\n");

View File

@@ -704,6 +704,7 @@ static void rk628_hdmi_bridge_mode_set(struct drm_bridge *bridge,
struct rk628 *rk628 = hdmi->rk628;
struct rk628_display_mode *src = rk628_display_get_src_mode(rk628);
struct rk628_display_mode *dst = rk628_display_get_dst_mode(rk628);
int flags;
/*
* Store the display mode for plugin/DPMS poweron events. rk628d hdmitx
@@ -728,7 +729,10 @@ static void rk628_hdmi_bridge_mode_set(struct drm_bridge *bridge,
dst->vsync_end = mode->vsync_end;
dst->vtotal = mode->vtotal;
dst->flags = mode->flags;
flags = src->flags;
rk628_mode_copy(src, dst);
src->flags = flags;
}
static bool
@@ -739,13 +743,11 @@ rk628_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
struct rk628_hdmi *hdmi = bridge_to_hdmi(bridge);
struct rk628 *rk628 = hdmi->rk628;
if (rk628->sync_pol == MODE_FLAG_NSYNC) {
adj->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
adj->flags |= (DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
} else {
adj->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
adj->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
}
adj->flags &= ~(DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_PVSYNC |
DRM_MODE_FLAG_NVSYNC);
adj->flags |= rk628->src_mode.flags;
return true;
}

View File

@@ -1514,20 +1514,12 @@ void rk628_post_process_init(struct rk628 *rk628)
struct rk628_display_mode *src = &rk628->src_mode;
const struct rk628_display_mode *dst = &rk628->dst_mode;
if (rk628_output_is_hdmi(rk628)) {
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_VSYNC_POL_MASK,
SW_VSYNC_POL(rk628->sync_pol));
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_HSYNC_POL_MASK,
SW_HSYNC_POL(rk628->sync_pol));
} else {
if (src->flags & DRM_MODE_FLAG_PVSYNC)
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
SW_VSYNC_POL_MASK, SW_VSYNC_POL(1));
if (src->flags & DRM_MODE_FLAG_PHSYNC)
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
SW_HSYNC_POL_MASK,
SW_HSYNC_POL(1));
}
if (src->flags & DRM_MODE_FLAG_PVSYNC)
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
SW_VSYNC_POL_MASK, SW_VSYNC_POL(1));
if (src->flags & DRM_MODE_FLAG_PHSYNC)
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
SW_HSYNC_POL_MASK, SW_HSYNC_POL(1));
rk628_post_process_scaler_init(rk628, src, dst);
}