mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
drm/rockchip: inno_hdmi: add rk3128 hdmi support
Change-Id: I929880020f4a72e61d21b7af4d73a98da337b10b Signed-off-by: Huicong Xu <xhc@rock-chips.com>
This commit is contained in:
@@ -47,6 +47,22 @@ struct inno_hdmi_i2c {
|
||||
struct completion cmp;
|
||||
};
|
||||
|
||||
enum inno_hdmi_dev_type {
|
||||
RK3036_HDMI,
|
||||
RK3128_HDMI,
|
||||
};
|
||||
|
||||
struct inno_hdmi_phy_config {
|
||||
unsigned long mpixelclock;
|
||||
u8 pre_emphasis; /* pre-emphasis value */
|
||||
u8 vlev_ctr; /* voltage level control */
|
||||
};
|
||||
|
||||
struct inno_hdmi_plat_data {
|
||||
enum inno_hdmi_dev_type dev_type;
|
||||
struct inno_hdmi_phy_config *phy_config;
|
||||
};
|
||||
|
||||
struct inno_hdmi {
|
||||
struct device *dev;
|
||||
struct drm_device *drm_dev;
|
||||
@@ -62,6 +78,7 @@ struct inno_hdmi {
|
||||
struct i2c_adapter *ddc;
|
||||
|
||||
unsigned int tmds_rate;
|
||||
const struct inno_hdmi_plat_data *plat_data;
|
||||
|
||||
struct hdmi_data_info hdmi_data;
|
||||
struct drm_display_mode previous_mode;
|
||||
@@ -189,12 +206,20 @@ static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable)
|
||||
|
||||
static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
|
||||
{
|
||||
const struct inno_hdmi_phy_config *phy_config =
|
||||
hdmi->plat_data->phy_config;
|
||||
|
||||
switch (mode) {
|
||||
case NORMAL:
|
||||
inno_hdmi_sys_power(hdmi, false);
|
||||
|
||||
hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
|
||||
hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
|
||||
for (; phy_config->mpixelclock != ~0UL; phy_config++)
|
||||
if (hdmi->tmds_rate <= phy_config->mpixelclock)
|
||||
break;
|
||||
if (!phy_config->mpixelclock)
|
||||
return;
|
||||
hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS,
|
||||
phy_config->pre_emphasis);
|
||||
hdmi_writeb(hdmi, HDMI_PHY_DRIVER, phy_config->vlev_ctr);
|
||||
|
||||
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
|
||||
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
|
||||
@@ -383,6 +408,12 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
|
||||
{
|
||||
int value;
|
||||
|
||||
if (hdmi->plat_data->dev_type == RK3036_HDMI) {
|
||||
value = BIT(20) | BIT(21);
|
||||
value |= mode->flags & DRM_MODE_FLAG_PHSYNC ? BIT(4) : 0;
|
||||
value |= mode->flags & DRM_MODE_FLAG_PVSYNC ? BIT(5) : 0;
|
||||
hdmi_writeb(hdmi, 0x148, value);
|
||||
}
|
||||
/* Set detail external video timing polarity and interlace mode */
|
||||
value = v_EXTERANL_VIDEO(1);
|
||||
value |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
|
||||
@@ -804,6 +835,41 @@ static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
|
||||
return adap;
|
||||
}
|
||||
|
||||
static struct inno_hdmi_phy_config rk3036_hdmi_phy_config[] = {
|
||||
/* pixelclk pre-emp vlev */
|
||||
{ 74250000, 0x3f, 0xbb },
|
||||
{ 165000000, 0x6f, 0xbb },
|
||||
{ ~0UL, 0x00, 0x00 }
|
||||
};
|
||||
|
||||
static struct inno_hdmi_phy_config rk3128_hdmi_phy_config[] = {
|
||||
/* pixelclk pre-emp vlev */
|
||||
{ 74250000, 0x3f, 0xaa },
|
||||
{ 165000000, 0x5f, 0xaa },
|
||||
{ ~0UL, 0x00, 0x00 }
|
||||
};
|
||||
|
||||
static const struct inno_hdmi_plat_data rk3036_hdmi_drv_data = {
|
||||
.dev_type = RK3036_HDMI,
|
||||
.phy_config = rk3036_hdmi_phy_config,
|
||||
};
|
||||
|
||||
static const struct inno_hdmi_plat_data rk3128_hdmi_drv_data = {
|
||||
.dev_type = RK3128_HDMI,
|
||||
.phy_config = rk3128_hdmi_phy_config,
|
||||
};
|
||||
|
||||
static const struct of_device_id inno_hdmi_dt_ids[] = {
|
||||
{ .compatible = "rockchip,rk3036-inno-hdmi",
|
||||
.data = &rk3036_hdmi_drv_data,
|
||||
},
|
||||
{ .compatible = "rockchip,rk3128-inno-hdmi",
|
||||
.data = &rk3128_hdmi_drv_data,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
|
||||
|
||||
static int inno_hdmi_bind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
@@ -820,6 +886,7 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
|
||||
|
||||
hdmi->dev = dev;
|
||||
hdmi->drm_dev = drm;
|
||||
hdmi->plat_data = device_get_match_data(hdmi->dev);
|
||||
|
||||
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
hdmi->regs = devm_ioremap_resource(dev, iores);
|
||||
@@ -918,13 +985,6 @@ static int inno_hdmi_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id inno_hdmi_dt_ids[] = {
|
||||
{ .compatible = "rockchip,rk3036-inno-hdmi",
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
|
||||
|
||||
struct platform_driver inno_hdmi_driver = {
|
||||
.probe = inno_hdmi_probe,
|
||||
.remove = inno_hdmi_remove,
|
||||
|
||||
Reference in New Issue
Block a user