#include <linux/delay.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
+#include <linux/of_gpio.h>
+#include <linux/rockchip/cpu.h>
#include <linux/rockchip/grf.h>
#include <linux/rockchip/iomap.h>
#include <linux/mfd/syscon.h>
#include "rockchip_hdmiv2.h"
#include "rockchip_hdmiv2_hw.h"
-#define HDMI_SEL_LCDC(x) ((((x)&1)<<4)|(1<<20))
-#define grf_writel(v, offset) writel_relaxed(v, RK_GRF_VIRT + offset)
-
static struct hdmi_dev *hdmi_dev;
static struct hdmi_property rk_hdmi_property = {
{I2C_MASTER_BASE, I2CM_SCDC_UPDATE1},
};
-static int rockchip_hdmiv2_reg_show(struct seq_file *s, void *v)
+static int hdmi_regs_ctrl_show(struct seq_file *s, void *v)
{
- int i = 0, j = 0;
- u32 val = 0;
+ u32 i = 0, j = 0, val = 0;
seq_puts(s, "\n>>>hdmi_ctl reg ");
for (i = 0; i < 16; i++)
for (j = hdmi_reg_table[i].reg_base;
j <= hdmi_reg_table[i].reg_end; j++) {
val = hdmi_readl(hdmi_dev, j);
- if ((j - hdmi_reg_table[i].reg_base)%16 == 0)
+ if ((j - hdmi_reg_table[i].reg_base) % 16 == 0)
seq_printf(s, "\n>>>hdmi_ctl %04x:", j);
seq_printf(s, " %02x", val);
}
}
seq_puts(s, "\n-----------------------------------------------------------------\n");
- /*rockchip_hdmiv2_dump_phy_regs(hdmi_dev);*/
return 0;
}
-static ssize_t rockchip_hdmiv2_reg_write(struct file *file,
- const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t hdmi_regs_ctrl_write(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
{
- u32 reg;
- u32 val;
+ u32 reg, val;
char kbuf[25];
if (copy_from_user(kbuf, buf, count))
return count;
}
-static int rockchip_hdmiv2_reg_open(struct inode *inode, struct file *file)
+static int hdmi_regs_phy_show(struct seq_file *s, void *v)
{
- struct hdmi_dev *hdmi_dev = inode->i_private;
+ u32 i, count;
- return single_open(file, rockchip_hdmiv2_reg_show, hdmi_dev);
+ if (hdmi_dev->soctype == HDMI_SOC_RK322X)
+ count = 0xff;
+ else
+ count = 0x28;
+ seq_puts(s, "\n>>>hdmi_phy reg ");
+ for (i = 0; i < count; i++)
+ seq_printf(s, "regs %02x val %04x\n",
+ i, rockchip_hdmiv2_read_phy(hdmi_dev, i));
+ return 0;
}
-static const struct file_operations rockchip_hdmiv2_reg_fops = {
- .owner = THIS_MODULE,
- .open = rockchip_hdmiv2_reg_open,
- .read = seq_read,
- .write = rockchip_hdmiv2_reg_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
+static ssize_t hdmi_regs_phy_write(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ u32 reg, val;
+ char kbuf[25];
+
+ if (copy_from_user(kbuf, buf, count))
+ return -EFAULT;
+ if (sscanf(kbuf, "%x%x", ®, &val) == -1)
+ return -EFAULT;
+ dev_info(hdmi_dev->hdmi->dev,
+ "/**********hdmi reg phy config******/");
+ dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val);
+ rockchip_hdmiv2_write_phy(hdmi_dev, reg, val);
+ return count;
+}
+
+#define HDMI_DEBUG_ENTRY(name) \
+static int hdmi_##name##_open(struct inode *inode, struct file *file) \
+{ \
+ return single_open(file, hdmi_##name##_show, inode->i_private); \
+} \
+\
+static const struct file_operations hdmi_##name##_fops = { \
+ .owner = THIS_MODULE, \
+ .open = hdmi_##name##_open, \
+ .read = seq_read, \
+ .write = hdmi_##name##_write, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+}
+
+HDMI_DEBUG_ENTRY(regs_phy);
+HDMI_DEBUG_ENTRY(regs_ctrl);
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
static void rockchip_hdmiv2_early_suspend(struct early_suspend *h)
{
struct hdmi *hdmi = hdmi_dev->hdmi;
- struct delay_work *delay_work;
struct pinctrl_state *gpio_state;
HDMIDBG("hdmi enter early suspend\n");
- delay_work = hdmi_submit_work(hdmi, HDMI_SUSPEND_CTL, 0, NULL);
- if (delay_work)
- flush_delayed_work_sync(delay_work);
+ hdmi_submit_work(hdmi, HDMI_SUSPEND_CTL, 0, 1);
/* iomux to gpio and pull down when suspend */
gpio_state = pinctrl_lookup_state(hdmi_dev->dev->pins->p, "gpio");
pinctrl_select_state(hdmi_dev->dev->pins->p, gpio_state);
hdmi_dev_initial(hdmi_dev);
if (hdmi->ops->hdcp_power_on_cb)
hdmi->ops->hdcp_power_on_cb();
- hdmi_submit_work(hdmi, HDMI_RESUME_CTL, 0, NULL);
+ hdmi_submit_work(hdmi, HDMI_RESUME_CTL, 0, 0);
}
#endif
-#define HDMI_PD_ON (1 << 0)
-#define HDMI_PCLK_ON (1 << 1)
-#define HDMI_HDCPCLK_ON (1 << 2)
-#define HDMI_CECCLK_ON (1 << 3)
+void ext_pll_set_27m_out(void)
+{
+ if (!hdmi_dev || hdmi_dev->soctype != HDMI_SOC_RK322X)
+ return;
+ /* PHY PLL VCO is 1080MHz, output pclk is 27MHz */
+ rockchip_hdmiv2_write_phy(hdmi_dev,
+ EXT_PHY_PLL_PRE_DIVIDER,
+ 1);
+ rockchip_hdmiv2_write_phy(hdmi_dev,
+ EXT_PHY_PLL_FB_DIVIDER,
+ 45);
+ rockchip_hdmiv2_write_phy(hdmi_dev,
+ EXT_PHY_PCLK_DIVIDER1,
+ 0x61);
+ rockchip_hdmiv2_write_phy(hdmi_dev,
+ EXT_PHY_PCLK_DIVIDER2,
+ 0x64);
+ rockchip_hdmiv2_write_phy(hdmi_dev,
+ EXT_PHY_TMDSCLK_DIVIDER,
+ 0x1d);
+}
static int rockchip_hdmiv2_clk_enable(struct hdmi_dev *hdmi_dev)
{
- if ((hdmi_dev->clk_on & HDMI_PD_ON) &&
- (hdmi_dev->clk_on & HDMI_PCLK_ON) &&
- (hdmi_dev->clk_on & HDMI_HDCPCLK_ON))
- return 0;
-
if ((hdmi_dev->clk_on & HDMI_PD_ON) == 0) {
- if (hdmi_dev->pd == NULL) {
- hdmi_dev->pd = devm_clk_get(hdmi_dev->dev, "pd_hdmi");
- if (IS_ERR(hdmi_dev->pd)) {
- dev_err(hdmi_dev->dev,
- "Unable to get hdmi pd\n");
- return -1;
- }
- }
- clk_prepare_enable(hdmi_dev->pd);
+ pm_runtime_get_sync(hdmi_dev->dev);
hdmi_dev->clk_on |= HDMI_PD_ON;
}
+ if (hdmi_dev->soctype == HDMI_SOC_RK322X ||
+ hdmi_dev->soctype == HDMI_SOC_RK3366 ||
+ hdmi_dev->soctype == HDMI_SOC_RK3399) {
+ if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) == 0) {
+ if (!hdmi_dev->pclk_phy) {
+ if (hdmi_dev->soctype == HDMI_SOC_RK322X)
+ hdmi_dev->pclk_phy =
+ devm_clk_get(hdmi_dev->dev,
+ "pclk_hdmi_phy");
+ else
+ hdmi_dev->pclk_phy =
+ devm_clk_get(hdmi_dev->dev,
+ "dclk_hdmi_phy");
+ if (IS_ERR(hdmi_dev->pclk_phy)) {
+ dev_err(hdmi_dev->dev,
+ "get hdmi phy pclk error\n");
+ return -1;
+ }
+ }
+ clk_prepare_enable(hdmi_dev->pclk_phy);
+ hdmi_dev->clk_on |= HDMI_EXT_PHY_CLK_ON;
+ }
+ }
if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) {
- if (hdmi_dev->pclk == NULL) {
+ if (!hdmi_dev->pclk) {
hdmi_dev->pclk =
devm_clk_get(hdmi_dev->dev, "pclk_hdmi");
if (IS_ERR(hdmi_dev->pclk)) {
}
if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) {
- if (hdmi_dev->hdcp_clk == NULL) {
+ if (!hdmi_dev->hdcp_clk) {
hdmi_dev->hdcp_clk =
devm_clk_get(hdmi_dev->dev, "hdcp_clk_hdmi");
if (IS_ERR(hdmi_dev->hdcp_clk)) {
if ((rk_hdmi_property.feature & SUPPORT_CEC) &&
(hdmi_dev->clk_on & HDMI_CECCLK_ON) == 0) {
- if (hdmi_dev->cec_clk == NULL) {
+ if (!hdmi_dev->cec_clk) {
hdmi_dev->cec_clk =
devm_clk_get(hdmi_dev->dev, "cec_clk_hdmi");
if (IS_ERR(hdmi_dev->cec_clk)) {
clk_prepare_enable(hdmi_dev->cec_clk);
hdmi_dev->clk_on |= HDMI_CECCLK_ON;
}
+
+ if ((hdmi_dev->clk_on & HDMI_SFRCLK_ON) == 0) {
+ if (!hdmi_dev->sfr_clk) {
+ hdmi_dev->sfr_clk =
+ devm_clk_get(hdmi_dev->dev, "sclk_hdmi_sfr");
+ if (IS_ERR(hdmi_dev->sfr_clk)) {
+ dev_err(hdmi_dev->dev,
+ "Unable to get hdmi sfr_clk\n");
+ return -1;
+ }
+ }
+ clk_prepare_enable(hdmi_dev->sfr_clk);
+ hdmi_dev->clk_on |= HDMI_SFRCLK_ON;
+ }
+
return 0;
}
if (hdmi_dev->clk_on == 0)
return 0;
- if ((hdmi_dev->clk_on & HDMI_PD_ON) && (hdmi_dev->pd != NULL)) {
- clk_disable_unprepare(hdmi_dev->pd);
+ if ((hdmi_dev->clk_on & HDMI_PD_ON)) {
+ pm_runtime_put(hdmi_dev->dev);
hdmi_dev->clk_on &= ~HDMI_PD_ON;
}
if ((hdmi_dev->clk_on & HDMI_PCLK_ON) &&
- (hdmi_dev->pclk != NULL)) {
+ (hdmi_dev->pclk)) {
clk_disable_unprepare(hdmi_dev->pclk);
hdmi_dev->clk_on &= ~HDMI_PCLK_ON;
}
if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) &&
- (hdmi_dev->hdcp_clk != NULL)) {
+ (hdmi_dev->hdcp_clk)) {
clk_disable_unprepare(hdmi_dev->hdcp_clk);
hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON;
}
+ if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) &&
+ hdmi_dev->pclk_phy) {
+ clk_disable_unprepare(hdmi_dev->pclk_phy);
+ hdmi_dev->clk_on &= ~HDMI_EXT_PHY_CLK_ON;
+ }
+
+ if ((hdmi_dev->clk_on & HDMI_SFRCLK_ON) &&
+ (hdmi_dev->sfr_clk)) {
+ clk_disable_unprepare(hdmi_dev->sfr_clk);
+ hdmi_dev->clk_on &= ~HDMI_SFRCLK_ON;
+ }
+
+
return 0;
}
unsigned long action, void *data)
{
struct fb_event *event = data;
- int blank_mode = *((int *)event->data);
struct hdmi *hdmi = hdmi_dev->hdmi;
- struct delayed_work *delay_work;
+ struct pinctrl_state *gpio_state;
+#ifdef CONFIG_PINCTRL
+ struct dev_pin_info *pins = hdmi_dev->dev->pins;
+#endif
if (action == FB_EARLY_EVENT_BLANK) {
- switch (blank_mode) {
+ switch (*((int *)event->data)) {
case FB_BLANK_UNBLANK:
break;
default:
HDMIDBG("suspend hdmi\n");
if (!hdmi->sleep) {
- delay_work =
- hdmi_submit_work(hdmi,
- HDMI_SUSPEND_CTL,
- 0, NULL);
- if (delay_work)
- flush_delayed_work(delay_work);
+ hdmi_submit_work(hdmi,
+ HDMI_SUSPEND_CTL,
+ 0, 1);
+ if (hdmi_dev->hdcp2_en)
+ hdmi_dev->hdcp2_en(0);
+ mutex_lock(&hdmi->pclk_lock);
rockchip_hdmiv2_clk_disable(hdmi_dev);
+ mutex_unlock(&hdmi->pclk_lock);
+ #ifdef CONFIG_PINCTRL
+ if (hdmi_dev->soctype == HDMI_SOC_RK3288)
+ gpio_state =
+ pinctrl_lookup_state(pins->p,
+ "sleep");
+ else
+ gpio_state =
+ pinctrl_lookup_state(pins->p,
+ "gpio");
+ pinctrl_select_state(pins->p,
+ gpio_state);
+ #endif
}
break;
}
} else if (action == FB_EVENT_BLANK) {
- switch (blank_mode) {
+ switch (*((int *)event->data)) {
case FB_BLANK_UNBLANK:
HDMIDBG("resume hdmi\n");
if (hdmi->sleep) {
+ #ifdef CONFIG_PINCTRL
+ pinctrl_select_state(pins->p,
+ pins->default_state);
+ #endif
+ mutex_lock(&hdmi->pclk_lock);
rockchip_hdmiv2_clk_enable(hdmi_dev);
+ mutex_unlock(&hdmi->pclk_lock);
rockchip_hdmiv2_dev_initial(hdmi_dev);
if (hdmi->ops->hdcp_power_on_cb)
hdmi->ops->hdcp_power_on_cb();
+ if (hdmi_dev->hdcp2_reset)
+ hdmi_dev->hdcp2_reset();
+ if (hdmi_dev->hdcp2_en)
+ hdmi_dev->hdcp2_en(1);
hdmi_submit_work(hdmi, HDMI_RESUME_CTL,
- 0, NULL);
+ 0, 0);
}
break;
default:
static struct notifier_block rockchip_hdmiv2_fb_notifier = {
.notifier_call = rockchip_hdmiv2_fb_event_notify,
};
+
#ifdef HDMI_INT_USE_POLL
static void rockchip_hdmiv2_irq_work_func(struct work_struct *work)
{
if (hdmi_dev->enable) {
rockchip_hdmiv2_dev_irq(0, hdmi_dev);
queue_delayed_work(hdmi_dev->workqueue,
- &(hdmi_dev->delay_work),
+ &hdmi_dev->delay_work,
msecs_to_jiffies(50));
}
}
static struct hdmi_ops rk_hdmi_ops;
-
#if defined(CONFIG_OF)
static const struct of_device_id rk_hdmi_dt_ids[] = {
+ {.compatible = "rockchip,rk322x-hdmi",},
{.compatible = "rockchip,rk3288-hdmi",},
+ {.compatible = "rockchip,rk3366-hdmi",},
{.compatible = "rockchip,rk3368-hdmi",},
+ {.compatible = "rockchip,rk3399-hdmi",},
{}
};
hdmi_dev->soctype = HDMI_SOC_RK3288;
} else if (!strcmp(match->compatible, "rockchip,rk3368-hdmi")) {
hdmi_dev->soctype = HDMI_SOC_RK3368;
+ } else if (!strcmp(match->compatible, "rockchip,rk322x-hdmi")) {
+ hdmi_dev->soctype = HDMI_SOC_RK322X;
+ } else if (!strcmp(match->compatible, "rockchip,rk3366-hdmi")) {
+ hdmi_dev->soctype = HDMI_SOC_RK3366;
+ } else if (!strcmp(match->compatible, "rockchip,rk3399-hdmi")) {
+ hdmi_dev->soctype = HDMI_SOC_RK3399;
} else {
pr_err("It is not a valid rockchip soc!");
return -ENOMEM;
if (!of_property_read_u32(np, "rockchip,cec_enable", &val) &&
(val == 1)) {
- pr_info("hdmi support cec\n");
+ pr_debug("hdmi support cec\n");
rk_hdmi_property.feature |= SUPPORT_CEC;
}
if (!of_property_read_u32(np, "rockchip,hdcp_enable", &val) &&
(val == 1)) {
- pr_info("hdmi support hdcp\n");
+ pr_debug("hdmi support hdcp\n");
rk_hdmi_property.feature |= SUPPORT_HDCP;
}
+ if (!of_property_read_u32(np, "rockchip,defaultmode", &val) &&
+ (val > 0)) {
+ pr_debug("default mode is %d\n", val);
+ rk_hdmi_property.defaultmode = val;
+ } else {
+ rk_hdmi_property.defaultmode = HDMI_VIDEO_DEFAULT_MODE;
+ }
+ if (of_get_property(np, "rockchip,phy_table", &val)) {
+ hdmi_dev->phy_table = kmalloc(val, GFP_KERNEL);
+ if (!hdmi_dev->phy_table) {
+ pr_err("kmalloc phy table %d error\n", val);
+ return -ENOMEM;
+ }
+ hdmi_dev->phy_table_size =
+ val / sizeof(struct hdmi_dev_phy_para);
+ of_property_read_u32_array(np, "rockchip,phy_table",
+ (u32 *)hdmi_dev->phy_table,
+ val / sizeof(u32));
+ } else {
+ pr_info("hdmi phy_table not exist\n");
+ }
+
+ of_property_read_string(np, "rockchip,vendor",
+ &hdmi_dev->vendor_name);
+ of_property_read_string(np, "rockchip,product",
+ &hdmi_dev->product_name);
+ if (!of_property_read_u32(np, "rockchip,deviceinfo", &val))
+ hdmi_dev->deviceinfo = val & 0xff;
+
#ifdef CONFIG_MFD_SYSCON
hdmi_dev->grf_base =
syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+ if (IS_ERR(hdmi_dev->grf_base)) {
+ hdmi_dev->grf_base = NULL;
+ }
#endif
return 0;
}
platform_set_drvdata(pdev, hdmi_dev);
hdmi_dev->dev = &pdev->dev;
- rockchip_hdmiv2_parse_dt(hdmi_dev);
+ if (rockchip_hdmiv2_parse_dt(hdmi_dev))
+ goto failed;
/*request and remap iomem*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ret = -ENXIO;
goto failed;
}
- hdmi_dev->regbase_phy = res->start;
- hdmi_dev->regsize_phy = resource_size(res);
hdmi_dev->regbase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(hdmi_dev->regbase)) {
ret = PTR_ERR(hdmi_dev->regbase);
"cannot ioremap registers,err=%d\n", ret);
goto failed;
}
+ if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev,
+ "Unable to get phy register resource\n");
+ ret = -ENXIO;
+ goto failed;
+ }
+ hdmi_dev->phybase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(hdmi_dev->phybase)) {
+ ret = PTR_ERR(hdmi_dev->phybase);
+ dev_err(&pdev->dev,
+ "cannot ioremap registers,err=%d\n", ret);
+ goto failed;
+ }
+ }
- /*enable pd and pclk and hdcp_clk*/
+ hdmi_dev->reset = devm_reset_control_get(&pdev->dev, "hdmi");
+ if (IS_ERR(hdmi_dev->reset) &&
+ hdmi_dev->soctype != HDMI_SOC_RK3288) {
+ ret = PTR_ERR(hdmi_dev->reset);
+ dev_err(&pdev->dev, "failed to get hdmi reset: %d\n", ret);
+ goto failed;
+ }
+ pm_runtime_enable(hdmi_dev->dev);
+ /*enable pd and clk*/
if (rockchip_hdmiv2_clk_enable(hdmi_dev) < 0) {
+ dev_err(&pdev->dev, "failed to enable hdmi clk\n");
ret = -ENXIO;
goto failed1;
}
- /*lcdc source select*/
- if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
- grf_writel(HDMI_SEL_LCDC(rk_hdmi_property.videosrc),
- RK3288_GRF_SOC_CON6);
- /* select GPIO7_C0 as cec pin */
- grf_writel(((1 << 12) | (1 << 28)), RK3288_GRF_SOC_CON8);
- }
rockchip_hdmiv2_dev_init_ops(&rk_hdmi_ops);
/* Register HDMI device */
rk_hdmi_property.name = (char *)pdev->name;
rk_hdmi_property.priv = hdmi_dev;
if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
- /*rk_hdmi_property.feature |= SUPPORT_DEEP_10BIT;*/
+ rk_hdmi_property.feature |= SUPPORT_DEEP_10BIT;
if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
rk_hdmi_property.feature |=
SUPPORT_4K |
SUPPORT_4K |
SUPPORT_4K_4096 |
SUPPORT_YUV420 |
- SUPPORT_YCBCR_INPUT;
+ SUPPORT_YCBCR_INPUT |
+ SUPPORT_VESA_DMT;
+ } else if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
+ rk_hdmi_property.feature |=
+ SUPPORT_4K |
+ SUPPORT_4K_4096 |
+ SUPPORT_YCBCR_INPUT |
+ SUPPORT_1080I |
+ SUPPORT_480I_576I;
+ /*
+ *if (rockchip_get_cpu_version())
+ * rk_hdmi_property.feature |=
+ * SUPPORT_YUV420 |
+ * SUPPORT_DEEP_10BIT;
+ */
+ } else if (hdmi_dev->soctype == HDMI_SOC_RK3366) {
+ rk_hdmi_property.feature |=
+ SUPPORT_YCBCR_INPUT |
+ SUPPORT_1080I |
+ SUPPORT_480I_576I;
+ if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
+ rk_hdmi_property.feature |=
+ SUPPORT_4K |
+ SUPPORT_4K_4096 |
+ SUPPORT_YUV420 |
+ SUPPORT_YCBCR_INPUT |
+ SUPPORT_TMDS_600M;
+ } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
+ rk_hdmi_property.feature |=
+ SUPPORT_DEEP_10BIT |
+ SUPPORT_YCBCR_INPUT |
+ SUPPORT_1080I |
+ SUPPORT_480I_576I |
+ SUPPORT_VESA_DMT |
+ SUPPORT_RK_DISCRETE_VR;
+ if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
+ rk_hdmi_property.feature |=
+ SUPPORT_4K |
+ SUPPORT_4K_4096 |
+ SUPPORT_YUV420 |
+ SUPPORT_YCBCR_INPUT |
+ SUPPORT_TMDS_600M;
+ } else {
+ ret = -ENXIO;
+ goto failed1;
}
hdmi_dev->hdmi =
rockchip_hdmi_register(&rk_hdmi_property, &rk_hdmi_ops);
- if (hdmi_dev->hdmi == NULL) {
+ if (!hdmi_dev->hdmi) {
dev_err(&pdev->dev, "register hdmi device failed\n");
ret = -ENOMEM;
goto failed1;
if (IS_ERR(hdmi_dev->debugfs_dir))
dev_err(hdmi_dev->hdmi->dev,
"failed to create debugfs dir for rockchip hdmiv2!\n");
- else
- debugfs_create_file("hdmi", S_IRUSR,
+ else {
+ debugfs_create_file("regs_ctrl", S_IRUSR,
+ hdmi_dev->debugfs_dir,
+ hdmi_dev, &hdmi_regs_ctrl_fops);
+ debugfs_create_file("regs_phy", S_IRUSR,
hdmi_dev->debugfs_dir,
- hdmi_dev, &rockchip_hdmiv2_reg_fops);
+ hdmi_dev, &hdmi_regs_phy_fops);
+ }
#endif
- rk_display_device_enable(hdmi_dev->hdmi->ddev);
#ifndef HDMI_INT_USE_POLL
/* get and request the IRQ */
goto failed1;
}
- ret =
- devm_request_irq(hdmi_dev->dev, hdmi_dev->irq,
- rockchip_hdmiv2_dev_irq,
- IRQF_TRIGGER_HIGH,
- dev_name(hdmi_dev->dev), hdmi_dev);
+ ret = devm_request_irq(hdmi_dev->dev, hdmi_dev->irq,
+ rockchip_hdmiv2_dev_irq,
+ IRQF_TRIGGER_HIGH,
+ dev_name(hdmi_dev->dev), hdmi_dev);
if (ret) {
- dev_err(hdmi_dev->dev, "hdmi request_irq failed (%d).\n", ret);
+ dev_err(hdmi_dev->dev,
+ "hdmi request_irq failed (%d).\n",
+ ret);
goto failed1;
}
#else
hdmi_dev->workqueue =
create_singlethread_workqueue("rockchip hdmiv2 irq");
- INIT_DELAYED_WORK(&(hdmi_dev->delay_work),
+ INIT_DELAYED_WORK(&hdmi_dev->delay_work,
rockchip_hdmiv2_irq_work_func);
rockchip_hdmiv2_irq_work_func(NULL);
#endif
- dev_info(&pdev->dev, "rockchip hdmiv2 probe sucess.\n");
+ rk_display_device_enable(hdmi_dev->hdmi->ddev);
+ dev_info(&pdev->dev, "rockchip hdmiv2 probe success.\n");
return 0;
failed1:
rockchip_hdmi_unregister(hdmi_dev->hdmi);
failed:
+ kfree(hdmi_dev->phy_table);
kfree(hdmi_dev);
hdmi_dev = NULL;
- dev_err(&pdev->dev, "rk3288 hdmi probe error.\n");
+ dev_err(&pdev->dev, "rockchip hdmiv2 probe error.\n");
return ret;
}
+static int rockchip_hdmiv2_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ if (hdmi_dev &&
+ hdmi_dev->grf_base &&
+ hdmi_dev->soctype == HDMI_SOC_RK322X) {
+ regmap_write(hdmi_dev->grf_base,
+ RK322X_GRF_SOC_CON2,
+ RK322X_PLL_POWER_DOWN);
+ }
+ return 0;
+}
+
+static int rockchip_hdmiv2_resume(struct platform_device *pdev)
+{
+ if (hdmi_dev &&
+ hdmi_dev->grf_base &&
+ hdmi_dev->soctype == HDMI_SOC_RK322X) {
+ regmap_write(hdmi_dev->grf_base,
+ RK322X_GRF_SOC_CON2,
+ RK322X_PLL_POWER_UP);
+ }
+ return 0;
+}
+
static int rockchip_hdmiv2_remove(struct platform_device *pdev)
{
dev_info(&pdev->dev, "rk3288 hdmi driver removed.\n");
hdmi->ops->setmute)
hdmi->ops->setmute(hdmi, HDMI_VIDEO_MUTE);
}
+ pm_runtime_disable(hdmi_dev->dev);
}
static struct platform_driver rockchip_hdmiv2_driver = {
.of_match_table = of_match_ptr(rk_hdmi_dt_ids),
#endif
},
- .shutdown = rockchip_hdmiv2_shutdown,
+ .suspend = rockchip_hdmiv2_suspend,
+ .resume = rockchip_hdmiv2_resume,
+ .shutdown = rockchip_hdmiv2_shutdown,
};
static int __init rockchip_hdmiv2_init(void)