Skip to content

Commit ad10b82

Browse files
Andy Yanmmind
authored andcommitted
drm/rockchip: inno-hdmi: Fix video timing HSYNC/VSYNC polarity setting for rk3036
The HSYNC/VSYNC polarity of rk3036 HDMI are controlled by GRF. Without the polarity configuration in GRF, it can be observed from the HDMI protocol analyzer that the H/V front/back timing output by RK3036 HDMI are currently not in line with the specifications. Signed-off-by: Andy Yan <andy.yan@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> #rk3036-kylin Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://lore.kernel.org/r/20250422070455.432666-5-andyshrk@163.com
1 parent 31b4403 commit ad10b82

1 file changed

Lines changed: 35 additions & 1 deletion

File tree

drivers/gpu/drm/rockchip/inno_hdmi.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
#include <linux/delay.h>
1111
#include <linux/err.h>
1212
#include <linux/hdmi.h>
13+
#include <linux/mfd/syscon.h>
1314
#include <linux/mod_devicetable.h>
1415
#include <linux/module.h>
1516
#include <linux/mutex.h>
1617
#include <linux/platform_device.h>
18+
#include <linux/regmap.h>
1719

1820
#include <drm/drm_atomic.h>
1921
#include <drm/drm_atomic_helper.h>
@@ -29,15 +31,27 @@
2931

3032
#include "inno_hdmi.h"
3133

34+
#define HIWORD_UPDATE(val, mask) ((val) | (mask) << 16)
35+
3236
#define INNO_HDMI_MIN_TMDS_CLOCK 25000000U
3337

38+
#define RK3036_GRF_SOC_CON2 0x148
39+
#define RK3036_HDMI_PHSYNC BIT(4)
40+
#define RK3036_HDMI_PVSYNC BIT(5)
41+
42+
enum inno_hdmi_dev_type {
43+
RK3036_HDMI,
44+
RK3128_HDMI,
45+
};
46+
3447
struct inno_hdmi_phy_config {
3548
unsigned long pixelclock;
3649
u8 pre_emphasis;
3750
u8 voltage_level_control;
3851
};
3952

4053
struct inno_hdmi_variant {
54+
enum inno_hdmi_dev_type dev_type;
4155
struct inno_hdmi_phy_config *phy_configs;
4256
struct inno_hdmi_phy_config *default_phy_config;
4357
};
@@ -58,6 +72,7 @@ struct inno_hdmi {
5872
struct clk *pclk;
5973
struct clk *refclk;
6074
void __iomem *regs;
75+
struct regmap *grf;
6176

6277
struct drm_connector connector;
6378
struct rockchip_encoder encoder;
@@ -374,7 +389,15 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
374389
static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
375390
struct drm_display_mode *mode)
376391
{
377-
int value;
392+
int value, psync;
393+
394+
if (hdmi->variant->dev_type == RK3036_HDMI) {
395+
psync = mode->flags & DRM_MODE_FLAG_PHSYNC ? RK3036_HDMI_PHSYNC : 0;
396+
value = HIWORD_UPDATE(psync, RK3036_HDMI_PHSYNC);
397+
psync = mode->flags & DRM_MODE_FLAG_PVSYNC ? RK3036_HDMI_PVSYNC : 0;
398+
value |= HIWORD_UPDATE(psync, RK3036_HDMI_PVSYNC);
399+
regmap_write(hdmi->grf, RK3036_GRF_SOC_CON2, value);
400+
}
378401

379402
/* Set detail external video timing polarity and interlace mode */
380403
value = v_EXTERANL_VIDEO(1);
@@ -904,6 +927,15 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
904927
goto err_disable_pclk;
905928
}
906929

930+
if (hdmi->variant->dev_type == RK3036_HDMI) {
931+
hdmi->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
932+
if (IS_ERR(hdmi->grf)) {
933+
ret = dev_err_probe(dev, PTR_ERR(hdmi->grf),
934+
"Unable to get rockchip,grf\n");
935+
goto err_disable_clk;
936+
}
937+
}
938+
907939
irq = platform_get_irq(pdev, 0);
908940
if (irq < 0) {
909941
ret = irq;
@@ -988,11 +1020,13 @@ static void inno_hdmi_remove(struct platform_device *pdev)
9881020
}
9891021

9901022
static const struct inno_hdmi_variant rk3036_inno_hdmi_variant = {
1023+
.dev_type = RK3036_HDMI,
9911024
.phy_configs = rk3036_hdmi_phy_configs,
9921025
.default_phy_config = &rk3036_hdmi_phy_configs[1],
9931026
};
9941027

9951028
static const struct inno_hdmi_variant rk3128_inno_hdmi_variant = {
1029+
.dev_type = RK3128_HDMI,
9961030
.phy_configs = rk3128_hdmi_phy_configs,
9971031
.default_phy_config = &rk3128_hdmi_phy_configs[1],
9981032
};

0 commit comments

Comments
 (0)