clocks = <&clk_gates1 6>, <&clk_gates7 3>;
clock-names = "clk_usbphy1", "hclk_usb1";
};
+
+ hdmi: hdmi@20034000 {
+ compatible = "rockchip,rk3036-hdmi";
+ reg = <0x20034000 0x4000>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ rockchip,hdmi_lcdc_source = <0>;
+ //pinctrl-names = "default", "gpio";
+ //pinctrl-0 = <&i2c5_sda &i2c5_scl>;
+ //pinctrl-1 = <&i2c5_gpio>;
+ clocks = <&clk_gates3 8>;
+ clock-names = "pclk_hdmi";
+ status = "disabled";
+ };
vpu: vpu_service@10108000 {
compatible = "vpu_service";
config HDMI_RK616
bool "RK616 HDMI support"
- depends on MFD_RK616 || ARCH_RK3026
+#depends on MFD_RK616 || ARCH_RK3026
default y
help
Support rk616 hdmi if you say y here
};
#endif
-#if defined(CONFIG_ARCH_RK3026)
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
static int rk616_hdmi_clk_enable(struct rk_hdmi_device *hdmi_dev)
{
if (!hdmi_dev->clk_on) {
disable_irq_nosync(hdmi_drv->irq);
queue_work(hdmi_drv->workqueue, rk616_irq_work_struct);
} else {
- /* 3028a hdmi */
+ /* 3028a/3036 hdmi */
if ((hdmi_drv->suspend == 0) && (hdmi_drv->enable == 1)) {
hdmi_dbg(hdmi_drv->dev,
"line = %d, rk616_hdmi_irq irq triggered.\n",
lcdc_id = (screen.lcdc_id == 0) ? 1 : 0;
/* lcdc source select */
/* wait to modify!!
-#if defined(CONFIG_ARCH_RK3026)
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
grf_writel(HDMI_SEL_LCDC(lcdc_id), RK3036_GRF_SOC_CON6);
#endif
*/
return ret;
}
+#if defined(CONFIG_OF)
+static const struct of_device_id rk616_hdmi_of_match[] = {
+ {.compatible = "rockchip,rk616-hdmi",},
+ {.compatible = "rockchip,rk3036-hdmi",},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, rk616_hdmi_of_match);
+#endif
+
static int rk616_hdmi_probe(struct platform_device *pdev)
{
int ret;
- struct rk_hdmi_device *hdmi_dev;
+ //struct rk_hdmi_device *hdmi_dev;
struct hdmi *hdmi_drv;
struct resource __maybe_unused *mem;
struct resource __maybe_unused *res;
platform_set_drvdata(pdev, hdmi_dev);
spin_lock_init(&hdmi_dev->reg_lock);
-#ifdef CONFIG_ARCH_RK3026
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
hdmi_dev->rk616_drv = NULL;
#else
hdmi_dev->rk616_drv = dev_get_drvdata(pdev->dev.parent);
INIT_DELAYED_WORK(&(hdmi_drv->delay_work), hdmi_work);
INIT_DELAYED_WORK(&hdmi_dev->rk616_delay_work, rk616_delay_work_func);
-#ifdef CONFIG_ARCH_RK3026
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
/* enable clk */
hdmi_dev->hclk = devm_clk_get(hdmi_drv->dev, "pclk_hdmi");
if (IS_ERR(hdmi_dev->hclk)) {
ret = -ENXIO;
goto err1;
}
- rk616_hdmi_clk_enable(); /* enable clk may move to irq func */
+ rk616_hdmi_clk_enable(hdmi_dev); /* enable clk may move to irq func */
/* request and remap iomem */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
- dev_err(hdmi_dev->dev, "Unable to get register resource\n");
+ dev_err(hdmi_drv->dev, "Unable to get register resource\n");
ret = -ENXIO;
goto err2;
}
/* get the IRQ */
hdmi_drv->irq = platform_get_irq(pdev, 0);
if (hdmi_drv->irq <= 0) {
- dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n",
- hdmi->irq);
+ dev_err(hdmi_drv->dev, "failed to get hdmi irq resource (%d).\n",
+ hdmi_drv->irq);
hdmi_drv->irq = 0;
} else {
/* request the IRQ */
dev_info(hdmi_drv->dev, "rk616 hdmi probe success.\n");
return 0;
-#if defined(CONFIG_ARCH_RK3026)
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
err2:
rk616_hdmi_clk_disable(hdmi_dev);
#endif
static void rk616_hdmi_shutdown(struct platform_device *pdev)
{
- struct hdmi *hdmi_drv;
+ struct rk_hdmi_device *hdmi_dev = platform_get_drvdata(pdev);
+ struct hdmi *hdmi_drv = NULL;
if (hdmi_dev) {
hdmi_drv = &hdmi_dev->driver;
hdmi_dbg(hdmi_drv->dev, "rk616 hdmi shut down.\n");
}
-#if defined(CONFIG_OF)
-static const struct of_device_id rk616_hdmi_of_match[] = {
- {.compatible = "rockchip,rk616-hdmi",},
- {}
-};
-
-MODULE_DEVICE_TABLE(of, rk616_hdmi_of_match);
-#endif
static struct platform_driver rk616_hdmi_driver = {
.probe = rk616_hdmi_probe,
.remove = rk616_hdmi_remove,
.driver = {
-#ifdef CONFIG_ARCH_RK3026
- .name = "rk3026-hdmi",
-#else
.name = "rk616-hdmi",
-#endif
.owner = THIS_MODULE,
- .of_match_table = of_match_ptr(rk616_hdmi_of_match),
+ .of_match_table = of_match_ptr(rk616_hdmi_of_match),
},
.shutdown = rk616_hdmi_shutdown,
};
int regsize_phy;
struct clk *pd;
struct clk *hclk; /* HDMI AHP clk */
+ struct clk *pclk; /* HDMI APB clk */
struct delayed_work rk616_delay_work;
struct work_struct rk616_irq_work_struct;
struct mfd_rk616 *rk616_drv;
#include "rk616_hdmi.h"
#include "rk616_hdmi_hw.h"
-#ifndef CONFIG_ARCH_RK3026
+#if !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036)
+
static int rk616_set_polarity(struct mfd_rk616 *rk616_drv, int vic)
{
u32 val;
hdmi_writel(hdmi_dev, PHY_DRIVER, 0x99);
hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x0f);
}
-
- hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x2d);
- hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x2c);
- hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x28);
- hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x20);
+#ifndef SOC_CONFIG_RK3036
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x2d);
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x2c);
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x28);
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x20);
+#else
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x15);
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x14);
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x10);
+#endif
hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x0f);
hdmi_writel(hdmi_dev, 0xce, 0x00);
hdmi_writel(hdmi_dev, 0xce, 0x01);
hdmi_writel(hdmi_dev, PHY_DRIVER, 0x00);
hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x00);
hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x00);
- hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x2f);
+#ifndef SOC_CONFIG_RK3036
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x2f);
+#else
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x17);
+#endif
break;
default:
hdmi_dbg(hdmi_drv->dev, "unkown rk616 hdmi pwr mode %d\n",
}
}
}
-
- hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG);
+ //close edid irq
+#ifndef SOC_CONFIG_RK3036
+ hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG);
+#else
+ hdmi_writel(hdmi_dev, INTERRUPT_MASK1, 0);
+#endif
enable_irq(hdmi_drv->irq);
return ret;
struct rk_hdmi_device,
driver);
- hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &interrupt);
- if (interrupt)
- hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt);
-
+#ifndef SOC_CONFIG_RK3036
+ hdmi_readl(hdmi_dev, INTERRUPT_STATUS1,&interrupt);
+ if(interrupt){
+ hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt);
+ }
+#else
+ hdmi_readl(hdmi_dev, HDMI_STATUS,&interrupt);
+ if(interrupt){
+ hdmi_writel(hdmi_dev, HDMI_STATUS, interrupt);
+ }
+#endif
if (interrupt & m_HOTPLUG) {
if (hdmi_drv->state == HDMI_SLEEP)
hdmi_drv->state = WAIT_HOTPLUG;
msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL;
val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
hdmi_msk_reg(hdmi_dev, SYS_CTRL, msk, val);
+#ifndef SOC_CONFIG_RK3036
hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG);
+#else
+ hdmi_readl(hdmi_dev, HDMI_STATUS,&val);//enable hpg
+ val |= m_MASK_INT_HOTPLUG;
+ hdmi_writel(hdmi_dev, HDMI_STATUS,val);
+#endif
rk616_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
}
int rk616_hdmi_initial(struct hdmi *hdmi_drv)
{
int rc = HDMI_ERROR_SUCESS;
-#ifndef CONFIG_ARCH_RK3026
+#if !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036)
struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
struct rk_hdmi_device,
driver);
hdmi_drv->detect_hotplug = rk616_hdmi_detect_hotplug;
hdmi_drv->read_edid = rk616_hdmi_read_edid;
-#ifdef CONFIG_ARCH_RK3026
+#if defined(CONFIG_ARCH_RK3026)
rk3028_hdmi_reset_pclk();
rk616_hdmi_reset(hdmi_drv);
+#elif defined(SOC_CONFIG_RK3036)
+ rk616_hdmi_reset(hdmi_drv);
#else
hdmi_drv->set_vif = rk616_hdmi_set_vif;
rk616_hdmi_reset(hdmi_drv);
#ifndef _RK616_HDMI_HW_H
#define _RK616_HDMI_HW_H
+#define SOC_CONFIG_RK3036
+
#define RK616_HDMI_BASE 0x400
enum PWR_MODE {
NORMAL,
#define INTERRUPT_MASK1 0xc0
#define INTERRUPT_STATUS1 0xc1
+ #ifndef SOC_CONFIG_RK3036
#define m_INT_HOTPLUG (1 << 7)
+ #endif
#define m_INT_ACTIVE_VSYNC (1 << 5)
#define m_INT_EDID_READY (1 << 2)
#define m_INT_HDCP_OK (1 << 4)
#define HDMI_STATUS 0xc8
-#define m_HOTPLUG (1 << 7)
-#define m_DDC_SDA (1 << 5)
-#define m_DDC_SDC (1 << 4)
+ #define m_HOTPLUG (1 << 7)
+ #ifndef SOC_CONFIG_RK3036
+ #define m_DDC_SDA (1 << 5)
+ #define m_DDC_SDC (1 << 4)
+ #else
+ #define m_MASK_INT_HOTPLUG (1 << 5)
+ #define m_INT_HOTPLUG (1 << 1)
+ #endif
+
#define HDMI_COLORBAR 0xc9
#define PHY_PRE_DIV_RATIO 0xed
#define v_PRE_DIV_RATIO(n) (n & 0x1f)
-#ifndef CONFIG_ARCH_RK3026
+#if !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036)
static inline int hdmi_readl(struct rk_hdmi_device *hdmi_dev,
u16 offset, u32 *val)
{
int ret = 0;
u32 temp;
- temp = readl_relaxed(hdmi->regbase + (offset) * 0x04) & (0xFF - (msk));
- writel_relaxed(temp | ((val) & (msk)), hdmi->regbase + (offset) * 0x04);
+ temp = readl_relaxed(hdmi_dev->regbase + (offset) * 0x04) & (0xFF - (msk));
+ writel_relaxed(temp | ((val) & (msk)), hdmi_dev->regbase + (offset) * 0x04);
return ret;
}
-
+#if defined(CONFIG_ARCH_RK3026)
static inline void rk3028_hdmi_reset_pclk(void)
{
writel_relaxed(0x00010001, RK2928_CRU_BASE + 0x128);
writel_relaxed(0x00010000, RK2928_CRU_BASE + 0x128);
}
#endif
+#endif
extern int rk616_hdmi_initial(struct hdmi *hdmi);
extern void rk616_hdmi_work(struct hdmi *hdmi);
screen->hdmi_resolution = hdmi_mode[i].flag;
/* Pin polarity */
-#if defined(CONFIG_HDMI_RK616) && !defined(CONFIG_ARCH_RK3026)
+#if defined(CONFIG_HDMI_RK616) && !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036)
screen->pin_hsync = 0;
screen->pin_vsync = 0;
#else