mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
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
This commit is contained in:
parent
31b4403c6c
commit
ad10b82c2b
|
|
@ -10,10 +10,12 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/hdmi.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
|
|
@ -29,8 +31,19 @@
|
|||
|
||||
#include "inno_hdmi.h"
|
||||
|
||||
#define HIWORD_UPDATE(val, mask) ((val) | (mask) << 16)
|
||||
|
||||
#define INNO_HDMI_MIN_TMDS_CLOCK 25000000U
|
||||
|
||||
#define RK3036_GRF_SOC_CON2 0x148
|
||||
#define RK3036_HDMI_PHSYNC BIT(4)
|
||||
#define RK3036_HDMI_PVSYNC BIT(5)
|
||||
|
||||
enum inno_hdmi_dev_type {
|
||||
RK3036_HDMI,
|
||||
RK3128_HDMI,
|
||||
};
|
||||
|
||||
struct inno_hdmi_phy_config {
|
||||
unsigned long pixelclock;
|
||||
u8 pre_emphasis;
|
||||
|
|
@ -38,6 +51,7 @@ struct inno_hdmi_phy_config {
|
|||
};
|
||||
|
||||
struct inno_hdmi_variant {
|
||||
enum inno_hdmi_dev_type dev_type;
|
||||
struct inno_hdmi_phy_config *phy_configs;
|
||||
struct inno_hdmi_phy_config *default_phy_config;
|
||||
};
|
||||
|
|
@ -58,6 +72,7 @@ struct inno_hdmi {
|
|||
struct clk *pclk;
|
||||
struct clk *refclk;
|
||||
void __iomem *regs;
|
||||
struct regmap *grf;
|
||||
|
||||
struct drm_connector connector;
|
||||
struct rockchip_encoder encoder;
|
||||
|
|
@ -374,7 +389,15 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
|
|||
static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
int value;
|
||||
int value, psync;
|
||||
|
||||
if (hdmi->variant->dev_type == RK3036_HDMI) {
|
||||
psync = mode->flags & DRM_MODE_FLAG_PHSYNC ? RK3036_HDMI_PHSYNC : 0;
|
||||
value = HIWORD_UPDATE(psync, RK3036_HDMI_PHSYNC);
|
||||
psync = mode->flags & DRM_MODE_FLAG_PVSYNC ? RK3036_HDMI_PVSYNC : 0;
|
||||
value |= HIWORD_UPDATE(psync, RK3036_HDMI_PVSYNC);
|
||||
regmap_write(hdmi->grf, RK3036_GRF_SOC_CON2, value);
|
||||
}
|
||||
|
||||
/* Set detail external video timing polarity and interlace mode */
|
||||
value = v_EXTERANL_VIDEO(1);
|
||||
|
|
@ -904,6 +927,15 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
|
|||
goto err_disable_pclk;
|
||||
}
|
||||
|
||||
if (hdmi->variant->dev_type == RK3036_HDMI) {
|
||||
hdmi->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
|
||||
if (IS_ERR(hdmi->grf)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(hdmi->grf),
|
||||
"Unable to get rockchip,grf\n");
|
||||
goto err_disable_clk;
|
||||
}
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
ret = irq;
|
||||
|
|
@ -988,11 +1020,13 @@ static void inno_hdmi_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct inno_hdmi_variant rk3036_inno_hdmi_variant = {
|
||||
.dev_type = RK3036_HDMI,
|
||||
.phy_configs = rk3036_hdmi_phy_configs,
|
||||
.default_phy_config = &rk3036_hdmi_phy_configs[1],
|
||||
};
|
||||
|
||||
static const struct inno_hdmi_variant rk3128_inno_hdmi_variant = {
|
||||
.dev_type = RK3128_HDMI,
|
||||
.phy_configs = rk3128_hdmi_phy_configs,
|
||||
.default_phy_config = &rk3128_hdmi_phy_configs[1],
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user