From: zwl Date: Thu, 3 Jul 2014 08:43:50 +0000 (+0800) Subject: rk616 hdmi: coding reorganize for 3.10 and clean up unused code X-Git-Tag: firefly_0821_release~5001 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d35a4f57fe42d000ed032002f0e814bda60ba5d6;p=firefly-linux-kernel-4.4.55.git rk616 hdmi: coding reorganize for 3.10 and clean up unused code --- diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c index 6cee14244053..1262dd579c9c 100755 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c +++ b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c @@ -13,11 +13,8 @@ #include #include -//#include -//#include #include -//#include -#include +#include #if defined(CONFIG_DEBUG_FS) #include @@ -28,420 +25,520 @@ #include "rk616_hdmi.h" #include "rk616_hdmi_hw.h" -extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent); -extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi); - -struct hdmi *hdmi = NULL; +static struct rk_hdmi_device *hdmi_dev; #if defined(CONFIG_DEBUG_FS) static int rk616_hdmi_reg_show(struct seq_file *s, void *v) { int i = 0; u32 val = 0; - seq_printf(s, "\n>>>rk616_ctl reg"); - for (i = 0; i < 16; i++) { + + seq_puts(s, "\n>>>rk616_ctl reg"); + for (i = 0; i < 16; i++) seq_printf(s, " %2x", i); - } - seq_printf(s, "\n-----------------------------------------------------------------"); - - for(i=0; i<= PHY_PRE_DIV_RATIO; i++) { - hdmi_readl(i, &val); - if(i%16==0) - seq_printf(s,"\n>>>rk616_ctl %2x:", i); - seq_printf(s," %02x",val); + + seq_puts(s, + "\n-----------------------------------------------------------------"); + + for (i = 0; i <= PHY_PRE_DIV_RATIO; i++) { + hdmi_readl(hdmi_dev, i, &val); + if (i % 16 == 0) + seq_printf(s, "\n>>>rk616_ctl %2x:", i); + seq_printf(s, " %02x", val); } - seq_printf(s, "\n-----------------------------------------------------------------\n"); - + seq_puts(s, + "\n-----------------------------------------------------------------\n"); + return 0; } -static ssize_t rk616_hdmi_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos) -{ +static ssize_t rk616_hdmi_reg_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ u32 reg; u32 val; char kbuf[25]; + struct hdmi *hdmi_drv = &hdmi_dev->driver; + if (copy_from_user(kbuf, buf, count)) return -EFAULT; sscanf(kbuf, "%x%x", ®, &val); - if ((reg < 0) || (reg > 0xed)) { - dev_info(hdmi->dev, "it is no hdmi reg\n"); - return count; - } - dev_info(hdmi->dev, "/**********rk616 reg config******/"); - dev_info(hdmi->dev, "\n reg=%x val=%x\n", reg, val); - hdmi_writel(reg, val); + if ((reg < 0) || (reg > 0xed)) { + dev_info(hdmi_drv->dev, "it is no hdmi reg\n"); + return count; + } + dev_info(hdmi_drv->dev, "/**********rk616 reg config******/"); + dev_info(hdmi_drv->dev, "\n reg=%x val=%x\n", reg, val); + hdmi_writel(hdmi_dev, reg, val); return count; } static int rk616_hdmi_reg_open(struct inode *inode, struct file *file) { - struct mfd_rk616 *rk616 = inode->i_private; - return single_open(file,rk616_hdmi_reg_show,rk616); + struct mfd_rk616 *rk616_drv = inode->i_private; + + return single_open(file, rk616_hdmi_reg_show, rk616_drv); } static const struct file_operations rk616_hdmi_reg_fops = { - .owner = THIS_MODULE, - .open = rk616_hdmi_reg_open, - .read = seq_read, - .write = rk616_hdmi_reg_write, - .llseek = seq_lseek, - .release = single_release, + .owner = THIS_MODULE, + .open = rk616_hdmi_reg_open, + .read = seq_read, + .write = rk616_hdmi_reg_write, + .llseek = seq_lseek, + .release = single_release, }; #endif +#if defined(CONFIG_ARCH_RK3026) +static int rk616_hdmi_clk_enable(struct rk_hdmi_device *hdmi_dev) +{ + if (!hdmi_dev->clk_on) { + clk_prepare_enable(hdmi_dev->hclk); + spin_lock(&hdmi_dev->reg_lock); + hdmi_dev->clk_on = 1; + spin_unlock(&hdmi_dev->reg_lock); + } + + return 0; +} + +static int rk616_hdmi_clk_disable(struct rk_hdmi_device *hdmi_dev) +{ + if (!hdmi_dev->clk_on) { + spin_lock(&hdmi_dev->reg_lock); + hdmi_dev->clk_on = 0; + spin_unlock(&hdmi_dev->reg_lock); + clk_disable_unprepare(hdmi_dev->hclk); + } + + return 0; +} + +#endif + int rk616_hdmi_register_hdcp_callbacks(void (*hdcp_cb)(void), - void (*hdcp_irq_cb)(int status), - int (*hdcp_power_on_cb)(void), - void (*hdcp_power_off_cb)(void)) + void (*hdcp_irq_cb)(int status), + int (*hdcp_power_on_cb)(void), + void (*hdcp_power_off_cb)(void)) { - if(hdmi == NULL) + struct hdmi *hdmi_drv = &hdmi_dev->driver; + + if (hdmi_drv == NULL) return HDMI_ERROR_FALSE; - hdmi->hdcp_cb = hdcp_cb; - hdmi->hdcp_irq_cb = hdcp_irq_cb; - hdmi->hdcp_power_on_cb = hdcp_power_on_cb; - hdmi->hdcp_power_off_cb = hdcp_power_off_cb; + hdmi_drv->hdcp_cb = hdcp_cb; + hdmi_drv->hdcp_irq_cb = hdcp_irq_cb; + hdmi_drv->hdcp_power_on_cb = hdcp_power_on_cb; + hdmi_drv->hdcp_power_off_cb = hdcp_power_off_cb; return HDMI_ERROR_SUCESS; } -#ifdef CONFIG_HAS_EARLYSUSPEND -static void hdmi_early_suspend(struct early_suspend *h) +static void rk616_hdmi_early_suspend(void) { - hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state); + struct hdmi *hdmi_drv = &hdmi_dev->driver; - flush_delayed_work(&hdmi->delay_work); - mutex_lock(&hdmi->enable_mutex); - hdmi->suspend = 1; - if(!hdmi->enable) { - mutex_unlock(&hdmi->enable_mutex); + hdmi_dbg(hdmi_drv->dev, "hdmi enter early suspend pwr %d state %d\n", + hdmi_drv->pwr_mode, hdmi_drv->state); + + flush_delayed_work(&hdmi_drv->delay_work); + mutex_lock(&hdmi_drv->enable_mutex); + hdmi_drv->suspend = 1; + if (!hdmi_drv->enable) { + mutex_unlock(&hdmi_drv->enable_mutex); return; } - if (hdmi->irq) - disable_irq(hdmi->irq); + if (hdmi_drv->irq) + disable_irq(hdmi_drv->irq); - mutex_unlock(&hdmi->enable_mutex); - hdmi->command = HDMI_CONFIG_ENABLE; - init_completion(&hdmi->complete); - hdmi->wait = 1; - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0); - wait_for_completion_interruptible_timeout(&hdmi->complete, - msecs_to_jiffies(5000)); - flush_delayed_work(&hdmi->delay_work); + mutex_unlock(&hdmi_drv->enable_mutex); + hdmi_drv->command = HDMI_CONFIG_ENABLE; + init_completion(&hdmi_drv->complete); + hdmi_drv->wait = 1; + queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, 0); + wait_for_completion_interruptible_timeout(&hdmi_drv->complete, + msecs_to_jiffies(5000)); + flush_delayed_work(&hdmi_drv->delay_work); - return; } -static void hdmi_early_resume(struct early_suspend *h) +static void rk616_hdmi_early_resume(void) { - struct rk616_hdmi *rk616_hdmi; + struct hdmi *hdmi_drv = &hdmi_dev->driver; + struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; - rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi); - hdmi_dbg(hdmi->dev, "hdmi exit early resume\n"); + hdmi_dbg(hdmi_drv->dev, "hdmi exit early resume\n"); - mutex_lock(&hdmi->enable_mutex); + mutex_lock(&hdmi_drv->enable_mutex); - hdmi->suspend = 0; - rk616_hdmi_initial(hdmi); - if(hdmi->enable && hdmi->irq) { - enable_irq(hdmi->irq); - // hdmi_irq(); - rk616_hdmi_work(hdmi); + hdmi_drv->suspend = 0; + rk616_hdmi_initial(hdmi_drv); + if (hdmi_drv->enable && hdmi_drv->irq) { + enable_irq(hdmi_drv->irq); + rk616_hdmi_work(hdmi_drv); } - if (rk616_hdmi->rk616_drv && !gpio_is_valid(rk616_hdmi->rk616_drv->pdata->hdmi_irq)) - queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, 100); - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); - mutex_unlock(&hdmi->enable_mutex); - return; + if (rk616_drv && !gpio_is_valid(rk616_drv->pdata->hdmi_irq)) + queue_delayed_work(hdmi_drv->workqueue, + &hdmi_dev->rk616_delay_work, + msecs_to_jiffies(100)); + + queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, + msecs_to_jiffies(10)); + mutex_unlock(&hdmi_drv->enable_mutex); } -#endif -static void rk616_delay_work_func(struct work_struct *work) + +static int rk616_hdmi_fb_event_notify(struct notifier_block *self, + unsigned long action, void *data) { - struct rk616_hdmi *rk616_hdmi; + struct fb_event *event = data; + int blank_mode = *((int *)event->data); + + if (action == FB_EARLY_EVENT_BLANK) { + switch (blank_mode) { + case FB_BLANK_UNBLANK: + break; + default: + rk616_hdmi_early_suspend(); + break; + } + } else if (action == FB_EVENT_BLANK) { + switch (blank_mode) { + case FB_BLANK_UNBLANK: + rk616_hdmi_early_resume(); + break; + default: + break; + } + } - rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi); + return NOTIFY_OK; +} - if(hdmi->suspend == 0) { - if(hdmi->enable == 1) { - //hdmi_irq(); - rk616_hdmi_work(hdmi); - } +static struct notifier_block rk616_hdmi_fb_notifier = { + .notifier_call = rk616_hdmi_fb_event_notify, +}; + + +static void rk616_delay_work_func(struct work_struct *work) +{ + struct hdmi *hdmi_drv = &hdmi_dev->driver; + struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; + + if (hdmi_drv->suspend == 0) { + if (hdmi_drv->enable == 1) + rk616_hdmi_work(hdmi_drv); - if (rk616_hdmi->rk616_drv && !gpio_is_valid(rk616_hdmi->rk616_drv->pdata->hdmi_irq)) { - queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, 100); - } + if (rk616_drv && !gpio_is_valid(rk616_drv->pdata->hdmi_irq)) + queue_delayed_work(hdmi_drv->workqueue, + &hdmi_dev->rk616_delay_work, + msecs_to_jiffies(100)); } } static void __maybe_unused rk616_irq_work_func(struct work_struct *work) { - if((hdmi->suspend == 0) && (hdmi->enable == 1)) { - rk616_hdmi_work(hdmi); - } - dev_info(hdmi->dev, "func: %s, enable_irq\n", __func__); - enable_irq(hdmi->irq); + struct hdmi *hdmi_drv = &hdmi_dev->driver; + + if ((hdmi_drv->suspend == 0) && (hdmi_drv->enable == 1)) + rk616_hdmi_work(hdmi_drv); + + dev_info(hdmi_drv->dev, "func: %s, enable_irq\n", __func__); + enable_irq(hdmi_drv->irq); } static irqreturn_t rk616_hdmi_irq(int irq, void *dev_id) { - struct work_struct *rk616_irq_work_struct; - struct rk616_hdmi *rk616_hdmi; - - rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi); - if(rk616_hdmi->rk616_drv) { - rk616_irq_work_struct = dev_id; - disable_irq_nosync(hdmi->irq); - queue_work(hdmi->workqueue, rk616_irq_work_struct); - } else { - /* 3028a hdmi */ - if((hdmi->suspend == 0) && (hdmi->enable == 1)) { - printk(KERN_INFO "line = %d, rk616_hdmi_irq irq triggered.\n", __LINE__); - rk616_hdmi_work(hdmi); - } - } - return IRQ_HANDLED; + struct work_struct *rk616_irq_work_struct; + struct hdmi *hdmi_drv = &hdmi_dev->driver; + struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; + + if (rk616_drv) { + rk616_irq_work_struct = dev_id; + disable_irq_nosync(hdmi_drv->irq); + queue_work(hdmi_drv->workqueue, rk616_irq_work_struct); + } else { + /* 3028a hdmi */ + if ((hdmi_drv->suspend == 0) && (hdmi_drv->enable == 1)) { + hdmi_dbg(hdmi_drv->dev, + "line = %d, rk616_hdmi_irq irq triggered.\n", + __LINE__); + rk616_hdmi_work(hdmi_drv); + } + } + return IRQ_HANDLED; +} + +static int rk616_hdmi_drv_init(struct hdmi *hdmi_drv) +{ + int ret = 0; + int lcdc_id = 0; + struct rk_screen screen; + + rk_fb_get_prmry_screen(&screen); + + /* hdmi is extend as default,TODO modify if hdmi is primary */ + lcdc_id = (screen.lcdc_id == 0) ? 1 : 0; + /* lcdc source select */ + /* wait to modify!! +#if defined(CONFIG_ARCH_RK3026) + grf_writel(HDMI_SEL_LCDC(lcdc_id), RK3036_GRF_SOC_CON6); +#endif + */ + if (lcdc_id == 0) + hdmi_drv->lcdc = rk_get_lcdc_drv("lcdc0"); + else + hdmi_drv->lcdc = rk_get_lcdc_drv("lcdc1"); + if (IS_ERR(hdmi_drv->lcdc)) { + dev_err(hdmi_drv->dev, + "can not connect to video source lcdc\n"); + ret = -ENXIO; + return ret; + } + + hdmi_drv->xscale = 100; + hdmi_drv->yscale = 100; + + spin_lock_init(&hdmi_drv->irq_lock); + mutex_init(&hdmi_drv->enable_mutex); + hdmi_sys_init(hdmi_drv); + ret = rk616_hdmi_initial(hdmi_drv); + + return ret; } static int rk616_hdmi_probe(struct platform_device *pdev) { int ret; - struct rk616_hdmi *rk616_hdmi; - struct resource __maybe_unused *mem; - struct resource __maybe_unused *res; - struct device_node *np = pdev->dev.of_node; - - rk616_hdmi = devm_kzalloc(&pdev->dev, sizeof(*rk616_hdmi), GFP_KERNEL); - if(!rk616_hdmi) - { + struct rk_hdmi_device *hdmi_dev; + struct hdmi *hdmi_drv; + struct resource __maybe_unused *mem; + struct resource __maybe_unused *res; + + hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(struct rk_hdmi_device), + GFP_KERNEL); + if (!hdmi_dev) { dev_err(&pdev->dev, ">>rk616_hdmi kmalloc fail!"); return -ENOMEM; } - hdmi = &rk616_hdmi->g_hdmi; + + hdmi_drv = &hdmi_dev->driver; + hdmi_drv->dev = &pdev->dev; + platform_set_drvdata(pdev, hdmi_dev); + spin_lock_init(&hdmi_dev->reg_lock); #ifdef CONFIG_ARCH_RK3026 - rk616_hdmi->rk616_drv = NULL; + hdmi_dev->rk616_drv = NULL; #else - rk616_hdmi->rk616_drv = dev_get_drvdata(pdev->dev.parent); - if(!(rk616_hdmi->rk616_drv)) - { - dev_err(&pdev->dev,"null mfd device rk616!\n"); - return -ENODEV; + hdmi_dev->rk616_drv = dev_get_drvdata(pdev->dev.parent); + if (!(hdmi_dev->rk616_drv)) { + dev_err(hdmi_drv->dev, "null mfd device rk616!\n"); + goto err0; } - #endif - hdmi->dev = &pdev->dev; - platform_set_drvdata(pdev, hdmi); - - if(HDMI_SOURCE_DEFAULT == HDMI_SOURCE_LCDC0) - hdmi->lcdc = rk_get_lcdc_drv("lcdc0"); - else - hdmi->lcdc = rk_get_lcdc_drv("lcdc1"); - if(hdmi->lcdc == NULL) - { - dev_err(hdmi->dev, "can not connect to video source lcdc\n"); - ret = -ENXIO; + if (rk616_hdmi_drv_init(hdmi_drv)) goto err0; - } - hdmi->xscale = 100; - hdmi->yscale = 100; - - - hdmi_sys_init(hdmi); - - hdmi->workqueue = create_singlethread_workqueue("hdmi"); - INIT_DELAYED_WORK(&(hdmi->delay_work), hdmi_work); - -#ifdef CONFIG_HAS_EARLYSUSPEND - hdmi->early_suspend.suspend = hdmi_early_suspend; - hdmi->early_suspend.resume = hdmi_early_resume; - hdmi->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 10; - register_early_suspend(&hdmi->early_suspend); -#endif #ifdef CONFIG_SWITCH - hdmi->switch_hdmi.name="hdmi"; - switch_dev_register(&(hdmi->switch_hdmi)); + hdmi_drv->switch_hdmi.name = "hdmi"; + switch_dev_register(&(hdmi_drv->switch_hdmi)); #endif + hdmi_register_display_sysfs(hdmi_drv, NULL); + fb_register_client(&rk616_hdmi_fb_notifier); - spin_lock_init(&hdmi->irq_lock); - mutex_init(&hdmi->enable_mutex); + hdmi_drv->workqueue = create_singlethread_workqueue("hdmi"); + INIT_DELAYED_WORK(&(hdmi_drv->delay_work), hdmi_work); + INIT_DELAYED_WORK(&hdmi_dev->rk616_delay_work, rk616_delay_work_func); - INIT_DELAYED_WORK(&rk616_hdmi->rk616_delay_work, rk616_delay_work_func); +#ifdef CONFIG_ARCH_RK3026 + /* enable clk */ + hdmi_dev->hclk = devm_clk_get(hdmi_drv->dev, "pclk_hdmi"); + if (IS_ERR(hdmi_dev->hclk)) { + dev_err(hdmi_drv->dev, "Unable to get hdmi hclk\n"); + ret = -ENXIO; + goto err1; + } + rk616_hdmi_clk_enable(); /* 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"); + ret = -ENXIO; + goto err2; + } + hdmi_dev->regbase_phy = res->start; + hdmi_dev->regsize_phy = resource_size(res); + hdmi_dev->regbase = devm_ioremap_resource(hdmi_drv->dev, res); + if (IS_ERR(hdmi_dev->regbase)) { + ret = PTR_ERR(hdmi_dev->regbase); + dev_err(hdmi_drv->dev, "cannot ioremap registers,err=%d\n", + ret); + goto err2; + } /* get the IRQ */ - // if(rk616->pdata->hdmi_irq != INVALID_GPIO) - -#ifdef CONFIG_ARCH_RK3026 - hdmi->hclk = clk_get(NULL,"pclk_hdmi"); - if(IS_ERR(hdmi->hclk)) { - dev_err(hdmi->dev, "Unable to get hdmi hclk\n"); - ret = -ENXIO; - goto err0; - } - clk_enable(hdmi->hclk); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(hdmi->dev, "Unable to get register resource\n"); - ret = -ENXIO; - goto err0; - } - hdmi->regbase_phy = res->start; - hdmi->regsize_phy = (res->end - res->start) + 1; - mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name); - if (!mem) { - dev_err(hdmi->dev, "failed to request mem region for hdmi\n"); - ret = -ENOENT; - goto err0; - } - - dev_info(hdmi->dev, "res->start = 0x%x\n,res->end = 0x%x\n", res->start, res->end); - hdmi->regbase = (int)ioremap(res->start, (res->end - res->start) + 1); - if (!hdmi->regbase) { - dev_err(hdmi->dev, "cannot ioremap registers\n"); - ret = -ENXIO; - goto err1; - } - - // rk30_mux_api_set(GPIO0A7_I2C3_SDA_HDMI_DDCSDA_NAME, GPIO0A_HDMI_DDCSDA); - // rk30_mux_api_set(GPIO0A6_I2C3_SCL_HDMI_DDCSCL_NAME, GPIO0A_HDMI_DDCSCL); - // rk30_mux_api_set(GPIO0B7_HDMI_HOTPLUGIN_NAME, GPIO0B_HDMI_HOTPLUGIN); - iomux_set(HDMI_DDCSDA); - iomux_set(HDMI_DDCSCL); - iomux_set(HDMI_HOTPLUGIN); - - ret = rk616_hdmi_initial(hdmi); - /* get the IRQ */ - hdmi->irq = platform_get_irq(pdev, 0); - if(hdmi->irq <= 0) { - dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n", hdmi->irq); - hdmi->irq = 0; - } else { - /* request the IRQ */ - ret = request_irq(hdmi->irq, rk616_hdmi_irq, 0, dev_name(&pdev->dev), hdmi); - if (ret) { - dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret); - goto err1; - } - } + 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); + hdmi_drv->irq = 0; + } else { + /* request the IRQ */ + ret = devm_request_irq(hdmi_drv->dev, hdmi_drv->irq, + rk616_hdmi_irq, 0, + dev_name(hdmi_drv->dev), hdmi_drv); + if (ret) { + dev_err(hdmi_drv->dev, "hdmi request_irq failed (%d)\n", + ret); + goto err2; + } + } #else - ret = rk616_hdmi_initial(hdmi); - if(gpio_is_valid(rk616_hdmi->rk616_drv->pdata->hdmi_irq)) { - INIT_WORK(&rk616_hdmi->rk616_irq_work_struct, rk616_irq_work_func); - ret = gpio_request(rk616_hdmi->rk616_drv->pdata->hdmi_irq,"rk616_hdmi_irq"); - if(ret < 0) { - dev_err(hdmi->dev,"request gpio for rk616 hdmi irq fail\n"); - } - gpio_direction_input(rk616_hdmi->rk616_drv->pdata->hdmi_irq); - hdmi->irq = gpio_to_irq(rk616_hdmi->rk616_drv->pdata->hdmi_irq); - if(hdmi->irq <= 0) { - dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n", hdmi->irq); - ret = -ENXIO; - goto err1; - } - - /* request the IRQ */ - ret = request_irq(hdmi->irq, rk616_hdmi_irq, IRQF_TRIGGER_LOW, dev_name(&pdev->dev), &rk616_hdmi->rk616_irq_work_struct); - if (ret) { - dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret); - goto err1; - } - } else { - /* use roll polling method */ - hdmi->irq = 0; - } + if (gpio_is_valid(hdmi_dev->rk616_drv->pdata->hdmi_irq)) { + INIT_WORK(&hdmi_dev->rk616_irq_work_struct, + rk616_irq_work_func); + ret = gpio_request(hdmi_dev->rk616_drv->pdata->hdmi_irq, + "rk616_hdmi_irq"); + if (ret < 0) { + dev_err(hdmi_drv->dev, + "request gpio for rk616 hdmi irq fail\n"); + } + gpio_direction_input(hdmi_dev->rk616_drv->pdata->hdmi_irq); + hdmi_drv->irq = + gpio_to_irq(hdmi_dev->rk616_drv->pdata->hdmi_irq); + if (hdmi_drv->irq <= 0) { + dev_err(hdmi_drv->dev, + "failed to get hdmi irq resource (%d).\n", + hdmi_drv->irq); + ret = -ENXIO; + goto err1; + } + + /* request the IRQ */ + ret = devm_request_irq(hdmi_drv->dev, hdmi_drv->irq, + rk616_hdmi_irq, IRQF_TRIGGER_LOW, + dev_name(&pdev->dev), + &hdmi_dev->rk616_irq_work_struct); + if (ret) { + dev_err(hdmi_drv->dev, "hdmi request_irq failed (%d)\n", + ret); + goto err1; + } + } else { + /* use roll polling method */ + hdmi_drv->irq = 0; + } #endif - hdmi_register_display_sysfs(hdmi, NULL); #if defined(CONFIG_DEBUG_FS) - if(rk616_hdmi->rk616_drv && rk616_hdmi->rk616_drv->debugfs_dir) { - debugfs_create_file("hdmi", S_IRUSR, rk616_hdmi->rk616_drv->debugfs_dir, rk616_hdmi->rk616_drv, &rk616_hdmi_reg_fops); + if (hdmi_dev->rk616_drv && hdmi_dev->rk616_drv->debugfs_dir) { + debugfs_create_file("hdmi", S_IRUSR, + hdmi_dev->rk616_drv->debugfs_dir, + hdmi_dev->rk616_drv, &rk616_hdmi_reg_fops); } else { - rk616_hdmi->debugfs_dir = debugfs_create_dir("rk616", NULL); - if (IS_ERR(rk616_hdmi->debugfs_dir)) { - dev_err(hdmi->dev,"failed to create debugfs dir for rk616!\n"); - } else { - debugfs_create_file("hdmi", S_IRUSR, rk616_hdmi->debugfs_dir, rk616_hdmi, &rk616_hdmi_reg_fops); - } - } + hdmi_dev->debugfs_dir = debugfs_create_dir("rk616", NULL); + if (IS_ERR(hdmi_dev->debugfs_dir)) { + dev_err(hdmi_drv->dev, + "failed to create debugfs dir for rk616!\n"); + } else { + debugfs_create_file("hdmi", S_IRUSR, + hdmi_dev->debugfs_dir, hdmi_drv, + &rk616_hdmi_reg_fops); + } + } #endif - // rk616_delay_work_func(NULL); - queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, msecs_to_jiffies(0)); - dev_info(hdmi->dev, "rk616 hdmi probe success.\n"); + + queue_delayed_work(hdmi_drv->workqueue, &hdmi_dev->rk616_delay_work, + msecs_to_jiffies(0)); + dev_info(hdmi_drv->dev, "rk616 hdmi probe success.\n"); return 0; + +#if defined(CONFIG_ARCH_RK3026) +err2: + rk616_hdmi_clk_disable(hdmi_dev); +#endif + err1: + fb_unregister_client(&rk616_hdmi_fb_notifier); + hdmi_unregister_display_sysfs(hdmi_drv); #ifdef CONFIG_SWITCH - switch_dev_unregister(&(hdmi->switch_hdmi)); -#endif - hdmi_unregister_display_sysfs(hdmi); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&hdmi->early_suspend); + switch_dev_unregister(&(hdmi_drv->switch_hdmi)); #endif + err0: - hdmi_dbg(hdmi->dev, "rk616 hdmi probe error.\n"); - kfree(hdmi); - hdmi = NULL; + hdmi_dbg(hdmi_drv->dev, "rk616 hdmi probe error.\n"); + kfree(hdmi_dev); + hdmi_dev = NULL; return ret; } static int rk616_hdmi_remove(struct platform_device *pdev) { - if(hdmi) { - mutex_lock(&hdmi->enable_mutex); - if(!hdmi->suspend && hdmi->enable && hdmi->irq) - disable_irq(hdmi->irq); - mutex_unlock(&hdmi->enable_mutex); - if (hdmi->irq) { - free_irq(hdmi->irq, NULL); - } - flush_workqueue(hdmi->workqueue); - destroy_workqueue(hdmi->workqueue); + struct rk_hdmi_device *hdmi_dev = platform_get_drvdata(pdev); + struct hdmi *hdmi_drv = NULL; + + if (hdmi_dev) { + hdmi_drv = &hdmi_dev->driver; + mutex_lock(&hdmi_drv->enable_mutex); + if (!hdmi_drv->suspend && hdmi_drv->enable && hdmi_drv->irq) + disable_irq(hdmi_drv->irq); + mutex_unlock(&hdmi_drv->enable_mutex); + if (hdmi_drv->irq) + free_irq(hdmi_drv->irq, NULL); + + flush_workqueue(hdmi_drv->workqueue); + destroy_workqueue(hdmi_drv->workqueue); #ifdef CONFIG_SWITCH - switch_dev_unregister(&(hdmi->switch_hdmi)); + switch_dev_unregister(&(hdmi_drv->switch_hdmi)); #endif - hdmi_unregister_display_sysfs(hdmi); + hdmi_unregister_display_sysfs(hdmi_drv); #ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&hdmi->early_suspend); + unregister_early_suspend(&hdmi_drv->early_suspend); #endif - fb_destroy_modelist(&hdmi->edid.modelist); - if(hdmi->edid.audio) - kfree(hdmi->edid.audio); - if(hdmi->edid.specs) - { - if(hdmi->edid.specs->modedb) - kfree(hdmi->edid.specs->modedb); - kfree(hdmi->edid.specs); + fb_destroy_modelist(&hdmi_drv->edid.modelist); + if (hdmi_drv->edid.audio) + kfree(hdmi_drv->edid.audio); + if (hdmi_drv->edid.specs) { + if (hdmi_drv->edid.specs->modedb) + kfree(hdmi_drv->edid.specs->modedb); + kfree(hdmi_drv->edid.specs); } - kfree(hdmi); - hdmi = NULL; + + hdmi_dbg(hdmi_drv->dev, "rk616 hdmi removed.\n"); + kfree(hdmi_dev); + hdmi_dev = NULL; } - hdmi_dbg(hdmi->dev, "rk616 hdmi removed.\n"); + return 0; } static void rk616_hdmi_shutdown(struct platform_device *pdev) { - if(hdmi) { + struct hdmi *hdmi_drv; + + if (hdmi_dev) { + hdmi_drv = &hdmi_dev->driver; #ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&hdmi->early_suspend); -#endif - flush_delayed_work(&hdmi->delay_work); - mutex_lock(&hdmi->enable_mutex); - hdmi->suspend = 1; - if(!hdmi->enable) { - mutex_unlock(&hdmi->enable_mutex); - return; - } - if (hdmi->irq) - disable_irq(hdmi->irq); - mutex_unlock(&hdmi->enable_mutex); - } - hdmi_dbg(hdmi->dev, "rk616 hdmi shut down.\n"); + unregister_early_suspend(&hdmi_drv->early_suspend); +#endif + flush_delayed_work(&hdmi_drv->delay_work); + mutex_lock(&hdmi_drv->enable_mutex); + hdmi_drv->suspend = 1; + if (!hdmi_drv->enable) { + mutex_unlock(&hdmi_drv->enable_mutex); + return; + } + if (hdmi_drv->irq) + disable_irq(hdmi_drv->irq); + mutex_unlock(&hdmi_drv->enable_mutex); + } + hdmi_dbg(hdmi_drv->dev, "rk616 hdmi shut down.\n"); } #if defined(CONFIG_OF) @@ -454,18 +551,18 @@ 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 = { + .probe = rk616_hdmi_probe, + .remove = rk616_hdmi_remove, + .driver = { #ifdef CONFIG_ARCH_RK3026 - .name = "rk3026-hdmi", + .name = "rk3026-hdmi", #else - .name = "rk616-hdmi", + .name = "rk616-hdmi", #endif - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(rk616_hdmi_of_match), - }, - .shutdown = rk616_hdmi_shutdown, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rk616_hdmi_of_match), + }, + .shutdown = rk616_hdmi_shutdown, }; static int __init rk616_hdmi_init(void) @@ -478,7 +575,5 @@ static void __exit rk616_hdmi_exit(void) platform_driver_unregister(&rk616_hdmi_driver); } - -//fs_initcall(rk616_hdmi_init); late_initcall(rk616_hdmi_init); module_exit(rk616_hdmi_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.h b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.h index 66d5f410f778..35ff0927a75e 100755 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.h +++ b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.h @@ -4,12 +4,7 @@ #include "../../rk_hdmi.h" #include -#if defined(CONFIG_HDMI_SOURCE_LCDC1) -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC1 -#else -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC0 -#endif -enum{ +enum { INPUT_IIS, INPUT_SPDIF }; @@ -22,17 +17,23 @@ enum{ extern void rk616_hdmi_control_output(struct hdmi *hdmi, int enable); extern int rk616_hdmi_register_hdcp_callbacks(void (*hdcp_cb)(void), - void (*hdcp_irq_cb)(int status), - int (*hdcp_power_on_cb)(void), - void (*hdcp_power_off_cb)(void)); + void (*hdcp_irq_cb)(int status), + int (*hdcp_power_on_cb)(void), + void (*hdcp_power_off_cb)(void)); -struct rk616_hdmi { - struct hdmi g_hdmi; - //struct early_suspend early_suspend; //TODO Daisen - struct delayed_work rk616_delay_work; - struct work_struct rk616_irq_work_struct; - struct mfd_rk616 *rk616_drv; - struct dentry *debugfs_dir; +struct rk_hdmi_device { + int clk_on; + spinlock_t reg_lock; + struct hdmi driver; + void __iomem *regbase; + int regbase_phy; + int regsize_phy; + struct clk *pd; + struct clk *hclk; /* HDMI AHP clk */ + struct delayed_work rk616_delay_work; + struct work_struct rk616_irq_work_struct; + struct mfd_rk616 *rk616_drv; + struct dentry *debugfs_dir; }; -#endif /* __RK30_HDMI_H__ */ +#endif /* __RK616_HDMI_H__ */ diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c index cb28bfd650e9..4b51345b6a3f 100755 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c +++ b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c @@ -1,72 +1,74 @@ #include -#include -//#include +#include #include #include #include "rk616_hdmi.h" #include "rk616_hdmi_hw.h" -//#include - -// static char edid_result = 0; #ifndef CONFIG_ARCH_RK3026 -static int rk616_set_polarity(struct mfd_rk616 * rk616, int vic) +static int rk616_set_polarity(struct mfd_rk616 *rk616_drv, int vic) { - u32 val; - int ret; - u32 hdmi_polarity_mask = (3<<14); - - switch(vic) - { - - case HDMI_1920x1080p_60Hz: - case HDMI_1920x1080p_50Hz: - case HDMI_1920x1080i_60Hz: - case HDMI_1920x1080i_50Hz: - case HDMI_1280x720p_60Hz: - case HDMI_1280x720p_50Hz: - val = 0xc000; - ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, hdmi_polarity_mask, &val); - break; - - case HDMI_720x576p_50Hz_4_3: - case HDMI_720x576p_50Hz_16_9: - case HDMI_720x480p_60Hz_4_3: - case HDMI_720x480p_60Hz_16_9: - val = 0x0; - ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, hdmi_polarity_mask, &val); - break; - default: - val = 0x0; - ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, hdmi_polarity_mask, &val); - break; - } - return ret; + u32 val; + int ret; + u32 hdmi_polarity_mask = (3 << 14); + + switch (vic) { + + case HDMI_1920x1080p_60Hz: + case HDMI_1920x1080p_50Hz: + case HDMI_1920x1080i_60Hz: + case HDMI_1920x1080i_50Hz: + case HDMI_1280x720p_60Hz: + case HDMI_1280x720p_50Hz: + val = 0xc000; + ret = rk616_drv->write_dev_bits(rk616_drv, CRU_CFGMISC_CON, + hdmi_polarity_mask, &val); + break; + + case HDMI_720x576p_50Hz_4_3: + case HDMI_720x576p_50Hz_16_9: + case HDMI_720x480p_60Hz_4_3: + case HDMI_720x480p_60Hz_16_9: + val = 0x0; + ret = rk616_drv->write_dev_bits(rk616_drv, CRU_CFGMISC_CON, + hdmi_polarity_mask, &val); + break; + default: + val = 0x0; + ret = rk616_drv->write_dev_bits(rk616_drv, CRU_CFGMISC_CON, + hdmi_polarity_mask, &val); + break; + } + return ret; } -static int rk616_hdmi_set_vif(struct hdmi *hdmi, struct rk_screen *screen, bool connect) +static int rk616_hdmi_set_vif(struct hdmi *hdmi_drv, struct rk_screen *screen, + bool connect) { - struct rk616_hdmi *rk616_hdmi; - rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi); + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; - if (connect) - rk616_set_polarity(rk616_hdmi->rk616_drv, hdmi->vic); + if (connect) + rk616_set_polarity(rk616_drv, hdmi_drv->vic); - rk616_set_vif(rk616_hdmi->rk616_drv,screen,connect); + rk616_set_vif(rk616_drv, screen, connect); return 0; } -static int rk616_hdmi_init_pol_set(struct mfd_rk616 * rk616,int pol) +static int rk616_hdmi_init_pol_set(struct mfd_rk616 *rk616_drv, int pol) { u32 val; int ret; - int int_pol_mask = (1 << 5); + int int_pol_mask = (1 << 5); - if (pol) - val = 0x0; - else - val = 0x20; - ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, int_pol_mask, &val); + if (pol) + val = 0x0; + else + val = 0x20; + ret = rk616_drv->write_dev_bits(rk616_drv, CRU_CFGMISC_CON, + int_pol_mask, &val); return 0; } @@ -77,522 +79,562 @@ static inline void delay100us(void) msleep(1); } - -static void rk616_hdmi_av_mute(bool enable) +static void rk616_hdmi_av_mute(struct hdmi *hdmi_drv, bool enable) { - hdmi_writel(AV_MUTE, v_AUDIO_MUTE(enable) | v_VIDEO_MUTE(enable)); -} + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); -static void rk616_hdmi_sys_power_up(void) -{ - hdmi_msk_reg(SYS_CTRL,m_POWER, v_PWR_ON); + hdmi_writel(hdmi_dev, AV_MUTE, + v_AUDIO_MUTE(enable) | v_VIDEO_MUTE(enable)); } -static void rk616_hdmi_sys_power_down(void) + +static void rk616_hdmi_sys_power(struct hdmi *hdmi_drv, bool enable) { - hdmi_msk_reg(SYS_CTRL,m_POWER, v_PWR_OFF); -} + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + if (enable) + hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_POWER, v_PWR_ON); + else + hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_POWER, v_PWR_OFF); +} -static void rk616_hdmi_set_pwr_mode(struct hdmi *hdmi, int mode) +static void rk616_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode) { - if(hdmi->pwr_mode == mode) - return; - hdmi_dbg(hdmi->dev,"%s change pwr_mode %d --> %d\n",__FUNCTION__,hdmi->pwr_mode,mode); - switch(mode){ - case NORMAL: - hdmi_dbg(hdmi->dev,"%s change pwr_mode NORMALpwr_mode = %d, mode = %d\n",__FUNCTION__,hdmi->pwr_mode,mode); - rk616_hdmi_sys_power_down(); - if (!(hdmi->set_vif) && (hdmi->vic == HDMI_1920x1080p_60Hz || hdmi->vic == HDMI_1920x1080p_50Hz)) { - /* 3026 and 1080p */ - hdmi_writel(PHY_DRIVER,0xcc); - hdmi_writel(PHY_PRE_EMPHASIS,0x4f); - } else { - hdmi_writel(PHY_DRIVER,0xaa); - hdmi_writel(PHY_PRE_EMPHASIS,0x0f); - } - hdmi_writel(PHY_SYS_CTL,0x2d); - hdmi_writel(PHY_SYS_CTL,0x2c); - hdmi_writel(PHY_SYS_CTL,0x28); - hdmi_writel(PHY_SYS_CTL,0x20); - hdmi_writel(PHY_CHG_PWR,0x0f); - hdmi_writel(0xce, 0x00); - hdmi_writel(0xce, 0x01); - rk616_hdmi_av_mute(1); - rk616_hdmi_sys_power_up(); + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + + if (hdmi_drv->pwr_mode == mode) + return; + + hdmi_dbg(hdmi_drv->dev, "%s change pwr_mode %d --> %d\n", __func__, + hdmi_drv->pwr_mode, mode); + + switch (mode) { + case NORMAL: + hdmi_dbg(hdmi_drv->dev, + "%s change pwr_mode NORMAL pwr_mode = %d, mode = %d\n", + __func__, hdmi->pwr_mode, mode); + rk616_hdmi_sys_power(hdmi_drv, false); + if (!(hdmi_drv->set_vif) + && (hdmi_drv->vic == HDMI_1920x1080p_60Hz + || hdmi_drv->vic == HDMI_1920x1080p_50Hz)) { + /* 3026 and 1080p */ + hdmi_writel(hdmi_dev, PHY_DRIVER, 0xcc); + hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x4f); + } else { + 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); + hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x0f); + hdmi_writel(hdmi_dev, 0xce, 0x00); + hdmi_writel(hdmi_dev, 0xce, 0x01); + rk616_hdmi_av_mute(hdmi_drv, 1); + rk616_hdmi_sys_power(hdmi_drv, true); break; case LOWER_PWR: - hdmi_dbg(hdmi->dev,"%s change pwr_mode LOWER_PWR pwr_mode = %d, mode = %d\n",__FUNCTION__,hdmi->pwr_mode,mode); - rk616_hdmi_av_mute(0); - rk616_hdmi_sys_power_down(); - hdmi_writel(PHY_DRIVER,0x00); - hdmi_writel(PHY_PRE_EMPHASIS,0x00); - hdmi_writel(PHY_CHG_PWR,0x00); - hdmi_writel(PHY_SYS_CTL,0x2f); + hdmi_dbg(hdmi_drv->dev, + "%s change pwr_mode LOWER_PWR pwr_mode = %d, mode = %d\n", + __func__, hdmi->pwr_mode, mode); + rk616_hdmi_av_mute(hdmi_drv, 0); + rk616_hdmi_sys_power(hdmi_drv, false); + 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); break; default: - hdmi_dbg(hdmi->dev,"unkown rk616 hdmi pwr mode %d\n",mode); - } - hdmi->pwr_mode = mode; -} + hdmi_dbg(hdmi_drv->dev, "unkown rk616 hdmi pwr mode %d\n", + mode); + } + hdmi_drv->pwr_mode = mode; +} -int rk616_hdmi_detect_hotplug(struct hdmi *hdmi) +int rk616_hdmi_detect_hotplug(struct hdmi *hdmi_drv) { int value = 0; -#if 0 - hdmi_readl(INTERRUPT_STATUS1,&value); - if(value){ - hdmi_writel(INTERRUPT_STATUS1, value); - } -#endif - hdmi_readl(HDMI_STATUS,&value); - - hdmi_dbg(hdmi->dev, "[%s] value %02x\n", __FUNCTION__, value); + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + + hdmi_dbg(hdmi_drv->dev, "[%s] value %02x\n", __func__, value); + hdmi_readl(hdmi_dev, HDMI_STATUS, &value); value &= m_HOTPLUG; - if(value == m_HOTPLUG) + if (value == m_HOTPLUG) return HDMI_HPD_ACTIVED; - else if(value) + else if (value) return HDMI_HPD_INSERT; else return HDMI_HPD_REMOVED; } - -int rk616_hdmi_read_edid(struct hdmi *hdmi, int block, u8 * buf) +int rk616_hdmi_read_edid(struct hdmi *hdmi_drv, int block, u8 *buf) { - u32 c = 0; - u8 Segment = 0; - u8 Offset = 0; - - int ret = -1; - int i, j; - int ddc_bus_freq; - int trytime; - int checksum = 0; - - if(block%2) - Offset = HDMI_EDID_BLOCK_SIZE; - - if(block/2) - Segment = 1; - - ddc_bus_freq = (HDMI_SYS_FREG_CLK>>2)/HDMI_SCL_RATE; - hdmi_writel(DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); - hdmi_writel(DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); - - hdmi_dbg(hdmi->dev, "EDID DATA (Segment = %d Block = %d Offset = %d):\n", (int) Segment, (int) block, (int) Offset); - disable_irq(hdmi->irq); - - //enable edid interrupt - hdmi_writel(INTERRUPT_MASK1, m_INT_HOTPLUG | m_INT_EDID_READY); - - for (trytime = 0; trytime < 10; trytime++) { - c=0x04; - hdmi_writel(INTERRUPT_STATUS1, c); - - //set edid fifo first addr - c = 0x00; - hdmi_writel(EDID_FIFO_OFFSET, c); - - //set edid word address 00/80 - c = Offset; - hdmi_writel(EDID_WORD_ADDR, c); - - //set edid segment pointer - c = Segment; - hdmi_writel(EDID_SEGMENT_POINTER, c); - - for (i = 0; i < 10; i++) { - //wait edid interrupt - msleep(10); - c=0x00; - hdmi_readl(INTERRUPT_STATUS1, &c); - - if (c & 0x04) { - break; - } - - } - - if (c & 0x04) { - for(j = 0; j < HDMI_EDID_BLOCK_SIZE; j++){ - c = 0; - hdmi_readl(0x50, &c); - buf[j] = c; - checksum += c; + u32 c = 0; + u8 segment = 0; + u8 offset = 0; + int ret = -1; + int i, j; + int ddc_bus_freq; + int trytime; + int checksum = 0; + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + + if (block % 2) + offset = HDMI_EDID_BLOCK_SIZE; + + if (block / 2) + segment = 1; + + ddc_bus_freq = (HDMI_SYS_FREG_CLK >> 2) / HDMI_SCL_RATE; + hdmi_writel(hdmi_dev, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); + hdmi_writel(hdmi_dev, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); + + hdmi_dbg(hdmi_drv->dev, + "EDID DATA (Segment = %d Block = %d Offset = %d):\n", + (int)segment, (int)block, (int)offset); + disable_irq(hdmi_drv->irq); + + /* Enable edid interrupt */ + hdmi_writel(hdmi_dev, INTERRUPT_MASK1, + m_INT_HOTPLUG | m_INT_EDID_READY); + + for (trytime = 0; trytime < 10; trytime++) { + hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, 0x04); + + /* Set edid fifo first addr */ + hdmi_writel(hdmi_dev, EDID_FIFO_OFFSET, 0x00); + + /* Set edid word address 0x00/0x80 */ + hdmi_writel(hdmi_dev, EDID_WORD_ADDR, offset); + + /* Set edid segment pointer */ + hdmi_writel(hdmi_dev, EDID_SEGMENT_POINTER, segment); + + for (i = 0; i < 10; i++) { + /* Wait edid interrupt */ + msleep(10); + c = 0x00; + hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &c); + + if (c & m_INT_EDID_READY) + break; + } + + if (c & m_INT_EDID_READY) { + for (j = 0; j < HDMI_EDID_BLOCK_SIZE; j++) { + c = 0; + hdmi_readl(hdmi_dev, 0x50, &c); + buf[j] = c; + checksum += c; #ifdef HDMI_DEBUG - if(j%16==0) - printk("\n>>>0x%02x: ", j); + if (j % 16 == 0) + dev_info(hdmi_drv->dev, "\n>>>0x%02x: ", + j); - printk("0x%02x ",c); + dev_info(hdmi_drv->dev, "0x%02x ", c); #endif - } - - //clear EDID interrupt reg - c=0x04; - hdmi_writel(INTERRUPT_STATUS1, c); - - // printk("checksum = 0x%x\n", checksum); - if ((checksum &= 0xff) == 0) { - ret = 0; - hdmi_dbg(hdmi->dev, "[%s] edid read sucess\n", __FUNCTION__); - break; - } - } - } - - hdmi_writel(INTERRUPT_MASK1, m_INT_HOTPLUG); - enable_irq(hdmi->irq); - - return ret; + } + + /* clear EDID interrupt reg */ + hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, + m_INT_EDID_READY); + + if ((checksum & 0xff) == 0) { + ret = 0; + hdmi_dbg(hdmi_drv->dev, + "[%s] edid read sucess\n", __func__); + break; + } + } + } + + hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG); + enable_irq(hdmi_drv->irq); + + return ret; } -static void rk616_hdmi_config_avi(unsigned char vic, unsigned char output_color) +static void rk616_hdmi_config_avi(struct hdmi *hdmi_drv, + unsigned char vic, unsigned char output_color) { int i; char info[SIZE_AVI_INFOFRAME]; - + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + memset(info, 0, SIZE_AVI_INFOFRAME); - hdmi_writel(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); + hdmi_writel(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); info[0] = 0x82; info[1] = 0x02; - info[2] = 0x0D; + info[2] = 0x0D; info[3] = info[0] + info[1] + info[2]; info[4] = (AVI_COLOR_MODE_RGB << 5); - info[5] = (AVI_COLORIMETRY_NO_DATA << 6) | (AVI_CODED_FRAME_ASPECT_NO_DATA << 4) | ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME; + info[5] = + (AVI_COLORIMETRY_NO_DATA << 6) | (AVI_CODED_FRAME_ASPECT_NO_DATA << + 4) | + ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME; info[6] = 0; info[7] = vic; info[8] = 0; - // Calculate AVI InfoFrame ChecKsum + /* Calculate AVI InfoFrame ChecKsum */ for (i = 4; i < SIZE_AVI_INFOFRAME; i++) - { - info[3] += info[i]; - } + info[3] += info[i]; + info[3] = 0x100 - info[3]; - - for(i = 0; i < SIZE_AVI_INFOFRAME; i++) - hdmi_writel(CONTROL_PACKET_ADDR + i, info[i]); -} + for (i = 0; i < SIZE_AVI_INFOFRAME; i++) + hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]); +} -static int rk616_hdmi_config_video(struct hdmi *hdmi, struct hdmi_video_para *vpara) +static int rk616_hdmi_config_video(struct hdmi *hdmi_drv, + struct hdmi_video_para *vpara) { int value; struct fb_videomode *mode; - struct rk616_hdmi *rk616_hdmi; + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); - hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); - rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi); + hdmi_dbg(hdmi_drv->dev, "[%s]\n", __func__); - if(vpara == NULL) { - hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__); + if (vpara == NULL) { + hdmi_err(hdmi_drv->dev, "[%s] input parameter error\n", + __func__); return -1; } - if(hdmi->pwr_mode == LOWER_PWR) { - rk616_hdmi_set_pwr_mode(hdmi, NORMAL); - } + /* Output RGB as default */ + vpara->output_color = VIDEO_OUTPUT_RGB444; + if (hdmi_drv->pwr_mode == LOWER_PWR) + rk616_hdmi_set_pwr_mode(hdmi_drv, NORMAL); + /* Disable video and audio output */ + hdmi_writel(hdmi_dev, AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); - vpara->output_color = VIDEO_OUTPUT_RGB444; - if(hdmi->hdcp_power_off_cb) - hdmi->hdcp_power_off_cb(); - // Diable video and audio output - hdmi_writel(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); - - // Input video mode is SDR RGB24bit, Data enable signal from external - hdmi_writel(VIDEO_CONTRL1, v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | v_DE_EXTERNAL); - hdmi_writel(VIDEO_CONTRL2, v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | v_VIDEO_OUTPUT_FORMAT(vpara->output_color & 0xFF)); - - // Set HDMI Mode - hdmi_writel(HDCP_CTRL, v_HDMI_DVI(vpara->output_mode)); - - // Enable or disalbe color space convert - if(vpara->input_color != vpara->output_color) { + /* Input video mode is SDR RGB24bit, Data enable signal from external */ + hdmi_writel(hdmi_dev, VIDEO_CONTRL1, + v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | + v_DE_EXTERNAL); + hdmi_writel(hdmi_dev, VIDEO_CONTRL2, + v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | + v_VIDEO_OUTPUT_FORMAT(vpara->output_color & 0xFF)); + + /* Set HDMI Mode */ + hdmi_writel(hdmi_dev, HDCP_CTRL, v_HDMI_DVI(vpara->output_mode)); + + /* Enable or disalbe color space convert */ + if (vpara->input_color != vpara->output_color) value = v_SOF_DISABLE | v_CSC_ENABLE; - } else value = v_SOF_DISABLE; - hdmi_writel(VIDEO_CONTRL3, value); + hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); - // Set ext video + /* Set ext video timing */ #if 1 - hdmi_writel(VIDEO_TIMING_CTL, 0); + hdmi_writel(hdmi_dev, VIDEO_TIMING_CTL, 0); mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); - if(mode == NULL) - { - hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic); + if (mode == NULL) { + hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __func__, + vpara->vic); return -ENOENT; } - hdmi->tmdsclk = mode->pixclock; + hdmi_drv->tmdsclk = mode->pixclock; #else value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode); - if(mode->sync & FB_SYNC_HOR_HIGH_ACT) + if (mode->sync & FB_SYNC_HOR_HIGH_ACT) value |= v_HSYNC_POLARITY(1); - if(mode->sync & FB_SYNC_VERT_HIGH_ACT) + if (mode->sync & FB_SYNC_VERT_HIGH_ACT) value |= v_VSYNC_POLARITY(1); - hdmi_writel(VIDEO_TIMING_CTL, value); - - value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len; - hdmi_writel(VIDEO_EXT_HTOTAL_L, value & 0xFF); - hdmi_writel(VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); - + hdmi_writel(hdmi_dev, VIDEO_TIMING_CTL, value); + + value = mode->left_margin + mode->xres + mode->right_margin + + mode->hsync_len; + hdmi_writel(hdmi_dev, VIDEO_EXT_HTOTAL_L, value & 0xFF); + hdmi_writel(hdmi_dev, VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); + value = mode->left_margin + mode->right_margin + mode->hsync_len; - hdmi_writel(VIDEO_EXT_HBLANK_L, value & 0xFF); - hdmi_writel(VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); - + hdmi_writel(hdmi_dev, VIDEO_EXT_HBLANK_L, value & 0xFF); + hdmi_writel(hdmi_dev, VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); + value = mode->left_margin + mode->hsync_len; - hdmi_writel(VIDEO_EXT_HDELAY_L, value & 0xFF); - hdmi_writel(VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); - + hdmi_writel(hdmi_dev, VIDEO_EXT_HDELAY_L, value & 0xFF); + hdmi_writel(hdmi_dev, VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); + value = mode->hsync_len; - hdmi_writel(VIDEO_EXT_HDURATION_L, value & 0xFF); - hdmi_writel(VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); - - value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len; - hdmi_writel(VIDEO_EXT_VTOTAL_L, value & 0xFF); - hdmi_writel(VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); - + hdmi_writel(hdmi_dev, VIDEO_EXT_HDURATION_L, value & 0xFF); + hdmi_writel(hdmi_dev, VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); + + value = mode->upper_margin + mode->yres + mode->lower_margin + + mode->vsync_len; + hdmi_writel(hdmi_dev, VIDEO_EXT_VTOTAL_L, value & 0xFF); + hdmi_writel(hdmi_dev, VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); + value = mode->upper_margin + mode->vsync_len + mode->lower_margin; - hdmi_writel(VIDEO_EXT_VBLANK, value & 0xFF); + hdmi_writel(hdmi_dev, VIDEO_EXT_VBLANK, value & 0xFF); - if(vpara->vic == HDMI_720x480p_60Hz_4_3 || vpara->vic == HDMI_720x480p_60Hz_16_9) + if (vpara->vic == HDMI_720x480p_60Hz_4_3 + || vpara->vic == HDMI_720x480p_60Hz_16_9) value = 42; else value = mode->upper_margin + mode->vsync_len; - hdmi_writel(VIDEO_EXT_VDELAY, value & 0xFF); - + hdmi_writel(hdmi_dev, VIDEO_EXT_VDELAY, value & 0xFF); + value = mode->vsync_len; - hdmi_writel(VIDEO_EXT_VDURATION, value & 0xFF); + hdmi_writel(hdmi_dev, VIDEO_EXT_VDURATION, value & 0xFF); #endif - if(vpara->output_mode == OUTPUT_HDMI) { - rk616_hdmi_config_avi(vpara->vic, vpara->output_color); - hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); + if (vpara->output_mode == OUTPUT_HDMI) { + rk616_hdmi_config_avi(hdmi_drv, vpara->vic, + vpara->output_color); + hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __func__); + } else { + hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __func__); } - else { - hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__); + + if (hdmi_drv->set_vif) { + hdmi_writel(hdmi_dev, PHY_PRE_DIV_RATIO, 0x0f); + hdmi_writel(hdmi_dev, PHY_FEEDBACK_DIV_RATIO_LOW, 0x96); + } else { /* rk3028a */ + hdmi_writel(hdmi_dev, PHY_PRE_DIV_RATIO, 0x1e); + hdmi_writel(hdmi_dev, PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c); + hdmi_writel(hdmi_dev, PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01); } - - // if(rk616_hdmi->rk616_drv) { - if (hdmi->set_vif) { - hdmi_writel(0xed, 0x0f); - hdmi_writel(0xe7, 0x96); - } else { // rk3028a - hdmi_writel(0xed, 0x1e); - hdmi_writel(0xe7, 0x2c); - hdmi_writel(0xe8, 0x01); - } return 0; } -static void rk616_hdmi_config_aai(void) +static void rk616_hdmi_config_aai(struct hdmi *hdmi_drv) { int i; char info[SIZE_AUDIO_INFOFRAME]; - + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + memset(info, 0, SIZE_AUDIO_INFOFRAME); - + info[0] = 0x84; info[1] = 0x01; info[2] = 0x0A; - - info[3] = info[0] + info[1] + info[2]; + + info[3] = info[0] + info[1] + info[2]; for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++) - info[3] += info[i]; - + info[3] += info[i]; + info[3] = 0x100 - info[3]; - - hdmi_writel(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI); - for(i = 0; i < SIZE_AUDIO_INFOFRAME; i++) - hdmi_writel(CONTROL_PACKET_ADDR + i, info[i]); + + hdmi_writel(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI); + for (i = 0; i < SIZE_AUDIO_INFOFRAME; i++) + hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]); } -static int rk616_hdmi_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio) +static int rk616_hdmi_config_audio(struct hdmi *hdmi_drv, + struct hdmi_audio *audio) { int rate, N, channel, mclk_fs; - - if(audio->channel < 3) + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + + if (audio->channel < 3) channel = I2S_CHANNEL_1_2; - else if(audio->channel < 5) + else if (audio->channel < 5) channel = I2S_CHANNEL_3_4; - else if(audio->channel < 7) + else if (audio->channel < 7) channel = I2S_CHANNEL_5_6; else channel = I2S_CHANNEL_7_8; - - switch(audio->rate) - { - case HDMI_AUDIO_FS_32000: - rate = AUDIO_32K; - N = N_32K; - mclk_fs = MCLK_384FS; - break; - case HDMI_AUDIO_FS_44100: - rate = AUDIO_441K; - N = N_441K; - mclk_fs = MCLK_256FS; - break; - case HDMI_AUDIO_FS_48000: - rate = AUDIO_48K; - N = N_48K; - mclk_fs = MCLK_256FS; - break; - case HDMI_AUDIO_FS_88200: - rate = AUDIO_882K; - N = N_882K; - mclk_fs = MCLK_128FS; - break; - case HDMI_AUDIO_FS_96000: - rate = AUDIO_96K; - N = N_96K; - mclk_fs = MCLK_128FS; - break; - case HDMI_AUDIO_FS_176400: - rate = AUDIO_1764K; - N = N_1764K; - mclk_fs = MCLK_128FS; - break; - case HDMI_AUDIO_FS_192000: - rate = AUDIO_192K; - N = N_192K; - mclk_fs = MCLK_128FS; - break; - default: - dev_err(hdmi->dev, "[%s] not support such sample rate %d\n", __FUNCTION__, audio->rate); - return -ENOENT; + + switch (audio->rate) { + case HDMI_AUDIO_FS_32000: + rate = AUDIO_32K; + N = N_32K; + mclk_fs = MCLK_384FS; + break; + case HDMI_AUDIO_FS_44100: + rate = AUDIO_441K; + N = N_441K; + mclk_fs = MCLK_256FS; + break; + case HDMI_AUDIO_FS_48000: + rate = AUDIO_48K; + N = N_48K; + mclk_fs = MCLK_256FS; + break; + case HDMI_AUDIO_FS_88200: + rate = AUDIO_882K; + N = N_882K; + mclk_fs = MCLK_128FS; + break; + case HDMI_AUDIO_FS_96000: + rate = AUDIO_96K; + N = N_96K; + mclk_fs = MCLK_128FS; + break; + case HDMI_AUDIO_FS_176400: + rate = AUDIO_1764K; + N = N_1764K; + mclk_fs = MCLK_128FS; + break; + case HDMI_AUDIO_FS_192000: + rate = AUDIO_192K; + N = N_192K; + mclk_fs = MCLK_128FS; + break; + default: + dev_err(hdmi_drv->dev, "[%s] not support such sample rate %d\n", + __func__, audio->rate); + return -ENOENT; } - //set_audio source I2S - if(HDMI_CODEC_SOURCE_SELECT == INPUT_IIS){ - hdmi_writel(AUDIO_CTRL1, 0x00); - hdmi_writel(AUDIO_SAMPLE_RATE, rate); - hdmi_writel(AUDIO_I2S_MODE, v_I2S_MODE(I2S_STANDARD) | v_I2S_CHANNEL(channel) ); - hdmi_writel(AUDIO_I2S_MAP, 0x00); - hdmi_writel(AUDIO_I2S_SWAPS_SPDIF, 0); // no swap - }else{ - hdmi_writel(AUDIO_CTRL1, 0x08); - hdmi_writel(AUDIO_I2S_SWAPS_SPDIF, 0); // no swap + /* set_audio source I2S */ + if (HDMI_CODEC_SOURCE_SELECT == INPUT_IIS) { + hdmi_writel(hdmi_dev, AUDIO_CTRL1, 0x00); + hdmi_writel(hdmi_dev, AUDIO_SAMPLE_RATE, rate); + hdmi_writel(hdmi_dev, AUDIO_I2S_MODE, + v_I2S_MODE(I2S_STANDARD) | v_I2S_CHANNEL(channel)); + hdmi_writel(hdmi_dev, AUDIO_I2S_MAP, 0x00); + /* no swap */ + hdmi_writel(hdmi_dev, AUDIO_I2S_SWAPS_SPDIF, 0); + } else { + hdmi_writel(hdmi_dev, AUDIO_CTRL1, 0x08); + /* no swap */ + hdmi_writel(hdmi_dev, AUDIO_I2S_SWAPS_SPDIF, 0); } - - //Set N value - hdmi_writel(AUDIO_N_H, (N >> 16) & 0x0F); - hdmi_writel(AUDIO_N_M, (N >> 8) & 0xFF); - hdmi_writel(AUDIO_N_L, N & 0xFF); - rk616_hdmi_config_aai(); - - return 0; + + /* Set N value */ + hdmi_writel(hdmi_dev, AUDIO_N_H, (N >> 16) & 0x0F); + hdmi_writel(hdmi_dev, AUDIO_N_M, (N >> 8) & 0xFF); + hdmi_writel(hdmi_dev, AUDIO_N_L, N & 0xFF); + rk616_hdmi_config_aai(hdmi_drv); + + return 0; } -void rk616_hdmi_control_output(struct hdmi *hdmi, int enable) +void rk616_hdmi_control_output(struct hdmi *hdmi_drv, int enable) { int mutestatus = 0; - - if(enable) { - if(hdmi->pwr_mode == LOWER_PWR) - rk616_hdmi_set_pwr_mode(hdmi, NORMAL); - hdmi_readl(AV_MUTE,&mutestatus); - if(mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) { - hdmi_writel(AV_MUTE, v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + + if (enable) { + if (hdmi_drv->pwr_mode == LOWER_PWR) + rk616_hdmi_set_pwr_mode(hdmi_drv, NORMAL); + hdmi_readl(hdmi_dev, AV_MUTE, &mutestatus); + if (mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) { + hdmi_writel(hdmi_dev, AV_MUTE, + v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); } - rk616_hdmi_sys_power_up(); - rk616_hdmi_sys_power_down(); - rk616_hdmi_sys_power_up(); - hdmi_writel(0xce, 0x00); + rk616_hdmi_sys_power(hdmi_drv, true); + rk616_hdmi_sys_power(hdmi_drv, false); + rk616_hdmi_sys_power(hdmi_drv, true); + hdmi_writel(hdmi_dev, 0xce, 0x00); delay100us(); - hdmi_writel(0xce, 0x01); - } - else { - hdmi_writel(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); + hdmi_writel(hdmi_dev, 0xce, 0x01); + } else { + hdmi_writel(hdmi_dev, AV_MUTE, + v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); } } -int rk616_hdmi_removed(struct hdmi *hdmi) +int rk616_hdmi_removed(struct hdmi *hdmi_drv) { - dev_printk(KERN_INFO , hdmi->dev , "Removed.\n"); - rk616_hdmi_set_pwr_mode(hdmi, LOWER_PWR); + dev_info(hdmi_drv->dev, "Removed.\n"); + if (hdmi_drv->hdcp_power_off_cb) + hdmi_drv->hdcp_power_off_cb(); + rk616_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR); return HDMI_ERROR_SUCESS; } - -void rk616_hdmi_work(struct hdmi *hdmi) -{ +void rk616_hdmi_work(struct hdmi *hdmi_drv) +{ u32 interrupt = 0; - // int value = 0; - - - hdmi_readl(INTERRUPT_STATUS1,&interrupt); - if(interrupt){ - hdmi_writel(INTERRUPT_STATUS1, interrupt); - } + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); - if(interrupt & m_HOTPLUG){ - if(hdmi->state == HDMI_SLEEP) - hdmi->state = WAIT_HOTPLUG; - //if(hdmi->pwr_mode == LOWER_PWR) - // rk616_hdmi_set_pwr_mode(NORMAL); + hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &interrupt); + if (interrupt) + hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt); - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(40)); + if (interrupt & m_HOTPLUG) { + if (hdmi_drv->state == HDMI_SLEEP) + hdmi_drv->state = WAIT_HOTPLUG; - } + queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, + msecs_to_jiffies(40)); -#if 0 - if(hdmi->state == HDMI_SLEEP) { -// hdmi_dbg(hdmi->dev, "hdmi return to sleep mode\n"); - rk616_hdmi_set_pwr_mode(hdmi, LOWER_PWR); } -#endif -#if 0 - if(hdmi->hdcp_irq_cb) - hdmi->hdcp_irq_cb(interrupt2); -#endif + + if (hdmi_drv->hdcp_irq_cb) + hdmi_drv->hdcp_irq_cb(0); } -static void rk616_hdmi_reset(struct hdmi *hdmi) +static void rk616_hdmi_reset(struct hdmi *hdmi_drv) { u32 val = 0; u32 msk = 0; - - hdmi_msk_reg(SYS_CTRL,m_RST_DIGITAL,v_NOT_RST_DIGITAL); + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + + hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL); delay100us(); - hdmi_msk_reg(SYS_CTRL,m_RST_ANALOG,v_NOT_RST_ANALOG); + hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG); delay100us(); 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(SYS_CTRL,msk,val); - hdmi_writel(INTERRUPT_MASK1,m_INT_HOTPLUG); - rk616_hdmi_set_pwr_mode(hdmi, LOWER_PWR); + 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); + hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG); + rk616_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR); } -int rk616_hdmi_initial(struct hdmi *hdmi) +int rk616_hdmi_initial(struct hdmi *hdmi_drv) { int rc = HDMI_ERROR_SUCESS; - struct rk616_hdmi *rk616_hdmi; - rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi); +#ifndef CONFIG_ARCH_RK3026 + struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, + struct rk_hdmi_device, + driver); + struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; +#endif - hdmi->pwr_mode = NORMAL; - hdmi->remove = rk616_hdmi_removed ; - hdmi->control_output = rk616_hdmi_control_output; - hdmi->config_video = rk616_hdmi_config_video; - hdmi->config_audio = rk616_hdmi_config_audio; - hdmi->detect_hotplug = rk616_hdmi_detect_hotplug; - hdmi->read_edid = rk616_hdmi_read_edid; + hdmi_drv->pwr_mode = NORMAL; + hdmi_drv->remove = rk616_hdmi_removed; + hdmi_drv->control_output = rk616_hdmi_control_output; + hdmi_drv->config_video = rk616_hdmi_config_video; + hdmi_drv->config_audio = rk616_hdmi_config_audio; + hdmi_drv->detect_hotplug = rk616_hdmi_detect_hotplug; + hdmi_drv->read_edid = rk616_hdmi_read_edid; #ifdef CONFIG_ARCH_RK3026 - rk3028_hdmi_reset_pclk(); - rk616_hdmi_reset(hdmi); + rk3028_hdmi_reset_pclk(); + rk616_hdmi_reset(hdmi_drv); #else - hdmi->set_vif = rk616_hdmi_set_vif; - rk616_hdmi_reset(hdmi); - rk616_hdmi_init_pol_set(rk616_hdmi->rk616_drv, 0); + hdmi_drv->set_vif = rk616_hdmi_set_vif; + rk616_hdmi_reset(hdmi_drv); + rk616_hdmi_init_pol_set(rk616_drv, 0); #endif - - if(hdmi->hdcp_power_on_cb) - rc = hdmi->hdcp_power_on_cb(); + + if (hdmi_drv->hdcp_power_on_cb) + rc = hdmi_drv->hdcp_power_on_cb(); return rc; } diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h index 082f92243db1..1d3c24417d75 100755 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h +++ b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h @@ -2,15 +2,14 @@ #define _RK616_HDMI_HW_H #define RK616_HDMI_BASE 0x400 -enum PWR_MODE{ - NORMAL, - LOWER_PWR, +enum PWR_MODE { + NORMAL, + LOWER_PWR, }; enum { - OUTPUT_DVI = 0, - OUTPUT_HDMI - }; - + OUTPUT_DVI = 0, + OUTPUT_HDMI +}; #ifdef RK616_USE_MCLK_12M #define HDMI_SYS_FREG_CLK 12000000 @@ -19,171 +18,168 @@ enum { #endif #define HDMI_SCL_RATE (100*1000) -#define DDC_BUS_FREQ_L 0x4b -#define DDC_BUS_FREQ_H 0x4c - +#define DDC_BUS_FREQ_L 0x4b +#define DDC_BUS_FREQ_H 0x4c #define SYS_CTRL 0x00 -#define m_RST_ANALOG (1<<6) -#define v_RST_ANALOG (0<<6) -#define v_NOT_RST_ANALOG (1<<6) - -#define m_RST_DIGITAL (1<<5) -#define v_RST_DIGITAL (0<<5) -#define v_NOT_RST_DIGITAL (1<<5) - -#define m_REG_CLK_INV (1<<4) -#define v_REG_CLK_NOT_INV (0<<4) -#define v_REG_CLK_INV (1<<4) -#define m_VCLK_INV (1<<3) -#define v_VCLK_NOT_INV (0<<3) -#define v_VCLK_INV (1<<3) -#define m_REG_CLK_SOURCE (1<<2) -#define v_REG_CLK_SOURCE_TMDS (0<<2) -#define v_REG_CLK_SOURCE_SYS (1<<2) -#define m_POWER (1<<1) -#define v_PWR_ON (0<<1) -#define v_PWR_OFF (1<<1) -#define m_INT_POL (1<<0) -#define v_INT_POL_HIGH 1 -#define v_INT_POL_LOW 0 - - -#define VIDEO_CONTRL1 0x01 - #define m_VIDEO_INPUT_FORMAT (7 << 1) - #define m_DE_SOURCE (1 << 0) - enum { - VIDEO_INPUT_SDR_RGB444 = 0, - VIDEO_INPUT_DDR_RGB444 = 5, - VIDEO_INPUT_DDR_YCBCR422 = 6 - }; - #define v_VIDEO_INPUT_FORMAT(n) (n << 1) - #define v_DE_EXTERNAL 1 - #define v_DE_INTERANL 0 - -#define VIDEO_CONTRL2 0x02 - #define m_VIDEO_OUTPUT_FORMAT (3 << 6) - #define m_VIDEO_INPUT_BITS (3 << 4) - #define v_VIDEO_OUTPUT_FORMAT(n)(n << 6) - #define v_VIDEO_INPUT_BITS(n) (n << 4) - enum{ - VIDEO_INPUT_12BITS = 0, - VIDEO_INPUT_10BITS, - VIDEO_INPUT_8BITS - }; -#define VIDEO_CONTRL3 0x04 - #define m_SOF (1 << 3) - #define m_CSC (1 << 0) - #define v_SOF_ENABLE (0 << 3) - #define v_SOF_DISABLE (1 << 3) - #define v_CSC_ENABLE 1 - #define v_CSC_DISABLE 0 - -#define AV_MUTE 0x05 - #define m_AVMUTE_CLEAR (1 << 7) - #define m_AVMUTE_ENABLE (1 << 6) - #define m_AUDIO_MUTE (1 << 1) - #define m_VIDEO_BLACK (1 << 0) - #define v_AUDIO_MUTE(n) (n << 1) - #define v_VIDEO_MUTE(n) (n << 0) - -#define VIDEO_TIMING_CTL 0x08 - #define v_HSYNC_POLARITY(n) (n << 3) - #define v_VSYNC_POLARITY(n) (n << 2) - #define v_INETLACE(n) (n << 1) - #define v_EXTERANL_VIDEO(n) (n << 0) - -#define VIDEO_EXT_HTOTAL_L 0x09 -#define VIDEO_EXT_HTOTAL_H 0x0a -#define VIDEO_EXT_HBLANK_L 0x0b -#define VIDEO_EXT_HBLANK_H 0x0c -#define VIDEO_EXT_HDELAY_L 0x0d -#define VIDEO_EXT_HDELAY_H 0x0e +#define m_RST_ANALOG (1 << 6) +#define v_RST_ANALOG (0 << 6) +#define v_NOT_RST_ANALOG (1 << 6) + +#define m_RST_DIGITAL (1 << 5) +#define v_RST_DIGITAL (0 << 5) +#define v_NOT_RST_DIGITAL (1 << 5) + +#define m_REG_CLK_INV (1 << 4) +#define v_REG_CLK_NOT_INV (0 << 4) +#define v_REG_CLK_INV (1 << 4) +#define m_VCLK_INV (1 << 3) +#define v_VCLK_NOT_INV (0 << 3) +#define v_VCLK_INV (1 << 3) +#define m_REG_CLK_SOURCE (1 << 2) +#define v_REG_CLK_SOURCE_TMDS (0 << 2) +#define v_REG_CLK_SOURCE_SYS (1 << 2) +#define m_POWER (1 << 1) +#define v_PWR_ON (0 << 1) +#define v_PWR_OFF (1 << 1) +#define m_INT_POL (1 << 0) +#define v_INT_POL_HIGH 1 +#define v_INT_POL_LOW 0 + +#define VIDEO_CONTRL1 0x01 +#define m_VIDEO_INPUT_FORMAT (7 << 1) +#define m_DE_SOURCE (1 << 0) +enum { + VIDEO_INPUT_SDR_RGB444 = 0, + VIDEO_INPUT_DDR_RGB444 = 5, + VIDEO_INPUT_DDR_YCBCR422 = 6 +}; +#define v_VIDEO_INPUT_FORMAT(n) (n << 1) +#define v_DE_EXTERNAL 1 +#define v_DE_INTERANL 0 + +#define VIDEO_CONTRL2 0x02 +#define m_VIDEO_OUTPUT_FORMAT (3 << 6) +#define m_VIDEO_INPUT_BITS (3 << 4) +#define v_VIDEO_OUTPUT_FORMAT(n)(n << 6) +#define v_VIDEO_INPUT_BITS(n) (n << 4) +enum { + VIDEO_INPUT_12BITS = 0, + VIDEO_INPUT_10BITS, + VIDEO_INPUT_8BITS +}; +#define VIDEO_CONTRL3 0x04 +#define m_SOF (1 << 3) +#define m_CSC (1 << 0) +#define v_SOF_ENABLE (0 << 3) +#define v_SOF_DISABLE (1 << 3) +#define v_CSC_ENABLE 1 +#define v_CSC_DISABLE 0 + +#define AV_MUTE 0x05 +#define m_AVMUTE_CLEAR (1 << 7) +#define m_AVMUTE_ENABLE (1 << 6) +#define m_AUDIO_MUTE (1 << 1) +#define m_VIDEO_BLACK (1 << 0) +#define v_AUDIO_MUTE(n) (n << 1) +#define v_VIDEO_MUTE(n) (n << 0) + +#define VIDEO_TIMING_CTL 0x08 +#define v_HSYNC_POLARITY(n) (n << 3) +#define v_VSYNC_POLARITY(n) (n << 2) +#define v_INETLACE(n) (n << 1) +#define v_EXTERANL_VIDEO(n) (n << 0) + +#define VIDEO_EXT_HTOTAL_L 0x09 +#define VIDEO_EXT_HTOTAL_H 0x0a +#define VIDEO_EXT_HBLANK_L 0x0b +#define VIDEO_EXT_HBLANK_H 0x0c +#define VIDEO_EXT_HDELAY_L 0x0d +#define VIDEO_EXT_HDELAY_H 0x0e #define VIDEO_EXT_HDURATION_L 0x0f #define VIDEO_EXT_HDURATION_H 0x10 -#define VIDEO_EXT_VTOTAL_L 0x11 -#define VIDEO_EXT_VTOTAL_H 0x12 -#define VIDEO_EXT_VBLANK 0x13 -#define VIDEO_EXT_VDELAY 0x14 -#define VIDEO_EXT_VDURATION 0x15 - -#define AUDIO_CTRL1 0x35 - enum { - CTS_SOURCE_INTERNAL = 0, - CTS_SOURCE_EXTERNAL - }; - #define v_CTS_SOURCE(n) (n << 7) - enum { - DOWNSAMPLE_DISABLE = 0, - DOWNSAMPLE_1_2, - DOWNSAMPLE_1_4 - }; - #define v_DOWN_SAMPLE(n) (n << 5) - enum { - AUDIO_SOURCE_IIS = 0, - AUDIO_SOURCE_SPDIF - }; - #define v_AUDIO_SOURCE(n) (n << 3) - #define v_MCLK_ENABLE(n) (n << 2) - enum { - MCLK_128FS = 0, - MCLK_256FS, - MCLK_384FS, - MCLK_512FS - }; - #define v_MCLK_RATIO(n) (n) - -#define AUDIO_SAMPLE_RATE 0x37 - enum { - AUDIO_32K = 0x3, - AUDIO_441K = 0x0, - AUDIO_48K = 0x2, - AUDIO_882K = 0x8, - AUDIO_96K = 0xa, - AUDIO_1764K = 0xc, - AUDIO_192K = 0xe, - }; - -#define AUDIO_I2S_MODE 0x38 - enum { - I2S_CHANNEL_1_2 = 1, - I2S_CHANNEL_3_4 = 3, - I2S_CHANNEL_5_6 = 7, - I2S_CHANNEL_7_8 = 0xf - }; - #define v_I2S_CHANNEL(n) ((n) << 2) - enum { - I2S_STANDARD = 0, - I2S_LEFT_JUSTIFIED, - I2S_RIGHT_JUSTIFIED - }; - #define v_I2S_MODE(n) (n) - -#define AUDIO_I2S_MAP 0x39 +#define VIDEO_EXT_VTOTAL_L 0x11 +#define VIDEO_EXT_VTOTAL_H 0x12 +#define VIDEO_EXT_VBLANK 0x13 +#define VIDEO_EXT_VDELAY 0x14 +#define VIDEO_EXT_VDURATION 0x15 + +#define AUDIO_CTRL1 0x35 +enum { + CTS_SOURCE_INTERNAL = 0, + CTS_SOURCE_EXTERNAL +}; +#define v_CTS_SOURCE(n) (n << 7) +enum { + DOWNSAMPLE_DISABLE = 0, + DOWNSAMPLE_1_2, + DOWNSAMPLE_1_4 +}; +#define v_DOWN_SAMPLE(n) (n << 5) +enum { + AUDIO_SOURCE_IIS = 0, + AUDIO_SOURCE_SPDIF +}; +#define v_AUDIO_SOURCE(n) (n << 3) +#define v_MCLK_ENABLE(n) (n << 2) +enum { + MCLK_128FS = 0, + MCLK_256FS, + MCLK_384FS, + MCLK_512FS +}; +#define v_MCLK_RATIO(n) (n) + +#define AUDIO_SAMPLE_RATE 0x37 +enum { + AUDIO_32K = 0x3, + AUDIO_441K = 0x0, + AUDIO_48K = 0x2, + AUDIO_882K = 0x8, + AUDIO_96K = 0xa, + AUDIO_1764K = 0xc, + AUDIO_192K = 0xe, +}; + +#define AUDIO_I2S_MODE 0x38 +enum { + I2S_CHANNEL_1_2 = 1, + I2S_CHANNEL_3_4 = 3, + I2S_CHANNEL_5_6 = 7, + I2S_CHANNEL_7_8 = 0xf +}; +#define v_I2S_CHANNEL(n) ((n) << 2) +enum { + I2S_STANDARD = 0, + I2S_LEFT_JUSTIFIED, + I2S_RIGHT_JUSTIFIED +}; +#define v_I2S_MODE(n) (n) + +#define AUDIO_I2S_MAP 0x39 #define AUDIO_I2S_SWAPS_SPDIF 0x3a - #define v_SPIDF_FREQ(n) (n) +#define v_SPIDF_FREQ(n) (n) -#define N_32K 0x1000 -#define N_441K 0x1880 -#define N_882K 0x3100 -#define N_1764K 0x6200 -#define N_48K 0x1800 +#define N_32K 0x1000 +#define N_441K 0x1880 +#define N_882K 0x3100 +#define N_1764K 0x6200 +#define N_48K 0x1800 #define N_96K 0x3000 -#define N_192K 0x6000 +#define N_192K 0x6000 -#define AUDIO_N_H 0x3f -#define AUDIO_N_M 0x40 -#define AUDIO_N_L 0x41 +#define AUDIO_N_H 0x3f +#define AUDIO_N_M 0x40 +#define AUDIO_N_L 0x41 -#define AUDIO_CTS_H 0x45 -#define AUDIO_CTS_M 0x46 -#define AUDIO_CTS_L 0x47 +#define AUDIO_CTS_H 0x45 +#define AUDIO_CTS_M 0x46 +#define AUDIO_CTS_L 0x47 +#define DDC_CLK_L 0x4b +#define DDC_CLK_H 0x4c -#define DDC_CLK_L 0x4b -#define DDC_CLK_H 0x4c - -#define EDID_SEGMENT_POINTER 0x4d +#define EDID_SEGMENT_POINTER 0x4d #define EDID_WORD_ADDR 0x4e #define EDID_FIFO_OFFSET 0x4f #define EDID_FIFO_ADDR 0x50 @@ -194,11 +190,10 @@ enum { INFOFRAME_AVI = 0x06, INFOFRAME_AAI = 0x08 }; -#define CONTROL_PACKET_ADDR 0xa0 - +#define CONTROL_PACKET_ADDR 0xa0 -#define SIZE_AVI_INFOFRAME 0x11 // 14 bytes -#define SIZE_AUDIO_INFOFRAME 0x0F // 15 bytes +#define SIZE_AVI_INFOFRAME 0x11 /* 14 bytes */ +#define SIZE_AUDIO_INFOFRAME 0x0F /* 15 bytes */ enum { AVI_COLOR_MODE_RGB = 0, AVI_COLOR_MODE_YCBCR422, @@ -222,134 +217,145 @@ enum { ACTIVE_ASPECT_RATE_14_9 }; -#define HDCP_CTRL 0x52 - #define m_HDMI_DVI (1 << 1) - #define v_HDMI_DVI(n) (n << 1) +#define HDCP_CTRL 0x52 +#define m_HDMI_DVI (1 << 1) +#define v_HDMI_DVI(n) (n << 1) #define INTERRUPT_MASK1 0xc0 #define INTERRUPT_STATUS1 0xc1 - #define m_INT_HOTPLUG (1 << 7) - #define m_INT_ACTIVE_VSYNC (1 << 5) - #define m_INT_EDID_READY (1 << 2) - +#define m_INT_HOTPLUG (1 << 7) +#define m_INT_ACTIVE_VSYNC (1 << 5) +#define m_INT_EDID_READY (1 << 2) + #define INTERRUPT_MASK2 0xc2 #define INTERRUPT_STATUS2 0xc3 - #define m_INT_HDCP_ERR (1 << 7) - #define m_INT_BKSV_FLAG (1 << 6) - #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 PHY_SYNC 0xce //sync phy parameter -#define PHY_SYS_CTL 0xe0 - #define m_TMDS_CLK_SOURCE (1<<5) - #define v_TMDS_FROM_PLL (0<<5) - #define v_TMDS_FROM_GEN (1<<5) - #define m_PHASE_CLK (1<<4) - #define v_DEFAULT_PHASE (0<<4) - #define v_SYNC_PHASE (1<<4) - #define m_TMDS_CURRENT_PWR (1<<3) - #define v_TURN_ON_CURRENT (0<<3) - #define v_CAT_OFF_CURRENT (1<<3) - #define m_BANDGAP_PWR (1<<2) - #define v_BANDGAP_PWR_UP (0<<2) - #define v_BANDGAP_PWR_DOWN (1<<2) - #define m_PLL_PWR (1<<1) - #define v_PLL_PWR_UP (0<<1) - #define v_PLL_PWR_DOWN (1<<1) - #define m_TMDS_CHG_PWR (1<<0) - #define v_TMDS_CHG_PWR_UP (0<<0) - #define v_TMDS_CHG_PWR_DOWN (1<<0) - -#define PHY_CHG_PWR 0xe1 - #define v_CLK_CHG_PWR(n) ((n&1)<<3) - #define v_DATA_CHG_PWR(n) ((n&7)<<0) - -#define PHY_DRIVER 0xe2 - #define v_CLK_MAIN_DRIVER(n) (n << 4) - #define v_DATA_MAIN_DRIVER(n) (n << 0) - +#define m_INT_HDCP_ERR (1 << 7) +#define m_INT_BKSV_FLAG (1 << 6) +#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 HDMI_COLORBAR 0xc9 + +#define PHY_SYNC 0xce /* sync phy parameter */ +#define PHY_SYS_CTL 0xe0 +#define m_TMDS_CLK_SOURCE (1 << 5) +#define v_TMDS_FROM_PLL (0 << 5) +#define v_TMDS_FROM_GEN (1 << 5) +#define m_PHASE_CLK (1 << 4) +#define v_DEFAULT_PHASE (0 << 4) +#define v_SYNC_PHASE (1 << 4) +#define m_TMDS_CURRENT_PWR (1 << 3) +#define v_TURN_ON_CURRENT (0 << 3) +#define v_CAT_OFF_CURRENT (1 << 3) +#define m_BANDGAP_PWR (1 << 2) +#define v_BANDGAP_PWR_UP (0 << 2) +#define v_BANDGAP_PWR_DOWN (1 << 2) +#define m_PLL_PWR (1 << 1) +#define v_PLL_PWR_UP (0 << 1) +#define v_PLL_PWR_DOWN (1 << 1) +#define m_TMDS_CHG_PWR (1 << 0) +#define v_TMDS_CHG_PWR_UP (0 << 0) +#define v_TMDS_CHG_PWR_DOWN (1 << 0) + +#define PHY_CHG_PWR 0xe1 +#define v_CLK_CHG_PWR(n) ((n & 1) << 3) +#define v_DATA_CHG_PWR(n) ((n & 7) << 0) + +#define PHY_DRIVER 0xe2 +#define v_CLK_MAIN_DRIVER(n) (n << 4) +#define v_DATA_MAIN_DRIVER(n) (n << 0) + #define PHY_PRE_EMPHASIS 0xe3 - #define v_PRE_EMPHASIS(n) ((n&7)<<4) - #define v_CLK_PRE_DRIVER(n) ((n&3)<<2) - #define v_DATA_PRE_DRIVER(n) ((n&3)<<0) - +#define v_PRE_EMPHASIS(n) ((n & 7) << 4) +#define v_CLK_PRE_DRIVER(n) ((n & 3) << 2) +#define v_DATA_PRE_DRIVER(n) ((n & 3) << 0) + #define PHY_FEEDBACK_DIV_RATIO_LOW 0xe7 - #define v_FEEDBACK_DIV_LOW(n) (n&0xff) -#define PHY_FEEDBACK_DIV_RATIO_HIGH 0xe8 - #define v_FEEDBACK_DIV_HIGH(n) (n&1) +#define v_FEEDBACK_DIV_LOW(n) (n & 0xff) +#define PHY_FEEDBACK_DIV_RATIO_HIGH 0xe8 +#define v_FEEDBACK_DIV_HIGH(n) (n & 1) -#define PHY_PRE_DIV_RATIO 0xed - #define v_PRE_DIV_RATIO(n) (n&1f) +#define PHY_PRE_DIV_RATIO 0xed +#define v_PRE_DIV_RATIO(n) (n & 0x1f) -extern struct hdmi *hdmi; #ifndef CONFIG_ARCH_RK3026 -static inline int hdmi_readl(u16 offset, u32 *val) +static inline int hdmi_readl(struct rk_hdmi_device *hdmi_dev, + u16 offset, u32 *val) { - int ret; - struct rk616_hdmi *rk616_hdmi; - rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi); + int ret; + struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; - ret = rk616_hdmi->rk616_drv->read_dev(rk616_hdmi->rk616_drv, (RK616_HDMI_BASE + ((offset)<<2)), val); - return ret; + ret = rk616_drv->read_dev(rk616_drv, + (RK616_HDMI_BASE + ((offset) << 2)), val); + return ret; } -static inline int hdmi_writel(u16 offset, u32 val) +static inline int hdmi_writel(struct rk_hdmi_device *hdmi_dev, + u16 offset, u32 val) { - int ret; - struct rk616_hdmi *rk616_hdmi; - rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi); + int ret; + struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; - ret = rk616_hdmi->rk616_drv->write_dev(rk616_hdmi->rk616_drv, (RK616_HDMI_BASE + ((offset)<<2)), &val); - return ret; + ret = rk616_drv->write_dev(rk616_drv, + (RK616_HDMI_BASE + ((offset) << 2)), &val); + return ret; } -static inline int hdmi_msk_reg(u16 offset, u32 msk, u32 val) +static inline int hdmi_msk_reg(struct rk_hdmi_device *hdmi_dev, u16 offset, + u32 msk, u32 val) { - int ret; - struct rk616_hdmi *rk616_hdmi; - rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi); + int ret; + struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; - ret = rk616_hdmi->rk616_drv->write_dev_bits(rk616_hdmi->rk616_drv, (RK616_HDMI_BASE + ((offset)<<2)), msk, &val); - return ret; + ret = rk616_drv->write_dev_bits(rk616_drv, + (RK616_HDMI_BASE + ((offset) << 2)), + msk, &val); + return ret; } #else -static inline int hdmi_readl(u16 offset, u32 *val) +static inline int hdmi_readl(struct rk_hdmi_device *hdmi_dev, u16 offset, + u32 *val) { - int ret = 0; - *val = readl_relaxed(hdmi->regbase + (offset) * 0x04); - return ret; + int ret = 0; + + *val = readl_relaxed(hdmi_dev->regbase + (offset) * 0x04); + return ret; } -static inline int hdmi_writel(u16 offset, u32 val) +static inline int hdmi_writel(struct rk_hdmi_device *hdmi_dev, u16 offset, + u32 val) { - int ret = 0; - writel_relaxed(val, hdmi->regbase + (offset) * 0x04); - return ret; + int ret = 0; + + writel_relaxed(val, hdmi_dev->regbase + (offset) * 0x04); + return ret; } -static inline int hdmi_msk_reg(u16 offset, u32 msk, u32 val) +static inline int hdmi_msk_reg(struct rk_hdmi_device *hdmi_dev, u16 offset, + u32 msk, 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); - return ret; + int ret = 0; + u32 temp; + + temp = readl_relaxed(hdmi->regbase + (offset) * 0x04) & (0xFF - (msk)); + writel_relaxed(temp | ((val) & (msk)), hdmi->regbase + (offset) * 0x04); + return ret; } + static inline void rk3028_hdmi_reset_pclk(void) { - writel_relaxed(0x00010001,RK2928_CRU_BASE+ 0x128); - msleep(100); - writel_relaxed(0x00010000, RK2928_CRU_BASE + 0x128); + writel_relaxed(0x00010001, RK2928_CRU_BASE + 0x128); + msleep(100); + writel_relaxed(0x00010000, RK2928_CRU_BASE + 0x128); } #endif extern int rk616_hdmi_initial(struct hdmi *hdmi); extern void rk616_hdmi_work(struct hdmi *hdmi); - #endif