From: Zheng Yang Date: Mon, 2 Feb 2015 03:06:04 +0000 (+0800) Subject: hdmi: update driver to v2.0: X-Git-Tag: firefly_0821_release~4263^2~63 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fa7ee75d42c5fd29b929d3e5ac9ecaec98a48213;p=firefly-linux-kernel-4.4.55.git hdmi: update driver to v2.0: 1. Rename rk3036 hdmi to rockchip_hdmiv1, support hdmi v1.4; 2. Rename rk3288 hdmi to rockchip_hdmiv2, support hdmi v2.0; 3. Support transmmit 3D picture. 4. 3288 hdmi support HDCP, CEC and TMDSCLK 600M. 5. HDMI video source default is LCDC0, it can be modified in dts by follow: rockchip,hdmi_video_source = ; HDCP and CEC function default is disabled , it can be enabled in dts file by follow: rockchip,hdcp_enable = <1>; rockchip,cec_enable = <1>; More information please see Documentation/devicetree/bindings/video/rockchip_hdmi.txt --- diff --git a/Documentation/devicetree/bindings/video/rockchip_hdmi.txt b/Documentation/devicetree/bindings/video/rockchip_hdmi.txt index 3935dcfdbc13..cdea37199f54 100644 --- a/Documentation/devicetree/bindings/video/rockchip_hdmi.txt +++ b/Documentation/devicetree/bindings/video/rockchip_hdmi.txt @@ -1,7 +1,11 @@ Device-Tree bindings for rockchip hdmi driver Required properties: -- compatible: value should be "rockchip,rk3288-hdmi". +- compatible: value should be following value: + "rockchip,rk3288-hdmi", + "rockchip,rk3368-hdmi", + "rockchip,rk3036-hdmi", + "rockchip,rk312x-hdmi", - reg: physical base address of the hdmi and length of memory mapped region. - interrupts: interrupt number to the cpu. @@ -12,10 +16,18 @@ Required properties: clock-names property. - clocks-names: list of clock names sorted in the same order as the clocks property. Must contain "pclk_hdmi" and "hdcp_clk_hdmi". -- rockchips,hdmi_audio_source: hdmi audio source that is described as follow +- rockchip,hdmi_audio_source: hdmi audio source that is described as follow <0>: hdmi audio source from the I2S interface <1>: hdmi audio source from the SPDIF interface - +- rockchip,hdmi_video_source: hdmi video source that is described as follow + hdmi video source from LCDC0/VOP0 + hdmi video source from LCDC1/VOP1 +- rockchip,hdcp_enable: hdmi hdcp function is described as follow + <0>: hdcp function is disabled. + <1>: hdcp function is enabled. +- rockchip,cec_enable: hdmi cec function is described as follow + <0>: cec function is disabled. + <1>: cec function is enabled. Example: hdmi: hdmi@ff980000 { @@ -27,6 +39,9 @@ Example: pinctrl-1 = <&i2c5_gpio>; clocks = <&clk_gates16 9>, <&clk_gates5 12>; clock-names = "pclk_hdmi", "hdcp_clk_hdmi"; - rockchips,hdmi_audio_source = <0>; + rockchip,hdmi_video_source = ; + rockchip,hdmi_audio_source = <0>; + rockchip,hdcp_enable = <0>; + rockchip,cec_enable = <0>; }; diff --git a/arch/arm/boot/dts/rk312x.dtsi b/arch/arm/boot/dts/rk312x.dtsi index 592fb3cf4cff..ea52b54ff41f 100755 --- a/arch/arm/boot/dts/rk312x.dtsi +++ b/arch/arm/boot/dts/rk312x.dtsi @@ -763,6 +763,8 @@ pinctrl-1 = <&hdmi_gpio>; clocks = <&clk_gates3 8>, <&pd_hdmi>; clock-names = "pclk_hdmi", "pd_hdmi"; + rockchip,hdcp_enable = <0>; + rockchip,cec_enable = <0>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/rk3288-p977.dts b/arch/arm/boot/dts/rk3288-p977.dts index 405e3022c581..3332f90de4a1 100755 --- a/arch/arm/boot/dts/rk3288-p977.dts +++ b/arch/arm/boot/dts/rk3288-p977.dts @@ -492,7 +492,7 @@ &hdmi { status = "okay"; - rockchips,hdmi_audio_source = <0>; + rockchip,hdmi_video_source = ; }; &adc { diff --git a/arch/arm/boot/dts/rk3288-p977_8846.dts b/arch/arm/boot/dts/rk3288-p977_8846.dts index 4e20b449b675..a7b2e452e93d 100755 --- a/arch/arm/boot/dts/rk3288-p977_8846.dts +++ b/arch/arm/boot/dts/rk3288-p977_8846.dts @@ -549,7 +549,7 @@ &hdmi { status = "okay"; - rockchips,hdmi_audio_source = <0>; + rockchip,hdmi_video_source = ; }; &adc { diff --git a/arch/arm/boot/dts/rk3288-tb.dts b/arch/arm/boot/dts/rk3288-tb.dts index fde9d45df930..023ec6a84b67 100755 --- a/arch/arm/boot/dts/rk3288-tb.dts +++ b/arch/arm/boot/dts/rk3288-tb.dts @@ -634,7 +634,7 @@ &hdmi { status = "okay"; - rockchips,hdmi_audio_source = <0>; + rockchip,hdmi_video_source = ; }; &adc { diff --git a/arch/arm/boot/dts/rk3288-tb_8846.dts b/arch/arm/boot/dts/rk3288-tb_8846.dts index 7f5e80990fc7..d013f0694513 100755 --- a/arch/arm/boot/dts/rk3288-tb_8846.dts +++ b/arch/arm/boot/dts/rk3288-tb_8846.dts @@ -658,7 +658,7 @@ &hdmi { status = "okay"; - rockchips,hdmi_audio_source = <0>; + rockchip,hdmi_video_source = ; }; &adc { diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index a122e61efd9f..a4650a9e921e 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -735,6 +735,10 @@ pinctrl-1 = <&i2c5_gpio>; clocks = <&clk_gates16 9>, <&clk_gates5 12>, <&clk_gates5 11>; clock-names = "pclk_hdmi", "hdcp_clk_hdmi", "cec_clk_hdmi"; + rockchip,hdmi_video_source = ; + rockchip,hdmi_audio_source = <0>; + rockchip,hdcp_enable = <0>; + rockchip,cec_enable = <0>; status = "disabled"; }; diff --git a/drivers/video/rockchip/display-sys.c b/drivers/video/rockchip/display-sys.c index dd1f9da3987e..b85d5db7e680 100755 --- a/drivers/video/rockchip/display-sys.c +++ b/drivers/video/rockchip/display-sys.c @@ -5,7 +5,8 @@ #include #include -static struct list_head display_device_list; +static struct list_head main_display_device_list; +static struct list_head aux_display_device_list; static ssize_t display_show_name(struct device *dev, struct device_attribute *attr, char *buf) @@ -23,6 +24,14 @@ static ssize_t display_show_type(struct device *dev, return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type); } +static ssize_t display_show_property(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct rk_display_device *dsp = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", dsp->property); +} + static ssize_t display_show_enable(struct device *dev, struct device_attribute *attr, char *buf) { @@ -68,6 +77,8 @@ static int mode_string(char *buf, unsigned int offset, { char v = 'p'; + if (mode->xres == 0 && mode->yres == 0) + return snprintf(&buf[offset], PAGE_SIZE - offset, "auto\n"); /* if (mode->flag & FB_MODE_IS_DETAILED) m = 'D'; @@ -80,16 +91,22 @@ static int mode_string(char *buf, unsigned int offset, v = 'i'; if (mode->vmode & FB_VMODE_DOUBLE) v = 'd'; - - return snprintf(&buf[offset], PAGE_SIZE - offset, "%dx%d%c-%d\n", - mode->xres, mode->yres, v, mode->refresh); + if (mode->flag) + return snprintf(&buf[offset], PAGE_SIZE - offset, + "%dx%d%c-%d(YCbCr420)\n", + mode->xres, mode->yres, v, mode->refresh); + else + return snprintf(&buf[offset], PAGE_SIZE - offset, + "%dx%d%c-%d\n", + mode->xres, mode->yres, v, mode->refresh); } + static ssize_t display_show_modes(struct device *dev, struct device_attribute *attr, char *buf) { struct rk_display_device *dsp = dev_get_drvdata(dev); struct list_head *modelist, *pos; - struct fb_modelist *fb_modelist; + struct display_modelist *display_modelist; const struct fb_videomode *mode; int i; @@ -100,9 +117,14 @@ static ssize_t display_show_modes(struct device *dev, return 0; } i = 0; + if (dsp->priority == DISPLAY_PRIORITY_HDMI) + i += snprintf(buf, PAGE_SIZE, "auto\n"); + list_for_each(pos, modelist) { - fb_modelist = list_entry(pos, struct fb_modelist, list); - mode = &fb_modelist->mode; + display_modelist = list_entry(pos, + struct display_modelist, + list); + mode = &display_modelist->mode; i += mode_string(buf, i, mode); } return i; @@ -127,19 +149,26 @@ static ssize_t display_store_mode(struct device *dev, struct rk_display_device *dsp = dev_get_drvdata(dev); char mstr[100]; struct list_head *modelist, *pos; - struct fb_modelist *fb_modelist; + struct display_modelist *display_modelist; struct fb_videomode *mode; size_t i; + if (!memcmp(buf, "auto", 4)) { + if (dsp->ops && dsp->ops->setmode) + dsp->ops->setmode(dsp, NULL); + return count; + } + if (dsp->ops && dsp->ops->getmodelist) { if (dsp->ops && dsp->ops->getmodelist) { if (dsp->ops->getmodelist(dsp, &modelist)) return -EINVAL; } list_for_each(pos, modelist) { - fb_modelist = list_entry(pos, - struct fb_modelist, list); - mode = &fb_modelist->mode; + display_modelist = list_entry(pos, + struct display_modelist, + list); + mode = &display_modelist->mode; i = mode_string(mstr, 0, mode); if (strncmp(mstr, buf, max(count, i)) == 0) { if (dsp->ops && dsp->ops->setmode) @@ -202,23 +231,85 @@ static ssize_t display_store_scale(struct device *dev, return -EINVAL; } -static ssize_t display_show_debug(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t display_show_3dmode(struct device *dev, + struct device_attribute *attr, char *buf) { + struct rk_display_device *dsp = dev_get_drvdata(dev); + struct list_head *modelist, *pos; + struct display_modelist *display_modelist; + struct fb_videomode mode; + int i = 0, cur_3d_mode = -1; + + if (dsp->ops && dsp->ops->getmodelist) { + if (dsp->ops->getmodelist(dsp, &modelist)) + return -EINVAL; + } else { + return 0; + } + + if (dsp->ops && dsp->ops->getmode) { + if (dsp->ops->getmode(dsp, &mode)) + return -EINVAL; + } else { + return 0; + } + + list_for_each(pos, modelist) { + display_modelist = list_entry(pos, + struct display_modelist, + list); + if (fb_mode_is_equal(&mode, &display_modelist->mode)) + break; + else + display_modelist = NULL; + } + if (display_modelist) + i = snprintf(buf, PAGE_SIZE, "3dmodes=%d\n", + display_modelist->format_3d); + else + i = snprintf(buf, PAGE_SIZE, "3dmodes=0\n"); + + if (dsp->ops && dsp->ops->get3dmode) + cur_3d_mode = dsp->ops->get3dmode(dsp); + i += snprintf(buf + i, PAGE_SIZE - i, "cur3dmode=%d", cur_3d_mode); + return i; +} + +static ssize_t display_store_3dmode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct rk_display_device *dsp = dev_get_drvdata(dev); + int mode; + + if (dsp->ops && dsp->ops->set3dmode) { + if (!kstrtoint(buf, 0, &mode)) + dsp->ops->set3dmode(dsp, mode); + return count; + } return -EINVAL; } -static ssize_t display_store_debug(struct device *dev, +static ssize_t display_show_color(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct rk_display_device *dsp = dev_get_drvdata(dev); + + if(dsp->ops && dsp->ops->getcolor) + return dsp->ops->getcolor(dsp, buf); + else + return 0; +} + +static ssize_t display_store_color(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int cmd; struct rk_display_device *dsp = dev_get_drvdata(dev); - if (dsp->ops && dsp->ops->setdebug) { - if (kstrtoint(buf, 0, &cmd) != -1) - dsp->ops->setdebug(dsp, cmd); - return count; + if(dsp->ops && dsp->ops->setcolor) { + if (!dsp->ops->setcolor(dsp, buf, count)); + return count; } return -EINVAL; } @@ -239,8 +330,6 @@ static ssize_t display_show_sinkaudioinfo(struct device *dev, return -EINVAL; } - - static ssize_t display_show_monspecs(struct device *dev, struct device_attribute *attr, char *buf) { @@ -258,18 +347,41 @@ static ssize_t display_show_monspecs(struct device *dev, return -EINVAL; } +static ssize_t display_show_debug(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return -EINVAL; +} + +static ssize_t display_store_debug(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int cmd; + struct rk_display_device *dsp = dev_get_drvdata(dev); + + if(dsp->ops && dsp->ops->setdebug) { + if (sscanf(buf, "%d", &cmd) != -1) + dsp->ops->setdebug(dsp, cmd); + return count; + } + return -EINVAL; +} static struct device_attribute display_attrs[] = { __ATTR(name, S_IRUGO, display_show_name, NULL), __ATTR(type, S_IRUGO, display_show_type, NULL), - __ATTR(enable, 0664, display_show_enable, display_store_enable), + __ATTR(property, S_IRUGO, display_show_property, NULL), + __ATTR(enable, 0666, display_show_enable, display_store_enable), __ATTR(connect, S_IRUGO, display_show_connect, NULL), __ATTR(modes, S_IRUGO, display_show_modes, NULL), - __ATTR(mode, 0664, display_show_mode, display_store_mode), - __ATTR(scale, 0664, display_show_scale, display_store_scale), - __ATTR(debug, 0664, display_show_debug, display_store_debug), + __ATTR(mode, 0666, display_show_mode, display_store_mode), + __ATTR(scale, 0666, display_show_scale, display_store_scale), + __ATTR(3dmode, 0666, display_show_3dmode, display_store_3dmode), + __ATTR(color, 0666, display_show_color, display_store_color), __ATTR(audioinfo, S_IRUGO, display_show_sinkaudioinfo, NULL), __ATTR(monspecs, S_IRUGO, display_show_monspecs, NULL), + __ATTR(debug, 0664, display_show_debug, display_store_debug), __ATTR_NULL }; @@ -295,6 +407,34 @@ static int display_resume(struct device *dev) return 0; }; +int display_add_videomode(const struct fb_videomode *mode, + struct list_head *head) +{ + struct list_head *pos; + struct display_modelist *modelist; + struct fb_videomode *m; + int found = 0; + + list_for_each(pos, head) { + modelist = list_entry(pos, struct display_modelist, list); + m = &modelist->mode; + if (fb_mode_is_equal(m, mode)) { + found = 1; + break; + } + } + if (!found) { + modelist = kmalloc(sizeof(*modelist), + GFP_KERNEL); + + if (!modelist) + return -ENOMEM; + modelist->mode = *mode; + list_add(&modelist->list, head); + } + return 0; +} + void rk_display_device_enable(struct rk_display_device *ddev) { struct list_head *pos, *head; @@ -302,7 +442,11 @@ void rk_display_device_enable(struct rk_display_device *ddev) struct rk_display_device *dev_enable = NULL; int enable = 0, connect; - head = &display_device_list; + if (ddev->property == DISPLAY_MAIN) + head = &main_display_device_list; + else + head = &aux_display_device_list; + list_for_each(pos, head) { dev = list_entry(pos, struct rk_display_device, list); enable = dev->ops->getenable(dev); @@ -334,10 +478,15 @@ void rk_display_device_enable_other(struct rk_display_device *ddev) #ifndef CONFIG_DISPLAY_AUTO_SWITCH return; #else - struct list_head *pos, *head = &display_device_list; + struct list_head *pos, *head; struct rk_display_device *dev; int connect = 0; + if (ddev->property == DISPLAY_MAIN) + head = &main_display_device_list; + else + head = &aux_display_device_list; + list_for_each_prev(pos, head) { dev = list_entry(pos, struct rk_display_device, list); if (dev != ddev) { @@ -357,10 +506,15 @@ void rk_display_device_disable_other(struct rk_display_device *ddev) #ifndef CONFIG_DISPLAY_AUTO_SWITCH return; #else - struct list_head *pos, *head = &display_device_list; + struct list_head *pos, *head; struct rk_display_device *dev; int enable = 0; + if (ddev->property == DISPLAY_MAIN) + head = &main_display_device_list; + else + head = &aux_display_device_list; + list_for_each(pos, head) { dev = list_entry(pos, struct rk_display_device, list); if (dev != ddev) { @@ -374,12 +528,17 @@ void rk_display_device_disable_other(struct rk_display_device *ddev) } EXPORT_SYMBOL(rk_display_device_disable_other); -void rk_display_device_select(int priority) +void rk_display_device_select(int property, int priority) { - struct list_head *pos, *head = &display_device_list; + struct list_head *pos, *head; struct rk_display_device *dev; int enable, found = 0; + if (property == DISPLAY_MAIN) + head = &main_display_device_list; + else + head = &aux_display_device_list; + list_for_each(pos, head) { dev = list_entry(pos, struct rk_display_device, list); if (dev->priority == priority) @@ -427,9 +586,18 @@ struct rk_display_device mutex_unlock(&allocated_dsp_lock); if (new_dev->idx >= 0) { - new_dev->dev = device_create(display_class, parent, - MKDEV(0, 0), new_dev, - "%s", new_dev->type); + if (new_dev->property == DISPLAY_MAIN) + new_dev->dev = + device_create(display_class, parent, + MKDEV(0, 0), new_dev, + "%s", new_dev->type); + else + new_dev->dev = + device_create(display_class, parent, + MKDEV(0, 0), new_dev, + "display%d.%s", + new_dev->property, + new_dev->type); if (!IS_ERR(new_dev->dev)) { new_dev->parent = parent; new_dev->driver = driver; @@ -441,7 +609,11 @@ struct rk_display_device struct list_head *pos, *head; struct rk_display_device *dev; - head = &display_device_list; + if (new_dev->property == DISPLAY_MAIN) + head = &main_display_device_list; + else + head = &aux_display_device_list; + list_for_each(pos, head) { dev = list_entry(pos, @@ -494,7 +666,8 @@ static int __init rk_display_class_init(void) display_class->suspend = display_suspend; display_class->resume = display_resume; mutex_init(&allocated_dsp_lock); - INIT_LIST_HEAD(&display_device_list); + INIT_LIST_HEAD(&main_display_device_list); + INIT_LIST_HEAD(&aux_display_device_list); return 0; } diff --git a/drivers/video/rockchip/hdmi/Kconfig b/drivers/video/rockchip/hdmi/Kconfig old mode 100755 new mode 100644 index 6aff41b0b852..ed16d20bfb76 --- a/drivers/video/rockchip/hdmi/Kconfig +++ b/drivers/video/rockchip/hdmi/Kconfig @@ -1,15 +1,15 @@ menuconfig RK_HDMI bool "Rockchip HDMI support" - depends on FB_ROCKCHIP || DRM_ROCKCHIP + depends on FB_ROCKCHIP select FB_MODE_HELPERS -if RK_HDMI -source "drivers/video/rockchip/hdmi/chips/Kconfig" -endif +source "drivers/video/rockchip/hdmi/rockchip-hdmiv1/Kconfig" +source "drivers/video/rockchip/hdmi/rockchip-hdmiv2/Kconfig" config RK_HDMI_DEBUG - bool "Rockchip HDMI Debugging" + bool "Rockchip HDMI Debugging" depends on RK_HDMI default n - help - Enableds verbose debugging the the HDMI drivers + help + Enableds verbose debugging the the HDMI drivers + diff --git a/drivers/video/rockchip/hdmi/Makefile b/drivers/video/rockchip/hdmi/Makefile old mode 100755 new mode 100644 index 267b8b528ecb..cabca13757bb --- a/drivers/video/rockchip/hdmi/Makefile +++ b/drivers/video/rockchip/hdmi/Makefile @@ -4,5 +4,6 @@ ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG -obj-$(CONFIG_RK_HDMI) += rk_hdmi_edid.o rk_hdmi_lcdc.o rk_hdmi_task.o rk_hdmi_sysfs.o rk_hdmi_parse_dt.o -obj-$(CONFIG_RK_HDMI) += chips/ +obj-$(CONFIG_RK_HDMI) += rockchip-hdmi-core.o rockchip-hdmi-lcdc.o rockchip-hdmi-edid.o rockchip-hdmi-sysfs.o rockchip-hdmi-cec.o +obj-$(CONFIG_RK_HDMI_V2) += rockchip-hdmiv2/ +obj-$(CONFIG_RK_HDMI_V1) += rockchip-hdmiv1/ diff --git a/drivers/video/rockchip/hdmi/chips/Kconfig b/drivers/video/rockchip/hdmi/chips/Kconfig deleted file mode 100755 index a0f5b3d2cf0f..000000000000 --- a/drivers/video/rockchip/hdmi/chips/Kconfig +++ /dev/null @@ -1,73 +0,0 @@ -config HDMI_RK30 - bool "RK30 HDMI support" - depends on LCDC_RK30 - help - Support rk30 hdmi if you say y here - -if HDMI_RK30 -source "drivers/video/rockchip/hdmi/chips/rk30/Kconfig" -endif - -config HDMI_RK2928 - bool "RK2928 HDMI support" - depends on LCDC_RK2928 - help - Support rk2928 hdmi if you say y here - -if HDMI_RK2928 -source "drivers/video/rockchip/hdmi/chips/rk2928/Kconfig" -endif - -config HDMI_CAT66121 - bool "CAT66121 HDMI support" - help - Support cat66121 hdmi if you say y here - -if HDMI_CAT66121 -source "drivers/video/rockchip/hdmi/chips/cat66121/Kconfig" -endif - -config HDMI_RK610 - bool "RK610 HDMI support" - depends on MFD_RK610 - help - Support rk610 hdmi if you say y here - -if HDMI_RK610 -source "drivers/video/rockchip/hdmi/chips/rk610/Kconfig" -endif - -config HDMI_RK616 - bool "RK616 HDMI support" -depends on MFD_RK616 || ARCH_RK3026 - default y - help - Support rk616 hdmi if you say y here - -if HDMI_RK616 -source "drivers/video/rockchip/hdmi/chips/rk616/Kconfig" -endif - -config HDMI_RK3288 - bool "RK3288 HDMI support" - default y - help - Support rk3288 hdmi if you say y here - -config HDMI_RK3036 - bool "RK3036 HDMI support" - default y - help - Support rk3036 hdmi if you say y here - -if HDMI_RK3036 -source "drivers/video/rockchip/hdmi/chips/rk3036/Kconfig" -endif - -choice - prompt "HDMI Source LCDC select" -config HDMI_SOURCE_LCDC0 - bool "lcdc0" -config HDMI_SOURCE_LCDC1 - bool "lcdc1" -endchoice diff --git a/drivers/video/rockchip/hdmi/chips/Makefile b/drivers/video/rockchip/hdmi/chips/Makefile deleted file mode 100755 index 8f37bd42efba..000000000000 --- a/drivers/video/rockchip/hdmi/chips/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Makefile for HDMI linux kernel module. -# - -ccflags-$(CONFIG_HDMI_RK30_DEBUG) = -DDEBUG -DHDMI_DEBUG - -obj-$(CONFIG_HDMI_RK30) += rk30/ -obj-$(CONFIG_HDMI_RK2928) += rk2928/ -obj-$(CONFIG_HDMI_RK610) += rk610/ -obj-$(CONFIG_HDMI_CAT66121) += cat66121/ -obj-$(CONFIG_HDMI_RK616) += rk616/ -obj-$(CONFIG_HDMI_RK3036) += rk3036/ -obj-$(CONFIG_HDMI_RK3288) += rk3288/ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/Kconfig b/drivers/video/rockchip/hdmi/chips/cat66121/Kconfig deleted file mode 100755 index 457a6ee27023..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config SUPPORT_HDCP - bool "HDCP support" - depends on HDMI_CAT66121 - default n - help - HDCP Interface. This adds the High Definition Content Protection Interface. - See http://www.digital-cp.com/ for HDCP specification. - - diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/Makefile b/drivers/video/rockchip/hdmi/chips/cat66121/Makefile deleted file mode 100755 index 8ddc0d3f70d3..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG - -obj-$(CONFIG_HDMI_CAT66121) += cat66121_hdmi.o \ - cat66121_hdmi_hw.o \ - hdmitx_input.o \ - hdmitx_drv.o \ - csc.o - -obj-$(CONFIG_SUPPORT_HDCP) += hdmitx_hdcp.o \ - sha1.o - diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.c b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.c deleted file mode 100755 index a0792156a7f3..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.c +++ /dev/null @@ -1,405 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_DEBUG_FS) -#include -#include -#include -#endif -#include -#include - -#include "cat66121_hdmi.h" -#include "cat66121_hdmi_hw.h" - -#define HDMI_POLL_MDELAY 50//100 -struct cat66121_hdmi_pdata *cat66121_hdmi = NULL; -struct hdmi *hdmi=NULL; - -extern struct rk_lcdc_driver * rk_get_lcdc_drv(char *name); -extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent); -extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi); -static void cat66121_irq_work_func(struct work_struct *work); -#if 0 -int cat66121_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)) -{ - 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; - - return HDMI_ERROR_SUCESS; -} -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND -static void hdmi_early_suspend(struct early_suspend *h) -{ - hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state); - 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 != INVALID_GPIO) - disable_irq(hdmi->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); - return; -} - -static void hdmi_early_resume(struct early_suspend *h) -{ - hdmi_dbg(hdmi->dev, "hdmi exit early resume\n"); - mutex_lock(&hdmi->enable_mutex); - - hdmi->suspend = 0; - if(hdmi->irq == INVALID_GPIO){ - queue_delayed_work(cat66121_hdmi->workqueue, &cat66121_hdmi->delay_work, HDMI_POLL_MDELAY); - }else if(hdmi->enable){ - enable_irq(hdmi->irq); - } - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); - mutex_unlock(&hdmi->enable_mutex); - return; -} -#endif - -static void cat66121_irq_work_func(struct work_struct *work) -{ - if(hdmi->suspend == 0) { - if(hdmi->enable == 1) { - cat66121_hdmi_interrupt(hdmi); - if(hdmi->hdcp_irq_cb) - hdmi->hdcp_irq_cb(0); - } - if(!gpio_is_valid(hdmi->irq)){ - queue_delayed_work(cat66121_hdmi->workqueue, &cat66121_hdmi->delay_work, HDMI_POLL_MDELAY); - } - } -} - -static irqreturn_t cat66121_thread_interrupt(int irq, void *dev_id) -{ - cat66121_irq_work_func(NULL); - msleep(HDMI_POLL_MDELAY); - hdmi_dbg(hdmi->dev, "%s irq=%d\n", __func__,irq); - return IRQ_HANDLED; -} - -#if defined(CONFIG_DEBUG_FS) -static int hdmi_read_p0_reg(struct i2c_client *client, char reg, char *val) -{ - //return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL; //TODO Daisen - return 0; -} - -static int hdmi_write_p0_reg(struct i2c_client *client, char reg, char *val) -{ - //return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL; //TODO Daisen - return 0; -} -static int hdmi_reg_show(struct seq_file *s, void *v) -{ - - int i; - char val; - struct i2c_client *client=cat66121_hdmi->client; - - for(i=0;i<256;i++) - { - hdmi_read_p0_reg(client, i, &val); - if(i%16==0) - seq_printf(s,"\n>>>hdmi_hdmi %x:",i); - seq_printf(s," %2x",val); - } - seq_printf(s,"\n"); - - return 0; -} - -static ssize_t hdmi_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos) -{ - struct i2c_client *client=NULL; - u32 reg,val; - char kbuf[25]; - client = cat66121_hdmi->client; - - if (copy_from_user(kbuf, buf, count)) - return -EFAULT; - sscanf(kbuf, "%x%x", ®,&val); - hdmi_write_p0_reg(client, reg, (u8*)&val); - - return count; -} - -static int hdmi_reg_open(struct inode *inode, struct file *file) -{ - return single_open(file,hdmi_reg_show,hdmi); -} - -static const struct file_operations hdmi_reg_fops = { - .owner = THIS_MODULE, - .open = hdmi_reg_open, - .read = seq_read, - .write = hdmi_reg_write, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - -static int rk_hdmi_drv_init(struct hdmi *hdmi_drv) -{ - int ret = 0; - struct rk_screen screen; - - rk_fb_get_prmry_screen(&screen); - if(screen.lcdc_id == 1) - hdmi_drv->lcdc = rk_get_lcdc_drv("lcdc0"); - else - hdmi_drv->lcdc = rk_get_lcdc_drv("lcdc1"); - if(hdmi_drv->lcdc == NULL) - { - dev_err(hdmi_drv->dev, "can not connect to video source lcdc\n"); - ret = -ENXIO; - return ret; - } - -#ifdef SUPPORT_HDCP - hdmi_drv->irq = INVALID_GPIO; -#endif - - hdmi_sys_init(hdmi_drv); - hdmi_drv->xscale = 100; - hdmi_drv->yscale = 100; - hdmi_drv->insert = cat66121_hdmi_sys_insert; - hdmi_drv->remove = cat66121_hdmi_sys_remove; - hdmi_drv->control_output = cat66121_hdmi_sys_enalbe_output; - hdmi_drv->config_video = cat66121_hdmi_sys_config_video; - hdmi_drv->config_audio = cat66121_hdmi_sys_config_audio; - hdmi_drv->detect_hotplug = cat66121_hdmi_sys_detect_hpd; - hdmi_drv->read_edid = cat66121_hdmi_sys_read_edid; - - #ifdef CONFIG_HAS_EARLYSUSPEND - hdmi_drv->early_suspend.suspend = hdmi_early_suspend; - hdmi_drv->early_suspend.resume = hdmi_early_resume; - hdmi_drv->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 10; - register_early_suspend(&hdmi_drv->early_suspend); - #endif - - hdmi_register_display_sysfs(hdmi_drv, NULL); - - #ifdef CONFIG_SWITCH - hdmi_drv->switch_hdmi.name="hdmi"; - switch_dev_register(&(hdmi_drv->switch_hdmi)); - #endif - - spin_lock_init(&hdmi_drv->irq_lock); - mutex_init(&hdmi_drv->enable_mutex); - - return 0; -} - -#if defined(CONFIG_OF) -static const struct of_device_id cat66121_dt_ids[] = { - {.compatible = "ite,cat66121",}, - {} -}; -MODULE_DEVICE_TABLE(of, cat66121_dt_ids); -#endif - -static int cat66121_hdmi_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id) -{ - int rc = 0; - - printk("%s,line=%d\n", __func__,__LINE__); - - if (client->dev.of_node) { - if (!of_match_device(cat66121_dt_ids, &client->dev)) { - dev_err(&client->dev,"Failed to find matching dt id\n"); - return -EINVAL; - } - } - - cat66121_hdmi = kzalloc(sizeof(struct cat66121_hdmi_pdata), GFP_KERNEL); - if(!cat66121_hdmi) - { - dev_err(&client->dev, "no memory for state\n"); - return -ENOMEM; - } - cat66121_hdmi->client = client; - i2c_set_clientdata(client, cat66121_hdmi); - - hdmi = kmalloc(sizeof(struct hdmi), GFP_KERNEL); - if(!hdmi) - { - dev_err(&client->dev, "cat66121 hdmi kmalloc fail!"); - goto err_kzalloc_hdmi; - } - memset(hdmi, 0, sizeof(struct hdmi)); - hdmi->dev = &client->dev; - - rk_hdmi_parse_dt(hdmi); - //power on - rk_hdmi_pwr_enable(hdmi); - - if(cat66121_detect_device()!=1){ - dev_err(hdmi->dev, "can't find it66121 device \n"); - rc = -ENXIO; - goto err_request_lcdc; - } - - cat66121_hdmi->plug_status = -1; - rk_hdmi_drv_init(hdmi); - cat66121_hdmi_sys_init(hdmi); - - hdmi->workqueue = create_singlethread_workqueue("hdmi"); - INIT_DELAYED_WORK(&(hdmi->delay_work), hdmi_work); - - if(gpio_is_valid(hdmi->irq)) { - //cat66121_irq_work_func(NULL); - if((rc = gpio_request(hdmi->irq, "hdmi gpio")) < 0) - { - dev_err(&client->dev, "fail to request gpio %d\n", hdmi->irq); - goto err_request_lcdc; - } - - cat66121_hdmi->gpio = hdmi->irq; - //gpio_pull_updown(hdmi->irq, GPIOPullUp); //TODO Daisen - gpio_direction_input(hdmi->irq); - hdmi->irq = gpio_to_irq(hdmi->irq); - if(hdmi->irq <= 0) { - dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n", hdmi->irq); - goto err_request_irq; - } - - if((rc = request_threaded_irq(hdmi->irq, NULL ,cat66121_thread_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT, dev_name(&client->dev), hdmi)) < 0) - { - dev_err(&client->dev, "fail to request hdmi irq\n"); - goto err_request_irq; - } - }else{ - cat66121_hdmi->workqueue = create_singlethread_workqueue("cat66121 irq"); - INIT_DELAYED_WORK(&(cat66121_hdmi->delay_work), cat66121_irq_work_func); - cat66121_irq_work_func(NULL); - } - -#if defined(CONFIG_DEBUG_FS) - { - struct dentry *debugfs_dir = debugfs_create_dir("it66121", NULL); - if (IS_ERR(debugfs_dir)) - { - dev_err(&client->dev,"failed to create debugfs dir for it66121!\n"); - } - else - debugfs_create_file("hdmi", S_IRUSR,debugfs_dir,hdmi,&hdmi_reg_fops); - } -#endif - - dev_info(&client->dev, "cat66121 hdmi i2c probe ok\n"); - - return 0; - -err_request_irq: - gpio_free(hdmi->irq); -err_request_lcdc: - kfree(hdmi); - hdmi = NULL; -err_kzalloc_hdmi: - kfree(cat66121_hdmi); - cat66121_hdmi = NULL; - dev_err(&client->dev, "cat66121 hdmi probe error\n"); - return rc; - -} - -static int cat66121_hdmi_i2c_remove(struct i2c_client *client) -{ - hdmi_dbg(hdmi->dev, "%s\n", __func__); - 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); - #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); - #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); - } - kfree(hdmi); - hdmi = NULL; - } - return 0; -} - -static void cat66121_hdmi_i2c_shutdown(struct i2c_client *client) -{ - if(hdmi) { - #ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&hdmi->early_suspend); - #endif - } - printk(KERN_INFO "cat66121 hdmi shut down.\n"); -} - -static const struct i2c_device_id cat66121_hdmi_id[] = { - { "cat66121_hdmi", 0 }, - { } -}; - -static struct i2c_driver cat66121_hdmi_i2c_driver = { - .driver = { - .name = "cat66121_hdmi", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(cat66121_dt_ids), - }, - .probe = cat66121_hdmi_i2c_probe, - .remove = cat66121_hdmi_i2c_remove, - .shutdown = cat66121_hdmi_i2c_shutdown, - .id_table = cat66121_hdmi_id, -}; - -static int __init cat66121_hdmi_init(void) -{ - return i2c_add_driver(&cat66121_hdmi_i2c_driver); -} - -static void __exit cat66121_hdmi_exit(void) -{ - i2c_del_driver(&cat66121_hdmi_i2c_driver); -} - -//module_init(cat66121_hdmi_init); -device_initcall_sync(cat66121_hdmi_init); -module_exit(cat66121_hdmi_exit); diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.h b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.h deleted file mode 100755 index 0896c39b9949..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __cat66121_HDMI_H__ -#define __cat66121_HDMI_H__ -#include "../../rk_hdmi.h" - -#if defined(CONFIG_HDMI_SOURCE_LCDC1) -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC1 -#else -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC0 -#endif - - -struct cat66121_hdmi_pdata { - int gpio; - struct i2c_client *client; - struct delayed_work delay_work; - struct workqueue_struct *workqueue; - int plug_status; -}; - -extern struct cat66121_hdmi_pdata *cat66121_hdmi; - -extern int cat66121_detect_device(void); -extern int cat66121_hdmi_sys_init(struct hdmi *hdmi_drv); -extern void cat66121_hdmi_interrupt(struct hdmi *hdmi_drv); -extern int cat66121_hdmi_sys_detect_hpd(struct hdmi *hdmi_drv); -extern int cat66121_hdmi_sys_insert(struct hdmi *hdmi_drv); -extern int cat66121_hdmi_sys_remove(struct hdmi *hdmi_drv); -extern int cat66121_hdmi_sys_read_edid(struct hdmi *hdmi_drv, int block, unsigned char *buff); -extern int cat66121_hdmi_sys_config_video(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara); -extern int cat66121_hdmi_sys_config_audio(struct hdmi *hdmi_drv,struct hdmi_audio *audio); -extern void cat66121_hdmi_sys_enalbe_output(struct hdmi *hdmi_drv, int enable); -extern int cat66121_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)); -#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.c deleted file mode 100755 index bcfe8c8ae47e..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.c +++ /dev/null @@ -1,712 +0,0 @@ -#include -#include "cat66121_hdmi.h" -#include "cat66121_hdmi_hw.h" -#include -//#include -//#include -#include "hdmitx.h" - -extern HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT] ; -#define HDMITX_INPUT_SIGNAL_TYPE 0 // for default(Sync Sep Mode) -#define INPUT_SPDIF_ENABLE 0 -/******************************* - * Global Data - ******************************/ -_XDATA unsigned char CommunBuff[128] ; -static unsigned int pixelrep; -static BYTE bInputColorMode = INPUT_COLOR_MODE; -static char bOutputColorMode = F_MODE_RGB444; -#ifdef SUPPORT_HDCP -static void hdcp_delay_work_func(struct work_struct *work); -static DECLARE_DELAYED_WORK(hdcp_delay_work,hdcp_delay_work_func); -#endif -static DEFINE_MUTEX(handler_mutex); - -HDMITXDEV InstanceData = -{ - - 0, // BYTE I2C_DEV ; - HDMI_TX_I2C_SLAVE_ADDR, // BYTE I2C_ADDR ; - - ///////////////////////////////////////////////// - // Interrupt Type - ///////////////////////////////////////////////// - 0x40, // BYTE bIntType ; // = 0 ; - ///////////////////////////////////////////////// - // Video Property - ///////////////////////////////////////////////// - INPUT_SIGNAL_TYPE ,// BYTE bInputVideoSignalType ; // for Sync Embedded,CCIR656,InputDDR - - ///////////////////////////////////////////////// - // Audio Property - ///////////////////////////////////////////////// - I2S_FORMAT, // BYTE bOutputAudioMode ; // = 0 ; - FALSE , // BYTE bAudioChannelSwap ; // = 0 ; - 0x01, // BYTE bAudioChannelEnable ; - INPUT_SAMPLE_FREQ ,// BYTE bAudFs ; - 0, // unsigned long TMDSClock ; - FALSE, // BYTE bAuthenticated:1 ; - FALSE, // BYTE bHDMIMode: 1; - FALSE, // BYTE bIntPOL:1 ; // 0 = Low Active - FALSE, // BYTE bHPD:1 ; -}; - -/* I2C read/write funcs */ -BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr) -{ - struct i2c_msg msgs[2]; - SYS_STATUS ret = -1; - BYTE buf[1]; - - buf[0] = RegAddr; - - /* Write device addr fisrt */ - msgs[0].addr = cat66121_hdmi->client->addr; - msgs[0].flags = !I2C_M_RD; - msgs[0].len = 1; - msgs[0].buf = &buf[0]; - msgs[0].scl_rate= 100*1000; - /* Then, begin to read data */ - msgs[1].addr = cat66121_hdmi->client->addr; - msgs[1].flags = I2C_M_RD; - msgs[1].len = 1; - msgs[1].buf = &buf[0]; - msgs[1].scl_rate= 100*1000; - - ret = i2c_transfer(cat66121_hdmi->client->adapter, msgs, 2); - if(ret != 2) - printk("I2C transfer Error! ret = %d\n", ret); - - //ErrorF("Reg%02xH: 0x%02x\n", RegAddr, buf[0]); - return buf[0]; -} - -SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr, BYTE data) -{ - struct i2c_msg msg; - SYS_STATUS ret = -1; - BYTE buf[2]; - - buf[0] = RegAddr; - buf[1] = data; - - msg.addr = cat66121_hdmi->client->addr; - msg.flags = !I2C_M_RD; - msg.len = 2; - msg.buf = buf; - msg.scl_rate= 100*1000; - - ret = i2c_transfer(cat66121_hdmi->client->adapter, &msg, 1); - if(ret != 1) - printk("I2C transfer Error!\n"); - - return ret; -} - -SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr, BYTE *pData, int N) -{ - struct i2c_msg msgs[2]; - SYS_STATUS ret = -1; - - pData[0] = RegAddr; - - msgs[0].addr = cat66121_hdmi->client->addr; - msgs[0].flags = !I2C_M_RD; - msgs[0].len = 1; - msgs[0].buf = &pData[0]; - msgs[0].scl_rate= 100*1000; - - msgs[1].addr = cat66121_hdmi->client->addr; - msgs[1].flags = I2C_M_RD; - msgs[1].len = N; - msgs[1].buf = pData; - msgs[1].scl_rate= 100*1000; - - ret = i2c_transfer(cat66121_hdmi->client->adapter, msgs, 2); - if(ret != 2) - printk("I2C transfer Error! ret = %d\n", ret); - - return ret; -} - -SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr, BYTE *pData, int N) -{ - struct i2c_msg msg; - SYS_STATUS ret = -1; - BYTE buf[N + 1]; - - buf[0] = RegAddr; - memcpy(&buf[1], pData, N); - - msg.addr = cat66121_hdmi->client->addr; - msg.flags = !I2C_M_RD; - msg.len = N + 1; - msg.buf = buf; // gModify.Exp."Include RegAddr" - msg.scl_rate= 100*1000; - - ret = i2c_transfer(cat66121_hdmi->client->adapter, &msg, 1); - if(ret != 1) - printk("I2C transfer Error! ret = %d\n", ret); - - return ret; -} -SYS_STATUS HDMITX_SetI2C_Byte(BYTE Reg,BYTE Mask,BYTE Value) -{ - BYTE Temp; - if( Mask != 0xFF ) - { - Temp=HDMITX_ReadI2C_Byte(Reg); - Temp&=(~Mask); - Temp|=Value&Mask; - } - else - { - Temp=Value; - } - return HDMITX_WriteI2C_Byte(Reg,Temp); -} - -int cat66121_detect_device(void) -{ - uint8_t VendorID0, VendorID1, DeviceID0, DeviceID1; - - Switch_HDMITX_Bank(0); - VendorID0 = HDMITX_ReadI2C_Byte(REG_TX_VENDOR_ID0); - VendorID1 = HDMITX_ReadI2C_Byte(REG_TX_VENDOR_ID1); - DeviceID0 = HDMITX_ReadI2C_Byte(REG_TX_DEVICE_ID0); - DeviceID1 = HDMITX_ReadI2C_Byte(REG_TX_DEVICE_ID1); - printk("CAT66121: Reg[0-3] = 0x[%02x].[%02x].[%02x].[%02x]\n", - VendorID0, VendorID1, DeviceID0, DeviceID1); - if( (VendorID0 == 0x54) && (VendorID1 == 0x49)) - // &&(DeviceID0 == 0x12) && (DeviceID1 == 0x16) ) - return 1; - - printk("[CAT66121] Device not found!\n"); - - return 0; -} -int cat66121_hdmi_sys_init(struct hdmi *hdmi_drv) -{ - hdmi_dbg(hdmi_drv->dev, "[%s]\n", __FUNCTION__); - HDMITX_InitTxDev(&InstanceData); - InitHDMITX(); - msleep(1); - return HDMI_ERROR_SUCESS; -} - -#ifdef SUPPORT_HDCP -static void hdcp_delay_work_func(struct work_struct *work) -{ - if(0==(B_TXVIDSTABLE&HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS))) - { - schedule_delayed_work(&hdcp_delay_work, msecs_to_jiffies(100)); - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate(): Video not stable\n")); - }else{ - HDMITX_EnableHDCP(TRUE); - } -} -#endif -void cat66121_InterruptClr(void) -{ - char intclr3,intdata4; - intdata4= HDMITX_ReadI2C_Byte(0xEE); - HDMITX_DEBUG_PRINTF(("REG_TX_INT_STAT4=%x \n",intdata4)); - intclr3 = (HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS))|B_TX_CLR_AUD_CTS | B_TX_INTACTDONE ; - if( intdata4 ) - { - HDMITX_WriteI2C_Byte(0xEE,intdata4); // clear ext interrupt ; - HDMITX_DEBUG_PRINTF(("%s%s%s%s%s%s%s\n", - (intdata4&0x40)?"video parameter change \n":"", - (intdata4&0x20)?"HDCP Pj check done \n":"", - (intdata4&0x10)?"HDCP Ri check done \n":"", - (intdata4&0x8)? "DDC bus hang \n":"", - (intdata4&0x4)? "Video input FIFO auto reset \n":"", - (intdata4&0x2)? "No audio input interrupt \n":"", - (intdata4&0x1)? "Audio decode error interrupt \n":"")); - } - - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,0xFF); - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0xFF); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,intclr3); // clear interrupt. - intclr3 &= ~(B_TX_INTACTDONE); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,intclr3); // INTACTDONE reset to zero. -} -void cat66121_hdmi_interrupt(struct hdmi *hdmi_drv) -{ - char sysstat = 0; - mutex_lock(&handler_mutex); - sysstat = HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS); - if((sysstat & B_TX_INT_ACTIVE) || ((B_TX_HPDETECT & cat66121_hdmi->plug_status) != (B_TX_HPDETECT & sysstat))) { - char intdata1,intdata2,intdata3; - intdata1 = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1); - intdata2 = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT2); - intdata3 = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT3); - HDMITX_DEBUG_PRINTF(("REG_TX_INT_STAT1=%x \n",intdata1)); - HDMITX_DEBUG_PRINTF(("REG_TX_INT_STAT2=%x \n",intdata2)); - HDMITX_DEBUG_PRINTF(("REG_TX_INT_STAT3=%x \n",intdata3)); - if(getHDMI_PowerStatus()==FALSE){ - HDMITX_PowerOn(); - } - - /******* Clear interrupt **********/ - cat66121_InterruptClr(); - /******** handler interrupt event ********/ - - if(intdata1 & B_TX_INT_DDCFIFO_ERR) - { - HDMITX_DEBUG_PRINTF(("DDC FIFO Error.\n")); - hdmitx_ClearDDCFIFO(); - } - if(intdata1 & B_TX_INT_DDC_BUS_HANG) - { - HDMITX_DEBUG_PRINTF(("DDC BUS HANG.\n")); - hdmitx_AbortDDC(); -#ifdef SUPPORT_HDCP - if(hdmiTxDev[0].bAuthenticated) - { - HDMITX_DEBUG_PRINTF(("when DDC hang,and aborted DDC,the HDCP authentication need to restart.\n")); - hdmitx_hdcp_ResumeAuthentication(); - } -#endif - } - if(intdata1 & B_TX_INT_AUD_OVERFLOW ){ - HDMITX_DEBUG_PRINTF(("AUDIO FIFO OVERFLOW.\n")); - HDMITX_OrReg_Byte(REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST)); - HDMITX_AndReg_Byte(REG_TX_SW_RST,~(B_HDMITX_AUD_RST|B_TX_AREF_RST)); - } - - if(intdata3 & B_TX_INT_VIDSTABLE) - { - sysstat = HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS); - if(sysstat & B_TXVIDSTABLE) - { - hdmitx_FireAFE(); - } - } - -#ifdef SUPPORT_HDCP - if(intdata2 & B_TX_INT_AUTH_FAIL){ - hdmiTxDev[0].bAuthenticated = FALSE; - hdmitx_AbortDDC(); -#if 0 - if(getHDMITX_LinkStatus()) - { - // AudioModeDetect(); - if(getHDMITX_AuthenticationDone() ==FALSE) - { - HDMITX_DEBUG_PRINTF(("getHDMITX_AuthenticationDone() ==FALSE\n") ); - HDMITX_EnableHDCP(TRUE); - setHDMITX_AVMute(FALSE); - } - } -#endif - }else if(intdata2 & B_TX_INT_AUTH_DONE){ - HDMITX_SetI2C_Byte(REG_TX_INT_MASK2, B_TX_AUTH_DONE_MASK, B_TX_AUTH_DONE_MASK); - HDMITX_DEBUG_PRINTF(("getHDMITX_AuthenticationDone() ==SUCCESS\n") ); - } -#endif - if((intdata1 & B_TX_INT_HPD_PLUG)|| ((B_TX_HPDETECT & cat66121_hdmi->plug_status) != (B_TX_HPDETECT & sysstat))) { - hdmiTxDev[0].bAuthenticated = FALSE; - if(sysstat & B_TX_HPDETECT){ - HDMITX_DEBUG_PRINTF(("HPD plug\n") ); - }else{ - HDMITX_DEBUG_PRINTF(("HPD unplug\n") ); - } - cat66121_hdmi->plug_status = sysstat; - if(hdmi_drv->state == HDMI_SLEEP) - hdmi_drv->state = WAIT_HOTPLUG; - queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, msecs_to_jiffies(0)); - } - if(intdata1 & (B_TX_INT_RX_SENSE)) { - hdmiTxDev[0].bAuthenticated = FALSE; - } - } - -#ifdef SUPPORT_HDCP - if(hdmi_drv->display == HDMI_ENABLE) - { - if(getHDMITX_LinkStatus()) - { - // AudioModeDetect(); - if(getHDMITX_AuthenticationDone() ==FALSE) - { - HDMITX_DEBUG_PRINTF(("getHDMITX_AuthenticationDone() ==FALSE\n") ); - HDMITX_EnableHDCP(TRUE); - setHDMITX_AVMute(FALSE); - } - } - } -#endif - - mutex_unlock(&handler_mutex); -} - -int cat66121_hdmi_sys_detect_hpd(struct hdmi *hdmi_drv) -{ - char HPD= 0; - BYTE sysstat; - - -#ifdef SUPPORT_HDCP - if((cat66121_hdmi->plug_status != 0) && (cat66121_hdmi->plug_status != 1)) - cat66121_hdmi->plug_status = HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS); - - sysstat = cat66121_hdmi->plug_status; -#else - sysstat = HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS); -#endif - - HPD = ((sysstat & B_TX_HPDETECT) == B_TX_HPDETECT)?TRUE:FALSE; - if(HPD) - return HDMI_HPD_ACTIVED; - else - return HDMI_HPD_REMOVED; -} - -int cat66121_hdmi_sys_read_edid(struct hdmi *hdmi_drv, int block, unsigned char *buff) -{ - hdmi_dbg(hdmi_drv->dev, "[%s]\n", __FUNCTION__); - return (getHDMITX_EDIDBlock(block, buff) == TRUE)?HDMI_ERROR_SUCESS:HDMI_ERROR_FALSE; -} - -void ConfigfHdmiVendorSpecificInfoFrame(BYTE _3D_Stru) -{ - VendorSpecific_InfoFrame *VS_Info; - - VS_Info=(VendorSpecific_InfoFrame *)CommunBuff ; - - VS_Info->pktbyte.VS_HB[0] = VENDORSPEC_INFOFRAME_TYPE|0x80; - VS_Info->pktbyte.VS_HB[1] = VENDORSPEC_INFOFRAME_VER; - VS_Info->pktbyte.VS_HB[2] = (_3D_Stru == Side_by_Side)?6:5; - VS_Info->pktbyte.VS_DB[0] = 0x03; - VS_Info->pktbyte.VS_DB[1] = 0x0C; - VS_Info->pktbyte.VS_DB[2] = 0x00; - VS_Info->pktbyte.VS_DB[3] = 0x40; - switch(_3D_Stru) - { - case Side_by_Side: - case Frame_Pcaking: - case Top_and_Botton: - VS_Info->pktbyte.VS_DB[4] = (_3D_Stru<<4); - break; - default: - VS_Info->pktbyte.VS_DB[4] = (Frame_Pcaking<<4); - break ; - } - VS_Info->pktbyte.VS_DB[5] = 0x00; - HDMITX_EnableVSInfoFrame(TRUE,(BYTE *)VS_Info); -} - -static void cat66121_sys_config_avi(int VIC, int bOutputColorMode, int aspec, int Colorimetry, int pixelrep) -{ - AVI_InfoFrame *AviInfo; - //hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); - AviInfo = (AVI_InfoFrame *)CommunBuff ; - - AviInfo->pktbyte.AVI_HB[0] = AVI_INFOFRAME_TYPE|0x80 ; - AviInfo->pktbyte.AVI_HB[1] = AVI_INFOFRAME_VER ; - AviInfo->pktbyte.AVI_HB[2] = AVI_INFOFRAME_LEN ; - - switch(bOutputColorMode) - { - case F_MODE_YUV444: - // AviInfo->info.ColorMode = 2 ; - AviInfo->pktbyte.AVI_DB[0] = (2<<5)|(1<<4); - break ; - case F_MODE_YUV422: - // AviInfo->info.ColorMode = 1 ; - AviInfo->pktbyte.AVI_DB[0] = (1<<5)|(1<<4); - break ; - case F_MODE_RGB444: - default: - // AviInfo->info.ColorMode = 0 ; - AviInfo->pktbyte.AVI_DB[0] = (0<<5)|(1<<4); - break ; - } - AviInfo->pktbyte.AVI_DB[0] |= 0x02 ; - AviInfo->pktbyte.AVI_DB[1] = 8 ; - AviInfo->pktbyte.AVI_DB[1] |= (aspec != HDMI_16x9)?(1<<4):(2<<4); // 4:3 or 16:9 - AviInfo->pktbyte.AVI_DB[1] |= (Colorimetry != HDMI_ITU709)?(1<<6):(2<<6); // 4:3 or 16:9 - AviInfo->pktbyte.AVI_DB[2] = 0 ; - AviInfo->pktbyte.AVI_DB[3] = VIC ; - AviInfo->pktbyte.AVI_DB[4] = pixelrep & 3 ; - AviInfo->pktbyte.AVI_DB[5] = 0 ; - AviInfo->pktbyte.AVI_DB[6] = 0 ; - AviInfo->pktbyte.AVI_DB[7] = 0 ; - AviInfo->pktbyte.AVI_DB[8] = 0 ; - AviInfo->pktbyte.AVI_DB[9] = 0 ; - AviInfo->pktbyte.AVI_DB[10] = 0 ; - AviInfo->pktbyte.AVI_DB[11] = 0 ; - AviInfo->pktbyte.AVI_DB[12] = 0 ; - - HDMITX_EnableAVIInfoFrame(TRUE, (unsigned char *)AviInfo); - -} - -int cat66121_hdmi_sys_config_video(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara) -{ - struct fb_videomode *mode; - HDMI_Aspec aspec ; - HDMI_Colorimetry Colorimetry ; - VIDEOPCLKLEVEL level ; - - if(vpara == NULL) { - hdmi_err(hdmi_drv->dev, "[%s] input parameter error\n", __FUNCTION__); - return -1; - } - -#ifdef SUPPORT_HDCP - HDMITX_EnableHDCP(FALSE); -#endif - - // output Color mode -#ifndef DISABLE_HDMITX_CSC - switch(vpara->output_color) - { - case HDMI_COLOR_YCbCr444: - bOutputColorMode = F_MODE_YUV444 ; - break ; - case HDMI_COLOR_YCbCr422: - bOutputColorMode = F_MODE_YUV422 ; - break ; - case HDMI_COLOR_RGB: - default: - bOutputColorMode = F_MODE_RGB444 ; - break ; - } -#else - bOutputColorMode = F_MODE_RGB444 ; -#endif - - // Set ext video - mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); - if(mode == NULL) - { - hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic); - return -ENOENT; - } - - hdmi_drv->tmdsclk = mode->pixclock; - switch(vpara->vic) - { - case HDMI_640x480p60: - pixelrep = 0 ; - aspec = HDMI_4x3 ; - Colorimetry = HDMI_ITU601 ; - break ; - case HDMI_480p60: - pixelrep = 0 ; - aspec = HDMI_4x3 ; - Colorimetry = HDMI_ITU601 ; - break ; - case HDMI_480p60_16x9: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU601 ; - break ; - case HDMI_720p60: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - break ; - case HDMI_1080i60: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - break ; - case HDMI_480i60: - pixelrep = 1 ; - aspec = HDMI_4x3 ; - Colorimetry = HDMI_ITU601 ; - break ; - case HDMI_480i60_16x9: - pixelrep = 1 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU601 ; - break ; - case HDMI_1080p60: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - break ; - case HDMI_576p50: - pixelrep = 0 ; - aspec = HDMI_4x3 ; - Colorimetry = HDMI_ITU601 ; - break ; - case HDMI_576p50_16x9: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU601 ; - break ; - case HDMI_720p50: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - break ; - case HDMI_1080i50: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - break ; - case HDMI_576i50: - pixelrep = 1 ; - aspec = HDMI_4x3 ; - Colorimetry = HDMI_ITU601 ; - break ; - case HDMI_576i50_16x9: - pixelrep = 1 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU601 ; - break ; - case HDMI_1080p50: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - break ; - case HDMI_1080p24: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - break ; - case HDMI_1080p25: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - break ; - case HDMI_1080p30: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - break ; - - case HDMI_720p30: - pixelrep = 0 ; - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - default: - aspec = HDMI_16x9 ; - Colorimetry = HDMI_ITU709 ; - } - if( Colorimetry == HDMI_ITU709 ) - { - bInputColorMode |= F_VIDMODE_ITU709 ; - } - else - { - bInputColorMode &= ~F_VIDMODE_ITU709 ; - } - if( vpara->vic != HDMI_640x480p60) - { - bInputColorMode |= F_VIDMODE_16_235 ; - } - else - { - bInputColorMode &= ~F_VIDMODE_16_235 ; - } - - if( (hdmi_drv->tmdsclk*(pixelrep+1))>80000000L ) - { - level = PCLK_HIGH ; - } - else if((hdmi_drv->tmdsclk*(pixelrep+1))>20000000L) - { - level = PCLK_MEDIUM ; - } - else - { - level = PCLK_LOW ; - } - - HDMITX_EnableVideoOutput(level,bInputColorMode,bOutputColorMode ,vpara->output_mode); - - if(vpara->output_mode == OUTPUT_HDMI) { - cat66121_sys_config_avi(vpara->vic, bOutputColorMode, aspec, Colorimetry, pixelrep); -#ifdef OUTPUT_3D_MODE - ConfigfHdmiVendorSpecificInfoFrame(OUTPUT_3D_MODE); -#endif - - } - else { - HDMITX_EnableAVIInfoFrame(FALSE ,NULL); - HDMITX_EnableVSInfoFrame(FALSE,NULL); - } - setHDMITX_VideoSignalType(INPUT_SIGNAL_TYPE); -#ifdef SUPPORT_SYNCEMBEDDED - if(INPUT_SIGNAL_TYPE & T_MODE_SYNCEMB) - { - setHDMITX_SyncEmbeddedByVIC(vpara->vic,INPUT_SIGNAL_TYPE); - } -#endif - - return HDMI_ERROR_SUCESS; -} - -static void cat66121_hdmi_config_aai(void) -{ - int i ; - Audio_InfoFrame *AudioInfo ; - AudioInfo = (Audio_InfoFrame *)CommunBuff ; - - AudioInfo->pktbyte.AUD_HB[0] = AUDIO_INFOFRAME_TYPE ; - AudioInfo->pktbyte.AUD_HB[1] = 1 ; - AudioInfo->pktbyte.AUD_HB[2] = AUDIO_INFOFRAME_LEN ; - AudioInfo->pktbyte.AUD_DB[0] = 1 ; - for( i = 1 ;i < AUDIO_INFOFRAME_LEN ; i++ ) - { - AudioInfo->pktbyte.AUD_DB[i] = 0 ; - } - HDMITX_EnableAudioInfoFrame(TRUE, (unsigned char *)AudioInfo); -} - -int cat66121_hdmi_sys_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio) -{ - cat66121_hdmi_config_aai(); - HDMITX_EnableAudioOutput( - CNOFIG_INPUT_AUDIO_TYPE, - CONFIG_INPUT_AUDIO_SPDIF, - INPUT_SAMPLE_FREQ_HZ, - audio->channel, - NULL, // pointer to cahnnel status. - hdmi_drv->tmdsclk*(pixelrep+1)); - return HDMI_ERROR_SUCESS; -} - -void cat66121_hdmi_sys_enalbe_output(struct hdmi *hdmi_drv, int enable) -{ - hdmi_dbg(hdmi_drv->dev, "[%s]\n", __FUNCTION__); - - if(enable){ -#if 0//def SUPPORT_HDCP - cancel_delayed_work_sync(&hdcp_delay_work); - schedule_delayed_work(&hdcp_delay_work, msecs_to_jiffies(100)); -#endif - setHDMITX_AVMute(FALSE); - }else{ - setHDMITX_AVMute(TRUE); - } - DumpHDMITXReg() ; -} - -int cat66121_hdmi_sys_insert(struct hdmi *hdmi_drv) -{ - hdmi_dbg(hdmi_drv->dev, "[%s]\n", __FUNCTION__); - if(getHDMI_PowerStatus()==FALSE) - HDMITX_PowerOn(); - - HDMITX_DisableAudioOutput(); - return 0; -} - -int cat66121_hdmi_sys_remove(struct hdmi *hdmi_drv) -{ - hdmi_dbg(hdmi_drv->dev, "[%s]\n", __FUNCTION__); -#if 0//def SUPPORT_HDCP - cancel_delayed_work_sync(&hdcp_delay_work); - HDMITX_EnableHDCP(FALSE); -#endif - HDMITX_DisableVideoOutput(); - if(getHDMI_PowerStatus()==TRUE) - HDMITX_PowerDown(); - return 0; -} diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.h deleted file mode 100755 index e8775d02ee77..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.h +++ /dev/null @@ -1,265 +0,0 @@ -#ifndef _CAT6611_HDMI_HW_H -#define _CAT6611_HDMI_HW_H - -#include "typedef.h" -#include "config.h" -#include "debug.h" -#include "hdmitx_drv.h" -#define CAT6611_SCL_RATE 100 * 1000 -#define I2S 0 -#define SPDIF 1 - -#ifndef I2S_FORMAT -#define I2S_FORMAT 0x01 // 32bit audio -#endif - -#ifndef INPUT_SAMPLE_FREQ - #define INPUT_SAMPLE_FREQ AUDFS_48KHz -#endif //INPUT_SAMPLE_FREQ - -#ifndef INPUT_SAMPLE_FREQ_HZ - #define INPUT_SAMPLE_FREQ_HZ 44100L -#endif //INPUT_SAMPLE_FREQ_HZ - -#ifndef OUTPUT_CHANNEL - #define OUTPUT_CHANNEL 2 -#endif //OUTPUT_CHANNEL - -#ifndef CNOFIG_INPUT_AUDIO_TYPE - #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_LPCM - // #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_NLPCM - // #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_HBR -#endif //CNOFIG_INPUT_AUDIO_TYPE - -#ifndef CONFIG_INPUT_AUDIO_SPDIF - #define CONFIG_INPUT_AUDIO_SPDIF I2S - // #define CONFIG_INPUT_AUDIO_SPDIF SPDIF -#endif //CONFIG_INPUT_AUDIO_SPDIF - -#ifndef INPUT_SIGNAL_TYPE -#define INPUT_SIGNAL_TYPE 0 // 24 bit sync seperate -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Internal Data Type -//////////////////////////////////////////////////////////////////////////////// -enum { - OUTPUT_DVI = 0, - OUTPUT_HDMI - }; -typedef enum tagHDMI_Video_Type { - HDMI_Unkown = 0 , - HDMI_640x480p60 = 1 , - HDMI_480p60, - HDMI_480p60_16x9, - HDMI_720p60, - HDMI_1080i60, - HDMI_480i60, - HDMI_480i60_16x9, - HDMI_1080p60 = 16, - HDMI_576p50, - HDMI_576p50_16x9, - HDMI_720p50, - HDMI_1080i50, - HDMI_576i50, - HDMI_576i50_16x9, - HDMI_1080p50 = 31, - HDMI_1080p24, - HDMI_1080p25, - HDMI_1080p30, - HDMI_720p30 = 61, -} HDMI_Video_Type ; - -typedef enum tagHDMI_Aspec { - HDMI_4x3 , - HDMI_16x9 -} HDMI_Aspec; - -typedef enum tagHDMI_OutputColorMode { - HDMI_RGB444, - HDMI_YUV444, - HDMI_YUV422 -} HDMI_OutputColorMode ; - -typedef enum tagHDMI_Colorimetry { - HDMI_ITU601, - HDMI_ITU709 -} HDMI_Colorimetry ; - -struct VideoTiming { - ULONG VideoPixelClock ; - BYTE VIC ; - BYTE pixelrep ; - BYTE outputVideoMode ; -} ; - - - -typedef enum _TXVideo_State_Type { - TXVSTATE_Unplug = 0, - TXVSTATE_HPD, - TXVSTATE_WaitForMode, - TXVSTATE_WaitForVStable, - TXVSTATE_VideoInit, - TXVSTATE_VideoSetup, - TXVSTATE_VideoOn, - TXVSTATE_Reserved -} TXVideo_State_Type ; - - -typedef enum _TXAudio_State_Type { - TXASTATE_AudioOff = 0, - TXASTATE_AudioPrepare, - TXASTATE_AudioOn, - TXASTATE_AudioFIFOFail, - TXASTATE_Reserved -} TXAudio_State_Type ; -///////////////////////////////////////// -// RX Capability. -///////////////////////////////////////// -typedef struct { - BYTE b16bit:1 ; - BYTE b20bit:1 ; - BYTE b24bit:1 ; - BYTE Rsrv:5 ; -} LPCM_BitWidth ; - -typedef enum { - AUD_RESERVED_0 = 0 , - AUD_LPCM, - AUD_AC3, - AUD_MPEG1, - AUD_MP3, - AUD_MPEG2, - AUD_AAC, - AUD_DTS, - AUD_ATRAC, - AUD_ONE_BIT_AUDIO, - AUD_DOLBY_DIGITAL_PLUS, - AUD_DTS_HD, - AUD_MAT_MLP, - AUD_DST, - AUD_WMA_PRO, - AUD_RESERVED_15 -} AUDIO_FORMAT_CODE ; - -typedef union { - struct { - BYTE channel:3 ; - BYTE AudioFormatCode:4 ; - BYTE Rsrv1:1 ; - - BYTE b32KHz:1 ; - BYTE b44_1KHz:1 ; - BYTE b48KHz:1 ; - BYTE b88_2KHz:1 ; - BYTE b96KHz:1 ; - BYTE b176_4KHz:1 ; - BYTE b192KHz:1 ; - BYTE Rsrv2:1 ; - BYTE ucCode ; - } s ; - BYTE uc[3] ; -} AUDDESCRIPTOR ; - -typedef union { - struct { - BYTE FL_FR:1 ; - BYTE LFE:1 ; - BYTE FC:1 ; - BYTE RL_RR:1 ; - BYTE RC:1 ; - BYTE FLC_FRC:1 ; - BYTE RLC_RRC:1 ; - BYTE Reserve:1 ; - BYTE Unuse[2] ; - } s ; - BYTE uc[3] ; -} SPK_ALLOC ; - -#define CEA_SUPPORT_UNDERSCAN (1<<7) -#define CEA_SUPPORT_AUDIO (1<<6) -#define CEA_SUPPORT_YUV444 (1<<5) -#define CEA_SUPPORT_YUV422 (1<<4) -#define CEA_NATIVE_MASK 0xF - - -#define HDMI_DC_SUPPORT_AI (1<<7) -#define HDMI_DC_SUPPORT_48 (1<<6) -#define HDMI_DC_SUPPORT_36 (1<<5) -#define HDMI_DC_SUPPORT_30 (1<<4) -#define HDMI_DC_SUPPORT_Y444 (1<<3) -#define HDMI_DC_SUPPORT_DVI_DUAL 1 - -typedef union _tag_DCSUPPORT { - struct { - BYTE DVI_Dual:1 ; - BYTE Rsvd:2 ; - BYTE DC_Y444:1 ; - BYTE DC_30Bit:1 ; - BYTE DC_36Bit:1 ; - BYTE DC_48Bit:1 ; - BYTE SUPPORT_AI:1 ; - } info ; - BYTE uc ; -} DCSUPPORT ; - -typedef union _LATENCY_SUPPORT{ - struct { - BYTE Rsvd:6 ; - BYTE I_Latency_Present:1 ; - BYTE Latency_Present:1 ; - } info ; - BYTE uc ; -} LATENCY_SUPPORT ; - -#define HDMI_IEEEOUI 0x0c03 -#define MAX_VODMODE_COUNT 32 -#define MAX_AUDDES_COUNT 4 - -typedef struct _RX_CAP{ - BYTE VideoMode ; - BYTE NativeVDOMode ; - BYTE VDOMode[8] ; - BYTE AUDDesCount ; - AUDDESCRIPTOR AUDDes[MAX_AUDDES_COUNT] ; - BYTE PA[2] ; - ULONG IEEEOUI ; - DCSUPPORT dc ; - BYTE MaxTMDSClock ; - LATENCY_SUPPORT lsupport ; - SPK_ALLOC SpeakerAllocBlk ; - BYTE ValidCEA:1 ; - BYTE ValidHDMI:1 ; - BYTE Valid3D:1 ; -} RX_CAP ; - -/////////////////////////////////////////////////////////////////////// -// Output Mode Type -/////////////////////////////////////////////////////////////////////// - -#define RES_ASPEC_4x3 0 -#define RES_ASPEC_16x9 1 -#define F_MODE_REPT_NO 0 -#define F_MODE_REPT_TWICE 1 -#define F_MODE_REPT_QUATRO 3 -#define F_MODE_CSC_ITU601 0 -#define F_MODE_CSC_ITU709 1 - -BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr); -SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr,BYTE d); -SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr,BYTE *pData,int N); -SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr,BYTE *pData,int N); -SYS_STATUS HDMITX_SetI2C_Byte(BYTE Reg,BYTE Mask,BYTE Value); - -void InitHDMITX_Variable(void); -#if 0 -//void HDMITX_ChangeDisplayOption(HDMI_Video_Type VideoMode, HDMI_OutputColorMode OutputColorMode); -//void HDMITX_SetOutput(); -//int HDMITX_DevLoopProc(); -//void ConfigfHdmiVendorSpecificInfoFrame(BYTE _3D_Stru); -void HDMITX_ChangeAudioOption(BYTE Option, BYTE channelNum, BYTE AudioFs); -void HDMITX_SetAudioOutput(); -void HDMITX_ChangeColorDepth(BYTE colorDepth); -#endif -#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/config.h b/drivers/video/rockchip/hdmi/chips/cat66121/config.h deleted file mode 100755 index fa50fb20c999..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/config.h +++ /dev/null @@ -1,140 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ -#ifndef _CONFIG_H_ -#define _CONFIG_H_ -//#pragma message("config.h") - -#ifdef EXTERN_HDCPROM -#pragma message("Defined EXTERN_HDCPROM") -#endif // EXTERN_HDCPROM - -#define SUPPORT_EDID -//#define SUPPORT_AUDIO_MONITOR -#define AudioOutDelayCnt 250 - -#ifdef CONFIG_SUPPORT_HDCP -#define SUPPORT_HDCP -#define SUPPORT_SHA -#endif - - -////////////////////////////////////////////////////////////////////////////////////////// -// Video Configuration -////////////////////////////////////////////////////////////////////////////////////////// -// 2010/01/26 added a option to disable HDCP. -#define SUPPORT_OUTPUTYUV -#define SUPPORT_OUTPUTRGB -#define DISABLE_HDMITX_CSC - -#define SUPPORT_INPUTRGB -#define SUPPORT_INPUTYUV444 -#define SUPPORT_INPUTYUV422 -// #define SUPPORT_SYNCEMBEDDED -// #define SUPPORT_DEGEN -#define NON_SEQUENTIAL_YCBCR422 - - - -#define INPUT_COLOR_MODE F_MODE_RGB444 -//#define INPUT_COLOR_MODE F_MODE_YUV422 -//#define INPUT_COLOR_MODE F_MODE_YUV444 - -#define INPUT_COLOR_DEPTH 24 -// #define INPUT_COLOR_DEPTH 30 -// #define INPUT_COLOR_DEPTH 36 - -//#define OUTPUT_COLOR_MODE F_MODE_YUV422 -//#define OUTPUT_COLOR_MODE F_MODE_YUV444 -#define OUTPUT_COLOR_MODE F_MODE_RGB444 - -//#define OUTPUT_3D_MODE Frame_Pcaking -//#define OUTPUT_3D_MODE Top_and_Botton -//#define OUTPUT_3D_MODE Side_by_Side - -// #define INV_INPUT_ACLK -#define INV_INPUT_PCLK - -#ifdef SUPPORT_SYNCEMBEDDED - // #define INPUT_SIGNAL_TYPE (T_MODE_SYNCEMB) // 16 bit sync embedded - // #define INPUT_SIGNAL_TYPE (T_MODE_SYNCEMB | T_MODE_CCIR656) // 8 bit sync embedded - #define INPUT_SIGNAL_TYPE (T_MODE_SYNCEMB|T_MODE_INDDR|T_MODE_PCLKDIV2) // 16 bit sync embedded DDR - // #define INPUT_SIGNAL_TYPE (T_MODE_SYNCEMB|T_MODE_INDDR) // 8 bit sync embedded DDR - - #define SUPPORT_INPUTYUV422 - #ifdef INPUT_COLOR_MODE - #undef INPUT_COLOR_MODE - #endif // INPUT_COLOR_MODE - #define INPUT_COLOR_MODE F_MODE_YUV422 -#else -// #pragma message ("Defined seperated sync.") - #define INPUT_SIGNAL_TYPE 0 // 24 bit sync seperate - //#define INPUT_SIGNAL_TYPE ( T_MODE_DEGEN ) - //#define INPUT_SIGNAL_TYPE ( T_MODE_INDDR) - //#define INPUT_SIGNAL_TYPE ( T_MODE_SYNCEMB) - //#define INPUT_SIGNAL_TYPE ( T_MODE_CCIR656 | T_MODE_SYNCEMB ) -#endif - - -#if defined(SUPPORT_INPUTYUV444) || defined(SUPPORT_INPUTYUV422) -#define SUPPORT_INPUTYUV -#endif - -#ifdef SUPPORT_SYNCEMBEDDED -#pragma message("defined SUPPORT_SYNCEMBEDDED for Sync Embedded timing input or CCIR656 input.") -#endif - - -////////////////////////////////////////////////////////////////////////////////////////// -// Audio Configuration -////////////////////////////////////////////////////////////////////////////////////////// - -// #define SUPPORT_HBR_AUDIO -#define USE_SPDIF_CHSTAT -#ifndef SUPPORT_HBR_AUDIO - #define INPUT_SAMPLE_FREQ AUDFS_48KHz - #define INPUT_SAMPLE_FREQ_HZ 44100L - #define OUTPUT_CHANNEL 2 // 3 // 4 // 5//6 //7 //8 - - #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_LPCM - // #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_NLPCM - #define CONFIG_INPUT_AUDIO_SPDIF FALSE // I2S - // #define CONFIG_INPUT_AUDIO_SPDIF TRUE // SPDIF - - // #define I2S_FORMAT 0x00 // 24bit I2S audio - #define I2S_FORMAT 0x01 // 32bit I2S audio - // #define I2S_FORMAT 0x02 // 24bit I2S audio, right justify - // #define I2S_FORMAT 0x03 // 32bit I2S audio, right justify - -#else // SUPPORT_HBR_AUDIO - - #define INPUT_SAMPLE_FREQ AUDFS_768KHz - #define INPUT_SAMPLE_FREQ_HZ 768000L - #define OUTPUT_CHANNEL 8 - #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_HBR - #define CONFIG_INPUT_AUDIO_SPDIF FALSE // I2S - // #define CONFIG_INPUT_AUDIO_SPDIF TRUE // SPDIF - #define I2S_FORMAT 0x47 // 32bit audio -#endif - - - -////////////////////////////////////////////////////////////////////////////////////////// -// Audio Monitor Configuration -////////////////////////////////////////////////////////////////////////////////////////// -// #define HDMITX_AUTO_MONITOR_INPUT -// #define HDMITX_INPUT_INFO - -#ifdef HDMITX_AUTO_MONITOR_INPUT -#define HDMITX_INPUT_INFO -#endif - - -#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/csc.c b/drivers/video/rockchip/hdmi/chips/cat66121/csc.c deleted file mode 100755 index 6823a12dc2a4..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/csc.c +++ /dev/null @@ -1,83 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/01/06 -// @fileversion: COMMON_2.00 -//******************************************/ - -#include "config.h" -#include "typedef.h" - -#if (defined (SUPPORT_OUTPUTYUV)) && (defined (SUPPORT_INPUTRGB)) - - BYTE _CODE bCSCMtx_RGB2YUV_ITU601_16_235[] = - { - 0x00,0x80,0x00, - 0xB2,0x04,0x65,0x02,0xE9,0x00, - 0x93,0x3C,0x18,0x04,0x55,0x3F, - 0x49,0x3D,0x9F,0x3E,0x18,0x04 - } ; - - BYTE _CODE bCSCMtx_RGB2YUV_ITU601_0_255[] = - { - 0x10,0x80,0x10, - 0x09,0x04,0x0E,0x02,0xC9,0x00, - 0x0F,0x3D,0x84,0x03,0x6D,0x3F, - 0xAB,0x3D,0xD1,0x3E,0x84,0x03 - } ; - - BYTE _CODE bCSCMtx_RGB2YUV_ITU709_16_235[] = - { - 0x00,0x80,0x00, - 0xB8,0x05,0xB4,0x01,0x94,0x00, - 0x4a,0x3C,0x17,0x04,0x9F,0x3F, - 0xD9,0x3C,0x10,0x3F,0x17,0x04 - } ; - - BYTE _CODE bCSCMtx_RGB2YUV_ITU709_0_255[] = - { - 0x10,0x80,0x10, - 0xEa,0x04,0x77,0x01,0x7F,0x00, - 0xD0,0x3C,0x83,0x03,0xAD,0x3F, - 0x4B,0x3D,0x32,0x3F,0x83,0x03 - } ; -#endif - -#if (defined (SUPPORT_OUTPUTRGB)) && (defined (SUPPORT_INPUTYUV)) - - BYTE _CODE bCSCMtx_YUV2RGB_ITU601_16_235[] = - { - 0x00,0x00,0x00, - 0x00,0x08,0x6B,0x3A,0x50,0x3D, - 0x00,0x08,0xF5,0x0A,0x02,0x00, - 0x00,0x08,0xFD,0x3F,0xDA,0x0D - } ; - - BYTE _CODE bCSCMtx_YUV2RGB_ITU601_0_255[] = - { - 0x04,0x00,0xA7, - 0x4F,0x09,0x81,0x39,0xDD,0x3C, - 0x4F,0x09,0xC4,0x0C,0x01,0x00, - 0x4F,0x09,0xFD,0x3F,0x1F,0x10 - } ; - - BYTE _CODE bCSCMtx_YUV2RGB_ITU709_16_235[] = - { - 0x00,0x00,0x00, - 0x00,0x08,0x55,0x3C,0x88,0x3E, - 0x00,0x08,0x51,0x0C,0x00,0x00, - 0x00,0x08,0x00,0x00,0x84,0x0E - } ; - - BYTE _CODE bCSCMtx_YUV2RGB_ITU709_0_255[] = - { - 0x04,0x00,0xA7, - 0x4F,0x09,0xBA,0x3B,0x4B,0x3E, - 0x4F,0x09,0x57,0x0E,0x02,0x00, - 0x4F,0x09,0xFE,0x3F,0xE8,0x10 - } ; -#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/debug.h b/drivers/video/rockchip/hdmi/chips/cat66121/debug.h deleted file mode 100755 index 81211dadd4ea..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/debug.h +++ /dev/null @@ -1,107 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ -#ifndef _DEBUG_H_ -#define _DEBUG_H_ - -#ifdef CONFIG_RK_HDMI_DEBUG -#define Debug_message 1 -#else -#define Debug_message 0 -#endif - -//#pragma message("debug.h") - -#if Debug_message - - #define HDMITX_DEBUG_PRINTF(x) printk x - #define HDCP_DEBUG_PRINTF(x) printk x - #define EDID_DEBUG_PRINTF(x) printk x - #define HDMITX_DEBUG_INFO(x) printk x -#else - #define HDMITX_DEBUG_PRINTF(x) - #define HDCP_DEBUG_PRINTF(x) - #define EDID_DEBUG_PRINTF(x) - #define HDMITX_DEBUG_INFO(x) -#endif - - -#if( Debug_message & (1<<1)) - #define HDMITX_DEBUG_PRINTF1(x) printk x - #define HDCP_DEBUG_PRINTF1(x) printk x - #define EDID_DEBUG_PRINTF1(x) printk x -#else - #define HDMITX_DEBUG_PRINTF1(x) - #define HDCP_DEBUG_PRINTF1(x) - #define EDID_DEBUG_PRINTF1(x) -#endif - -#if( Debug_message & (1<<2)) - #define HDMITX_DEBUG_PRINTF2(x) printk x - #define HDCP_DEBUG_PRINTF2(x) printk x - #define EDID_DEBUG_PRINTF2(x) printk x -#else - #define HDMITX_DEBUG_PRINTF2(x) - #define HDCP_DEBUG_PRINTF2(x) - #define EDID_DEBUG_PRINTF2(x) -#endif - -#if( Debug_message & (1<<3)) - #define HDMITX_DEBUG_PRINTF3(x) printk x - #define HDCP_DEBUG_PRINTF3(x) printk x - #define EDID_DEBUG_PRINTF3(x) printk x -#else - #define HDMITX_DEBUG_PRINTF3(x) - #define HDCP_DEBUG_PRINTF3(x) - #define EDID_DEBUG_PRINTF3(x) -#endif - -#if( Debug_message & (1<<4)) - #define HDMITX_DEBUG_PRINTF4(x) printk x - #define HDCP_DEBUG_PRINTF4(x) printk x - #define EDID_DEBUG_PRINTF4(x) printk x -#else - #define HDMITX_DEBUG_PRINTF4(x) - #define HDCP_DEBUG_PRINTF4(x) - #define EDID_DEBUG_PRINTF4(x) -#endif - -#if( Debug_message & (1<<5)) - #define HDMITX_DEBUG_PRINTF5(x) printk x - #define HDCP_DEBUG_PRINTF5(x) printk x - #define EDID_DEBUG_PRINTF5(x) printk x -#else - #define HDMITX_DEBUG_PRINTF5(x) - #define HDCP_DEBUG_PRINTF5(x) - #define EDID_DEBUG_PRINTF5(x) -#endif - -#if( Debug_message & (1<<6)) - #define HDMITX_DEBUG_PRINTF6(x) printk x - #define HDCP_DEBUG_PRINTF6(x) printk x - #define EDID_DEBUG_PRINTF6(x) printk x -#else - #define HDMITX_DEBUG_PRINTF6(x) - #define HDCP_DEBUG_PRINTF6(x) - #define EDID_DEBUG_PRINTF6(x) -#endif - -#if( Debug_message & (1<<7)) - #define HDMITX_DEBUG_PRINTF7(x) printk x - #define HDCP_DEBUG_PRINTF7(x) printk x - #define EDID_DEBUG_PRINTF7(x) printk x -#else - #define HDMITX_DEBUG_PRINTF7(x) - #define HDCP_DEBUG_PRINTF7(x) - #define EDID_DEBUG_PRINTF7(x) -#endif - - -#endif// _DEBUG_H_ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx.h b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx.h deleted file mode 100755 index ec2670e1f431..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx.h +++ /dev/null @@ -1,58 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ - -#ifndef _HDMITX_H_ -#define _HDMITX_H_ -#include -#include -#include -#include -#include - -#include "debug.h" -#include "config.h" -#include "typedef.h" -#include "hdmitx_drv.h" - -#define HDMITX_MAX_DEV_COUNT 1 - - -/////////////////////////////////////////////////////////////////////// -// Output Mode Type -/////////////////////////////////////////////////////////////////////// - -#define RES_ASPEC_4x3 0 -#define RES_ASPEC_16x9 1 -#define F_MODE_REPT_NO 0 -#define F_MODE_REPT_TWICE 1 -#define F_MODE_REPT_QUATRO 3 -#define F_MODE_CSC_ITU601 0 -#define F_MODE_CSC_ITU709 1 - - -#define TIMER_LOOP_LEN 10 -#define MS(x) (((x)+(TIMER_LOOP_LEN-1))/TIMER_LOOP_LEN); // for timer loop - -// #define SUPPORT_AUDI_AudSWL 16 // Jeilin case. -#define SUPPORT_AUDI_AudSWL 24 // Jeilin case. - -#if(SUPPORT_AUDI_AudSWL==16) - #define CHTSTS_SWCODE 0x02 -#elif(SUPPORT_AUDI_AudSWL==18) - #define CHTSTS_SWCODE 0x04 -#elif(SUPPORT_AUDI_AudSWL==20) - #define CHTSTS_SWCODE 0x03 -#else - #define CHTSTS_SWCODE 0x0B -#endif - -#endif // _HDMITX_H_ - diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.c b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.c deleted file mode 100755 index 9f59b1af63b5..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.c +++ /dev/null @@ -1,2624 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ - -///////////////////////////////////////////////////////////////////// -// HDMITX.C -// Driver code for platform independent -///////////////////////////////////////////////////////////////////// -#include "hdmitx.h" -#include "hdmitx_drv.h" -#define FALLING_EDGE_TRIGGER - -#define MSCOUNT 1000 -#define LOADING_UPDATE_TIMEOUT (3000/32) // 3sec -// USHORT u8msTimer = 0 ; -// USHORT TimerServF = TRUE ; - -////////////////////////////////////////////////////////////////////// -// Authentication status -////////////////////////////////////////////////////////////////////// - -// #define TIMEOUT_WAIT_AUTH MS(2000) - -HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT] ; - -#ifndef INV_INPUT_PCLK -#define PCLKINV 0 -#else -#define PCLKINV B_TX_VDO_LATCH_EDGE -#endif - -#ifndef INV_INPUT_ACLK - #define InvAudCLK 0 -#else - #define InvAudCLK B_TX_AUDFMT_FALL_EDGE_SAMPLE_WS -#endif - -#define INIT_CLK_HIGH -// #define INIT_CLK_LOW - -_CODE RegSetEntry HDMITX_Init_Table[] = { - - {0x0F, 0x40, 0x00}, - - {0x62, 0x08, 0x00}, - {0x64, 0x04, 0x00}, - {0x01,0x00,0x00},//idle(100); - - {0x04, 0x20, 0x20}, - {0x04, 0x1D, 0x1D}, - {0x01,0x00,0x00},//idle(100); - {0x0F, 0x01, 0x00}, // bank 0 ; - #ifdef INIT_CLK_LOW - {0x62, 0x90, 0x10}, - {0x64, 0x89, 0x09}, - {0x68, 0x10, 0x10}, - #endif - - {0xD1, 0x0E, 0x0C}, - {0x65, 0x03, 0x00}, - #ifdef NON_SEQUENTIAL_YCBCR422 // for ITE HDMIRX - {0x71, 0xFC, 0x1C}, - #else - {0x71, 0xFC, 0x18}, - #endif - - {0x8D, 0xFF, CEC_I2C_SLAVE_ADDR}, - {0x0F, 0x08, 0x08}, - - {0xF8,0xFF,0xC3}, - {0xF8,0xFF,0xA5}, - {0x20, 0x80, 0x80}, - {0x37, 0x01, 0x00}, - {0x20, 0x80, 0x00}, - {0xF8,0xFF,0xFF}, - - {0x59, 0xD8, 0x40|PCLKINV}, - {0xE1, 0x20, InvAudCLK}, - {0x05, 0xC0, 0x40}, - {REG_TX_INT_MASK1, 0xFF, ~(B_TX_RXSEN_MASK|B_TX_HPD_MASK)}, - {REG_TX_INT_MASK2, 0xFF, ~(B_TX_KSVLISTCHK_MASK|B_TX_AUTH_DONE_MASK|B_TX_AUTH_FAIL_MASK)}, - {REG_TX_INT_MASK3, 0xFF, ~(0x0)}, - {0x0C, 0xFF, 0xFF}, - {0x0D, 0xFF, 0xFF}, - {0x0E, 0x03, 0x03}, - - {0x0C, 0xFF, 0x00}, - {0x0D, 0xFF, 0x00}, - {0x0E, 0x02, 0x00}, - {0x09, 0x03, 0x00}, // Enable HPD and RxSen Interrupt - {0,0,0} -}; - -_CODE RegSetEntry HDMITX_DefaultVideo_Table[] = { - - //////////////////////////////////////////////////// - // Config default output format. - //////////////////////////////////////////////////// - {0x72, 0xff, 0x00}, - {0x70, 0xff, 0x00}, -#ifndef DEFAULT_INPUT_YCBCR -// GenCSC\RGB2YUV_ITU709_16_235.c - {0x72, 0xFF, 0x02}, - {0x73, 0xFF, 0x00}, - {0x74, 0xFF, 0x80}, - {0x75, 0xFF, 0x00}, - {0x76, 0xFF, 0xB8}, - {0x77, 0xFF, 0x05}, - {0x78, 0xFF, 0xB4}, - {0x79, 0xFF, 0x01}, - {0x7A, 0xFF, 0x93}, - {0x7B, 0xFF, 0x00}, - {0x7C, 0xFF, 0x49}, - {0x7D, 0xFF, 0x3C}, - {0x7E, 0xFF, 0x18}, - {0x7F, 0xFF, 0x04}, - {0x80, 0xFF, 0x9F}, - {0x81, 0xFF, 0x3F}, - {0x82, 0xFF, 0xD9}, - {0x83, 0xFF, 0x3C}, - {0x84, 0xFF, 0x10}, - {0x85, 0xFF, 0x3F}, - {0x86, 0xFF, 0x18}, - {0x87, 0xFF, 0x04}, -#else -// GenCSC\YUV2RGB_ITU709_16_235.c - {0x0F, 0x01, 0x00}, - {0x72, 0xFF, 0x03}, - {0x73, 0xFF, 0x00}, - {0x74, 0xFF, 0x80}, - {0x75, 0xFF, 0x00}, - {0x76, 0xFF, 0x00}, - {0x77, 0xFF, 0x08}, - {0x78, 0xFF, 0x53}, - {0x79, 0xFF, 0x3C}, - {0x7A, 0xFF, 0x89}, - {0x7B, 0xFF, 0x3E}, - {0x7C, 0xFF, 0x00}, - {0x7D, 0xFF, 0x08}, - {0x7E, 0xFF, 0x51}, - {0x7F, 0xFF, 0x0C}, - {0x80, 0xFF, 0x00}, - {0x81, 0xFF, 0x00}, - {0x82, 0xFF, 0x00}, - {0x83, 0xFF, 0x08}, - {0x84, 0xFF, 0x00}, - {0x85, 0xFF, 0x00}, - {0x86, 0xFF, 0x87}, - {0x87, 0xFF, 0x0E}, -#endif - // 2012/12/20 added by Keming's suggestion test - {0x88, 0xF0, 0x00}, - //~jauchih.tseng@ite.com.tw - {0x04, 0x08, 0x00}, - {0,0,0} -}; -_CODE RegSetEntry HDMITX_SetHDMI_Table[] = { - - //////////////////////////////////////////////////// - // Config default HDMI Mode - //////////////////////////////////////////////////// - {0xC0, 0x01, 0x01}, - {0xC1, 0x03, 0x03}, - {0xC6, 0x03, 0x03}, - {0,0,0} -}; - -_CODE RegSetEntry HDMITX_SetDVI_Table[] = { - - //////////////////////////////////////////////////// - // Config default HDMI Mode - //////////////////////////////////////////////////// - {0x0F, 0x01, 0x01}, - {0x58, 0xFF, 0x00}, - {0x0F, 0x01, 0x00}, - {0xC0, 0x01, 0x00}, - {0xC1, 0x03, 0x02}, - {0xC6, 0x03, 0x00}, - {0,0,0} -}; - -_CODE RegSetEntry HDMITX_DefaultAVIInfo_Table[] = { - - //////////////////////////////////////////////////// - // Config default avi infoframe - //////////////////////////////////////////////////// - {0x0F, 0x01, 0x01}, - {0x58, 0xFF, 0x10}, - {0x59, 0xFF, 0x08}, - {0x5A, 0xFF, 0x00}, - {0x5B, 0xFF, 0x00}, - {0x5C, 0xFF, 0x00}, - {0x5D, 0xFF, 0x57}, - {0x5E, 0xFF, 0x00}, - {0x5F, 0xFF, 0x00}, - {0x60, 0xFF, 0x00}, - {0x61, 0xFF, 0x00}, - {0x62, 0xFF, 0x00}, - {0x63, 0xFF, 0x00}, - {0x64, 0xFF, 0x00}, - {0x65, 0xFF, 0x00}, - {0x0F, 0x01, 0x00}, - {0xCD, 0x03, 0x03}, - {0,0,0} -}; -_CODE RegSetEntry HDMITX_DeaultAudioInfo_Table[] = { - - //////////////////////////////////////////////////// - // Config default audio infoframe - //////////////////////////////////////////////////// - {0x0F, 0x01, 0x01}, - {0x68, 0xFF, 0x00}, - {0x69, 0xFF, 0x00}, - {0x6A, 0xFF, 0x00}, - {0x6B, 0xFF, 0x00}, - {0x6C, 0xFF, 0x00}, - {0x6D, 0xFF, 0x71}, - {0x0F, 0x01, 0x00}, - {0xCE, 0x03, 0x03}, - - {0,0,0} -}; - -_CODE RegSetEntry HDMITX_Aud_CHStatus_LPCM_20bit_48Khz[] = -{ - {0x0F, 0x01, 0x01}, - {0x33, 0xFF, 0x00}, - {0x34, 0xFF, 0x18}, - {0x35, 0xFF, 0x00}, - {0x91, 0xFF, 0x00}, - {0x92, 0xFF, 0x00}, - {0x93, 0xFF, 0x01}, - {0x94, 0xFF, 0x00}, - {0x98, 0xFF, 0x02}, - {0x99, 0xFF, 0xDA}, - {0x0F, 0x01, 0x00}, - {0,0,0}//end of table -} ; - -_CODE RegSetEntry HDMITX_AUD_SPDIF_2ch_24bit[] = -{ - {0x0F, 0x11, 0x00}, - {0x04, 0x14, 0x04}, - {0xE0, 0xFF, 0xD1}, - {0xE1, 0xFF, 0x01}, - {0xE2, 0xFF, 0xE4}, - {0xE3, 0xFF, 0x10}, - {0xE4, 0xFF, 0x00}, - {0xE5, 0xFF, 0x00}, - {0x04, 0x14, 0x00}, - {0,0,0}//end of table -} ; - -_CODE RegSetEntry HDMITX_AUD_I2S_2ch_24bit[] = -{ - {0x0F, 0x11, 0x00}, - {0x04, 0x14, 0x04}, - {0xE0, 0xFF, 0xC1}, - {0xE1, 0xFF, 0x01}, - {0xE2, 0xFF, 0xE4}, - {0xE3, 0xFF, 0x00}, - {0xE4, 0xFF, 0x00}, - {0xE5, 0xFF, 0x00}, - {0x04, 0x14, 0x00}, - {0,0,0}//end of table -} ; - -_CODE RegSetEntry HDMITX_DefaultAudio_Table[] = { - - //////////////////////////////////////////////////// - // Config default audio output format. - //////////////////////////////////////////////////// - {0x0F, 0x21, 0x00}, - {0x04, 0x14, 0x04}, - {0xE0, 0xFF, 0xC1}, - {0xE1, 0xFF, 0x01}, - {0xE2, 0xFF, 0xE4}, - {0xE3, 0xFF, 0x00}, - {0xE4, 0xFF, 0x00}, - {0xE5, 0xFF, 0x00}, - {0x0F, 0x01, 0x01}, - {0x33, 0xFF, 0x00}, - {0x34, 0xFF, 0x18}, - {0x35, 0xFF, 0x00}, - {0x91, 0xFF, 0x00}, - {0x92, 0xFF, 0x00}, - {0x93, 0xFF, 0x01}, - {0x94, 0xFF, 0x00}, - {0x98, 0xFF, 0x02}, - {0x99, 0xFF, 0xDB}, - {0x0F, 0x01, 0x00}, - {0x04, 0x14, 0x00}, - - {0x00, 0x00, 0x00} // End of Table. -} ; - -_CODE RegSetEntry HDMITX_PwrDown_Table[] = { - // Enable GRCLK - {0x0F, 0x40, 0x00}, - // PLL Reset - {0x61, 0x10, 0x10}, // DRV_RST - {0x62, 0x08, 0x00}, // XP_RESETB - {0x64, 0x04, 0x00}, // IP_RESETB - {0x01, 0x00, 0x00}, // idle(100); - - // PLL PwrDn - {0x61, 0x20, 0x20}, // PwrDn DRV - {0x62, 0x44, 0x44}, // PwrDn XPLL - {0x64, 0x40, 0x40}, // PwrDn IPLL - - // HDMITX PwrDn - {0x05, 0x01, 0x01}, // PwrDn PCLK - {0x0F, 0x78, 0x78}, // PwrDn GRCLK - {0x00, 0x00, 0x00} // End of Table. -}; - -_CODE RegSetEntry HDMITX_PwrOn_Table[] = { - {0x0F, 0x78, 0x38}, // PwrOn GRCLK - {0x05, 0x01, 0x00}, // PwrOn PCLK - - // PLL PwrOn - {0x61, 0x20, 0x00}, // PwrOn DRV - {0x62, 0x44, 0x00}, // PwrOn XPLL - {0x64, 0x40, 0x00}, // PwrOn IPLL - - // PLL Reset OFF - {0x61, 0x10, 0x00}, // DRV_RST - {0x62, 0x08, 0x08}, // XP_RESETB - {0x64, 0x04, 0x04}, // IP_RESETB - {0x0F, 0x78, 0x08}, // PwrOn IACLK - {0x00, 0x00, 0x00} // End of Table. -}; - -#ifdef DETECT_VSYNC_CHG_IN_SAV -BOOL EnSavVSync = FALSE ; -#endif -static bool PowerStatus=FALSE; - -////////////////////////////////////////////////////////////////////// -// Function Prototype -////////////////////////////////////////////////////////////////////// -void hdmitx_LoadRegSetting(RegSetEntry table[]); - -void HDMITX_InitTxDev(HDMITXDEV *pInstance) -{ - if(pInstance && 0 < HDMITX_MAX_DEV_COUNT) - { - hdmiTxDev[0] = *pInstance ; - } -} - -void InitHDMITX() -{ - hdmitx_LoadRegSetting(HDMITX_Init_Table); -// HDMITX_WriteI2C_Byte(REG_TX_PLL_CTRL,0xff); - hdmiTxDev[0].bIntPOL = (hdmiTxDev[0].bIntType&B_TX_INTPOL_ACTH)?TRUE:FALSE ; - - // Avoid power loading in un play status. - ////////////////////////////////////////////////////////////////// - // Setup HDCP ROM - ////////////////////////////////////////////////////////////////// -#ifdef HDMITX_INPUT_INFO - hdmiTxDev[0].RCLK = CalcRCLK(); -#endif - hdmitx_LoadRegSetting(HDMITX_DefaultVideo_Table); - hdmitx_LoadRegSetting(HDMITX_SetHDMI_Table); - hdmitx_LoadRegSetting(HDMITX_DefaultAVIInfo_Table); - hdmitx_LoadRegSetting(HDMITX_DeaultAudioInfo_Table); - hdmitx_LoadRegSetting(HDMITX_Aud_CHStatus_LPCM_20bit_48Khz); - hdmitx_LoadRegSetting(HDMITX_AUD_SPDIF_2ch_24bit); - HDMITX_PowerDown(); - - HDMITX_DEBUG_PRINTF(( - "-----------------------------------------------------\n" - "Init HDMITX\n" - "-----------------------------------------------------\n")); - - DumpHDMITXReg(); -} - -BOOL getHDMITX_LinkStatus() -{ - if(B_TX_RXSENDETECT & HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS)) - { - if(0==HDMITX_ReadI2C_Byte(REG_TX_AFE_DRV_CTRL)) - { - //HDMITX_DEBUG_PRINTF(("getHDMITX_LinkStatus()!!\n") ); - return TRUE; - } - } - //HDMITX_DEBUG_PRINTF(("GetTMDS not Ready()!!\n") ); - - return FALSE; -} - -#if 0 -BYTE CheckHDMITX(BYTE *pHPD,BYTE *pHPDChange) -{ - BYTE intdata1,intdata2,intdata3,sysstat; - BYTE intclr3 = 0 ; - BYTE PrevHPD = hdmiTxDev[0].bHPD ; - BYTE HPD ; - sysstat = HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS); - // HDMITX_DEBUG_PRINTF(("REG_TX_SYS_STATUS = %X \n",sysstat)); - - if((sysstat & (B_TX_HPDETECT/*|B_TX_RXSENDETECT*/)) == (B_TX_HPDETECT/*|B_TX_RXSENDETECT*/)) - { - HPD = TRUE; - } - else - { - HPD = FALSE; - } - // CheckClockStable(sysstat); - // 2007/06/20 added by jj_tseng@chipadvanced.com - - if(pHPDChange) - { - *pHPDChange = (HPD!=PrevHPD)?TRUE:FALSE ; // default give pHPDChange value compared to previous HPD value. - - } - //~jj_tseng@chipadvanced.com 2007/06/20 - - if(HPD==FALSE) - { - hdmiTxDev[0].bAuthenticated = FALSE ; - } - if(sysstat & B_TX_INT_ACTIVE) - { - HDMITX_DEBUG_PRINTF(("REG_TX_SYS_STATUS = 0x%02X \n",(int)sysstat)); - - intdata1 = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1); - HDMITX_DEBUG_PRINTF(("INT_Handler: reg%X = %X\n",(int)REG_TX_INT_STAT1,(int)intdata1)); - if(intdata1 & B_TX_INT_AUD_OVERFLOW) - { - HDMITX_DEBUG_PRINTF(("B_TX_INT_AUD_OVERFLOW.\n")); - HDMITX_OrReg_Byte(REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST)); - HDMITX_AndReg_Byte(REG_TX_SW_RST,~(B_HDMITX_AUD_RST|B_TX_AREF_RST)); - //AudioDelayCnt=AudioOutDelayCnt; - //LastRefaudfreqnum=0; - } - if(intdata1 & B_TX_INT_DDCFIFO_ERR) - { - HDMITX_DEBUG_PRINTF(("DDC FIFO Error.\n")); - hdmitx_ClearDDCFIFO(); - hdmiTxDev[0].bAuthenticated= FALSE ; - } - if(intdata1 & B_TX_INT_DDC_BUS_HANG) - { - HDMITX_DEBUG_PRINTF(("DDC BUS HANG.\n")); - hdmitx_AbortDDC(); - - if(hdmiTxDev[0].bAuthenticated) - { - HDMITX_DEBUG_PRINTF(("when DDC hang,and aborted DDC,the HDCP authentication need to restart.\n")); - #ifdef SUPPORT_HDCP - hdmitx_hdcp_ResumeAuthentication(); - #endif - } - } - if(intdata1 & (B_TX_INT_HPD_PLUG/*|B_TX_INT_RX_SENSE*/)) - { - - if(pHPDChange) - { - *pHPDChange = TRUE ; - } - if(HPD == FALSE) - { - /* - HDMITX_WriteI2C_Byte(REG_TX_SW_RST,B_TX_AREF_RST|B_HDMITX_VID_RST|B_HDMITX_AUD_RST|B_TX_HDCP_RST_HDMITX); - delay1ms(1); - HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST|B_TX_AFE_DRV_PWD); - */ - //HDMITX_DEBUG_PRINTF(("Unplug,%x %x\n",(int)HDMITX_ReadI2C_Byte(REG_TX_SW_RST),(int)HDMITX_ReadI2C_Byte(REG_TX_AFE_DRV_CTRL))); - } - } - if(intdata1 & (B_TX_INT_RX_SENSE)) - { - hdmiTxDev[0].bAuthenticated = FALSE; - } - intdata2 = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT2); - HDMITX_DEBUG_PRINTF(("INT_Handler: reg%X = %X\n",(int)REG_TX_INT_STAT2,(int)intdata2)); - - #ifdef SUPPORT_HDCP - if(intdata2 & B_TX_INT_AUTH_DONE) - { - HDMITX_DEBUG_PRINTF(("interrupt Authenticate Done.\n")); - HDMITX_OrReg_Byte(REG_TX_INT_MASK2,(BYTE)B_TX_AUTH_DONE_MASK); - //hdmiTxDev[0].bAuthenticated = TRUE ; - //setHDMITX_AVMute(FALSE); - } - if(intdata2 & B_TX_INT_AUTH_FAIL) - { - hdmiTxDev[0].bAuthenticated = FALSE; - //HDMITX_DEBUG_PRINTF(("interrupt Authenticate Fail.\n")); - hdmitx_AbortDDC(); // @emily add - //hdmitx_hdcp_ResumeAuthentication(); - } - #endif // SUPPORT_HDCP - -#if 1 - intdata3 = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT3); - HDMITX_DEBUG_PRINTF(("INT_Handler: reg%X = %X\n",(int)REG_TX_INT_STAT3,(int)intdata3)); - if(intdata3 & B_TX_INT_VIDSTABLE) - { - sysstat = HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS); - if(sysstat & B_TXVIDSTABLE) - { - hdmitx_FireAFE(); - } - } -#endif - intdata3= HDMITX_ReadI2C_Byte(0xEE); - if( intdata3 ) - { - HDMITX_WriteI2C_Byte(0xEE,intdata3); // clear ext interrupt ; - HDMITX_DEBUG_PRINTF(("%s%s%s%s%s%s%s\n", - (intdata3&0x40)?"video parameter change \n":"", - (intdata3&0x20)?"HDCP Pj check done \n":"", - (intdata3&0x10)?"HDCP Ri check done \n":"", - (intdata3&0x8)? "DDC bus hang \n":"", - (intdata3&0x4)? "Video input FIFO auto reset \n":"", - (intdata3&0x2)? "No audio input interrupt \n":"", - (intdata3&0x1)? "Audio decode error interrupt \n":"")); - } - - intclr3 = (HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS))|B_TX_CLR_AUD_CTS | B_TX_INTACTDONE ; - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,intclr3); // clear interrupt. - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,0xFF); - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0xFF); - intclr3 &= ~(B_TX_INTACTDONE); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,intclr3); // INTACTDONE reset to zero. - } - // - // else - // { - // if(pHPDChange) - // { - // if(HPD != PrevHPD) - // { - // *pHPDChange = TRUE; - // } - // else - // { - // *pHPDChange = FALSE; - // } - // } - // } - if(pHPDChange) - { - if((*pHPDChange==TRUE) &&(HPD==FALSE)) - { - HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST|B_TX_AFE_DRV_PWD); - } - } - if(pHPD) - { - *pHPD = HPD ; - } - hdmiTxDev[0].bHPD = HPD ; - return HPD ; -} -#endif -void HDMITX_PowerOn() -{ - PowerStatus = TRUE; - hdmitx_LoadRegSetting(HDMITX_PwrOn_Table); -} - -void HDMITX_PowerDown() -{ - PowerStatus = FALSE; - hdmitx_LoadRegSetting(HDMITX_PwrDown_Table); -} -BOOL getHDMI_PowerStatus() -{ - return PowerStatus; -} - -void setHDMITX_AVMute(BYTE bEnable) -{ - Switch_HDMITX_Bank(0); - HDMITX_SetI2C_Byte(REG_TX_GCP,B_TX_SETAVMUTE, bEnable?B_TX_SETAVMUTE:0 ); - HDMITX_WriteI2C_Byte(REG_TX_PKT_GENERAL_CTRL,B_TX_ENABLE_PKT|B_TX_REPEAT_PKT); -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_LoadRegSetting() -// Input: RegSetEntry SettingTable[] ; -// Return: N/A -// Remark: if an entry {0, 0, 0} will be terminated. -////////////////////////////////////////////////////////////////////// - -void hdmitx_LoadRegSetting(RegSetEntry table[]) -{ - int i ; - - for( i = 0 ; ; i++ ) - { - if( table[i].offset == 0 && table[i].invAndMask == 0 && table[i].OrMask == 0 ) - { - return ; - } - else if( table[i].invAndMask == 0 && table[i].OrMask == 0 ) - { - HDMITX_DEBUG_PRINTF2(("delay(%d)\n",(int)table[i].offset)); - delay1ms(table[i].offset); - } - else if( table[i].invAndMask == 0xFF ) - { - HDMITX_DEBUG_PRINTF2(("HDMITX_WriteI2C_Byte(%02x,%02x)\n",(int)table[i].offset,(int)table[i].OrMask)); - HDMITX_WriteI2C_Byte(table[i].offset,table[i].OrMask); - } - else - { - HDMITX_DEBUG_PRINTF2(("HDMITX_SetI2C_Byte(%02x,%02x,%02x)\n",(int)table[i].offset,(int)table[i].invAndMask,(int)table[i].OrMask)); - HDMITX_SetI2C_Byte(table[i].offset,table[i].invAndMask,table[i].OrMask); - } - } -} - -///***************************************** -// @file -//******************************************/ - -BOOL getHDMITX_EDIDBlock(int EDIDBlockID,BYTE *pEDIDData) -{ - if(!pEDIDData) - { - return FALSE ; - } - if(getHDMITX_EDIDBytes(pEDIDData,EDIDBlockID/2,(EDIDBlockID%2)*128,128) == ER_FAIL) - { - return FALSE ; - } -#if Debug_message - { - int j=0; - EDID_DEBUG_PRINTF(("------BlockID=%d------\n",EDIDBlockID)); - for( j = 0 ; j < 128 ; j++ ) - { - EDID_DEBUG_PRINTF(("%02X%c",(int)pEDIDData[j],(7 == (j&7))?'\n':' ')); - } - } -#endif - return TRUE ; -} - -////////////////////////////////////////////////////////////////////// -// Function: getHDMITX_EDIDBytes -// Parameter: pData - the pointer of buffer to receive EDID ucdata. -// bSegment - the segment of EDID readback. -// offset - the offset of EDID ucdata in the segment. in byte. -// count - the read back bytes count,cannot exceed 32 -// Return: ER_SUCCESS if successfully getting EDID. ER_FAIL otherwise. -// Remark: function for read EDID ucdata from reciever. -// Side-Effect: DDC master will set to be HOST. DDC FIFO will be used and dirty. -////////////////////////////////////////////////////////////////////// - -SYS_STATUS getHDMITX_EDIDBytes(BYTE *pData,BYTE bSegment,BYTE offset,SHORT Count) -{ - SHORT RemainedCount,ReqCount ; - BYTE bCurrOffset ; - SHORT TimeOut ; - BYTE *pBuff = pData ; - BYTE ucdata ; - - // HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(%08lX,%d,%d,%d)\n",(ULONG)pData,(int)bSegment,(int)offset,(int)Count)); - if(!pData) - { -// HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(): Invallid pData pointer %08lX\n",(ULONG)pData)); - return ER_FAIL ; - } - if(HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1) & B_TX_INT_DDC_BUS_HANG) - { - HDMITX_DEBUG_PRINTF(("Called hdmitx_AboutDDC()\n")); - hdmitx_AbortDDC(); - - } - // HDMITX_OrReg_Byte(REG_TX_INT_CTRL,(1<<1)); - - hdmitx_ClearDDCFIFO(); - - RemainedCount = Count ; - bCurrOffset = offset ; - - Switch_HDMITX_Bank(0); - - while(RemainedCount > 0) - { - - ReqCount = (RemainedCount > DDC_FIFO_MAXREQ)?DDC_FIFO_MAXREQ:RemainedCount ; - HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(): ReqCount = %d,bCurrOffset = %d\n",(int)ReqCount,(int)bCurrOffset)); - - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); - HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_FIFO_CLR); - - for(TimeOut = 0 ; TimeOut < 200 ; TimeOut++) - { - ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); - - if(ucdata&B_TX_DDC_DONE) - { - break ; - } - if((ucdata & B_TX_DDC_ERROR)||(HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1) & B_TX_INT_DDC_BUS_HANG)) - { - HDMITX_DEBUG_PRINTF(("Called hdmitx_AboutDDC()\n")); - hdmitx_AbortDDC(); - return ER_FAIL ; - } - } - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); - HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,DDC_EDID_ADDRESS); // for EDID ucdata get - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,bCurrOffset); - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,(BYTE)ReqCount); - HDMITX_WriteI2C_Byte(REG_TX_DDC_EDIDSEG,bSegment); - HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_EDID_READ); - - bCurrOffset += ReqCount ; - RemainedCount -= ReqCount ; - - for(TimeOut = 250 ; TimeOut > 0 ; TimeOut --) - { - delay1ms(1); - ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); - if(ucdata & B_TX_DDC_DONE) - { - break ; - } - if(ucdata & B_TX_DDC_ERROR) - { - HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(): DDC_STATUS = %02X,fail.\n",(int)ucdata)); - // HDMITX_AndReg_Byte(REG_TX_INT_CTRL,~(1<<1)); - return ER_FAIL ; - } - } - if(TimeOut == 0) - { - HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(): DDC TimeOut %d . \n",(int)ucdata)); - // HDMITX_AndReg_Byte(REG_TX_INT_CTRL,~(1<<1)); - return ER_FAIL ; - } - do - { - *(pBuff++) = HDMITX_ReadI2C_Byte(REG_TX_DDC_READFIFO); - ReqCount -- ; - }while(ReqCount > 0); - - } - // HDMITX_AndReg_Byte(REG_TX_INT_CTRL,~(1<<1)); - return ER_SUCCESS ; -} - -///////////////////////////// -// DDC Function. -////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_ClearDDCFIFO -// Parameter: N/A -// Return: N/A -// Remark: clear the DDC FIFO. -// Side-Effect: DDC master will set to be HOST. -////////////////////////////////////////////////////////////////////// - -void hdmitx_ClearDDCFIFO() -{ - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); - HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_FIFO_CLR); -} - -void hdmitx_GenerateDDCSCLK() -{ - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); - HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_GEN_SCLCLK); -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_AbortDDC -// Parameter: N/A -// Return: N/A -// Remark: Force abort DDC and reset DDC bus. -// Side-Effect: -////////////////////////////////////////////////////////////////////// - -void hdmitx_AbortDDC() -{ - BYTE CPDesire,SWReset,DDCMaster ; - BYTE uc, timeout, i ; - // save the SW reset,DDC master,and CP Desire setting. - SWReset = HDMITX_ReadI2C_Byte(REG_TX_SW_RST); - CPDesire = HDMITX_ReadI2C_Byte(REG_TX_HDCP_DESIRE); - DDCMaster = HDMITX_ReadI2C_Byte(REG_TX_DDC_MASTER_CTRL); - - HDMITX_WriteI2C_Byte(REG_TX_HDCP_DESIRE,CPDesire&(~B_TX_CPDESIRE)); // @emily change order - HDMITX_WriteI2C_Byte(REG_TX_SW_RST,SWReset|B_TX_HDCP_RST_HDMITX); // @emily change order - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); - - // 2009/01/15 modified by Jau-Chih.Tseng@ite.com.tw - // do abort DDC twice. - for( i = 0 ; i < 2 ; i++ ) - { - HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_ABORT); - - for( timeout = 0 ; timeout < 200 ; timeout++ ) - { - uc = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); - if (uc&B_TX_DDC_DONE) - { - break ; // success - } - if( uc & (B_TX_DDC_NOACK|B_TX_DDC_WAITBUS|B_TX_DDC_ARBILOSE) ) - { -// HDMITX_DEBUG_PRINTF(("hdmitx_AbortDDC Fail by reg16=%02X\n",(int)uc)); - break ; - } - delay1ms(1); // delay 1 ms to stable. - } - } - //~Jau-Chih.Tseng@ite.com.tw - -} - -///***************************************** -// @file -//******************************************/ - -extern HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT] ; - -void WaitTxVidStable(void); -void hdmitx_SetInputMode(BYTE InputMode,BYTE bInputSignalType); -void hdmitx_SetCSCScale(BYTE bInputMode,BYTE bOutputMode); -void hdmitx_SetupAFE(VIDEOPCLKLEVEL PCLKLevel); -void hdmitx_FireAFE(void); - -////////////////////////////////////////////////////////////////////// -// utility function for main.. -////////////////////////////////////////////////////////////////////// - -#ifndef DISABLE_HDMITX_CSC - #if (defined (SUPPORT_OUTPUTYUV)) && (defined (SUPPORT_INPUTRGB)) - extern _CODE BYTE bCSCMtx_RGB2YUV_ITU601_16_235[] ; - extern _CODE BYTE bCSCMtx_RGB2YUV_ITU601_0_255[] ; - extern _CODE BYTE bCSCMtx_RGB2YUV_ITU709_16_235[] ; - extern _CODE BYTE bCSCMtx_RGB2YUV_ITU709_0_255[] ; - #endif - - #if (defined (SUPPORT_OUTPUTRGB)) && (defined (SUPPORT_INPUTYUV)) - extern _CODE BYTE bCSCMtx_YUV2RGB_ITU601_16_235[] ; - extern _CODE BYTE bCSCMtx_YUV2RGB_ITU601_0_255[] ; - extern _CODE BYTE bCSCMtx_YUV2RGB_ITU709_16_235[] ; - extern _CODE BYTE bCSCMtx_YUV2RGB_ITU709_0_255[] ; - - #endif -#endif// DISABLE_HDMITX_CSC - -////////////////////////////////////////////////////////////////////// -// Function Body. -////////////////////////////////////////////////////////////////////// - -void HDMITX_DisableVideoOutput() -{ - BYTE uc = HDMITX_ReadI2C_Byte(REG_TX_SW_RST) | B_HDMITX_VID_RST ; - HDMITX_WriteI2C_Byte(REG_TX_SW_RST,uc); - HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST|B_TX_AFE_DRV_PWD); - HDMITX_SetI2C_Byte(0x62, 0x90, 0x00); - HDMITX_SetI2C_Byte(0x64, 0x89, 0x00); -} - -BOOL HDMITX_EnableVideoOutput(VIDEOPCLKLEVEL level,BYTE inputColorMode,BYTE outputColorMode,BYTE bHDMI) -{ - // bInputVideoMode,bOutputVideoMode,hdmiTxDev[0].bInputVideoSignalType,bAudioInputType,should be configured by upper F/W or loaded from EEPROM. - // should be configured by initsys.c - // VIDEOPCLKLEVEL level ; - switch(level) - { - case PCLK_HIGH: - HDMITX_WriteI2C_Byte(REG_TX_PLL_CTRL,0x30 /*0xff*/); - break ; - default: - HDMITX_WriteI2C_Byte(REG_TX_PLL_CTRL,0x00); - break ; - } - HDMITX_WriteI2C_Byte(REG_TX_SW_RST,B_HDMITX_VID_RST|B_HDMITX_AUD_RST|B_TX_AREF_RST|B_TX_HDCP_RST_HDMITX); - - hdmiTxDev[0].bHDMIMode = (BYTE)bHDMI ; - // 2009/12/09 added by jau-chih.tseng@ite.com.tw - Switch_HDMITX_Bank(1); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB1,0x00); - Switch_HDMITX_Bank(0); - //~jau-chih.tseng@ite.com.tw - - if(hdmiTxDev[0].bHDMIMode) - { - setHDMITX_AVMute(TRUE); - } - hdmitx_SetInputMode(inputColorMode,hdmiTxDev[0].bInputVideoSignalType); - - hdmitx_SetCSCScale(inputColorMode,outputColorMode); - - if(hdmiTxDev[0].bHDMIMode) - { - HDMITX_WriteI2C_Byte(REG_TX_HDMI_MODE,B_TX_HDMI_MODE); - } - else - { - HDMITX_WriteI2C_Byte(REG_TX_HDMI_MODE,B_TX_DVI_MODE); - } -#ifdef INVERT_VID_LATCHEDGE - uc = HDMITX_ReadI2C_Byte(REG_TX_CLK_CTRL1); - uc |= B_TX_VDO_LATCH_EDGE ; - HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL1, uc); -#endif - - hdmitx_SetupAFE(level); // pass if High Freq request - HDMITX_WriteI2C_Byte(REG_TX_SW_RST, B_HDMITX_AUD_RST|B_TX_AREF_RST|B_TX_HDCP_RST_HDMITX); - - hdmitx_FireAFE(); - - return TRUE ; -} - -////////////////////////////////////////////////////////////////////// -// export this for dynamic change input signal -////////////////////////////////////////////////////////////////////// -BOOL setHDMITX_VideoSignalType(BYTE inputSignalType) -{ - hdmiTxDev[0].bInputVideoSignalType = inputSignalType ; - // hdmitx_SetInputMode(inputColorMode,hdmiTxDev[0].bInputVideoSignalType); - return TRUE ; -} - -void WaitTxVidStable() -{ -#if 0 - BYTE i ; - for( i = 0 ; i < 20 ; i++ ) - { - delay1ms(15); - if((HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS) & B_TXVIDSTABLE) == 0 ) - { - continue ; - } - delay1ms(15); - if((HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS) & B_TXVIDSTABLE) == 0 ) - { - continue ; - } - delay1ms(15); - if((HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS) & B_TXVIDSTABLE) == 0 ) - { - continue ; - } - delay1ms(15); - if((HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS) & B_TXVIDSTABLE) == 0 ) - { - continue ; - } - break ; - } -#endif -} -// void CheckClockStable(BYTE SystemStat) -// { -// static BYTE Stablecnt=20; -// if(0==(SystemStat&B_TXVIDSTABLE)) -// { -// if(0==Stablecnt--) -// { -// HDMITX_ToggleBit(0x59,3); -// Stablecnt=20; -// } -// } -// else -// { -// Stablecnt=20; -// } -// } - -void setHDMITX_ColorDepthPhase(BYTE ColorDepth,BYTE bPhase) -{ -#ifdef IT6615 - BYTE uc ; - BYTE bColorDepth ; - - if(ColorDepth == 30) - { - bColorDepth = B_TX_CD_30 ; - HDMITX_DEBUG_PRINTF(("bColorDepth = B_TX_CD_30\n")); - } - else if (ColorDepth == 36) - { - bColorDepth = B_TX_CD_36 ; - HDMITX_DEBUG_PRINTF(("bColorDepth = B_TX_CD_36\n")); - } - /* - else if (ColorDepth == 24) - { - bColorDepth = B_TX_CD_24 ; - //bColorDepth = 0 ;//modify JJ by mail 20100423 1800 // not indicated - } - */ - else - { - bColorDepth = 0 ; // not indicated - } - Switch_HDMITX_Bank(0); - HDMITX_SetI2C_Byte(REG_TX_GCP,B_TX_COLOR_DEPTH_MASK ,bColorDepth); - HDMITX_DEBUG_PRINTF(("setHDMITX_ColorDepthPhase(%02X), regC1 = %02X\n",(int)bColorDepth,(int)HDMITX_ReadI2C_Byte(REG_TX_GCP))) ; -#endif -} - -#ifdef SUPPORT_SYNCEMBEDDED - -struct CRT_TimingSetting { - BYTE fmt; - WORD HActive; - WORD VActive; - WORD HTotal; - WORD VTotal; - WORD H_FBH; - WORD H_SyncW; - WORD H_BBH; - WORD V_FBH; - WORD V_SyncW; - WORD V_BBH; - BYTE Scan:1; - BYTE VPolarity:1; - BYTE HPolarity:1; -}; - -// VDEE_L, VDEE_H, VRS2S_L, VRS2S_H, VRS2E_L, VRS2E_H, HalfL_L, HalfL_H, VDE2S_L, VDE2S_H, HVP&Progress -_CODE struct CRT_TimingSetting TimingTable[] = -{ - // VIC H V HTotal VTotal HFT HSW HBP VF VSW VB - { 1, 640, 480, 800, 525, 16, 96, 48, 10, 2, 33, PROG, Vneg, Hneg},// 640x480@60Hz - CEA Mode [ 1] - { 2, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@60Hz - CEA Mode [ 2] - { 3, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@60Hz - CEA Mode [ 3] - { 4, 1280, 720, 1650, 750, 110, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@60Hz - CEA Mode [ 4] - { 5, 1920, 540, 2200, 562, 88, 44, 148, 2, 5, 15, INTERLACE, Vpos, Hpos},// 1920x1080(I)@60Hz - CEA Mode [ 5] - { 6, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [ 6] - { 7, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [ 7] - // { 8, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, PROG, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [ 8] - // { 9, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, PROG, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [ 9] - // { 10, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [10] - // { 11, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [11] - // { 12, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, PROG, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [12] - // { 13, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, PROG, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [13] - // { 14, 1440, 480, 1716, 525, 32, 124, 120, 9, 6, 30, PROG, Vneg, Hneg},// 1440x480@60Hz - CEA Mode [14] - // { 15, 1440, 480, 1716, 525, 32, 124, 120, 9, 6, 30, PROG, Vneg, Hneg},// 1440x480@60Hz - CEA Mode [15] - { 16, 1920, 1080, 2200, 1125, 88, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@60Hz - CEA Mode [16] - { 17, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@50Hz - CEA Mode [17] - { 18, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@50Hz - CEA Mode [18] - { 19, 1280, 720, 1980, 750, 440, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@50Hz - CEA Mode [19] - { 20, 1920, 540, 2640, 562, 528, 44, 148, 2, 5, 15, INTERLACE, Vpos, Hpos},// 1920x1080(I)@50Hz - CEA Mode [20] - { 21, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@50Hz - CEA Mode [21] - { 22, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@50Hz - CEA Mode [22] - // { 23, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, PROG, Vneg, Hneg},// 1440x288@50Hz - CEA Mode [23] - // { 24, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, PROG, Vneg, Hneg},// 1440x288@50Hz - CEA Mode [24] - // { 25, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@50Hz - CEA Mode [25] - // { 26, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@50Hz - CEA Mode [26] - // { 27, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, PROG, Vneg, Hneg},// 1440x288@50Hz - CEA Mode [27] - // { 28, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, PROG, Vneg, Hneg},// 1440x288@50Hz - CEA Mode [28] - // { 29, 1440, 576, 1728, 625, 24, 128, 136, 5, 5, 39, PROG, Vpos, Hneg},// 1440x576@50Hz - CEA Mode [29] - // { 30, 1440, 576, 1728, 625, 24, 128, 136, 5, 5, 39, PROG, Vpos, Hneg},// 1440x576@50Hz - CEA Mode [30] - { 31, 1920, 1080, 2640, 1125, 528, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@50Hz - CEA Mode [31] - { 32, 1920, 1080, 2750, 1125, 638, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@24Hz - CEA Mode [32] - { 33, 1920, 1080, 2640, 1125, 528, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@25Hz - CEA Mode [33] - { 34, 1920, 1080, 2200, 1125, 88, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@30Hz - CEA Mode [34] - // { 35, 2880, 480, 1716*2, 525, 32*2, 124*2, 120*2, 9, 6, 30, PROG, Vneg, Hneg},// 2880x480@60Hz - CEA Mode [35] - // { 36, 2880, 480, 1716*2, 525, 32*2, 124*2, 120*2, 9, 6, 30, PROG, Vneg, Hneg},// 2880x480@60Hz - CEA Mode [36] - // { 37, 2880, 576, 3456, 625, 24*2, 128*2, 136*2, 5, 5, 39, PROG, Vneg, Hneg},// 2880x576@50Hz - CEA Mode [37] - // { 38, 2880, 576, 3456, 625, 24*2, 128*2, 136*2, 5, 5, 39, PROG, Vneg, Hneg},// 2880x576@50Hz - CEA Mode [38] - // { 39, 1920, 540, 2304, 625, 32, 168, 184, 23, 5, 57, INTERLACE, Vneg, Hpos},// 1920x1080@50Hz - CEA Mode [39] - // { 40, 1920, 540, 2640, 562, 528, 44, 148, 2, 5, 15, INTERLACE, Vpos, Hpos},// 1920x1080(I)@100Hz - CEA Mode [40] - // { 41, 1280, 720, 1980, 750, 440, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@100Hz - CEA Mode [41] - // { 42, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@100Hz - CEA Mode [42] - // { 43, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@100Hz - CEA Mode [43] - // { 44, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@100Hz - CEA Mode [44] - // { 45, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@100Hz - CEA Mode [45] - // { 46, 1920, 540, 2200, 562, 88, 44, 148, 2, 5, 15, INTERLACE, Vpos, Hpos},// 1920x1080(I)@120Hz - CEA Mode [46] - // { 47, 1280, 720, 1650, 750, 110, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@120Hz - CEA Mode [47] - // { 48, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@120Hz - CEA Mode [48] - // { 49, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@120Hz - CEA Mode [49] - // { 50, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@120Hz - CEA Mode [50] - // { 51, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@120Hz - CEA Mode [51] - // { 52, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@200Hz - CEA Mode [52] - // { 53, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@200Hz - CEA Mode [53] - // { 54, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@200Hz - CEA Mode [54] - // { 55, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@200Hz - CEA Mode [55] - // { 56, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@120Hz - CEA Mode [56] - // { 57, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@120Hz - CEA Mode [57] - // { 58, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@120Hz - CEA Mode [58] - // { 59, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@120Hz - CEA Mode [59] - { 60, 1280, 720, 3300, 750, 1760, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@24Hz - CEA Mode [60] - { 61, 1280, 720, 3960, 750, 2420, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@25Hz - CEA Mode [61] - { 62, 1280, 720, 3300, 750, 1760, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@30Hz - CEA Mode [62] - // { 63, 1920, 1080, 2200, 1125, 88, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@120Hz - CEA Mode [63] - // { 64, 1920, 1080, 2640, 1125, 528, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@100Hz - CEA Mode [64] -}; - -#define MaxIndex (sizeof(TimingTable)/sizeof(struct CRT_TimingSetting)) -BOOL setHDMITX_SyncEmbeddedByVIC(BYTE VIC,BYTE bInputType) -{ - int i ; - BYTE fmt_index=0; - - // if Embedded Video,need to generate timing with pattern register - Switch_HDMITX_Bank(0); - - HDMITX_DEBUG_PRINTF(("setHDMITX_SyncEmbeddedByVIC(%d,%x)\n",(int)VIC,(int)bInputType)); - if( VIC > 0 ) - { - for(i=0;i< MaxIndex;i ++) - { - if(TimingTable[i].fmt==VIC) - { - fmt_index=i; - HDMITX_DEBUG_PRINTF(("fmt_index=%02x)\n",(int)fmt_index)); - HDMITX_DEBUG_PRINTF(("***Fine Match Table ***\n")); - break; - } - } - } - else - { - HDMITX_DEBUG_PRINTF(("***No Match VIC == 0 ***\n")); - return FALSE ; - } - - if(i>=MaxIndex) - { - //return FALSE; - HDMITX_DEBUG_PRINTF(("***No Match VIC ***\n")); - return FALSE ; - } - //if( bInputSignalType & T_MODE_SYNCEMB ) - { - int HTotal, HDES, VTotal, VDES; - int HDEW, VDEW, HFP, HSW, VFP, VSW; - int HRS, HRE; - int VRS, VRE; - int H2ndVRRise; - int VRS2nd, VRE2nd; - BYTE Pol; - - HTotal =TimingTable[fmt_index].HTotal; - HDEW =TimingTable[fmt_index].HActive; - HFP =TimingTable[fmt_index].H_FBH; - HSW =TimingTable[fmt_index].H_SyncW; - HDES =HSW+TimingTable[fmt_index].H_BBH; - VTotal =TimingTable[fmt_index].VTotal; - VDEW =TimingTable[fmt_index].VActive; - VFP =TimingTable[fmt_index].V_FBH; - VSW =TimingTable[fmt_index].V_SyncW; - VDES =VSW+TimingTable[fmt_index].V_BBH; - - Pol = (TimingTable[fmt_index].HPolarity==Hpos)?(1<<1):0 ; - Pol |= (TimingTable[fmt_index].VPolarity==Vpos)?(1<<2):0 ; - - // SyncEmb case===== - if( bInputType & T_MODE_CCIR656) - { - HRS = HFP - 1; - } - else - { - HRS = HFP - 2; - /* - if(VIC==HDMI_1080p60 || - VIC==HDMI_1080p50 ) - { - HDMITX_OrReg_Byte(0x59, (1<<3)); - } - else - { - HDMITX_AndReg_Byte(0x59, ~(1<<3)); - } - */ - } - HRE = HRS + HSW; - H2ndVRRise = HRS+ HTotal/2; - - VRS = VFP; - VRE = VRS + VSW; - - // VTotal>>=1; - - if(PROG == TimingTable[fmt_index].Scan) - { // progressive mode - VRS2nd = 0xFFF; - VRE2nd = 0x3F; - } - else - { // interlaced mode - if(39 == TimingTable[fmt_index].fmt) - { - VRS2nd = VRS + VTotal - 1; - VRE2nd = VRS2nd + VSW; - } - else - { - VRS2nd = VRS + VTotal; - VRE2nd = VRS2nd + VSW; - } - } - #ifdef DETECT_VSYNC_CHG_IN_SAV - if( EnSavVSync ) - { - VRS -= 1; - VRE -= 1; - if( !pSetVTiming->ScanMode ) // interlaced mode - { - VRS2nd -= 1; - VRE2nd -= 1; - } - } - #endif // DETECT_VSYNC_CHG_IN_SAV - HDMITX_SetI2C_Byte(0x90, 0x06, Pol); - // write H2ndVRRise - HDMITX_SetI2C_Byte(0x90, 0xF0, (H2ndVRRise&0x0F)<<4); - HDMITX_WriteI2C_Byte(0x91, (H2ndVRRise&0x0FF0)>>4); - // write HRS/HRE - HDMITX_WriteI2C_Byte(0x95, HRS&0xFF); - HDMITX_WriteI2C_Byte(0x96, HRE&0xFF); - HDMITX_WriteI2C_Byte(0x97, ((HRE&0x0F00)>>4)+((HRS&0x0F00)>>8)); - // write VRS/VRE - HDMITX_WriteI2C_Byte(0xa0, VRS&0xFF); - HDMITX_WriteI2C_Byte(0xa1, ((VRE&0x0F)<<4)+((VRS&0x0F00)>>8)); - HDMITX_WriteI2C_Byte(0xa2, VRS2nd&0xFF); - HDMITX_WriteI2C_Byte(0xa6, (VRE2nd&0xF0)+((VRE&0xF0)>>4)); - HDMITX_WriteI2C_Byte(0xa3, ((VRE2nd&0x0F)<<4)+((VRS2nd&0xF00)>>8)); - HDMITX_WriteI2C_Byte(0xa4, H2ndVRRise&0xFF); - HDMITX_WriteI2C_Byte(0xa5, (/*EnDEOnly*/0<<5)+((TimingTable[fmt_index].Scan==INTERLACE)?(1<<4):0)+((H2ndVRRise&0xF00)>>8)); - HDMITX_SetI2C_Byte(0xb1, 0x51, ((HRE&0x1000)>>6)+((HRS&0x1000)>>8)+((HDES&0x1000)>>12)); - HDMITX_SetI2C_Byte(0xb2, 0x05, ((H2ndVRRise&0x1000)>>10)+((H2ndVRRise&0x1000)>>12)); - } - return TRUE ; -} - -#endif // SUPPORT_SYNCEMBEDDED - -//~jj_tseng@chipadvanced.com 2007/01/02 - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_SetInputMode -// Parameter: InputMode,bInputSignalType -// InputMode - use [1:0] to identify the color space for reg70[7:6], -// definition: -// #define F_MODE_RGB444 0 -// #define F_MODE_YUV422 1 -// #define F_MODE_YUV444 2 -// #define F_MODE_CLRMOD_MASK 3 -// bInputSignalType - defined the CCIR656 D[0],SYNC Embedded D[1],and -// DDR input in D[2]. -// Return: N/A -// Remark: program Reg70 with the input value. -// Side-Effect: Reg70. -////////////////////////////////////////////////////////////////////// - -void hdmitx_SetInputMode(BYTE InputColorMode,BYTE bInputSignalType) -{ - BYTE ucData ; - - ucData = HDMITX_ReadI2C_Byte(REG_TX_INPUT_MODE); - ucData &= ~(M_TX_INCOLMOD|B_TX_2X656CLK|B_TX_SYNCEMB|B_TX_INDDR|B_TX_PCLKDIV2); - ucData |= 0x01;//input clock delay 1 for 1080P DDR - - switch(InputColorMode & F_MODE_CLRMOD_MASK) - { - case F_MODE_YUV422: - ucData |= B_TX_IN_YUV422 ; - break ; - case F_MODE_YUV444: - ucData |= B_TX_IN_YUV444 ; - break ; - case F_MODE_RGB444: - default: - ucData |= B_TX_IN_RGB ; - break ; - } - if(bInputSignalType & T_MODE_PCLKDIV2) - { - ucData |= B_TX_PCLKDIV2 ; HDMITX_DEBUG_PRINTF(("PCLK Divided by 2 mode\n")); - } - if(bInputSignalType & T_MODE_CCIR656) - { - ucData |= B_TX_2X656CLK ; HDMITX_DEBUG_PRINTF(("CCIR656 mode\n")); - } - if(bInputSignalType & T_MODE_SYNCEMB) - { - ucData |= B_TX_SYNCEMB ; HDMITX_DEBUG_PRINTF(("Sync Embedded mode\n")); - } - if(bInputSignalType & T_MODE_INDDR) - { - ucData |= B_TX_INDDR ; HDMITX_DEBUG_PRINTF(("Input DDR mode\n")); - } - HDMITX_WriteI2C_Byte(REG_TX_INPUT_MODE,ucData); -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_SetCSCScale -// Parameter: bInputMode - -// D[1:0] - Color Mode -// D[4] - Colorimetry 0: ITU_BT601 1: ITU_BT709 -// D[5] - Quantization 0: 0_255 1: 16_235 -// D[6] - Up/Dn Filter 'Required' -// 0: no up/down filter -// 1: enable up/down filter when csc need. -// D[7] - Dither Filter 'Required' -// 0: no dither enabled. -// 1: enable dither and dither free go "when required". -// bOutputMode - -// D[1:0] - Color mode. -// Return: N/A -// Remark: reg72~reg8D will be programmed depended the input with table. -// Side-Effect: -////////////////////////////////////////////////////////////////////// - -void hdmitx_SetCSCScale(BYTE bInputMode,BYTE bOutputMode) -{ - BYTE ucData = 0,csc = B_HDMITX_CSC_BYPASS ; - BYTE i ; - BYTE filter = 0 ; // filter is for Video CTRL DN_FREE_GO,EN_DITHER,and ENUDFILT - - // (1) YUV422 in,RGB/YUV444 output (Output is 8-bit,input is 12-bit) - // (2) YUV444/422 in,RGB output (CSC enable,and output is not YUV422) - // (3) RGB in,YUV444 output (CSC enable,and output is not YUV422) - // - // YUV444/RGB24 <-> YUV422 need set up/down filter. - HDMITX_DEBUG_PRINTF(("hdmitx_SetCSCScale(BYTE bInputMode = %x,BYTE bOutputMode = %x)\n", (int)bInputMode, (int)bOutputMode)) ; - switch(bInputMode&F_MODE_CLRMOD_MASK) - { - #ifdef SUPPORT_INPUTYUV444 - case F_MODE_YUV444: - HDMITX_DEBUG_PRINTF(("Input mode is YUV444 ")); - switch(bOutputMode&F_MODE_CLRMOD_MASK) - { - case F_MODE_YUV444: - HDMITX_DEBUG_PRINTF(("Output mode is YUV444\n")); - csc = B_HDMITX_CSC_BYPASS ; - break ; - - case F_MODE_YUV422: - HDMITX_DEBUG_PRINTF(("Output mode is YUV422\n")); - if(bInputMode & F_VIDMODE_EN_UDFILT) // YUV444 to YUV422 need up/down filter for processing. - { - filter |= B_TX_EN_UDFILTER ; - } - csc = B_HDMITX_CSC_BYPASS ; - break ; - case F_MODE_RGB444: - HDMITX_DEBUG_PRINTF(("Output mode is RGB24\n")); - csc = B_HDMITX_CSC_YUV2RGB ; - if(bInputMode & F_VIDMODE_EN_DITHER) // YUV444 to RGB24 need dither - { - filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; - } - break ; - } - break ; - #endif - - #ifdef SUPPORT_INPUTYUV422 - case F_MODE_YUV422: - HDMITX_DEBUG_PRINTF(("Input mode is YUV422\n")); - switch(bOutputMode&F_MODE_CLRMOD_MASK) - { - case F_MODE_YUV444: - HDMITX_DEBUG_PRINTF(("Output mode is YUV444\n")); - csc = B_HDMITX_CSC_BYPASS ; - if(bInputMode & F_VIDMODE_EN_UDFILT) // YUV422 to YUV444 need up filter - { - filter |= B_TX_EN_UDFILTER ; - } - if(bInputMode & F_VIDMODE_EN_DITHER) // YUV422 to YUV444 need dither - { - filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; - } - break ; - case F_MODE_YUV422: - HDMITX_DEBUG_PRINTF(("Output mode is YUV422\n")); - csc = B_HDMITX_CSC_BYPASS ; - - break ; - - case F_MODE_RGB444: - HDMITX_DEBUG_PRINTF(("Output mode is RGB24\n")); - csc = B_HDMITX_CSC_YUV2RGB ; - if(bInputMode & F_VIDMODE_EN_UDFILT) // YUV422 to RGB24 need up/dn filter. - { - filter |= B_TX_EN_UDFILTER ; - } - if(bInputMode & F_VIDMODE_EN_DITHER) // YUV422 to RGB24 need dither - { - filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; - } - break ; - } - break ; - #endif - - #ifdef SUPPORT_INPUTRGB - case F_MODE_RGB444: - HDMITX_DEBUG_PRINTF(("Input mode is RGB24\n")); - switch(bOutputMode&F_MODE_CLRMOD_MASK) - { - case F_MODE_YUV444: - HDMITX_DEBUG_PRINTF(("Output mode is YUV444\n")); - csc = B_HDMITX_CSC_RGB2YUV ; - - if(bInputMode & F_VIDMODE_EN_DITHER) // RGB24 to YUV444 need dither - { - filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; - } - break ; - - case F_MODE_YUV422: - HDMITX_DEBUG_PRINTF(("Output mode is YUV422\n")); - if(bInputMode & F_VIDMODE_EN_UDFILT) // RGB24 to YUV422 need down filter. - { - filter |= B_TX_EN_UDFILTER ; - } - if(bInputMode & F_VIDMODE_EN_DITHER) // RGB24 to YUV422 need dither - { - filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; - } - csc = B_HDMITX_CSC_RGB2YUV ; - break ; - - case F_MODE_RGB444: - HDMITX_DEBUG_PRINTF(("Output mode is RGB24\n")); - csc = B_HDMITX_CSC_BYPASS ; - break ; - } - break ; - #endif - } -#ifndef DISABLE_HDMITX_CSC - - #ifdef SUPPORT_INPUTRGB - // set the CSC metrix registers by colorimetry and quantization - if(csc == B_HDMITX_CSC_RGB2YUV) - { - HDMITX_DEBUG_PRINTF(("CSC = RGB2YUV %x ",csc)); - switch(bInputMode&(F_VIDMODE_ITU709|F_VIDMODE_16_235)) - { - case F_VIDMODE_ITU709|F_VIDMODE_16_235: - HDMITX_DEBUG_PRINTF(("ITU709 16-235 ")); - for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU709_16_235[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU709_16_235[i]));} - break ; - case F_VIDMODE_ITU709|F_VIDMODE_0_255: - HDMITX_DEBUG_PRINTF(("ITU709 0-255 ")); - for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU709_0_255[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU709_0_255[i]));} - break ; - case F_VIDMODE_ITU601|F_VIDMODE_16_235: - HDMITX_DEBUG_PRINTF(("ITU601 16-235 ")); - for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU601_16_235[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU601_16_235[i]));} - break ; - case F_VIDMODE_ITU601|F_VIDMODE_0_255: - default: - HDMITX_DEBUG_PRINTF(("ITU601 0-255 ")); - for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU601_0_255[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU601_0_255[i]));} - break ; - } - } - #endif - - #ifdef SUPPORT_INPUTYUV - if (csc == B_HDMITX_CSC_YUV2RGB) - { - HDMITX_DEBUG_PRINTF(("CSC = YUV2RGB %x ",csc)); - - switch(bInputMode&(F_VIDMODE_ITU709|F_VIDMODE_16_235)) - { - case F_VIDMODE_ITU709|F_VIDMODE_16_235: - HDMITX_DEBUG_PRINTF(("ITU709 16-235 ")); - for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU709_16_235[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU709_16_235[i]));} - break ; - case F_VIDMODE_ITU709|F_VIDMODE_0_255: - HDMITX_DEBUG_PRINTF(("ITU709 0-255 ")); - for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU709_0_255[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU709_0_255[i]));} - break ; - case F_VIDMODE_ITU601|F_VIDMODE_16_235: - HDMITX_DEBUG_PRINTF(("ITU601 16-235 ")); - for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU601_16_235[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU601_16_235[i]));} - break ; - case F_VIDMODE_ITU601|F_VIDMODE_0_255: - default: - HDMITX_DEBUG_PRINTF(("ITU601 0-255 ")); - for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU601_0_255[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU601_0_255[i]));} - break ; - } - } - #endif -#else// DISABLE_HDMITX_CSC - csc = B_HDMITX_CSC_BYPASS ; -#endif// DISABLE_HDMITX_CSC - - if( csc == B_HDMITX_CSC_BYPASS ) - { - HDMITX_SetI2C_Byte(0xF, 0x10, 0x10); - } - else - { - HDMITX_SetI2C_Byte(0xF, 0x10, 0x00); - } - ucData = HDMITX_ReadI2C_Byte(REG_TX_CSC_CTRL) & ~(M_TX_CSC_SEL|B_TX_DNFREE_GO|B_TX_EN_DITHER|B_TX_EN_UDFILTER); - ucData |= filter|csc ; - - HDMITX_WriteI2C_Byte(REG_TX_CSC_CTRL,ucData); - - // set output Up/Down Filter,Dither control - -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_SetupAFE -// Parameter: VIDEOPCLKLEVEL level -// PCLK_LOW - for 13.5MHz (for mode less than 1080p) -// PCLK MEDIUM - for 25MHz~74MHz -// PCLK HIGH - PCLK > 80Hz (for 1080p mode or above) -// Return: N/A -// Remark: set reg62~reg65 depended on HighFreqMode -// reg61 have to be programmed at last and after video stable input. -// Side-Effect: -////////////////////////////////////////////////////////////////////// - -void hdmitx_SetupAFE(VIDEOPCLKLEVEL level) -{ - - HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST);/* 0x10 */ - switch(level) - { - case PCLK_HIGH: - HDMITX_SetI2C_Byte(0x62, 0x90, 0x80); - HDMITX_SetI2C_Byte(0x64, 0x89, 0x80); - HDMITX_SetI2C_Byte(0x68, 0x10, 0x80); - HDMITX_DEBUG_PRINTF(("hdmitx_SetupAFE()===================HIGHT\n")); - break ; - default: - HDMITX_SetI2C_Byte(0x62, 0x90, 0x10); - HDMITX_SetI2C_Byte(0x64, 0x89, 0x09); - HDMITX_SetI2C_Byte(0x68, 0x10, 0x10); - HDMITX_DEBUG_PRINTF(("hdmitx_SetupAFE()===================LOW\n")); - break ; - } - HDMITX_SetI2C_Byte(REG_TX_SW_RST,B_TX_REF_RST_HDMITX|B_HDMITX_VID_RST,0); - HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,0); - delay1ms(1); -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_FireAFE -// Parameter: N/A -// Return: N/A -// Remark: write reg61 with 0x04 -// When program reg61 with 0x04,then audio and video circuit work. -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -void hdmitx_FireAFE() -{ - Switch_HDMITX_Bank(0); - HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,0); -} - -///***************************************** -// @file -//******************************************/ - -BYTE AudioDelayCnt=0; -BYTE LastRefaudfreqnum=0; -BOOL bForceCTS = FALSE; - -////////////////////////////////////////////////////////////////////// -// Audio Output -////////////////////////////////////////////////////////////////////// - -void setHDMITX_ChStat(BYTE ucIEC60958ChStat[]) -{ - BYTE uc ; - - Switch_HDMITX_Bank(1); - uc = (ucIEC60958ChStat[0] <<1)& 0x7C ; - HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_MODE,uc); - HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CAT,ucIEC60958ChStat[1]); // 192, audio CATEGORY - HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_SRCNUM,ucIEC60958ChStat[2]&0xF); - HDMITX_WriteI2C_Byte(REG_TX_AUD0CHST_CHTNUM,(ucIEC60958ChStat[2]>>4)&0xF); - HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CA_FS,ucIEC60958ChStat[3]); // choose clock - HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_OFS_WL,ucIEC60958ChStat[4]); - Switch_HDMITX_Bank(0); -} - -void setHDMITX_UpdateChStatFs(ULONG Fs) -{ - BYTE uc ; - - ///////////////////////////////////// - // Fs should be the following value. - // #define AUDFS_22p05KHz 4 - // #define AUDFS_44p1KHz 0 - // #define AUDFS_88p2KHz 8 - // #define AUDFS_176p4KHz 12 - // - // #define AUDFS_24KHz 6 - // #define AUDFS_48KHz 2 - // #define AUDFS_96KHz 10 - // #define AUDFS_192KHz 14 - // - // #define AUDFS_768KHz 9 - // - // #define AUDFS_32KHz 3 - // #define AUDFS_OTHER 1 - ///////////////////////////////////// - - Switch_HDMITX_Bank(1); - uc = HDMITX_ReadI2C_Byte(REG_TX_AUDCHST_CA_FS); // choose clock - HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CA_FS,uc); // choose clock - uc &= 0xF0 ; - uc |= (Fs&0xF); - - uc = HDMITX_ReadI2C_Byte(REG_TX_AUDCHST_OFS_WL); - uc &= 0xF ; - uc |= ((~Fs) << 4)&0xF0 ; - HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_OFS_WL,uc); - - Switch_HDMITX_Bank(0); -} - -void setHDMITX_LPCMAudio(BYTE AudioSrcNum, BYTE AudSWL, BOOL bSPDIF) -{ - - BYTE AudioEnable, AudioFormat ; - - AudioEnable = 0 ; - AudioFormat = hdmiTxDev[0].bOutputAudioMode ; - - switch(AudSWL) - { - case 16: - AudioEnable |= M_TX_AUD_16BIT ; - break ; - case 18: - AudioEnable |= M_TX_AUD_18BIT ; - break ; - case 20: - AudioEnable |= M_TX_AUD_20BIT ; - break ; - case 24: - default: - AudioEnable |= M_TX_AUD_24BIT ; - break ; - } - if( bSPDIF ) - { - AudioFormat &= ~0x40 ; - AudioEnable |= B_TX_AUD_SPDIF|B_TX_AUD_EN_I2S0 ; - } - else - { - AudioFormat |= 0x40 ; - switch(AudioSrcNum) - { - case 4: - AudioEnable |= B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ; - break ; - - case 3: - AudioEnable |= B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ; - break ; - - case 2: - AudioEnable |= B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ; - break ; - - case 1: - default: - AudioFormat &= ~0x40 ; - AudioEnable |= B_TX_AUD_EN_I2S0 ; - break ; - - } - } - AudioFormat|=0x01;//mingchih add - hdmiTxDev[0].bAudioChannelEnable=AudioEnable; - - Switch_HDMITX_Bank(0); - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0,AudioEnable&0xF0); - - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL1,AudioFormat); // regE1 bOutputAudioMode should be loaded from ROM image. - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping. -#ifdef USE_SPDIF_CHSTAT - if( bSPDIF ) - { - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL); - } - else - { - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); - } -#else // not USE_SPDIF_CHSTAT - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); -#endif // USE_SPDIF_CHSTAT - - HDMITX_WriteI2C_Byte(REG_TX_AUD_SRCVALID_FLAT,0x00); - HDMITX_WriteI2C_Byte(REG_TX_AUD_HDAUDIO,0x00); // regE5 = 0 ; - - if( bSPDIF ) - { - BYTE i ; - HDMITX_OrReg_Byte(0x5c,(1<<6)); - for( i = 0 ; i < 100 ; i++ ) - { - if(HDMITX_ReadI2C_Byte(REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK) - { - break ; // stable clock. - } - } - } -} - -void setHDMITX_NLPCMAudio(BOOL bSPDIF) // no Source Num, no I2S. -{ - BYTE AudioEnable, AudioFormat ; - BYTE i ; - - AudioFormat = 0x01 ; // NLPCM must use standard I2S mode. - if( bSPDIF ) - { - AudioEnable = M_TX_AUD_24BIT|B_TX_AUD_SPDIF; - } - else - { - AudioEnable = M_TX_AUD_24BIT; - } - - Switch_HDMITX_Bank(0); - // HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF); - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, AudioEnable); - //HDMITX_AndREG_Byte(REG_TX_SW_RST,~(B_HDMITX_AUD_RST|B_TX_AREF_RST)); - - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL1,0x01); // regE1 bOutputAudioMode should be loaded from ROM image. - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping. - -#ifdef USE_SPDIF_CHSTAT - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL); -#else // not USE_SPDIF_CHSTAT - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); -#endif // USE_SPDIF_CHSTAT - - HDMITX_WriteI2C_Byte(REG_TX_AUD_SRCVALID_FLAT,0x00); - HDMITX_WriteI2C_Byte(REG_TX_AUD_HDAUDIO,0x00); // regE5 = 0 ; - - if( bSPDIF ) - { - for( i = 0 ; i < 100 ; i++ ) - { - if(HDMITX_ReadI2C_Byte(REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK) - { - break ; // stable clock. - } - } - } - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, AudioEnable|B_TX_AUD_EN_I2S0); -} - -void setHDMITX_HBRAudio(BOOL bSPDIF) -{ - // BYTE rst; - Switch_HDMITX_Bank(0); - - // rst = HDMITX_ReadI2C_Byte(REG_TX_SW_RST); - // rst &= ~(B_HDMITX_AUD_RST|B_TX_AREF_RST); - - // HDMITX_WriteI2C_Byte(REG_TX_SW_RST, rst | B_HDMITX_AUD_RST ); - - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL1,0x47); // regE1 bOutputAudioMode should be loaded from ROM image. - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping. - - if( bSPDIF ) - { - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF); - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL); - } - else - { - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT); - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); - } - HDMITX_WriteI2C_Byte(REG_TX_AUD_SRCVALID_FLAT,0x08); - HDMITX_WriteI2C_Byte(REG_TX_AUD_HDAUDIO,B_TX_HBR); // regE5 = 0 ; - - //uc = HDMITX_ReadI2C_Byte(REG_TX_CLK_CTRL1); - //uc &= ~M_TX_AUD_DIV ; - //HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL1, uc); - - if( bSPDIF ) - { - BYTE i ; - for( i = 0 ; i < 100 ; i++ ) - { - if(HDMITX_ReadI2C_Byte(REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK) - { - break ; // stable clock. - } - } - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF|B_TX_AUD_EN_SPDIF); - } - else - { - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0); - } - HDMITX_AndReg_Byte(0x5c,~(1<<6)); - hdmiTxDev[0].bAudioChannelEnable=HDMITX_ReadI2C_Byte(REG_TX_AUDIO_CTRL0); - // HDMITX_WriteI2C_Byte(REG_TX_SW_RST, rst ); -} - -void setHDMITX_DSDAudio() -{ - // to be continue - // BYTE rst; - // rst = HDMITX_ReadI2C_Byte(REG_TX_SW_RST); - - //HDMITX_WriteI2C_Byte(REG_TX_SW_RST, rst | (B_HDMITX_AUD_RST|B_TX_AREF_RST) ); - - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL1,0x41); // regE1 bOutputAudioMode should be loaded from ROM image. - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping. - - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT); - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); - - HDMITX_WriteI2C_Byte(REG_TX_AUD_SRCVALID_FLAT,0x00); - HDMITX_WriteI2C_Byte(REG_TX_AUD_HDAUDIO,B_TX_DSD); // regE5 = 0 ; - //HDMITX_WriteI2C_Byte(REG_TX_SW_RST, rst & ~(B_HDMITX_AUD_RST|B_TX_AREF_RST) ); - - //uc = HDMITX_ReadI2C_Byte(REG_TX_CLK_CTRL1); - //uc &= ~M_TX_AUD_DIV ; - //HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL1, uc); - - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0); -} - -void HDMITX_DisableAudioOutput() -{ - //BYTE uc = (HDMITX_ReadI2C_Byte(REG_TX_SW_RST) | (B_HDMITX_AUD_RST | B_TX_AREF_RST)); - //HDMITX_WriteI2C_Byte(REG_TX_SW_RST,uc); - AudioDelayCnt=AudioOutDelayCnt; - LastRefaudfreqnum=0; - HDMITX_SetI2C_Byte(REG_TX_SW_RST, (B_HDMITX_AUD_RST | B_TX_AREF_RST), (B_HDMITX_AUD_RST | B_TX_AREF_RST) ); - HDMITX_SetI2C_Byte(0x0F, 0x10, 0x10 ); -} - -void HDMITX_EnableAudioOutput(BYTE AudioType, BOOL bSPDIF, ULONG SampleFreq, BYTE ChNum, BYTE *pIEC60958ChStat, ULONG TMDSClock) -{ - static _IDATA BYTE ucIEC60958ChStat[5] ; - - BYTE Fs ; - AudioDelayCnt=36; - LastRefaudfreqnum=0; - hdmiTxDev[0].TMDSClock=TMDSClock; - hdmiTxDev[0].bAudioChannelEnable=0; - hdmiTxDev[0].bSPDIF_OUT=bSPDIF; - - HDMITX_DEBUG_PRINTF1(("HDMITX_EnableAudioOutput(%02X, %s, %ld, %d, %p, %ld);\n", - AudioType, bSPDIF?"SPDIF":"I2S",SampleFreq, ChNum, pIEC60958ChStat, TMDSClock - )); - - HDMITX_OrReg_Byte(REG_TX_SW_RST,(B_HDMITX_AUD_RST | B_TX_AREF_RST)); - HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL0,B_TX_AUTO_OVER_SAMPLING_CLOCK|B_TX_EXT_256FS|0x01); - - HDMITX_SetI2C_Byte(0x0F, 0x10, 0x00 ); // power on the ACLK - - if(bSPDIF) - { - if(AudioType==T_AUDIO_HBR) - { - HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL0,0x81); - } - HDMITX_OrReg_Byte(REG_TX_AUDIO_CTRL0,B_TX_AUD_SPDIF); - } - else - { - HDMITX_AndReg_Byte(REG_TX_AUDIO_CTRL0,(~B_TX_AUD_SPDIF)); - } - if( AudioType != T_AUDIO_DSD) - { - // one bit audio have no channel status. - switch(SampleFreq) - { - case 44100L: Fs = AUDFS_44p1KHz ; break ; - case 88200L: Fs = AUDFS_88p2KHz ; break ; - case 176400L: Fs = AUDFS_176p4KHz ; break ; - case 32000L: Fs = AUDFS_32KHz ; break ; - case 48000L: Fs = AUDFS_48KHz ; break ; - case 96000L: Fs = AUDFS_96KHz ; break ; - case 192000L: Fs = AUDFS_192KHz ; break ; - case 768000L: Fs = AUDFS_768KHz ; break ; - default: - SampleFreq = 48000L ; - Fs = AUDFS_48KHz ; - break ; // default, set Fs = 48KHz. - } - #ifdef SUPPORT_AUDIO_MONITOR - hdmiTxDev[0].bAudFs=AUDFS_OTHER; - #else - hdmiTxDev[0].bAudFs=Fs; - #endif - setHDMITX_NCTS(hdmiTxDev[0].bAudFs); - if( pIEC60958ChStat == NULL ) - { - ucIEC60958ChStat[0] = 0 ; - ucIEC60958ChStat[1] = 0 ; - ucIEC60958ChStat[2] = (ChNum+1)/2 ; - - if(ucIEC60958ChStat[2]<1) - { - ucIEC60958ChStat[2] = 1 ; - } - else if( ucIEC60958ChStat[2] >4 ) - { - ucIEC60958ChStat[2] = 4 ; - } - ucIEC60958ChStat[3] = Fs ; - ucIEC60958ChStat[4] = (((~Fs)<<4) & 0xF0) | CHTSTS_SWCODE ; // Fs | 24bit word length - pIEC60958ChStat = ucIEC60958ChStat ; - } - } - HDMITX_SetI2C_Byte(REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST),B_TX_AREF_RST); - - switch(AudioType) - { - case T_AUDIO_HBR: - HDMITX_DEBUG_PRINTF(("T_AUDIO_HBR\n")); - pIEC60958ChStat[0] |= 1<<1 ; - pIEC60958ChStat[2] = 0; - pIEC60958ChStat[3] &= 0xF0 ; - pIEC60958ChStat[3] |= AUDFS_768KHz ; - pIEC60958ChStat[4] |= (((~AUDFS_768KHz)<<4) & 0xF0)| 0xB ; - setHDMITX_ChStat(pIEC60958ChStat); - setHDMITX_HBRAudio(bSPDIF); - - break ; - case T_AUDIO_DSD: - HDMITX_DEBUG_PRINTF(("T_AUDIO_DSD\n")); - setHDMITX_DSDAudio(); - break ; - case T_AUDIO_NLPCM: - HDMITX_DEBUG_PRINTF(("T_AUDIO_NLPCM\n")); - pIEC60958ChStat[0] |= 1<<1 ; - setHDMITX_ChStat(pIEC60958ChStat); - setHDMITX_NLPCMAudio(bSPDIF); - break ; - case T_AUDIO_LPCM: - HDMITX_DEBUG_PRINTF(("T_AUDIO_LPCM\n")); - pIEC60958ChStat[0] &= ~(1<<1); - - setHDMITX_ChStat(pIEC60958ChStat); - setHDMITX_LPCMAudio((ChNum+1)/2, SUPPORT_AUDI_AudSWL, bSPDIF); - // can add auto adjust - break ; - } - HDMITX_AndReg_Byte(REG_TX_INT_MASK1,(~B_TX_AUDIO_OVFLW_MASK)); - HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, hdmiTxDev[0].bAudioChannelEnable); - - HDMITX_SetI2C_Byte(REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST),0); -} - -void hdmitx_AutoAdjustAudio() -{ - unsigned long SampleFreq,cTMDSClock ; - unsigned long N ; - ULONG aCTS=0; - BYTE fs, uc,LoopCnt=10; - if(bForceCTS) - { - Switch_HDMITX_Bank(0); - HDMITX_WriteI2C_Byte(0xF8, 0xC3); - HDMITX_WriteI2C_Byte(0xF8, 0xA5); - HDMITX_AndReg_Byte(REG_TX_PKT_SINGLE_CTRL,~B_TX_SW_CTS); // D[1] = 0, HW auto count CTS - HDMITX_WriteI2C_Byte(0xF8, 0xFF); - } - //delay1ms(50); - Switch_HDMITX_Bank(1); - N = ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudN2)&0xF) << 16 ; - N |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudN1)) <<8 ; - N |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudN0)); - - while(LoopCnt--) - { ULONG TempCTS=0; - aCTS = ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt2)) << 12 ; - aCTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt1)) <<4 ; - aCTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt0)&0xf0)>>4 ; - if(aCTS==TempCTS) - {break;} - TempCTS=aCTS; - } - Switch_HDMITX_Bank(0); - if( aCTS == 0) - { - HDMITX_DEBUG_PRINTF(("aCTS== 0")); - return; - } - uc = HDMITX_ReadI2C_Byte(REG_TX_GCP); - - cTMDSClock = hdmiTxDev[0].TMDSClock ; - //TMDSClock=GetInputPclk(); - HDMITX_DEBUG_PRINTF(("PCLK = %u0,000\n",(WORD)(cTMDSClock/10000))); - switch(uc & 0x70) - { - case 0x50: - cTMDSClock *= 5 ; - cTMDSClock /= 4 ; - break ; - case 0x60: - cTMDSClock *= 3 ; - cTMDSClock /= 2 ; - } - SampleFreq = cTMDSClock/aCTS ; - SampleFreq *= N ; - SampleFreq /= 128 ; - //SampleFreq=48000; - - HDMITX_DEBUG_PRINTF(("SampleFreq = %u0\n",(WORD)(SampleFreq/10))); - if( SampleFreq>31000L && SampleFreq<=38050L ){fs = AUDFS_32KHz ;} - else if (SampleFreq < 46550L ) {fs = AUDFS_44p1KHz ;}//46050 - else if (SampleFreq < 68100L ) {fs = AUDFS_48KHz ;} - else if (SampleFreq < 92100L ) {fs = AUDFS_88p2KHz ;} - else if (SampleFreq < 136200L ) {fs = AUDFS_96KHz ;} - else if (SampleFreq < 184200L ) {fs = AUDFS_176p4KHz ;} - else if (SampleFreq < 240200L ) {fs = AUDFS_192KHz ;} - else if (SampleFreq < 800000L ) {fs = AUDFS_768KHz ;} - else - { - fs = AUDFS_OTHER; - HDMITX_DEBUG_PRINTF(("fs = AUDFS_OTHER\n")); - } - if(hdmiTxDev[0].bAudFs != fs) - { - hdmiTxDev[0].bAudFs=fs; - setHDMITX_NCTS(hdmiTxDev[0].bAudFs); // set N, CTS by new generated clock. - //CurrCTS=0; - return; - } - return; -} - -BOOL hdmitx_IsAudioChang() -{ - //ULONG pCTS=0; - BYTE FreDiff=0,Refaudfreqnum; - - //Switch_HDMITX_Bank(1); - //pCTS = ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt2)) << 12 ; - //pCTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt1)) <<4 ; - //pCTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt0)&0xf0)>>4 ; - //Switch_HDMITX_Bank(0); - Switch_HDMITX_Bank(0); - Refaudfreqnum=HDMITX_ReadI2C_Byte(0x60); - //HDMITX_DEBUG_PRINTF(("Refaudfreqnum=%X pCTS= %u",(WORD)Refaudfreqnum,(WORD)(pCTS/10000))); - //if((pCTS%10000)<1000)HDMITX_DEBUG_PRINTF(("0")); - //if((pCTS%10000)<100)HDMITX_DEBUG_PRINTF(("0")); - //if((pCTS%10000)<10)HDMITX_DEBUG_PRINTF(("0")); - //HDMITX_DEBUG_PRINTF(("%u\n",(WORD)(pCTS%10000))); - if((1<<4)&HDMITX_ReadI2C_Byte(0x5f)) - { - //printf("=======XXXXXXXXXXX=========\n"); - return FALSE; - } - if(LastRefaudfreqnum>Refaudfreqnum) - {FreDiff=LastRefaudfreqnum-Refaudfreqnum;} - else - {FreDiff=Refaudfreqnum-LastRefaudfreqnum;} - LastRefaudfreqnum=Refaudfreqnum; - if(3>8)&0xFF)); - HDMITX_WriteI2C_Byte(REGPktAudN2,(BYTE)((n>>16)&0xF)); - - if(bForceCTS) - { - ULONG SumCTS=0; - while(LoopCnt--) - { - delay1ms(30); - CTS = ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt2)) << 12 ; - CTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt1)) <<4 ; - CTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt0)&0xf0)>>4 ; - if( CTS == 0) - { - continue; - } - else - { - if(LastCTS>CTS ) - {diff=LastCTS-CTS;} - else - {diff=CTS-LastCTS;} - //HDMITX_DEBUG_PRINTF(("LastCTS= %u%u",(WORD)(LastCTS/10000),(WORD)(LastCTS%10000))); - //HDMITX_DEBUG_PRINTF((" CTS= %u%u\n",(WORD)(CTS/10000),(WORD)(CTS%10000))); - LastCTS=CTS; - if(5>diff) - { - CTSStableCnt++; - SumCTS+=CTS; - } - else - { - CTSStableCnt=0; - SumCTS=0; - continue; - } - if(CTSStableCnt>=32) - { - LastCTS=(SumCTS>>5); - break; - } - } - } - } - HDMITX_WriteI2C_Byte(REGPktAudCTS0,(BYTE)((LastCTS)&0xFF)); - HDMITX_WriteI2C_Byte(REGPktAudCTS1,(BYTE)((LastCTS>>8)&0xFF)); - HDMITX_WriteI2C_Byte(REGPktAudCTS2,(BYTE)((LastCTS>>16)&0xF)); - Switch_HDMITX_Bank(0); -#ifdef Force_CTS - bForceCTS = TRUE; -#endif - HDMITX_WriteI2C_Byte(0xF8, 0xC3); - HDMITX_WriteI2C_Byte(0xF8, 0xA5); - if(bForceCTS) - { - HDMITX_OrReg_Byte(REG_TX_PKT_SINGLE_CTRL,B_TX_SW_CTS); // D[1] = 0, HW auto count CTS - } - else - { - HDMITX_AndReg_Byte(REG_TX_PKT_SINGLE_CTRL,~B_TX_SW_CTS); // D[1] = 0, HW auto count CTS - } - HDMITX_WriteI2C_Byte(0xF8, 0xFF); - - if(FALSE==HBR_mode) //LPCM - { - BYTE uData; - Switch_HDMITX_Bank(1); - Fs = AUDFS_768KHz ; - HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CA_FS,0x00|Fs); - Fs = ~Fs ; // OFS is the one's complement of FS - uData = (0x0f&HDMITX_ReadI2C_Byte(REG_TX_AUDCHST_OFS_WL)); - HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_OFS_WL,(Fs<<4)|uData); - Switch_HDMITX_Bank(0); - } -} - -///***************************************** -// @file -//******************************************/ - -BOOL HDMITX_EnableVSInfoFrame(BYTE bEnable,BYTE *pVSInfoFrame) -{ - if(!bEnable) - { - hdmitx_DISABLE_VSDB_PKT(); - return TRUE ; - } - if(hdmitx_SetVSIInfoFrame((VendorSpecific_InfoFrame *)pVSInfoFrame) == ER_SUCCESS) - { - return TRUE ; - } - return FALSE ; -} - -BOOL HDMITX_EnableAVIInfoFrame(BYTE bEnable,BYTE *pAVIInfoFrame) -{ - if(!bEnable) - { - hdmitx_DISABLE_AVI_INFOFRM_PKT(); - return TRUE ; - } - if(hdmitx_SetAVIInfoFrame((AVI_InfoFrame *)pAVIInfoFrame) == ER_SUCCESS) - { - return TRUE ; - } - return FALSE ; -} - -BOOL HDMITX_EnableAudioInfoFrame(BYTE bEnable,BYTE *pAudioInfoFrame) -{ - if(!bEnable) - { - hdmitx_DISABLE_AVI_INFOFRM_PKT(); - return TRUE ; - } - if(hdmitx_SetAudioInfoFrame((Audio_InfoFrame *)pAudioInfoFrame) == ER_SUCCESS) - { - return TRUE ; - } - return FALSE ; -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_SetAVIInfoFrame() -// Parameter: pAVIInfoFrame - the pointer to HDMI AVI Infoframe ucData -// Return: N/A -// Remark: Fill the AVI InfoFrame ucData,and count checksum,then fill into -// AVI InfoFrame registers. -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -SYS_STATUS hdmitx_SetAVIInfoFrame(AVI_InfoFrame *pAVIInfoFrame) -{ - int i ; - byte checksum ; - - if(!pAVIInfoFrame) - { - return ER_FAIL ; - } - Switch_HDMITX_Bank(1); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB1,pAVIInfoFrame->pktbyte.AVI_DB[0]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB2,pAVIInfoFrame->pktbyte.AVI_DB[1]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB3,pAVIInfoFrame->pktbyte.AVI_DB[2]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB4,pAVIInfoFrame->pktbyte.AVI_DB[3]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB5,pAVIInfoFrame->pktbyte.AVI_DB[4]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB6,pAVIInfoFrame->pktbyte.AVI_DB[5]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB7,pAVIInfoFrame->pktbyte.AVI_DB[6]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB8,pAVIInfoFrame->pktbyte.AVI_DB[7]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB9,pAVIInfoFrame->pktbyte.AVI_DB[8]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB10,pAVIInfoFrame->pktbyte.AVI_DB[9]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB11,pAVIInfoFrame->pktbyte.AVI_DB[10]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB12,pAVIInfoFrame->pktbyte.AVI_DB[11]); - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB13,pAVIInfoFrame->pktbyte.AVI_DB[12]); - for(i = 0,checksum = 0; i < 13 ; i++) - { - checksum -= pAVIInfoFrame->pktbyte.AVI_DB[i] ; - } - /* - HDMITX_DEBUG_PRINTF(("SetAVIInfo(): ")); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB1))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB2))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB3))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB4))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB5))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB6))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB7))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB8))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB9))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB10))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB11))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB12))); - HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB13))); - HDMITX_DEBUG_PRINTF(("\n")); - */ - checksum -= AVI_INFOFRAME_VER+AVI_INFOFRAME_TYPE+AVI_INFOFRAME_LEN ; - HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_SUM,checksum); - - Switch_HDMITX_Bank(0); - hdmitx_ENABLE_AVI_INFOFRM_PKT(); - return ER_SUCCESS ; -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_SetAudioInfoFrame() -// Parameter: pAudioInfoFrame - the pointer to HDMI Audio Infoframe ucData -// Return: N/A -// Remark: Fill the Audio InfoFrame ucData,and count checksum,then fill into -// Audio InfoFrame registers. -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -SYS_STATUS hdmitx_SetAudioInfoFrame(Audio_InfoFrame *pAudioInfoFrame) -{ - BYTE checksum ; - - if(!pAudioInfoFrame) - { - return ER_FAIL ; - } - Switch_HDMITX_Bank(1); - checksum = 0x100-(AUDIO_INFOFRAME_VER+AUDIO_INFOFRAME_TYPE+AUDIO_INFOFRAME_LEN ); - HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_CC,pAudioInfoFrame->pktbyte.AUD_DB[0]); - checksum -= HDMITX_ReadI2C_Byte(REG_TX_PKT_AUDINFO_CC); checksum &= 0xFF ; - HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_SF,pAudioInfoFrame->pktbyte.AUD_DB[1]); - checksum -= HDMITX_ReadI2C_Byte(REG_TX_PKT_AUDINFO_SF); checksum &= 0xFF ; - HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_CA,pAudioInfoFrame->pktbyte.AUD_DB[3]); - checksum -= HDMITX_ReadI2C_Byte(REG_TX_PKT_AUDINFO_CA); checksum &= 0xFF ; - HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_DM_LSV,pAudioInfoFrame->pktbyte.AUD_DB[4]); - checksum -= HDMITX_ReadI2C_Byte(REG_TX_PKT_AUDINFO_DM_LSV); checksum &= 0xFF ; - - HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_SUM,checksum); - - Switch_HDMITX_Bank(0); - hdmitx_ENABLE_AUD_INFOFRM_PKT(); - return ER_SUCCESS ; -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_SetSPDInfoFrame() -// Parameter: pSPDInfoFrame - the pointer to HDMI SPD Infoframe ucData -// Return: N/A -// Remark: Fill the SPD InfoFrame ucData,and count checksum,then fill into -// SPD InfoFrame registers. -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -SYS_STATUS hdmitx_SetSPDInfoFrame(SPD_InfoFrame *pSPDInfoFrame) -{ - int i ; - BYTE ucData ; - - if(!pSPDInfoFrame) - { - return ER_FAIL ; - } - Switch_HDMITX_Bank(1); - for(i = 0,ucData = 0 ; i < 25 ; i++) - { - ucData -= pSPDInfoFrame->pktbyte.SPD_DB[i] ; - HDMITX_WriteI2C_Byte(REG_TX_PKT_SPDINFO_PB1+i,pSPDInfoFrame->pktbyte.SPD_DB[i]); - } - ucData -= SPD_INFOFRAME_VER+SPD_INFOFRAME_TYPE+SPD_INFOFRAME_LEN ; - HDMITX_WriteI2C_Byte(REG_TX_PKT_SPDINFO_SUM,ucData); // checksum - Switch_HDMITX_Bank(0); - hdmitx_ENABLE_SPD_INFOFRM_PKT(); - return ER_SUCCESS ; -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_SetMPEGInfoFrame() -// Parameter: pMPEGInfoFrame - the pointer to HDMI MPEG Infoframe ucData -// Return: N/A -// Remark: Fill the MPEG InfoFrame ucData,and count checksum,then fill into -// MPEG InfoFrame registers. -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -SYS_STATUS hdmitx_SetMPEGInfoFrame(MPEG_InfoFrame *pMPGInfoFrame) -{ - int i ; - BYTE ucData ; - - if(!pMPGInfoFrame) - { - return ER_FAIL ; - } - Switch_HDMITX_Bank(1); - - HDMITX_WriteI2C_Byte(REG_TX_PKT_MPGINFO_FMT,pMPGInfoFrame->info.FieldRepeat|(pMPGInfoFrame->info.MpegFrame<<1)); - HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_DB0,pMPGInfoFrame->pktbyte.MPG_DB[0]); - HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_DB1,pMPGInfoFrame->pktbyte.MPG_DB[1]); - HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_DB2,pMPGInfoFrame->pktbyte.MPG_DB[2]); - HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_DB3,pMPGInfoFrame->pktbyte.MPG_DB[3]); - - for(ucData = 0,i = 0 ; i < 5 ; i++) - { - ucData -= pMPGInfoFrame->pktbyte.MPG_DB[i] ; - } - ucData -= MPEG_INFOFRAME_VER+MPEG_INFOFRAME_TYPE+MPEG_INFOFRAME_LEN ; - - HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_SUM,ucData); - - Switch_HDMITX_Bank(0); - hdmitx_ENABLE_SPD_INFOFRM_PKT(); - - return ER_SUCCESS ; -} - -// 2009/12/04 added by Ming-chih.lung@ite.com.tw - -SYS_STATUS hdmitx_SetVSIInfoFrame(VendorSpecific_InfoFrame *pVSIInfoFrame) -{ - BYTE ucData=0 ; - - if(!pVSIInfoFrame) - { - return ER_FAIL ; - } - - Switch_HDMITX_Bank(1); - HDMITX_WriteI2C_Byte(0x80,pVSIInfoFrame->pktbyte.VS_DB[3]); - HDMITX_WriteI2C_Byte(0x81,pVSIInfoFrame->pktbyte.VS_DB[4]); - - ucData -= pVSIInfoFrame->pktbyte.VS_DB[3] ; - ucData -= pVSIInfoFrame->pktbyte.VS_DB[4] ; - - if( pVSIInfoFrame->pktbyte.VS_DB[4] & (1<<7 )) - { - ucData -= pVSIInfoFrame->pktbyte.VS_DB[5] ; - HDMITX_WriteI2C_Byte(0x82,pVSIInfoFrame->pktbyte.VS_DB[5]); - ucData -= VENDORSPEC_INFOFRAME_TYPE + VENDORSPEC_INFOFRAME_VER + 6 + 0x0C + 0x03 ; - } - else - { - ucData -= VENDORSPEC_INFOFRAME_TYPE + VENDORSPEC_INFOFRAME_VER + 5 + 0x0C + 0x03 ; - } - - pVSIInfoFrame->pktbyte.CheckSum=ucData; - - HDMITX_WriteI2C_Byte(0x83,pVSIInfoFrame->pktbyte.CheckSum); - Switch_HDMITX_Bank(0); - HDMITX_WriteI2C_Byte(REG_TX_3D_INFO_CTRL,B_TX_ENABLE_PKT|B_TX_REPEAT_PKT); - return ER_SUCCESS ; -} - -SYS_STATUS hdmitx_Set_GeneralPurpose_PKT(BYTE *pData) -{ - int i ; - - if( pData == NULL ) - { - return ER_FAIL ; - - } - Switch_HDMITX_Bank(1); - for( i = 0x38 ; i <= 0x56 ; i++) - { - HDMITX_WriteI2C_Byte(i, pData[i-0x38] ); - } - Switch_HDMITX_Bank(0); - hdmitx_ENABLE_GeneralPurpose_PKT(); - //hdmitx_ENABLE_NULL_PKT(); - return ER_SUCCESS ; -} - -////////////////////////////////////////////////////////////////////// -// Function: DumpHDMITXReg() -// Parameter: N/A -// Return: N/A -// Remark: Debug function,dumps the registers of CAT6611. -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -#if Debug_message -void DumpHDMITXReg() -{ - int i,j ; - BYTE ucData ; - - printk( "[%s]\n", __FUNCTION__); - HDMITX_DEBUG_PRINTF((" ")); - for(j = 0 ; j < 16 ; j++) - { - HDMITX_DEBUG_PRINTF((" %02X",(int)j)); - if((j == 3)||(j==7)||(j==11)) - { - HDMITX_DEBUG_PRINTF((" ")); - } - } - HDMITX_DEBUG_PRINTF(("\n -----------------------------------------------------\n")); - - Switch_HDMITX_Bank(0); - - for(i = 0 ; i < 0x100 ; i+=16) - { - HDMITX_DEBUG_PRINTF(("[%3X] ",i)); - for(j = 0 ; j < 16 ; j++) - { - if( (i+j)!= 0x17) - { - ucData = HDMITX_ReadI2C_Byte((BYTE)((i+j)&0xFF)); - HDMITX_DEBUG_PRINTF((" %02X",(int)ucData)); - } - else - { - HDMITX_DEBUG_PRINTF((" XX")); // for DDC FIFO - } - if((j == 3)||(j==7)||(j==11)) - { - HDMITX_DEBUG_PRINTF((" -")); - } - } - HDMITX_DEBUG_PRINTF(("\n")); - if((i % 0x40) == 0x30) - { - HDMITX_DEBUG_PRINTF((" -----------------------------------------------------\n")); - } - } - Switch_HDMITX_Bank(1); - for(i = 0x130; i < 0x200 ; i+=16) - { - HDMITX_DEBUG_PRINTF(("[%3X] ",i)); - for(j = 0 ; j < 16 ; j++) - { - ucData = HDMITX_ReadI2C_Byte((BYTE)((i+j)&0xFF)); - HDMITX_DEBUG_PRINTF((" %02X",(int)ucData)); - if((j == 3)||(j==7)||(j==11)) - { - HDMITX_DEBUG_PRINTF((" -")); - } - } - HDMITX_DEBUG_PRINTF(("\n")); - if((i % 0x40) == 0x20) - { - HDMITX_DEBUG_PRINTF((" -----------------------------------------------------\n")); - } - } - HDMITX_DEBUG_PRINTF((" -----------------------------------------------------\n")); - Switch_HDMITX_Bank(0); -} - -#endif - diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.h b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.h deleted file mode 100755 index 7a998933668d..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.h +++ /dev/null @@ -1,747 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ - -#ifndef _HDMITX_DRV_H_ -#define _HDMITX_DRV_H_ - -//#define EXTERN_HDCPROM -///////////////////////////////////////// -// DDC Address -///////////////////////////////////////// -#define DDC_HDCP_ADDRESS 0x74 -#define DDC_EDID_ADDRESS 0xA0 -#define DDC_FIFO_MAXREQ 0x20 - -// I2C address - -#define _80MHz 80000000 -#define HDMI_TX_I2C_SLAVE_ADDR 0x98 -#define CEC_I2C_SLAVE_ADDR 0x9C - -//#define DISABLE_HDMITX_CSC -/////////////////////////////////////////////////////////////////////// -// Register offset -/////////////////////////////////////////////////////////////////////// - -#define REG_TX_VENDOR_ID0 0x00 -#define REG_TX_VENDOR_ID1 0x01 -#define REG_TX_DEVICE_ID0 0x02 -#define REG_TX_DEVICE_ID1 0x03 - - #define O_TX_DEVID 0 - #define M_TX_DEVID 0xF - #define O_TX_REVID 4 - #define M_TX_REVID 0xF - -#define REG_TX_SW_RST 0x04 - #define B_TX_ENTEST (1<<7) - #define B_TX_REF_RST_HDMITX (1<<5) - #define B_TX_AREF_RST (1<<4) - #define B_HDMITX_VID_RST (1<<3) - #define B_HDMITX_AUD_RST (1<<2) - #define B_TX_HDMI_RST (1<<1) - #define B_TX_HDCP_RST_HDMITX (1<<0) - -#define REG_TX_INT_CTRL 0x05 - #define B_TX_INTPOL_ACTL 0 - #define B_TX_INTPOL_ACTH (1<<7) - #define B_TX_INT_PUSHPULL 0 - #define B_TX_INT_OPENDRAIN (1<<6) - -#define REG_TX_INT_STAT1 0x06 - #define B_TX_INT_AUD_OVERFLOW (1<<7) - #define B_TX_INT_ROMACQ_NOACK (1<<6) - #define B_TX_INT_RDDC_NOACK (1<<5) - #define B_TX_INT_DDCFIFO_ERR (1<<4) - #define B_TX_INT_ROMACQ_BUS_HANG (1<<3) - #define B_TX_INT_DDC_BUS_HANG (1<<2) - #define B_TX_INT_RX_SENSE (1<<1) - #define B_TX_INT_HPD_PLUG (1<<0) - -#define REG_TX_INT_STAT2 0x07 - #define B_TX_INT_HDCP_SYNC_DET_FAIL (1<<7) - #define B_TX_INT_VID_UNSTABLE (1<<6) - #define B_TX_INT_PKTACP (1<<5) - #define B_TX_INT_PKTNULL (1<<4) - #define B_TX_INT_PKTGENERAL (1<<3) - #define B_TX_INT_KSVLIST_CHK (1<<2) - #define B_TX_INT_AUTH_DONE (1<<1) - #define B_TX_INT_AUTH_FAIL (1<<0) - -#define REG_TX_INT_STAT3 0x08 - #define B_TX_INT_AUD_CTS (1<<6) - #define B_TX_INT_VSYNC (1<<5) - #define B_TX_INT_VIDSTABLE (1<<4) - #define B_TX_INT_PKTMPG (1<<3) - #define B_TX_INT_PKTSPD (1<<2) - #define B_TX_INT_PKTAUD (1<<1) - #define B_TX_INT_PKTAVI (1<<0) - -#define REG_TX_INT_MASK1 0x09 - #define B_TX_AUDIO_OVFLW_MASK (1<<7) - #define B_TX_DDC_NOACK_MASK (1<<5) - #define B_TX_DDC_FIFO_ERR_MASK (1<<4) - #define B_TX_DDC_BUS_HANG_MASK (1<<2) - #define B_TX_RXSEN_MASK (1<<1) - #define B_TX_HPD_MASK (1<<0) - -#define REG_TX_INT_MASK2 0x0A - #define B_TX_PKT_AVI_MASK (1<<7) - #define B_TX_PKT_VID_UNSTABLE_MASK (1<<6) - #define B_TX_PKT_ACP_MASK (1<<5) - #define B_TX_PKT_NULL_MASK (1<<4) - #define B_TX_PKT_GEN_MASK (1<<3) - #define B_TX_KSVLISTCHK_MASK (1<<2) - #define B_TX_AUTH_DONE_MASK (1<<1) - #define B_TX_AUTH_FAIL_MASK (1<<0) - -#define REG_TX_INT_MASK3 0x0B - #define B_TX_HDCP_SYNC_DET_FAIL_MASK (1<<6) - #define B_TX_AUDCTS_MASK (1<<5) - #define B_TX_VSYNC_MASK (1<<4) - #define B_TX_VIDSTABLE_MASK (1<<3) - #define B_TX_PKT_MPG_MASK (1<<2) - #define B_TX_PKT_SPD_MASK (1<<1) - #define B_TX_PKT_AUD_MASK (1<<0) - -#define REG_TX_INT_CLR0 0x0C - #define B_TX_CLR_PKTACP (1<<7) - #define B_TX_CLR_PKTNULL (1<<6) - #define B_TX_CLR_PKTGENERAL (1<<5) - #define B_TX_CLR_KSVLISTCHK (1<<4) - #define B_TX_CLR_AUTH_DONE (1<<3) - #define B_TX_CLR_AUTH_FAIL (1<<2) - #define B_TX_CLR_RXSENSE (1<<1) - #define B_TX_CLR_HPD (1<<0) - -#define REG_TX_INT_CLR1 0x0D - #define B_TX_CLR_VSYNC (1<<7) - #define B_TX_CLR_VIDSTABLE (1<<6) - #define B_TX_CLR_PKTMPG (1<<5) - #define B_TX_CLR_PKTSPD (1<<4) - #define B_TX_CLR_PKTAUD (1<<3) - #define B_TX_CLR_PKTAVI (1<<2) - #define B_TX_CLR_HDCP_SYNC_DET_FAIL (1<<1) - #define B_TX_CLR_VID_UNSTABLE (1<<0) - -#define REG_TX_SYS_STATUS 0x0E - // readonly - #define B_TX_INT_ACTIVE (1<<7) - #define B_TX_HPDETECT (1<<6) - #define B_TX_RXSENDETECT (1<<5) - #define B_TXVIDSTABLE (1<<4) - // read/write - #define O_TX_CTSINTSTEP 2 - #define M_TX_CTSINTSTEP (3<<2) - #define B_TX_CLR_AUD_CTS (1<<1) - #define B_TX_INTACTDONE (1<<0) - -#define REG_TX_BANK_CTRL 0x0F - #define B_TX_BANK0 0 - #define B_TX_BANK1 1 - -// DDC - -#define REG_TX_DDC_MASTER_CTRL 0x10 - #define B_TX_MASTERROM (1<<1) - #define B_TX_MASTERDDC (0<<1) - #define B_TX_MASTERHOST (1<<0) - #define B_TX_MASTERHDCP (0<<0) - -#define REG_TX_DDC_HEADER 0x11 -#define REG_TX_DDC_REQOFF 0x12 -#define REG_TX_DDC_REQCOUNT 0x13 -#define REG_TX_DDC_EDIDSEG 0x14 -#define REG_TX_DDC_CMD 0x15 - #define CMD_DDC_SEQ_BURSTREAD 0 - #define CMD_LINK_CHKREAD 2 - #define CMD_EDID_READ 3 - #define CMD_FIFO_CLR 9 - #define CMD_GEN_SCLCLK 0xA - #define CMD_DDC_ABORT 0xF - -#define REG_TX_DDC_STATUS 0x16 - #define B_TX_DDC_DONE (1<<7) - #define B_TX_DDC_ACT (1<<6) - #define B_TX_DDC_NOACK (1<<5) - #define B_TX_DDC_WAITBUS (1<<4) - #define B_TX_DDC_ARBILOSE (1<<3) - #define B_TX_DDC_ERROR (B_TX_DDC_NOACK|B_TX_DDC_WAITBUS|B_TX_DDC_ARBILOSE) - #define B_TX_DDC_FIFOFULL (1<<2) - #define B_TX_DDC_FIFOEMPTY (1<<1) - -#define REG_TX_DDC_READFIFO 0x17 -#define REG_TX_ROM_STARTADDR 0x18 -#define REG_TX_HDCP_HEADER 0x19 -#define REG_TX_ROM_HEADER 0x1A -#define REG_TX_BUSHOLD_T 0x1B -#define REG_TX_ROM_STAT 0x1C - #define B_TX_ROM_DONE (1<<7) - #define B_TX_ROM_ACTIVE (1<<6) - #define B_TX_ROM_NOACK (1<<5) - #define B_TX_ROM_WAITBUS (1<<4) - #define B_TX_ROM_ARBILOSE (1<<3) - #define B_TX_ROM_BUSHANG (1<<2) - -// HDCP -#define REG_TX_AN_GENERATE 0x1F - #define B_TX_START_CIPHER_GEN 1 - #define B_TX_STOP_CIPHER_GEN 0 - -#define REG_TX_CLK_CTRL0 0x58 - #define O_TX_OSCLK_SEL 5 - #define M_TX_OSCLK_SEL 3 - #define B_TX_AUTO_OVER_SAMPLING_CLOCK (1<<4) - #define O_TX_EXT_MCLK_SEL 2 - #define M_TX_EXT_MCLK_SEL (3< -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ -#include "hdmitx.h" -#include "hdmitx_drv.h" -#include "sha1.h" - -static BYTE countbit(BYTE b); - -extern HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT] ; - -#ifdef SUPPORT_SHA -_XDATA BYTE SHABuff[64] ; -_XDATA BYTE V[20] ; -_XDATA BYTE KSVList[32] ; -_XDATA BYTE Vr[20] ; -_XDATA BYTE M0[8] ; -#endif - -BOOL HDMITX_EnableHDCP(BYTE bEnable) -{ -#ifdef SUPPORT_HDCP - if(bEnable) - { - if(ER_FAIL == hdmitx_hdcp_Authenticate()) - { - HDCP_DEBUG_PRINTF(("ER_FAIL == hdmitx_hdcp_Authenticate\n")); - hdmitx_hdcp_ResetAuth(); - return FALSE ; - } - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate SUCCESS\n")); - } - else - { - hdmiTxDev[0].bAuthenticated=FALSE; - hdmitx_hdcp_ResetAuth(); - } -#endif - return TRUE ; -} - -#ifdef SUPPORT_HDCP - -BOOL getHDMITX_AuthenticationDone(void) -{ - //HDCP_DEBUG_PRINTF((" getHDMITX_AuthenticationDone() = %s\n",hdmiTxDev[0].bAuthenticated?"TRUE":"FALSE" )); - return hdmiTxDev[0].bAuthenticated; -} - -////////////////////////////////////////////////////////////////////// -// Authentication -////////////////////////////////////////////////////////////////////// -void hdmitx_hdcp_ClearAuthInterrupt(void) -{ - // BYTE uc ; - // uc = HDMITX_ReadI2C_Byte(REG_TX_INT_MASK2) & (~(B_TX_KSVLISTCHK_MASK|B_TX_AUTH_DONE_MASK|B_TX_AUTH_FAIL_MASK)); - HDMITX_SetI2C_Byte(REG_TX_INT_MASK2, B_TX_KSVLISTCHK_MASK|B_TX_AUTH_DONE_MASK|B_TX_AUTH_FAIL_MASK, 0); - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,B_TX_CLR_AUTH_FAIL|B_TX_CLR_AUTH_DONE|B_TX_CLR_KSVLISTCHK); - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,B_TX_INTACTDONE); -} - -void hdmitx_hdcp_ResetAuth(void) -{ - HDMITX_WriteI2C_Byte(REG_TX_LISTCTRL,0); - HDMITX_WriteI2C_Byte(REG_TX_HDCP_DESIRE,0); - HDMITX_OrReg_Byte(REG_TX_SW_RST,B_TX_HDCP_RST_HDMITX); - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); - hdmitx_hdcp_ClearAuthInterrupt(); - hdmitx_AbortDDC(); -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_hdcp_Auth_Fire() -// Parameter: N/A -// Return: N/A -// Remark: write anything to reg21 to enable HDCP authentication by HW -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -void hdmitx_hdcp_Auth_Fire(void) -{ - // HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Auth_Fire():\n")); - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHDCP); // MASTERHDCP,no need command but fire. - HDMITX_WriteI2C_Byte(REG_TX_AUTHFIRE,1); -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_hdcp_StartAnCipher -// Parameter: N/A -// Return: N/A -// Remark: Start the Cipher to free run for random number. When stop,An is -// ready in Reg30. -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -void hdmitx_hdcp_StartAnCipher(void) -{ - HDMITX_WriteI2C_Byte(REG_TX_AN_GENERATE,B_TX_START_CIPHER_GEN); - delay1ms(1); // delay 1 ms -} -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_hdcp_StopAnCipher -// Parameter: N/A -// Return: N/A -// Remark: Stop the Cipher,and An is ready in Reg30. -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -void hdmitx_hdcp_StopAnCipher(void) -{ - HDMITX_WriteI2C_Byte(REG_TX_AN_GENERATE,B_TX_STOP_CIPHER_GEN); -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_hdcp_GenerateAn -// Parameter: N/A -// Return: N/A -// Remark: start An ciper random run at first,then stop it. Software can get -// an in reg30~reg38,the write to reg28~2F -// Side-Effect: -////////////////////////////////////////////////////////////////////// - -void hdmitx_hdcp_GenerateAn(void) -{ - BYTE Data[8]; - BYTE i=0; -#if 1 - hdmitx_hdcp_StartAnCipher(); - // HDMITX_WriteI2C_Byte(REG_TX_AN_GENERATE,B_TX_START_CIPHER_GEN); - // delay1ms(1); // delay 1 ms - // HDMITX_WriteI2C_Byte(REG_TX_AN_GENERATE,B_TX_STOP_CIPHER_GEN); - - hdmitx_hdcp_StopAnCipher(); - - Switch_HDMITX_Bank(0); - // new An is ready in reg30 - HDMITX_ReadI2C_ByteN(REG_TX_AN_GEN,Data,8); -#else - Data[0] = 0 ;Data[1] = 0 ;Data[2] = 0 ;Data[3] = 0 ; - Data[4] = 0 ;Data[5] = 0 ;Data[6] = 0 ;Data[7] = 0 ; -#endif - for(i=0;i<8;i++) - { - HDMITX_WriteI2C_Byte(REG_TX_AN+i,Data[i]); - } - //HDMITX_WriteI2C_ByteN(REG_TX_AN,Data,8); -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_hdcp_GetBCaps -// Parameter: pBCaps - pointer of byte to get BCaps. -// pBStatus - pointer of two bytes to get BStatus -// Return: ER_SUCCESS if successfully got BCaps and BStatus. -// Remark: get B status and capability from HDCP reciever via DDC bus. -// Side-Effect: -////////////////////////////////////////////////////////////////////// - -SYS_STATUS hdmitx_hdcp_GetBCaps(PBYTE pBCaps ,PUSHORT pBStatus) -{ - BYTE ucdata ; - BYTE TimeOut ; - - Switch_HDMITX_Bank(0); - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); - HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,DDC_HDCP_ADDRESS); - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,0x40); // BCaps offset - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,3); - HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD); - - for(TimeOut = 200 ; TimeOut > 0 ; TimeOut --) - { - delay1ms(1); - - ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); - - if(ucdata & B_TX_DDC_DONE) - { - //HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): DDC Done.\n")); - break ; - } - if(ucdata & B_TX_DDC_ERROR) - { -// HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): DDC fail by reg16=%02X.\n",ucdata)); - return ER_FAIL ; - } - } - if(TimeOut == 0) - { - return ER_FAIL ; - } -#if 1 - ucdata = HDMITX_ReadI2C_Byte(REG_TX_BSTAT+1); - - *pBStatus = (USHORT)ucdata ; - *pBStatus <<= 8 ; - ucdata = HDMITX_ReadI2C_Byte(REG_TX_BSTAT); - *pBStatus |= ((USHORT)ucdata&0xFF); - *pBCaps = HDMITX_ReadI2C_Byte(REG_TX_BCAP); -#else - *pBCaps = HDMITX_ReadI2C_Byte(0x17); - *pBStatus = HDMITX_ReadI2C_Byte(0x17) & 0xFF ; - *pBStatus |= (int)(HDMITX_ReadI2C_Byte(0x17)&0xFF)<<8; - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): ucdata = %02X\n",(int)HDMITX_ReadI2C_Byte(0x16))); -#endif - return ER_SUCCESS ; -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_hdcp_GetBKSV -// Parameter: pBKSV - pointer of 5 bytes buffer for getting BKSV -// Return: ER_SUCCESS if successfuly got BKSV from Rx. -// Remark: Get BKSV from HDCP reciever. -// Side-Effect: N/A -////////////////////////////////////////////////////////////////////// - -SYS_STATUS hdmitx_hdcp_GetBKSV(BYTE *pBKSV) -{ - BYTE ucdata ; - BYTE TimeOut ; - - Switch_HDMITX_Bank(0); - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); - HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,DDC_HDCP_ADDRESS); - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,0x00); // BKSV offset - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,5); - HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD); - - for(TimeOut = 200 ; TimeOut > 0 ; TimeOut --) - { - delay1ms(1); - - ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); - if(ucdata & B_TX_DDC_DONE) - { - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): DDC Done.\n")); - break ; - } - if(ucdata & B_TX_DDC_ERROR) - { - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): DDC No ack or arbilose,%x,maybe cable did not connected. Fail.\n",ucdata)); - return ER_FAIL ; - } - } - if(TimeOut == 0) - { - return ER_FAIL ; - } - HDMITX_ReadI2C_ByteN(REG_TX_BKSV,(PBYTE)pBKSV,5); - - return ER_SUCCESS ; -} - -////////////////////////////////////////////////////////////////////// -// Function:hdmitx_hdcp_Authenticate -// Parameter: N/A -// Return: ER_SUCCESS if Authenticated without error. -// Remark: do Authentication with Rx -// Side-Effect: -// 1. hdmiTxDev[0].bAuthenticated global variable will be TRUE when authenticated. -// 2. Auth_done interrupt and AUTH_FAIL interrupt will be enabled. -////////////////////////////////////////////////////////////////////// -static BYTE countbit(BYTE b) -{ - BYTE i,count ; - for( i = 0, count = 0 ; i < 8 ; i++ ) - { - if( b & (1< 6) - { - HDCP_DEBUG_PRINTF(("Down Stream Count %d is over maximum supported number 6,fail.\n",(int)(BStatus & M_TX_DOWNSTREAM_COUNT))); - return ER_FAIL ; - } - */ - HDCP_DEBUG_PRINTF(("BCAPS = %02X BSTATUS = %04X\n", (int)BCaps, BStatus)); - hdmitx_hdcp_GetBKSV(BKSV); - HDCP_DEBUG_PRINTF(("BKSV %02X %02X %02X %02X %02X\n",(int)BKSV[0],(int)BKSV[1],(int)BKSV[2],(int)BKSV[3],(int)BKSV[4])); - - for(TimeOut = 0, ucdata = 0 ; TimeOut < 5 ; TimeOut ++) - { - ucdata += countbit(BKSV[TimeOut]); - } - if( ucdata != 20 ) - { - HDCP_DEBUG_PRINTF(("countbit error\n")); - return ER_FAIL ; - - } - Switch_HDMITX_Bank(0); // switch bank action should start on direct register writting of each function. - - HDMITX_AndReg_Byte(REG_TX_SW_RST,~(B_TX_HDCP_RST_HDMITX)); - - HDMITX_WriteI2C_Byte(REG_TX_HDCP_DESIRE,B_TX_CPDESIRE); - hdmitx_hdcp_ClearAuthInterrupt(); - - hdmitx_hdcp_GenerateAn(); - HDMITX_WriteI2C_Byte(REG_TX_LISTCTRL,0); - hdmiTxDev[0].bAuthenticated = FALSE ; - - hdmitx_ClearDDCFIFO(); - - if((BCaps & B_TX_CAP_HDMI_REPEATER) == 0) - { - hdmitx_hdcp_Auth_Fire(); - // wait for status ; - - for(TimeOut = 250 ; TimeOut > 0 ; TimeOut --) - { - delay1ms(5); // delay 1ms - ucdata = HDMITX_ReadI2C_Byte(REG_TX_AUTH_STAT); - // HDCP_DEBUG_PRINTF(("reg46 = %02x reg16 = %02x\n",(int)ucdata,(int)HDMITX_ReadI2C_Byte(0x16))); - - if(ucdata & B_TX_AUTH_DONE) - { - hdmiTxDev[0].bAuthenticated = TRUE ; - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate()-receiver: Authenticate SUCESS\n")); - break ; - } - ucdata = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT2); - if(ucdata & B_TX_INT_AUTH_FAIL) - { - - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,B_TX_CLR_AUTH_FAIL); - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,B_TX_INTACTDONE); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,0); - - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate()-receiver: Authenticate fail\n")); - hdmiTxDev[0].bAuthenticated = FALSE ; - return ER_FAIL ; - } - } - if(TimeOut == 0) - { - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate()-receiver: Time out. return fail\n")); - hdmiTxDev[0].bAuthenticated = FALSE ; - return ER_FAIL ; - } - return ER_SUCCESS ; - } - return hdmitx_hdcp_Authenticate_Repeater(); -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_hdcp_VerifyIntegration -// Parameter: N/A -// Return: ER_SUCCESS if success,if AUTH_FAIL interrupt status,return fail. -// Remark: no used now. -// Side-Effect: -////////////////////////////////////////////////////////////////////// - -SYS_STATUS hdmitx_hdcp_VerifyIntegration() -{ - // if any interrupt issued a Auth fail,returned the Verify Integration fail. - - if(HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1) & B_TX_INT_AUTH_FAIL) - { - hdmitx_hdcp_ClearAuthInterrupt(); - hdmiTxDev[0].bAuthenticated = FALSE ; - return ER_FAIL ; - } - if(hdmiTxDev[0].bAuthenticated == TRUE) - { - return ER_SUCCESS ; - } - return ER_FAIL ; -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_hdcp_Authenticate_Repeater -// Parameter: BCaps and BStatus -// Return: ER_SUCCESS if success,if AUTH_FAIL interrupt status,return fail. -// Remark: -// Side-Effect: as Authentication -////////////////////////////////////////////////////////////////////// - -void hdmitx_hdcp_CancelRepeaterAuthenticate() -{ - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_CancelRepeaterAuthenticate")); - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); - hdmitx_AbortDDC(); - HDMITX_WriteI2C_Byte(REG_TX_LISTCTRL,B_TX_LISTFAIL|B_TX_LISTDONE); - hdmitx_hdcp_ClearAuthInterrupt(); -} - -void hdmitx_hdcp_ResumeRepeaterAuthenticate() -{ - HDMITX_WriteI2C_Byte(REG_TX_LISTCTRL,B_TX_LISTDONE); - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERHDCP); -} - -#if 0 // def SUPPORT_SHA -// #define SHA_BUFF_COUNT 17 -// _XDATA ULONG w[SHA_BUFF_COUNT]; -// -// _XDATA ULONG sha[5] ; -// -// #define rol(x,y) (((x) << (y)) | (((ULONG)x) >> (32-y))) -// -// void SHATransform(ULONG * h) -// { -// int t,i; -// ULONG tmp ; -// -// h[0] = 0x67452301 ; -// h[1] = 0xefcdab89; -// h[2] = 0x98badcfe; -// h[3] = 0x10325476; -// h[4] = 0xc3d2e1f0; -// for( t = 0 ; t < 80 ; t++ ) -// { -// if((t>=16)&&(t<80)) { -// i=(t+SHA_BUFF_COUNT-3)%SHA_BUFF_COUNT; -// tmp = w[i]; -// i=(t+SHA_BUFF_COUNT-8)%SHA_BUFF_COUNT; -// tmp ^= w[i]; -// i=(t+SHA_BUFF_COUNT-14)%SHA_BUFF_COUNT; -// tmp ^= w[i]; -// i=(t+SHA_BUFF_COUNT-16)%SHA_BUFF_COUNT; -// tmp ^= w[i]; -// w[t%SHA_BUFF_COUNT] = rol(tmp,1); -// //HDCP_DEBUG_PRINTF(("w[%2d] = %08lX\n",t,w[t%SHA_BUFF_COUNT])); -// } -// -// if((t>=0)&&(t<20)) { -// tmp = rol(h[0],5) + ((h[1] & h[2]) | (h[3] & ~h[1])) + h[4] + w[t%SHA_BUFF_COUNT] + 0x5a827999; -// //HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); -// -// h[4] = h[3]; -// h[3] = h[2]; -// h[2] = rol(h[1],30); -// h[1] = h[0]; -// h[0] = tmp; -// -// } -// if((t>=20)&&(t<40)) { -// tmp = rol(h[0],5) + (h[1] ^ h[2] ^ h[3]) + h[4] + w[t%SHA_BUFF_COUNT] + 0x6ed9eba1; -// //HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); -// h[4] = h[3]; -// h[3] = h[2]; -// h[2] = rol(h[1],30); -// h[1] = h[0]; -// h[0] = tmp; -// } -// if((t>=40)&&(t<60)) { -// tmp = rol(h[0], 5) + ((h[1] & h[2]) | (h[1] & h[3]) | (h[2] & h[3])) + h[4] + w[t%SHA_BUFF_COUNT] + -// 0x8f1bbcdc; -// //HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); -// h[4] = h[3]; -// h[3] = h[2]; -// h[2] = rol(h[1],30); -// h[1] = h[0]; -// h[0] = tmp; -// } -// if((t>=60)&&(t<80)) { -// tmp = rol(h[0],5) + (h[1] ^ h[2] ^ h[3]) + h[4] + w[t%SHA_BUFF_COUNT] + 0xca62c1d6; -// //HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); -// h[4] = h[3]; -// h[3] = h[2]; -// h[2] = rol(h[1],30); -// h[1] = h[0]; -// h[0] = tmp; -// } -// } -// HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); -// -// h[0] += 0x67452301 ; -// h[1] += 0xefcdab89; -// h[2] += 0x98badcfe; -// h[3] += 0x10325476; -// h[4] += 0xc3d2e1f0; -// // HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); -// } -// -// /* ---------------------------------------------------------------------- -// * Outer SHA algorithm: take an arbitrary length byte string, -// * convert it into 16-word blocks with the prescribed padding at -// * the end,and pass those blocks to the core SHA algorithm. -// */ -// -// void SHA_Simple(void *p,LONG len,BYTE *output) -// { -// // SHA_State s; -// int i, t ; -// ULONG c ; -// char *pBuff = p ; -// -// for(i=0;i < len;i+=4) -// { -// -// t=i/4; -// w[t]=0; -// *((char *)&c)= pBuff[i]; -// *((char *)&c+1)= pBuff[i+1]; -// *((char *)&c+2)= pBuff[i+2]; -// *((char *)&c+3)= pBuff[i+3]; -// w[t]=c; -// } -// -// c=0x80; -// c<<=((3-len%4)*8); -// w[t] |= c; -// -// /* -// for( i = 0 ; i < len ; i++ ) -// { -// t = i/4 ; -// if( i%4 == 0 ) -// { -// w[t] = 0 ; -// } -// c = pBuff[i] ; -// c &= 0xFF ; -// c <<= (3-(i%4))*8 ; -// w[t] |= c ; -// // HDCP_DEBUG_PRINTF(("pBuff[%d] = %02x, c = %08lX, w[%d] = %08lX\n",i,pBuff[i],c,t,w[t])); -// } -// -// t = i/4 ; -// if( i%4 == 0 ) -// { -// w[t] = 0 ; -// } -// c = 0x80; -// c <<= ((3-i%4)*8); -// w[t]|= c ; -// */ -// t++ ; -// for( ; t < 15 ; t++ ) -// { -// w[t] = 0 ; -// } -// w[15] = len*8 ; -// -// for( t = 0 ; t< 16 ; t++ ) -// { -// HDCP_DEBUG_PRINTF(("w[%2d] = %08lX\n",t,w[t])); -// } -// -// SHATransform(sha); -// -// for( i = 0 ; i < 5 ; i++ ) -// { -// output[i*4] = (BYTE)(sha[i]&0xFF); -// output[i*4+1] = (BYTE)((sha[i]>>8)&0xFF); -// output[i*4+2] = (BYTE)((sha[i]>>16)&0xFF); -// output[i*4+3] = (BYTE)((sha[i]>>24)&0xFF); -// } -// } -#endif // 0 - -#ifdef SUPPORT_SHA - -SYS_STATUS hdmitx_hdcp_CheckSHA(BYTE pM0[],USHORT BStatus,BYTE pKSVList[],int cDownStream,BYTE Vr[]) -{ - int i,n ; - - for(i = 0 ; i < cDownStream*5 ; i++) - { - SHABuff[i] = pKSVList[i] ; - } - SHABuff[i++] = BStatus & 0xFF ; - SHABuff[i++] = (BStatus>>8) & 0xFF ; - for(n = 0 ; n < 8 ; n++,i++) - { - SHABuff[i] = pM0[n] ; - } - n = i ; - // SHABuff[i++] = 0x80 ; // end mask - for(; i < 64 ; i++) - { - SHABuff[i] = 0 ; - } - // n = cDownStream * 5 + 2 /* for BStatus */ + 8 /* for M0 */ ; - // n *= 8 ; - // SHABuff[62] = (n>>8) & 0xff ; - // SHABuff[63] = (n>>8) & 0xff ; -/* - for(i = 0 ; i < 64 ; i++) - { - if(i % 16 == 0) - { - HDCP_DEBUG_PRINTF(("SHA[]: ")); - } - HDCP_DEBUG_PRINTF((" %02X",SHABuff[i])); - if((i%16)==15) - { - HDCP_DEBUG_PRINTF(("\n")); - } - } - */ - SHA_Simple(SHABuff,n,V); - for(i = 0 ; i < 20 ; i++) - { - if(V[i] != Vr[i]) - { - HDCP_DEBUG_PRINTF(("V[] =")); - for(i = 0 ; i < 20 ; i++) - { - HDCP_DEBUG_PRINTF((" %02X",(int)V[i])); - } - HDCP_DEBUG_PRINTF(("\nVr[] =")); - for(i = 0 ; i < 20 ; i++) - { - HDCP_DEBUG_PRINTF((" %02X",(int)Vr[i])); - } - return ER_FAIL ; - } - } - return ER_SUCCESS ; -} - -#endif // SUPPORT_SHA - -SYS_STATUS hdmitx_hdcp_GetKSVList(BYTE *pKSVList,BYTE cDownStream) -{ - BYTE TimeOut = 100 ; - BYTE ucdata ; - - if( cDownStream == 0 ) - { - return ER_SUCCESS ; - } - if( /* cDownStream == 0 || */ pKSVList == NULL) - { - return ER_FAIL ; - } - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERHOST); - HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,0x74); - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,0x43); - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,cDownStream * 5); - HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD); - - for(TimeOut = 200 ; TimeOut > 0 ; TimeOut --) - { - - ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); - if(ucdata & B_TX_DDC_DONE) - { - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetKSVList(): DDC Done.\n")); - break ; - } - if(ucdata & B_TX_DDC_ERROR) - { - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetKSVList(): DDC Fail by REG_TX_DDC_STATUS = %x.\n",ucdata)); - return ER_FAIL ; - } - delay1ms(5); - } - if(TimeOut == 0) - { - return ER_FAIL ; - } - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetKSVList(): KSV")); - for(TimeOut = 0 ; TimeOut < cDownStream * 5 ; TimeOut++) - { - pKSVList[TimeOut] = HDMITX_ReadI2C_Byte(REG_TX_DDC_READFIFO); - HDCP_DEBUG_PRINTF((" %02X",(int)pKSVList[TimeOut])); - } - HDCP_DEBUG_PRINTF(("\n")); - return ER_SUCCESS ; -} - -SYS_STATUS hdmitx_hdcp_GetVr(BYTE *pVr) -{ - BYTE TimeOut ; - BYTE ucdata ; - - if(pVr == NULL) - { - return ER_FAIL ; - } - HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERHOST); - HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,0x74); - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,0x20); - HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,20); - HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD); - - for(TimeOut = 200 ; TimeOut > 0 ; TimeOut --) - { - ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); - if(ucdata & B_TX_DDC_DONE) - { - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetVr(): DDC Done.\n")); - break ; - } - if(ucdata & B_TX_DDC_ERROR) - { - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetVr(): DDC fail by REG_TX_DDC_STATUS = %x.\n",(int)ucdata)); - return ER_FAIL ; - } - delay1ms(5); - } - if(TimeOut == 0) - { - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetVr(): DDC fail by timeout.\n")); - return ER_FAIL ; - } - Switch_HDMITX_Bank(0); - - for(TimeOut = 0 ; TimeOut < 5 ; TimeOut++) - { - HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL ,TimeOut); - pVr[TimeOut*4] = (ULONG)HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE1); - pVr[TimeOut*4+1] = (ULONG)HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE2); - pVr[TimeOut*4+2] = (ULONG)HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE3); - pVr[TimeOut*4+3] = (ULONG)HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE4); -// HDCP_DEBUG_PRINTF(("V' = %02X %02X %02X %02X\n",(int)pVr[TimeOut*4],(int)pVr[TimeOut*4+1],(int)pVr[TimeOut*4+2],(int)pVr[TimeOut*4+3])); - } - return ER_SUCCESS ; -} - -SYS_STATUS hdmitx_hdcp_GetM0(BYTE *pM0) -{ - int i ; - - if(!pM0) - { - return ER_FAIL ; - } - HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,5); // read m0[31:0] from reg51~reg54 - pM0[0] = HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE1); - pM0[1] = HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE2); - pM0[2] = HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE3); - pM0[3] = HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE4); - HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,0); // read m0[39:32] from reg55 - pM0[4] = HDMITX_ReadI2C_Byte(REG_TX_AKSV_RD_BYTE5); - HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,1); // read m0[47:40] from reg55 - pM0[5] = HDMITX_ReadI2C_Byte(REG_TX_AKSV_RD_BYTE5); - HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,2); // read m0[55:48] from reg55 - pM0[6] = HDMITX_ReadI2C_Byte(REG_TX_AKSV_RD_BYTE5); - HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,3); // read m0[63:56] from reg55 - pM0[7] = HDMITX_ReadI2C_Byte(REG_TX_AKSV_RD_BYTE5); - - HDCP_DEBUG_PRINTF(("M[] =")); - for(i = 0 ; i < 8 ; i++) - { - HDCP_DEBUG_PRINTF(("0x%02x,",(int)pM0[i])); - } - HDCP_DEBUG_PRINTF(("\n")); - return ER_SUCCESS ; -} - -SYS_STATUS hdmitx_hdcp_Authenticate_Repeater() -{ - BYTE uc ,ii; - // BYTE revoked ; - // int i ; - BYTE cDownStream ; - - BYTE BCaps; - USHORT BStatus ; - USHORT TimeOut ; - - HDCP_DEBUG_PRINTF(("Authentication for repeater\n")); - // emily add for test,abort HDCP - // 2007/10/01 marked by jj_tseng@chipadvanced.com - // HDMITX_WriteI2C_Byte(0x20,0x00); - // HDMITX_WriteI2C_Byte(0x04,0x01); - // HDMITX_WriteI2C_Byte(0x10,0x01); - // HDMITX_WriteI2C_Byte(0x15,0x0F); - // delay1ms(100); - // HDMITX_WriteI2C_Byte(0x04,0x00); - // HDMITX_WriteI2C_Byte(0x10,0x00); - // HDMITX_WriteI2C_Byte(0x20,0x01); - // delay1ms(100); - // test07 = HDMITX_ReadI2C_Byte(0x7); - // test06 = HDMITX_ReadI2C_Byte(0x6); - // test08 = HDMITX_ReadI2C_Byte(0x8); - //~jj_tseng@chipadvanced.com - // end emily add for test - ////////////////////////////////////// - // Authenticate Fired - ////////////////////////////////////// - - hdmitx_hdcp_GetBCaps(&BCaps,&BStatus); - delay1ms(2); - if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) - { - HDCP_DEBUG_PRINTF(("HPD Before Fire Auth\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } - hdmitx_hdcp_Auth_Fire(); - //delay1ms(550); // emily add for test - for(ii=0;ii<55;ii++) //delay1ms(550); // emily add for test - { - if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) - { - goto hdmitx_hdcp_Repeater_Fail ; - } - delay1ms(10); - } - for(TimeOut = /*250*6*/10 ; TimeOut > 0 ; TimeOut --) - { - HDCP_DEBUG_PRINTF(("TimeOut = %d wait part 1\n",TimeOut)); - if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) - { - HDCP_DEBUG_PRINTF(("HPD at wait part 1\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } - uc = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1); - if(uc & B_TX_INT_DDC_BUS_HANG) - { - HDCP_DEBUG_PRINTF(("DDC Bus hang\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } - uc = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT2); - - if(uc & B_TX_INT_AUTH_FAIL) - { - /* - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,B_TX_CLR_AUTH_FAIL); - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,B_TX_INTACTDONE); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,0); - */ - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate_Repeater(): B_TX_INT_AUTH_FAIL.\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } - // emily add for test - // test =(HDMITX_ReadI2C_Byte(0x7)&0x4)>>2 ; - if(uc & B_TX_INT_KSVLIST_CHK) - { - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,B_TX_CLR_KSVLISTCHK); - HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,B_TX_INTACTDONE); - HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,0); - HDCP_DEBUG_PRINTF(("B_TX_INT_KSVLIST_CHK\n")); - break ; - } - delay1ms(5); - } - if(TimeOut == 0) - { - HDCP_DEBUG_PRINTF(("Time out for wait KSV List checking interrupt\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } - /////////////////////////////////////// - // clear KSVList check interrupt. - /////////////////////////////////////// - - for(TimeOut = 500 ; TimeOut > 0 ; TimeOut --) - { - HDCP_DEBUG_PRINTF(("TimeOut=%d at wait FIFO ready\n",TimeOut)); - if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) - { - HDCP_DEBUG_PRINTF(("HPD at wait FIFO ready\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } - if(hdmitx_hdcp_GetBCaps(&BCaps,&BStatus) == ER_FAIL) - { - HDCP_DEBUG_PRINTF(("Get BCaps fail\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } - if(BCaps & B_TX_CAP_KSV_FIFO_RDY) - { - HDCP_DEBUG_PRINTF(("FIFO Ready\n")); - break ; - } - delay1ms(5); - - } - if(TimeOut == 0) - { - HDCP_DEBUG_PRINTF(("Get KSV FIFO ready TimeOut\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } - HDCP_DEBUG_PRINTF(("Wait timeout = %d\n",TimeOut)); - - hdmitx_ClearDDCFIFO(); - hdmitx_GenerateDDCSCLK(); - cDownStream = (BStatus & M_TX_DOWNSTREAM_COUNT); - - if(/*cDownStream == 0 ||*/ cDownStream > 6 || BStatus & (B_TX_MAX_CASCADE_EXCEEDED|B_TX_DOWNSTREAM_OVER)) - { - HDCP_DEBUG_PRINTF(("Invalid Down stream count,fail\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } -#ifdef SUPPORT_SHA - if(hdmitx_hdcp_GetKSVList(KSVList,cDownStream) == ER_FAIL) - { - goto hdmitx_hdcp_Repeater_Fail ; - } -#if 0 - for(i = 0 ; i < cDownStream ; i++) - { - revoked=FALSE ; uc = 0 ; - for( TimeOut = 0 ; TimeOut < 5 ; TimeOut++ ) - { - // check bit count - uc += countbit(KSVList[i*5+TimeOut]); - } - if( uc != 20 ) revoked = TRUE ; - - if(revoked) - { -// HDCP_DEBUG_PRINTF(("KSVFIFO[%d] = %02X %02X %02X %02X %02X is revoked\n",i,(int)KSVList[i*5],(int)KSVList[i*5+1],(int)KSVList[i*5+2],(int)KSVList[i*5+3],(int)KSVList[i*5+4])); - goto hdmitx_hdcp_Repeater_Fail ; - } - } -#endif - - if(hdmitx_hdcp_GetVr(Vr) == ER_FAIL) - { - goto hdmitx_hdcp_Repeater_Fail ; - } - if(hdmitx_hdcp_GetM0(M0) == ER_FAIL) - { - goto hdmitx_hdcp_Repeater_Fail ; - } - // do check SHA - if(hdmitx_hdcp_CheckSHA(M0,BStatus,KSVList,cDownStream,Vr) == ER_FAIL) - { - goto hdmitx_hdcp_Repeater_Fail ; - } - if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) - { - HDCP_DEBUG_PRINTF(("HPD at Final\n")); - goto hdmitx_hdcp_Repeater_Fail ; - } -#endif // SUPPORT_SHA - - HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate()-receiver: Authenticate SUCESS\n")); - hdmitx_hdcp_ResumeRepeaterAuthenticate(); - hdmiTxDev[0].bAuthenticated = TRUE ; - return ER_SUCCESS ; - -hdmitx_hdcp_Repeater_Fail: - hdmitx_hdcp_CancelRepeaterAuthenticate(); - return ER_FAIL ; -} - -////////////////////////////////////////////////////////////////////// -// Function: hdmitx_hdcp_ResumeAuthentication -// Parameter: N/A -// Return: N/A -// Remark: called by interrupt handler to restart Authentication and Encryption. -// Side-Effect: as Authentication and Encryption. -////////////////////////////////////////////////////////////////////// - -void hdmitx_hdcp_ResumeAuthentication() -{ - setHDMITX_AVMute(TRUE); - if(hdmitx_hdcp_Authenticate() == ER_SUCCESS) - { - } - setHDMITX_AVMute(FALSE); -} - -#endif // SUPPORT_HDCP diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_hdcp.h b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_hdcp.h deleted file mode 100755 index 18c0434313c8..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_hdcp.h +++ /dev/null @@ -1,87 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ -#ifndef _HDMITX_HDCP_H_ -#define _HDMITX_HDCP_H_ - - -#define REG_TX_HDCP_DESIRE 0x20 - #define B_TX_ENABLE_HDPC11 (1<<1) - #define B_TX_CPDESIRE (1<<0) - -#define REG_TX_AUTHFIRE 0x21 -#define REG_TX_LISTCTRL 0x22 - #define B_TX_LISTFAIL (1<<1) - #define B_TX_LISTDONE (1<<0) - -#define REG_TX_AKSV 0x23 -#define REG_TX_AKSV0 0x23 -#define REG_TX_AKSV1 0x24 -#define REG_TX_AKSV2 0x25 -#define REG_TX_AKSV3 0x26 -#define REG_TX_AKSV4 0x27 - -#define REG_TX_AN 0x28 -#define REG_TX_AN_GEN 0x30 -#define REG_TX_ARI 0x38 -#define REG_TX_ARI0 0x38 -#define REG_TX_ARI1 0x39 -#define REG_TX_APJ 0x3A - -#define REG_TX_BKSV 0x3B -#define REG_TX_BRI 0x40 -#define REG_TX_BRI0 0x40 -#define REG_TX_BRI1 0x41 -#define REG_TX_BPJ 0x42 -#define REG_TX_BCAP 0x43 - #define B_TX_CAP_HDMI_REPEATER (1<<6) - #define B_TX_CAP_KSV_FIFO_RDY (1<<5) - #define B_TX_CAP_HDMI_FAST_MODE (1<<4) - #define B_CAP_HDCP_1p1 (1<<1) - #define B_TX_CAP_FAST_REAUTH (1<<0) -#define REG_TX_BSTAT 0x44 -#define REG_TX_BSTAT0 0x44 -#define REG_TX_BSTAT1 0x45 - #define B_TX_CAP_HDMI_MODE (1<<12) - #define B_TX_CAP_DVI_MODE (0<<12) - #define B_TX_MAX_CASCADE_EXCEEDED (1<<11) - #define M_TX_REPEATER_DEPTH (0x7<<8) - #define O_TX_REPEATER_DEPTH 8 - #define B_TX_DOWNSTREAM_OVER (1<<7) - #define M_TX_DOWNSTREAM_COUNT 0x7F - -#define REG_TX_AUTH_STAT 0x46 -#define B_TX_AUTH_DONE (1<<7) -//////////////////////////////////////////////////// -// Function Prototype -//////////////////////////////////////////////////// - -BOOL getHDMITX_AuthenticationDone(void); -void hdmitx_hdcp_ClearAuthInterrupt(void); -void hdmitx_hdcp_ResetAuth(void); -void hdmitx_hdcp_Auth_Fire(void); -void hdmitx_hdcp_StartAnCipher(void); -void hdmitx_hdcp_StopAnCipher(void); -void hdmitx_hdcp_GenerateAn(void); -SYS_STATUS hdmitx_hdcp_GetBCaps(PBYTE pBCaps ,PUSHORT pBStatus); -SYS_STATUS hdmitx_hdcp_GetBKSV(BYTE *pBKSV); - -void hdmitx_hdcp_Reset(void); -SYS_STATUS hdmitx_hdcp_Authenticate(void); -SYS_STATUS hdmitx_hdcp_VerifyIntegration(void); -void hdmitx_hdcp_CancelRepeaterAuthenticate(void); -void hdmitx_hdcp_ResumeRepeaterAuthenticate(void); -SYS_STATUS hdmitx_hdcp_CheckSHA(BYTE pM0[],USHORT BStatus,BYTE pKSVList[],int cDownStream,BYTE Vr[]); -SYS_STATUS hdmitx_hdcp_GetKSVList(BYTE *pKSVList,BYTE cDownStream); -SYS_STATUS hdmitx_hdcp_GetVr(BYTE *pVr); -SYS_STATUS hdmitx_hdcp_GetM0(BYTE *pM0); -SYS_STATUS hdmitx_hdcp_Authenticate_Repeater(void); -void hdmitx_hdcp_ResumeAuthentication(void); -#endif // _HDMITX_HDCP_H_ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.c b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.c deleted file mode 100755 index f9662f553190..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.c +++ /dev/null @@ -1,190 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ -#include "hdmitx.h" -#include "hdmitx_drv.h" - -#ifdef HDMITX_INPUT_INFO -extern HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT] ; - -LONG CalcRCLK(); -LONG CalcAudFS(); -LONG CalcRCLK(); - -#define InitCEC() HDMITX_SetI2C_Byte(0x0F, 0x08, 0x00) -#define DisableCEC() HDMITX_SetI2C_Byte(0x0F, 0x08, 0x08) - -LONG CalcAudFS() -{ - // LONG RCLK ; - LONG Cnt ; - LONG FS ; - - // RCLK = CalcRCLK(); - Switch_HDMITX_Bank(0); - Cnt = (LONG)HDMITX_ReadI2C_Byte(0x60); - FS = hdmiTxDev[0].RCLK / 2 ; - FS /= Cnt ; - HDMITX_DEBUG_PRINTF1(("FS = %ld RCLK = %ld, Cnt = %ld\n",FS,hdmiTxDev[0].RCLK,Cnt)) ; - return FS ; -} - -LONG CalcPCLK() -{ - BYTE uc, div ; - int i ; - long sum , count, PCLK ; - - Switch_HDMITX_Bank(0); - uc = HDMITX_ReadI2C_Byte(0x5F) & 0x80 ; - - if( ! uc ) - { - return 0 ; - } - // InitCEC(); - // // uc = CEC_ReadI2C_Byte(0x09) & 0xFE ; - // CEC_WriteI2C_Byte(0x09, 1); - // delay1ms(100); - // CEC_WriteI2C_Byte(0x09, 0); - // RCLK = CEC_ReadI2C_Byte(0x47); - // RCLK <<= 8 ; - // RCLK |= CEC_ReadI2C_Byte(0x46); - // RCLK <<= 8 ; - // RCLK |= CEC_ReadI2C_Byte(0x45); - // DisableCEC(); - // // RCLK *= 160 ; // RCLK /= 100 ; - // // RCLK in KHz. - - HDMITX_SetI2C_Byte(0xD7, 0xF0, 0x80); - delay1ms(1); - HDMITX_SetI2C_Byte(0xD7, 0x80, 0x00); - - count = HDMITX_ReadI2C_Byte(0xD7) & 0xF ; - count <<= 8 ; - count |= HDMITX_ReadI2C_Byte(0xD8); - - for( div = 7 ; div > 0 ; div-- ) - { - // printf("div = %d\n",(int)div) ; - if(count < (1<<(11-div)) ) - { - break ; - } - } - HDMITX_SetI2C_Byte(0xD7, 0x70, div<<4); - - uc = HDMITX_ReadI2C_Byte(0xD7) & 0x7F ; - for( i = 0 , sum = 0 ; i < 100 ; i ++ ) - { - HDMITX_WriteI2C_Byte(0xD7, uc|0x80) ; - delay1ms(1); - HDMITX_WriteI2C_Byte(0xD7, uc) ; - - count = HDMITX_ReadI2C_Byte(0xD7) & 0xF ; - count <<= 8 ; - count |= HDMITX_ReadI2C_Byte(0xD8); - sum += count ; - } - sum /= 100 ; count = sum ; - - HDMITX_DEBUG_PRINTF1(("RCLK(in GetPCLK) = %ld\n",hdmiTxDev[0].RCLK)); - HDMITX_DEBUG_PRINTF1(("div = %d, count = %d\n",(int)div,(int)count) ); - HDMITX_DEBUG_PRINTF1(("count = %ld\n",count) ); - - PCLK = hdmiTxDev[0].RCLK * 128 / count * 16 ; - PCLK *= (1<> 4 ; - HDMITX_SetI2C_Byte(0xA8,8,0) ; - return hTotal ; -} - -USHORT hdmitx_getInputVTotal() -{ - BYTE uc ; - USHORT vTotal ; - HDMITX_SetI2C_Byte(0x0F,1,0) ; - HDMITX_SetI2C_Byte(0xA8,8,8) ; - - uc = HDMITX_ReadI2C_Byte(0x99) ; - vTotal = ((USHORT)uc&0xF)<<8 ; - uc = HDMITX_ReadI2C_Byte(0x98) ; - vTotal |= uc; - HDMITX_SetI2C_Byte(0xA8,8,0) ; - return vTotal ; -} - -BOOL hdmitx_isInputInterlace() -{ - BYTE uc ; - - HDMITX_SetI2C_Byte(0x0F,1,0) ; - HDMITX_SetI2C_Byte(0xA8,8,8) ; - - uc = HDMITX_ReadI2C_Byte(0xA5) ; - HDMITX_SetI2C_Byte(0xA8,8,0) ; - return uc&(1<<4)?TRUE:FALSE ; -} - -BYTE hdmitx_getAudioCount() -{ - return HDMITX_ReadI2C_Byte(REG_TX_AUD_COUNT) ; -} -#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.h b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.h deleted file mode 100755 index b28ce9409658..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.h +++ /dev/null @@ -1,26 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ -#ifndef _HDMITX_DEBUG_H_ -#define _HDMITX_DEBUG_H_ - - -#ifdef HDMITX_INPUT_INFO -LONG CalcPCLK(); -LONG CalcAudFS(); -LONG CalcRCLK(); -BYTE hdmitx_getAudioCount() ; - -USHORT hdmitx_getInputHTotal(); -USHORT hdmitx_getInputVTotal(); -BOOL hdmitx_isInputInterlace(); -#endif - -#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/sha1.c b/drivers/video/rockchip/hdmi/chips/cat66121/sha1.c deleted file mode 100755 index 55b5d7f4c713..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/sha1.c +++ /dev/null @@ -1,150 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Hermes.Wu@ite.com.tw -// @date 2011/08/26 -// @fileversion: COMMON_FILE_1.01 -//******************************************/ - -#include "sha1.h" - - -#ifndef DISABLE_HDCP - -#define WCOUNT 17 -ULONG VH[5]; -ULONG w[WCOUNT]; - -#define rol(x,y)(((x)<< (y))| (((ULONG)x)>> (32-y))) - - -void SHATransform(ULONG * h) -{ - int t; - ULONG tmp; - - - h[0]=0x67452301; - h[1]=0xefcdab89; - h[2]=0x98badcfe; - h[3]=0x10325476; - h[4]=0xc3d2e1f0; - - for (t=0; t < 20; t++){ - if(t>=16) - { - tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT]; - w[(t)% WCOUNT]=rol(tmp,1); - } - HDCP_DEBUG_PRINTF2(("w[%d]=%08lX\n",t,w[(t)% WCOUNT])); - - tmp=rol(h[0],5)+ ((h[1] & h[2])| (h[3] & ~h[1]))+ h[4] + w[(t)% WCOUNT] + 0x5a827999; - HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); - - h[4]=h[3]; - h[3]=h[2]; - h[2]=rol(h[1],30); - h[1]=h[0]; - h[0]=tmp; - - } - for (t=20; t < 40; t++){ - tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT]; - w[(t)% WCOUNT]=rol(tmp,1); - HDCP_DEBUG_PRINTF2(("w[%d]=%08lX\n",t,w[(t)% WCOUNT])); - tmp=rol(h[0],5)+ (h[1] ^ h[2] ^ h[3])+ h[4] + w[(t)% WCOUNT] + 0x6ed9eba1; - HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); - h[4]=h[3]; - h[3]=h[2]; - h[2]=rol(h[1],30); - h[1]=h[0]; - h[0]=tmp; - } - for (t=40; t < 60; t++){ - tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT]; - w[(t)% WCOUNT]=rol(tmp,1); - HDCP_DEBUG_PRINTF2(("w[%d]=%08lX\n",t,w[(t)% WCOUNT])); - tmp=rol(h[0],5)+ ((h[1] & h[2])| (h[1] & h[3])| (h[2] & h[3]))+ h[4] + w[(t)% WCOUNT] + 0x8f1bbcdc; - HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); - h[4]=h[3]; - h[3]=h[2]; - h[2]=rol(h[1],30); - h[1]=h[0]; - h[0]=tmp; - } - for (t=60; t < 80; t++) - { - tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT]; - w[(t)% WCOUNT]=rol(tmp,1); - HDCP_DEBUG_PRINTF2(("w[%d]=%08lX\n",t,w[(t)% WCOUNT])); - tmp=rol(h[0],5)+ (h[1] ^ h[2] ^ h[3])+ h[4] + w[(t)% WCOUNT] + 0xca62c1d6; - HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); - h[4]=h[3]; - h[3]=h[2]; - h[2]=rol(h[1],30); - h[1]=h[0]; - h[0]=tmp; - } - HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); - h[0] +=0x67452301; - h[1] +=0xefcdab89; - h[2] +=0x98badcfe; - h[3] +=0x10325476; - h[4] +=0xc3d2e1f0; - - HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); -} - -void SHA_Simple(void *p,WORD len,BYTE *output) -{ - // SHA_State s; - WORD i,t; - ULONG c; - BYTE *pBuff=p; - - for(i=0;i < len;i++) - { - t=i/4; - if(i%4==0) - { - w[t]=0; - } - c=pBuff[i]; - c <<=(3-(i%4))*8; - w[t] |=c; - HDCP_DEBUG_PRINTF2(("pBuff[%d]=%02X,c=%08lX,w[%d]=%08lX\n",(int)i,(int)pBuff[i],c,(int)t,w[t])); - } - t=i/4; - if(i%4==0) - { - w[t]=0; - } - //c=0x80 << ((3-i%4)*24); - c=0x80; - c <<=((3-i%4)*8); - w[t]|=c;t++; - for(; t < 15;t++) - { - w[t]=0; - } - w[15]=len*8; - - for(i = 0 ; i < 16 ; i++) - { - HDCP_DEBUG_PRINTF2(("w[%d] = %08lX\n",i,w[i])); - } - - SHATransform(VH); - - for(i=0;i < 5;i++) - { - output[i*4+3]=(BYTE)((VH[i]>>24)&0xFF); - output[i*4+2]=(BYTE)((VH[i]>>16)&0xFF); - output[i*4+1]=(BYTE)((VH[i]>>8)&0xFF); - output[i*4+0]=(BYTE)(VH[i]&0xFF); - } -} -#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/sha1.h b/drivers/video/rockchip/hdmi/chips/cat66121/sha1.h deleted file mode 100755 index bc17860c5aa1..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/sha1.h +++ /dev/null @@ -1,36 +0,0 @@ -///***************************************** -// Copyright (C)2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-chih.Tseng@ite.com.tw -// @date 2010/06/04 -// @fileversion: COMMON_FILE_1.01 -//******************************************/ - -#ifndef _SHA_1_H_ -#define _SHA_1_H_ - -#include "config.h" -#include "typedef.h" - -#ifndef HDCP_DEBUG_PRINTF - #define HDCP_DEBUG_PRINTF(x) -#endif //HDCP_DEBUG_PRINTF - -#ifndef HDCP_DEBUG_PRINTF1 - #define HDCP_DEBUG_PRINTF1(x) -#endif //HDCP_DEBUG_PRINTF1 - -#ifndef HDCP_DEBUG_PRINTF2 - #define HDCP_DEBUG_PRINTF2(x) -#endif //HDCP_DEBUG_PRINTF2 - - -#ifndef DISABLE_HDCP -void SHA_Simple(void *p,WORD len,BYTE *output); -void SHATransform(ULONG * h); -#endif - -#endif // _SHA_1_H_ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/typedef.h b/drivers/video/rockchip/hdmi/chips/cat66121/typedef.h deleted file mode 100755 index e4e37ae2dfc8..000000000000 --- a/drivers/video/rockchip/hdmi/chips/cat66121/typedef.h +++ /dev/null @@ -1,380 +0,0 @@ -///***************************************** -// Copyright (C) 2009-2014 -// ITE Tech. Inc. All Rights Reserved -// Proprietary and Confidential -///***************************************** -// @file -// @author Jau-Chih.Tseng@ite.com.tw -// @date 2012/12/20 -// @fileversion: ITE_HDMITX_SAMPLE_3.14 -//******************************************/ - -#ifndef _TYPEDEF_H_ -#define _TYPEDEF_H_ - -////////////////////////////////////////////////// -// data type -////////////////////////////////////////////////// -#ifdef _MCU_8051_ - #define _CODE code - #define _DATA data - #define _XDATA xdata - #define _IDATA idata - typedef bit BOOL ; -#else - #define _CODE //const - #define _DATA - #define _IDATA - #define _XDATA - typedef int BOOL ; -#endif // _MCU_8051_ - -typedef _CODE unsigned char cBYTE; - - -typedef char CHAR,*PCHAR ; -typedef unsigned char uchar,*puchar ; -typedef unsigned char UCHAR,*PUCHAR ; -typedef unsigned char byte,*pbyte ; -typedef unsigned char BYTE,*PBYTE ; - -typedef short SHORT,*PSHORT ; -typedef unsigned short *pushort ; -typedef unsigned short USHORT,*PUSHORT ; -typedef unsigned short word,*pword ; -typedef unsigned short WORD,*PWORD ; -typedef unsigned int UINT,*PUINT ; - -typedef long LONG,*PLONG ; -typedef unsigned long *pulong ; -typedef unsigned long ULONG,*PULONG ; -typedef unsigned long dword,*pdword ; -typedef unsigned long DWORD,*PDWORD ; - -#define FALSE 0 -#define TRUE 1 - -#define SUCCESS 0 -#define FAIL -1 - -#define ON 1 -#define OFF 0 - -#define LO_ACTIVE TRUE -#define HI_ACTIVE FALSE - - -typedef enum _SYS_STATUS { - ER_SUCCESS = 0, - ER_FAIL, - ER_RESERVED -} SYS_STATUS ; - -#define ABS(x) (((x)>=0)?(x):(-(x))) - - - - - -/////////////////////////////////////////////////////////////////////// -// Video Data Type -/////////////////////////////////////////////////////////////////////// - -#define F_MODE_RGB444 0 -#define F_MODE_YUV422 1 -#define F_MODE_YUV444 2 -#define F_MODE_CLRMOD_MASK 3 - - -#define F_MODE_INTERLACE 1 - -#define F_VIDMODE_ITU709 (1<<4) -#define F_VIDMODE_ITU601 0 - -#define F_VIDMODE_0_255 0 -#define F_VIDMODE_16_235 (1<<5) - -#define F_VIDMODE_EN_UDFILT (1<<6) -#define F_VIDMODE_EN_DITHER (1<<7) - -#define T_MODE_CCIR656 (1<<0) -#define T_MODE_SYNCEMB (1<<1) -#define T_MODE_INDDR (1<<2) -#define T_MODE_PCLKDIV2 (1<<3) -#define T_MODE_DEGEN (1<<4) -#define T_MODE_SYNCGEN (1<<5) -///////////////////////////////////////////////////////////////////// -// Packet and Info Frame definition and datastructure. -///////////////////////////////////////////////////////////////////// - - -#define VENDORSPEC_INFOFRAME_TYPE 0x81 -#define AVI_INFOFRAME_TYPE 0x82 -#define SPD_INFOFRAME_TYPE 0x83 -#define AUDIO_INFOFRAME_TYPE 0x84 -#define MPEG_INFOFRAME_TYPE 0x85 - -#define VENDORSPEC_INFOFRAME_VER 0x01 -#define AVI_INFOFRAME_VER 0x02 -#define SPD_INFOFRAME_VER 0x01 -#define AUDIO_INFOFRAME_VER 0x01 -#define MPEG_INFOFRAME_VER 0x01 - -#define VENDORSPEC_INFOFRAME_LEN 5 -#define AVI_INFOFRAME_LEN 13 -#define SPD_INFOFRAME_LEN 25 -#define AUDIO_INFOFRAME_LEN 10 -#define MPEG_INFOFRAME_LEN 10 - -#define ACP_PKT_LEN 9 -#define ISRC1_PKT_LEN 16 -#define ISRC2_PKT_LEN 16 - -typedef union _VendorSpecific_InfoFrame -{ - struct { - BYTE Type ; - BYTE Ver ; - BYTE Len ; - - BYTE CheckSum; - - BYTE IEEE_0;//PB1 - BYTE IEEE_1;//PB2 - BYTE IEEE_2;//PB3 - - BYTE Rsvd:5 ;//PB4 - BYTE HDMI_Video_Format:3 ; - - BYTE Reserved_PB5:4 ;//PB5 - BYTE _3D_Structure:4 ; - - BYTE Reserved_PB6:4 ;//PB6 - BYTE _3D_Ext_Data:4 ; - } info ; - struct { - BYTE VS_HB[3] ; - BYTE CheckSum; - BYTE VS_DB[28] ; - } pktbyte ; -} VendorSpecific_InfoFrame ; - -typedef union _AVI_InfoFrame -{ - - struct { - BYTE Type; - BYTE Ver; - BYTE Len; - - BYTE checksum ; - - BYTE Scan:2; - BYTE BarInfo:2; - BYTE ActiveFmtInfoPresent:1; - BYTE ColorMode:2; - BYTE FU1:1; - - BYTE ActiveFormatAspectRatio:4; - BYTE PictureAspectRatio:2; - BYTE Colorimetry:2; - - BYTE Scaling:2; - BYTE FU2:6; - - BYTE VIC:7; - BYTE FU3:1; - - BYTE PixelRepetition:4; - BYTE FU4:4; - - short Ln_End_Top; - short Ln_Start_Bottom; - short Pix_End_Left; - short Pix_Start_Right; - } info; - - struct { - BYTE AVI_HB[3]; - BYTE checksum ; - BYTE AVI_DB[AVI_INFOFRAME_LEN]; - } pktbyte; -} AVI_InfoFrame; - -typedef union _Audio_InfoFrame { - - struct { - BYTE Type; - BYTE Ver; - BYTE Len; - BYTE checksum ; - - BYTE AudioChannelCount:3; - BYTE RSVD1:1; - BYTE AudioCodingType:4; - - BYTE SampleSize:2; - BYTE SampleFreq:3; - BYTE Rsvd2:3; - - BYTE FmtCoding; - - BYTE SpeakerPlacement; - - BYTE Rsvd3:3; - BYTE LevelShiftValue:4; - BYTE DM_INH:1; - } info; - - struct { - BYTE AUD_HB[3]; - BYTE checksum ; - BYTE AUD_DB[5]; - } pktbyte; - -} Audio_InfoFrame; - -typedef union _MPEG_InfoFrame { - struct { - BYTE Type; - BYTE Ver; - BYTE Len; - BYTE checksum ; - - ULONG MpegBitRate; - - BYTE MpegFrame:2; - BYTE Rvsd1:2; - BYTE FieldRepeat:1; - BYTE Rvsd2:3; - } info; - struct { - BYTE MPG_HB[3]; - BYTE checksum ; - BYTE MPG_DB[MPEG_INFOFRAME_LEN]; - } pktbyte; -} MPEG_InfoFrame; - -typedef union _SPD_InfoFrame { - struct { - BYTE Type; - BYTE Ver; - BYTE Len; - BYTE checksum ; - - char VN[8]; - char PD[16]; - BYTE SourceDeviceInfomation; - } info; - struct { - BYTE SPD_HB[3]; - BYTE checksum ; - BYTE SPD_DB[SPD_INFOFRAME_LEN]; - } pktbyte; -} SPD_InfoFrame; - -/////////////////////////////////////////////////////////////////////////// -// Using for interface. -/////////////////////////////////////////////////////////////////////////// - -#define PROG 1 -#define INTERLACE 0 -#define Vneg 0 -#define Hneg 0 -#define Vpos 1 -#define Hpos 1 - -typedef struct { - WORD H_ActiveStart; - WORD H_ActiveEnd; - WORD H_SyncStart; - WORD H_SyncEnd; - WORD V_ActiveStart; - WORD V_ActiveEnd; - WORD V_SyncStart; - WORD V_SyncEnd; - WORD V2_ActiveStart; - WORD V2_ActiveEnd; - WORD HTotal; - WORD VTotal; -} CEAVTiming; - -typedef struct { - BYTE VIC ; - BYTE PixelRep ; - WORD HActive; - WORD VActive; - WORD HTotal; - WORD VTotal; - ULONG PCLK; - BYTE xCnt; - WORD HFrontPorch; - WORD HSyncWidth; - WORD HBackPorch; - BYTE VFrontPorch; - BYTE VSyncWidth; - BYTE VBackPorch; - BYTE ScanMode:1; - BYTE VPolarity:1; - BYTE HPolarity:1; -} HDMI_VTiming; - -////////////////////////////////////////////////////////////////// -// Audio relate definition and macro. -////////////////////////////////////////////////////////////////// - -// 2008/08/15 added by jj_tseng@chipadvanced -#define F_AUDIO_ON (1<<7) -#define F_AUDIO_HBR (1<<6) -#define F_AUDIO_DSD (1<<5) -#define F_AUDIO_NLPCM (1<<4) -#define F_AUDIO_LAYOUT_1 (1<<3) -#define F_AUDIO_LAYOUT_0 (0<<3) - -// HBR - 1100 -// DSD - 1010 -// NLPCM - 1001 -// LPCM - 1000 - -#define T_AUDIO_MASK 0xF0 -#define T_AUDIO_OFF 0 -#define T_AUDIO_HBR (F_AUDIO_ON|F_AUDIO_HBR) -#define T_AUDIO_DSD (F_AUDIO_ON|F_AUDIO_DSD) -#define T_AUDIO_NLPCM (F_AUDIO_ON|F_AUDIO_NLPCM) -#define T_AUDIO_LPCM (F_AUDIO_ON) - -// for sample clock -#define AUDFS_22p05KHz 4 -#define AUDFS_44p1KHz 0 -#define AUDFS_88p2KHz 8 -#define AUDFS_176p4KHz 12 - -#define AUDFS_24KHz 6 -#define AUDFS_48KHz 2 -#define AUDFS_96KHz 10 -#define AUDFS_192KHz 14 - -#define AUDFS_768KHz 9 - -#define AUDFS_32KHz 3 -#define AUDFS_OTHER 1 - -// Audio Enable -#define ENABLE_SPDIF (1<<4) -#define ENABLE_I2S_SRC3 (1<<3) -#define ENABLE_I2S_SRC2 (1<<2) -#define ENABLE_I2S_SRC1 (1<<1) -#define ENABLE_I2S_SRC0 (1<<0) - -#define AUD_SWL_NOINDICATE 0x0 -#define AUD_SWL_16 0x2 -#define AUD_SWL_17 0xC -#define AUD_SWL_18 0x4 -#define AUD_SWL_20 0xA // for maximum 20 bit -#define AUD_SWL_21 0xD -#define AUD_SWL_22 0x5 -#define AUD_SWL_23 0x9 -#define AUD_SWL_24 0xB - - -#endif // _TYPEDEF_H_ diff --git a/drivers/video/rockchip/hdmi/chips/rk2928/Kconfig b/drivers/video/rockchip/hdmi/chips/rk2928/Kconfig deleted file mode 100755 index 49a9cbf65013..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk2928/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -config HDCP_RK2928 - bool "RK2928 HDCP support" - depends on HDMI_RK2928 - default n - help - HDCP Interface. This adds the High Definition Content Protection Interface. - See http://www.digital-cp.com/ for HDCP specification. - -config HDCP_RK2928_DEBUG - bool "RK2928 HDCP Debugging" - depends on HDCP_RK2928 - default n - help - Enableds verbose debugging the the HDCP drivers diff --git a/drivers/video/rockchip/hdmi/chips/rk2928/Makefile b/drivers/video/rockchip/hdmi/chips/rk2928/Makefile deleted file mode 100755 index 1e17c7641c67..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk2928/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for HDMI linux kernel module. -# - -ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG -ccflags-$(CONFIG_HDCP_RK2928_DEBUG) = -DHDCP_DEBUG - -obj-$(CONFIG_HDMI_RK2928) += rk2928_hdmi_hw.o rk2928_hdmi.o -obj-$(CONFIG_HDCP_RK2928) += rk2928_hdmi_hdcp.o rk2928_hdcp.o diff --git a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdcp.c deleted file mode 100755 index 25ff53203139..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdcp.c +++ /dev/null @@ -1,563 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "rk2928_hdmi.h" -#include "rk2928_hdcp.h" - -struct hdcp *hdcp = NULL; - -static void hdcp_work_queue(struct work_struct *work); - -/*----------------------------------------------------------------------------- - * Function: hdcp_submit_work - *----------------------------------------------------------------------------- - */ -static struct delayed_work *hdcp_submit_work(int event, int delay) -{ - struct hdcp_delayed_work *work; - - DBG("%s event %04x delay %d", __FUNCTION__, event, delay); - - work = kmalloc(sizeof(struct hdcp_delayed_work), GFP_ATOMIC); - - if (work) { - INIT_DELAYED_WORK(&work->work, hdcp_work_queue); - work->event = event; - queue_delayed_work(hdcp->workqueue, - &work->work, - msecs_to_jiffies(delay)); - } else { - printk(KERN_WARNING "HDCP: Cannot allocate memory to " - "create work\n"); - return 0; - } - - return &work->work; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_cancel_work - *----------------------------------------------------------------------------- - */ -static void hdcp_cancel_work(struct delayed_work **work) -{ - int ret = 0; - - if (*work) { - ret = cancel_delayed_work(*work); - if (ret != 1) { - ret = cancel_work_sync(&((*work)->work)); - printk(KERN_INFO "Canceling work failed - " - "cancel_work_sync done %d\n", ret); - } - kfree(*work); - *work = 0; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_failure - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_failure(void) -{ - if (hdcp->hdmi_state == HDMI_STOPPED) { - return; - } - - rk2928_hdcp_disable(); - rk2928_hdmi_control_output(false); - - hdcp_cancel_work(&hdcp->pending_wq_event); - - if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) { - if (hdcp->retry_cnt < HDCP_INFINITE_REAUTH) { - hdcp->retry_cnt--; - printk(KERN_INFO "HDCP: authentication failed - " - "retrying, attempts=%d\n", - hdcp->retry_cnt); - } else - printk(KERN_INFO "HDCP: authentication failed - " - "retrying\n"); - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - - hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT, - HDCP_REAUTH_DELAY); - } else { - printk(KERN_INFO "HDCP: authentication failed - " - "HDCP disabled\n"); - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } - -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_start_authentication - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_start_authentication(void) -{ - int status = HDCP_OK; - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - - DBG("HDCP: authentication start"); - - status = rk2928_hdcp_start_authentication(); - - if (status != HDCP_OK) { - DBG("HDCP: authentication failed"); - hdcp_wq_authentication_failure(); - } else { - hdcp->hdcp_state = HDCP_WAIT_KSV_LIST; -// hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_check_bksv - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_check_bksv(void) -{ - int status = HDCP_OK; - - DBG("Check BKSV start"); - - status = rk2928_hdcp_check_bksv(); - - if (status != HDCP_OK) { - printk(KERN_INFO "HDCP: Check BKSV failed"); - hdcp->retry_cnt = 0; - hdcp_wq_authentication_failure(); - } - else { - DBG("HDCP: Check BKSV successful"); - - hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - - /* Restore retry counter */ - if(hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_sucess - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_sucess(void) -{ - rk2928_hdmi_control_output(true); - printk(KERN_INFO "HDCP: authentication pass"); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_disable - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_disable(int event) -{ - printk(KERN_INFO "HDCP: disabled"); - - hdcp_cancel_work(&hdcp->pending_wq_event); - rk2928_hdcp_disable(); - if(event == HDCP_DISABLE_CTL) { - hdcp->hdcp_state = HDCP_DISABLED; - if(hdcp->hdmi_state == HDMI_STARTED) - rk2928_hdmi_control_output(true); - } - else if(event == HDCP_STOP_FRAME_EVENT) - hdcp->hdcp_state = HDCP_ENABLE_PENDING; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_work_queue - *----------------------------------------------------------------------------- - */ -static void hdcp_work_queue(struct work_struct *work) -{ - struct hdcp_delayed_work *hdcp_w = - container_of(work, struct hdcp_delayed_work, work.work); - int event = hdcp_w->event; - - mutex_lock(&hdcp->lock); - - DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d", - jiffies_to_msecs(jiffies), - hdcp->hdmi_state, - hdcp->hdcp_state, - (event & 0xFF00) >> 8, - event & 0xFF); - - if(event == HDCP_STOP_FRAME_EVENT) { - hdcp->hdmi_state = HDMI_STOPPED; - } - - if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) { - hdcp_wq_disable(event); - } - - if (event & HDCP_WORKQUEUE_SRC) - hdcp->pending_wq_event = 0; - - /* First handle HDMI state */ - if (event == HDCP_START_FRAME_EVENT) { - hdcp->pending_start = 0; - hdcp->hdmi_state = HDMI_STARTED; - } - - /**********************/ - /* HDCP state machine */ - /**********************/ - switch (hdcp->hdcp_state) { - case HDCP_DISABLED: - /* HDCP enable control or re-authentication event */ - if (event == HDCP_ENABLE_CTL) { - if(hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times; - if (hdcp->hdmi_state == HDMI_STARTED) - hdcp_wq_start_authentication(); - else - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } - break; - - case HDCP_ENABLE_PENDING: - /* HDMI start frame event */ - if (event == HDCP_START_FRAME_EVENT) - hdcp_wq_start_authentication(); - - break; - - case HDCP_AUTHENTICATION_START: - /* Re-authentication */ - if (event == HDCP_AUTH_REATT_EVENT) - hdcp_wq_start_authentication(); - - break; - - case HDCP_WAIT_KSV_LIST: - /* KSV failure */ - if (event == HDCP_FAIL_EVENT) { - printk(KERN_INFO "HDCP: KSV switch failure\n"); - - hdcp_wq_authentication_failure(); - } - /* KSV list ready event */ - else if (event == HDCP_KSV_LIST_RDY_EVENT) - hdcp_wq_check_bksv(); - break; - - case HDCP_LINK_INTEGRITY_CHECK: - /* Ri failure */ - if (event == HDCP_FAIL_EVENT) { - printk(KERN_INFO "HDCP: Ri check failure\n"); - hdcp_wq_authentication_failure(); - } - else if(event == HDCP_AUTH_PASS_EVENT) - hdcp_wq_authentication_sucess(); - break; - - default: - printk(KERN_WARNING "HDCP: error - unknow HDCP state\n"); - break; - } - - kfree(hdcp_w); - if(event == HDCP_STOP_FRAME_EVENT) - complete(&hdcp->complete); - - mutex_unlock(&hdcp->lock); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_start_frame_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_start_frame_cb(void) -{ - DBG("hdcp_start_frame_cb()"); - - /* Cancel any pending work */ - if (hdcp->pending_start) - hdcp_cancel_work(&hdcp->pending_start); - if (hdcp->pending_wq_event) - hdcp_cancel_work(&hdcp->pending_wq_event); - - hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT, - HDCP_ENABLE_DELAY); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_irq_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_irq_cb(int status) -{ - char interrupt1; - char interrupt2; - - rk2928_hdcp_interrupt(&interrupt1, &interrupt2); - DBG("%s 0x%02x 0x%02x", __FUNCTION__, interrupt1, interrupt2); - if(interrupt1 & m_INT_HDCP_ERR) - { - if( (hdcp->hdcp_state != HDCP_DISABLED) && - (hdcp->hdcp_state != HDCP_ENABLE_PENDING) ) - { - hdcp_submit_work(HDCP_FAIL_EVENT, 0); - } - } - else if(interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE)) - hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0); - else if(interrupt1 & m_INT_AUTH_SUCCESS) - hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_on_cb - *----------------------------------------------------------------------------- - */ -static int hdcp_power_on_cb(void) -{ - DBG("%s", __FUNCTION__); -// return rk2928_hdcp_load_key2mem(hdcp->keys); - return HDCP_OK; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_off_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_power_off_cb(void) -{ - DBG("%s", __FUNCTION__); - if(!hdcp->enable) - return; - - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - init_completion(&hdcp->complete); - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0)) - wait_for_completion_interruptible_timeout(&hdcp->complete, - msecs_to_jiffies(5000)); -} - -// Load HDCP key to external HDCP memory -static void hdcp_load_keys_cb(const struct firmware *fw, void *context) -{ - if (!fw) { - pr_err("HDCP: failed to load keys\n"); - return; - } - - if(fw->size < HDCP_KEY_SIZE) { - pr_err("HDCP: firmware wrong size %d\n", fw->size); - return; - } - - hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL); - if(hdcp->keys == NULL) { - pr_err("HDCP: can't allocated space for keys\n"); - return; - } - - memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE); - - printk(KERN_INFO "HDCP: load hdcp key success\n"); - - if(fw->size > HDCP_KEY_SIZE) { - DBG("%s invalid key size %d", __FUNCTION__, fw->size - HDCP_KEY_SIZE); - if((fw->size - HDCP_KEY_SIZE) % 5) { - pr_err("HDCP: failed to load invalid keys\n"); - return; - } - hdcp->invalidkeys = kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL); - if(hdcp->invalidkeys == NULL) { - pr_err("HDCP: can't allocated space for invalid keys\n"); - return; - } - memcpy(hdcp->invalidkeys, fw->data + HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE); - hdcp->invalidkey = (fw->size - HDCP_KEY_SIZE)/5; - printk(KERN_INFO "HDCP: loaded hdcp invalid key success\n"); - } -} - -static ssize_t hdcp_enable_read(struct device *device, - struct device_attribute *attr, char *buf) -{ - int enable = 0; - - if(hdcp) - enable = hdcp->enable; - - return snprintf(buf, PAGE_SIZE, "%d\n", enable); -} - -static ssize_t hdcp_enable_write(struct device *device, - struct device_attribute *attr, const char *buf, size_t count) -{ - int enable; - - if(hdcp == NULL) - return -EINVAL; - - sscanf(buf, "%d", &enable); - if(hdcp->enable != enable) - { - /* Post event to workqueue */ - if(enable) { - if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0) - return -EFAULT; - } - else { - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0) - return -EFAULT; - } - hdcp->enable = enable; - } - return count; -} - -static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, hdcp_enable_read, hdcp_enable_write); - -static ssize_t hdcp_trytimes_read(struct device *device, - struct device_attribute *attr, char *buf) -{ - int trytimes = 0; - - if(hdcp) - trytimes = hdcp->retry_times; - - return snprintf(buf, PAGE_SIZE, "%d\n", trytimes); -} - -static ssize_t hdcp_trytimes_wrtie(struct device *device, - struct device_attribute *attr, const char *buf, size_t count) -{ - int trytimes; - - if(hdcp == NULL) - return -EINVAL; - - sscanf(buf, "%d", &trytimes); - if(hdcp->retry_times != trytimes) - hdcp->retry_times = trytimes; - - return count; -} - - -static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR, hdcp_trytimes_read, hdcp_trytimes_wrtie); - - -static struct miscdevice mdev; - -static int __init rk2928_hdcp_init(void) -{ - int ret; - - DBG("[%s] %u", __FUNCTION__, jiffies_to_msecs(jiffies)); - - hdcp = kmalloc(sizeof(struct hdcp), GFP_KERNEL); - if(!hdcp) - { - printk(KERN_ERR ">>HDCP: kmalloc fail!"); - ret = -ENOMEM; - goto error0; - } - memset(hdcp, 0, sizeof(struct hdcp)); - mutex_init(&hdcp->lock); - - mdev.minor = MISC_DYNAMIC_MINOR; - mdev.name = "hdcp"; - mdev.mode = 0666; - if (misc_register(&mdev)) { - printk(KERN_ERR "HDCP: Could not add character driver\n"); - ret = HDMI_ERROR_FALSE; - goto error1; - } - ret = device_create_file(mdev.this_device, &dev_attr_enable); - if(ret) - { - printk(KERN_ERR "HDCP: Could not add sys file enable\n"); - ret = -EINVAL; - goto error2; - } - - ret = device_create_file(mdev.this_device, &dev_attr_trytimes); - if(ret) - { - printk(KERN_ERR "HDCP: Could not add sys file trytimes\n"); - ret = -EINVAL; - goto error3; - } - - hdcp->workqueue = create_singlethread_workqueue("hdcp"); - if (hdcp->workqueue == NULL) { - printk(KERN_ERR "HDCP,: create workqueue failed.\n"); - goto error4; - } - - - ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, - "hdcp.keys", mdev.this_device, GFP_KERNEL, - hdcp, hdcp_load_keys_cb); - if (ret < 0) { - printk(KERN_ERR "HDCP: request_firmware_nowait failed: %d\n", ret); - goto error5; - } - - rk2928_hdmi_register_hdcp_callbacks(hdcp_start_frame_cb, - hdcp_irq_cb, - hdcp_power_on_cb, - hdcp_power_off_cb); - - DBG("%s success %u", __FUNCTION__, jiffies_to_msecs(jiffies)); - return 0; - -error5: - destroy_workqueue(hdcp->workqueue); -error4: - device_remove_file(mdev.this_device, &dev_attr_trytimes); -error3: - device_remove_file(mdev.this_device, &dev_attr_enable); -error2: - misc_deregister(&mdev); -error1: - if(hdcp->keys) - kfree(hdcp->keys); - if(hdcp->invalidkeys) - kfree(hdcp->invalidkeys); - kfree(hdcp); -error0: - return ret; -} - -static void __exit rk2928_hdcp_exit(void) -{ - device_remove_file(mdev.this_device, &dev_attr_enable); - misc_deregister(&mdev); - if(hdcp->keys) - kfree(hdcp->keys); - if(hdcp->invalidkeys) - kfree(hdcp->invalidkeys); - kfree(hdcp); -} - -module_init(rk2928_hdcp_init); -module_exit(rk2928_hdcp_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdcp.h b/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdcp.h deleted file mode 100755 index 4d55037e5e5d..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdcp.h +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef __RK2928_HDCP_H__ -#define __RK2928_HDCP_H__ - -/***************************/ -/* Definitions */ -/***************************/ - -/* Status / error codes */ -#define HDCP_OK 0 -#define HDCP_KEY_ERR 1 -#define HDCP_KSV_ERR 2 - -/* Delays */ -#define HDCP_ENABLE_DELAY 300 -#define HDCP_REAUTH_DELAY 100 - -/* Event source */ -#define HDCP_SRC_SHIFT 8 -#define HDCP_IOCTL_SRC (0x1 << HDCP_SRC_SHIFT) -#define HDCP_HDMI_SRC (0x2 << HDCP_SRC_SHIFT) -#define HDCP_IRQ_SRC (0x4 << HDCP_SRC_SHIFT) -#define HDCP_WORKQUEUE_SRC (0x8 << HDCP_SRC_SHIFT) - -/* Event */ -#define HDCP_ENABLE_CTL (HDCP_IOCTL_SRC | 0) -#define HDCP_DISABLE_CTL (HDCP_IOCTL_SRC | 1) -#define HDCP_START_FRAME_EVENT (HDCP_HDMI_SRC | 2) -#define HDCP_STOP_FRAME_EVENT (HDCP_HDMI_SRC | 3) -#define HDCP_KSV_LIST_RDY_EVENT (HDCP_IRQ_SRC | 4) -#define HDCP_FAIL_EVENT (HDCP_IRQ_SRC | 5) -#define HDCP_AUTH_PASS_EVENT (HDCP_IRQ_SRC | 6) -#define HDCP_AUTH_REATT_EVENT (HDCP_WORKQUEUE_SRC | 7) - -/* Key size */ -#define HDCP_KEY_SIZE 308 - -/* HDCP DDC Clock */ -#define HDCP_DDC_CLK 100000 - -/* Authentication retry times */ -#define HDCP_INFINITE_REAUTH 0x100 - -/* HDCP Regs */ -#define HDCP_CTRL1 0x52 - #define m_AUTH_START (1 << 7) - #define m_BKSV_VALID (1 << 6) - #define m_BKSV_INVALID (1 << 5) - #define m_ENCRYPT_ENABLE (1 << 4) - #define m_AUTH_STOP (1 << 3) - #define m_ADVANED_ENABLE (1 << 2) - #define m_HDMI_DVI (1 << 1) - #define m_HDCP_RESET (1 << 0) - - #define v_AUTH_START(n) (n << 7) - #define v_BKSV_VALID(n) (n << 6) - #define v_BKSV_INVALID(n) (n << 5) - #define v_ENCRYPT_ENABLE(n) (n << 4) - #define v_AUTH_STOP(n) (n << 3) - #define v_ADVANED_ENABLE(n) (n << 2) - #define v_HDMI_DVI(n) (n << 1) - #define v_HDCP_RESET(n) (n << 0) - -#define HDCP_CTRL2 0x53 - #define m_DISABLE_127_CHECK (1 << 7) - #define m_SKIP_BKSV_CHECK (1 << 6) - #define m_ENABLE_PJ_CHECK (1 << 5) - #define m_DISABLE_DEVICE_NUMBER_CHECK (1 << 4) - #define m_DELAY_RI_1_CLK (1 << 3) - #define m_USE_PRESET_AN (1 << 2) - #define m_KEY_COMBINATION (3 << 0) - - #define v_DISABLE_127_CHECK(n) (n << 7) - #define v_SKIP_BKSV_CHECK(n) (n << 6) - #define v_ENABLE_PJ_CHECK(n) (n << 5) - #define v_DISABLE_DEVICE_NUMBER_CHECK(n)(n << 4) - #define v_DELAY_RI_1_CLK(n) (n << 3) - #define v_USE_PRESET_AN(n) (n << 2) - #define v_KEY_COMBINATION(n) (n << 0) - -#define HDCP_KEY_STATUS 0x54 - #define m_KEY_READY (1 << 0) - -#define HDCP_CTRL_SOFT 0x57 - #define m_DISABLE_127_CHECK (1 << 7) - #define m_SKIP_BKSV_CHECK (1 << 6) - #define m_NOT_AUTHENTICATED (1 << 5) - #define m_ENCRYPTED (1 << 4) - #define m_ADVANCED_CIPHER (1 << 3) - -#define HDCP_BCAPS_RX 0x58 -#define HDCP_TIMER_100MS 0x63 -#define HDCP_TIMER_5S 0x64 -#define HDCP_ERROR 0x65 - #define m_DDC_NO_ACK (1 << 3) - #define m_PJ_MISMACH (1 << 2) - #define m_RI_MISMACH (1 << 1) - #define m_BKSV_WRONG (1 << 0) - -#define HDCP_KSV_BYTE0 0x66 -#define HDCP_KSV_BYTE1 0x67 -#define HDCP_KSV_BYTE2 0x68 -#define HDCP_KSV_BYTE3 0x69 -#define HDCP_KSV_BYTE4 0x6a - -#define HDCP_AN_SEED 0x6c - -#define HDCP_BCAPS_TX 0x80 -#define HDCP_BSTATE_0 0x81 -#define HDCP_BSTATE_1 0x82 - -#define HDCP_KEY_FIFO 0x98 - -#define HDCP_INT_MASK1 0xc2 -#define HDCP_INT_STATUS1 0xc3 - #define m_INT_HDCP_ERR (1 << 7) - #define m_INT_BKSV_READY (1 << 6) - #define m_INT_BKSV_UPDATE (1 << 5) - #define m_INT_AUTH_SUCCESS (1 << 4) - #define m_INT_AUTH_READY (1 << 3) - -#define HDCP_INT_MASK2 0xc4 -#define HDCP_INT_STATUS2 0xc5 - #define m_INT_SOFT_MODE_READY (1 << 7) - #define m_INT_AUTH_M0_REDAY (1 << 6) - #define m_INT_1st_FRAME_ARRIVE (1 << 5) - #define m_INT_AN_READY (1 << 4) - #define m_INT_ENCRYPTED (1 << 2) - #define m_INT_NOT_ENCRYPTED_AVMUTE (1 << 1) - #define m_INT_NOT_ENCRYPTED_AVUNMUTE (1 << 0) - -enum hdcp_states { - HDCP_DISABLED, - HDCP_ENABLE_PENDING, - HDCP_AUTHENTICATION_START, - HDCP_WAIT_KSV_LIST, - HDCP_LINK_INTEGRITY_CHECK, -}; - -enum hdmi_states { - HDMI_STOPPED, - HDMI_STARTED -}; - -#define HDCP_PRIVATE_KEY_SIZE 280 -#define HDCP_KEY_SHA_SIZE 20 - -struct hdcp_keys{ - u8 KSV[8]; - u8 DeviceKey[HDCP_PRIVATE_KEY_SIZE]; - u8 sha1[HDCP_KEY_SHA_SIZE]; -}; - -struct hdcp_delayed_work { - struct delayed_work work; - int event; -}; - -struct hdcp { - int enable; - int retry_times; - struct hdcp_keys *keys; - int invalidkey; - char *invalidkeys; - struct mutex lock; - struct completion complete; - struct workqueue_struct *workqueue; - - enum hdmi_states hdmi_state; - enum hdcp_states hdcp_state; - - struct delayed_work *pending_start; - struct delayed_work *pending_wq_event; - int retry_cnt; -}; - -extern struct hdcp *hdcp; - -#ifdef HDCP_DEBUG -#define DBG(format, ...) \ - printk(KERN_INFO "HDCP: " format "\n", ## __VA_ARGS__) -#else -#define DBG(format, ...) -#endif - -extern void rk2928_hdcp_disable(void); -extern int rk2928_hdcp_start_authentication(void); -extern int rk2928_hdcp_check_bksv(void); -extern int rk2928_hdcp_load_key2mem(struct hdcp_keys *key); -extern void rk2928_hdcp_interrupt(char *status1, char *status2); -#endif /* __rk2928_HDCP_H__ */ \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi.c deleted file mode 100755 index ac8e70b3fb74..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi.c +++ /dev/null @@ -1,304 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "rk2928_hdmi.h" -#include "rk2928_hdmi_hw.h" - -struct hdmi *hdmi = NULL; - -extern irqreturn_t hdmi_irq(int irq, void *priv); -extern void hdmi_work(struct work_struct *work); -extern struct rk_lcdc_driver * rk_get_lcdc_drv(char *name); -extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent); -extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi); - -int rk2928_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)) -{ - if(hdmi == 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; - - return HDMI_ERROR_SUCESS; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void hdmi_early_suspend(struct early_suspend *h) -{ - hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state); - - rk30_mux_api_set(GPIO0A7_I2C3_SDA_HDMI_DDCSDA_NAME, GPIO0A_GPIO0A7); - rk30_mux_api_set(GPIO0A6_I2C3_SCL_HDMI_DDCSCL_NAME, GPIO0A_GPIO0A6); - - flush_delayed_work(&hdmi->delay_work); - mutex_lock(&hdmi->enable_mutex); - hdmi->suspend = 1; - if(!hdmi->enable) { - mutex_unlock(&hdmi->enable_mutex); - return; - } - disable_irq(hdmi->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); - - return; -} - -static void hdmi_early_resume(struct early_suspend *h) -{ - hdmi_dbg(hdmi->dev, "hdmi exit early resume\n"); - mutex_lock(&hdmi->enable_mutex); - - 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); - - hdmi->suspend = 0; - rk2928_hdmi_initial(); - if(hdmi->enable) { - enable_irq(hdmi->irq); - } - mutex_unlock(&hdmi->enable_mutex); - return; -} -#endif - -static inline void hdmi_io_remap(void) -{ - unsigned int value; - - // Remap HDMI IO Pin - 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); - - // Select LCDC0 as video source and enabled. -// value = (HDMI_SOURCE_DEFAULT << 14) | (1 << 30); -// writel(value, GRF_SOC_CON0 + rk2928_GRF_BASE); -} - -static int __devinit rk2928_hdmi_probe (struct platform_device *pdev) -{ - int ret; - struct resource *res; - struct resource *mem; - - hdmi = kmalloc(sizeof(struct hdmi), GFP_KERNEL); - if(!hdmi) - { - dev_err(&pdev->dev, ">>rk2928 hdmi kmalloc fail!"); - return -ENOMEM; - } - memset(hdmi, 0, sizeof(struct hdmi)); - 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; - goto err0; - } - hdmi->xscale = 100; - hdmi->yscale = 100; -#if 1 - 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); -#endif - 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; - } - - - 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; - } - - ret = rk2928_hdmi_initial(); - if(ret != HDMI_ERROR_SUCESS) - goto err1; - - hdmi_io_remap(); - hdmi_sys_init(); - - 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 - - hdmi_register_display_sysfs(hdmi, NULL); - #ifdef CONFIG_SWITCH - hdmi->switch_hdmi.name="hdmi"; - switch_dev_register(&(hdmi->switch_hdmi)); - #endif - - spin_lock_init(&hdmi->irq_lock); - mutex_init(&hdmi->enable_mutex); - - /* 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); - ret = -ENXIO; - goto err2; - } - - /* request the IRQ */ - ret = request_irq(hdmi->irq, hdmi_irq, 0, dev_name(&pdev->dev), hdmi); - if (ret) - { - dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret); - goto err2; - } - - dev_info(hdmi->dev, "rk2928 hdmi probe success.\n"); - return 0; -err2: - #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); - #endif - iounmap((void*)hdmi->regbase); -err1: - release_mem_region(res->start,(res->end - res->start) + 1); -#if 0 - clk_disable(hdmi->hclk); -#endif -err0: - hdmi_dbg(hdmi->dev, "rk2928 hdmi probe error.\n"); - kfree(hdmi); - hdmi = NULL; - return ret; -} - -static int __devexit rk2928_hdmi_remove(struct platform_device *pdev) -{ - if(hdmi) { - mutex_lock(&hdmi->enable_mutex); - if(!hdmi->suspend && hdmi->enable) - disable_irq(hdmi->irq); - mutex_unlock(&hdmi->enable_mutex); - free_irq(hdmi->irq, NULL); - flush_workqueue(hdmi->workqueue); - destroy_workqueue(hdmi->workqueue); - #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); - #endif - iounmap((void*)hdmi->regbase); - release_mem_region(hdmi->regbase_phy, hdmi->regsize_phy); - #if 0 - clk_disable(hdmi->hclk); - #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); - } - kfree(hdmi); - hdmi = NULL; - } - printk(KERN_INFO "rk2928 hdmi removed.\n"); - return 0; -} - -static void rk2928_hdmi_shutdown(struct platform_device *pdev) -{ - if(hdmi) { - #ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&hdmi->early_suspend); - #endif - } - printk(KERN_INFO "rk2928 hdmi shut down.\n"); -} - -static struct platform_driver rk2928_hdmi_driver = { - .probe = rk2928_hdmi_probe, - .remove = __devexit_p(rk2928_hdmi_remove), - .driver = { - .name = "rk2928-hdmi", - .owner = THIS_MODULE, - }, - .shutdown = rk2928_hdmi_shutdown, -}; - -static int __init rk2928_hdmi_init(void) -{ - return platform_driver_register(&rk2928_hdmi_driver); -} - -static void __exit rk2928_hdmi_exit(void) -{ - platform_driver_unregister(&rk2928_hdmi_driver); -} - - -//fs_initcall(rk2928_hdmi_init); -late_initcall(rk2928_hdmi_init); -module_exit(rk2928_hdmi_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi.h b/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi.h deleted file mode 100755 index 6aa9572b668e..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __RK30_HDMI_H__ -#define __RK30_HDMI_H__ - -#include "../../rk_hdmi.h" - -#if defined(CONFIG_HDMI_SOURCE_LCDC1) -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC1 -#else -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC0 -#endif - -extern void rk2928_hdmi_control_output(int enable); -extern int rk2928_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)); -#endif /* __RK30_HDMI_H__ */ diff --git a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi_hdcp.c deleted file mode 100755 index b83daca53d78..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi_hdcp.c +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include "rk2928_hdmi.h" -#include "rk2928_hdmi_hw.h" -#include "rk2928_hdcp.h" - -#define HDCPWrReg HDMIWrReg -#define HDCPRdReg HDMIRdReg -#define HDCPMskReg(temp, addr, msk, val) \ - temp = HDCPRdReg(addr) & (0xFF - (msk)) ; \ - HDCPWrReg(addr, temp | ( (val) & (msk) )); - -void rk2928_hdcp_disable(void) -{ - char temp; - - // Diable HDCP Interrupt - HDCPWrReg(HDCP_INT_MASK1, 0x00); - // Stop and Reset HDCP - HDCPMskReg(temp, HDCP_CTRL1, m_ENCRYPT_ENABLE | m_AUTH_STOP | m_HDCP_RESET, - v_ENCRYPT_ENABLE(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1) ) -} - -int rk2928_hdcp_load_key2mem(struct hdcp_keys *key) -{ - int i; - DBG("HDCP: rk2928_hdcp_load_key2mem start"); - // Write 40 private key - for(i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) - HDCPWrReg(HDCP_KEY_FIFO, key->DeviceKey[i]); - - // Write 1st aksv - for(i = 0; i < 5; i++) - HDCPWrReg(HDCP_KEY_FIFO, key->KSV[i]); - - // Write 2nd aksv - for(i = 0; i < 5; i++) - HDCPWrReg(HDCP_KEY_FIFO, key->KSV[i]); - DBG("HDCP: rk2928_hdcp_load_key2mem end"); - return HDCP_OK; -} - -int rk2928_hdcp_start_authentication(void) -{ - char temp; - int retry = 0; - - if(hdcp->keys == NULL) { - printk(KERN_ERR "HDCP: key is not loaded\n"); - return HDCP_KEY_ERR; - } - - // Select TMDS CLK to configure regs - HDCPMskReg(temp, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS); - - temp = HDCPRdReg(HDCP_KEY_STATUS); - while( ( temp & m_KEY_READY) == 0 ) { - if(retry > 10) { - printk(KERN_ERR "HDCP: loaded key error\n"); - return HDCP_KEY_ERR; - } - rk2928_hdcp_load_key2mem(hdcp->keys); - msleep(1); - temp = HDCPRdReg(HDCP_KEY_STATUS); - } - - // Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b) - DBG("TMDS frequency %d", hdmi->tmdsclk); - retry = hdmi->tmdsclk/(HDCP_DDC_CLK*4); - HDCPWrReg(DDC_CLK_L, retry & 0xFF); - HDCPWrReg(DDC_CLK_H, (retry >> 8) & 0xFF); - - HDCPWrReg(HDCP_CTRL2, 0x00); - - //Enable interrupt - HDCPWrReg(HDCP_INT_MASK1, m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE | m_INT_AUTH_SUCCESS | m_INT_AUTH_READY); -// HDCPWrReg(HDCP_INT_MASK2, 0xFF); - //Start authentication - HDCPMskReg(temp, HDCP_CTRL1, m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE, v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) | v_ADVANED_ENABLE(0)); - - return HDCP_OK; -} - -int rk2928_hdcp_check_bksv(void) -{ - int i, j; - char temp = 0, bksv[5]; - char *invalidkey; - - for(i = 0; i < 5; i++) { - bksv[i] = HDCPRdReg(HDCP_KSV_BYTE0 + (4 - i)) & 0xFF; - } - DBG("bksv is 0x%02x%02x%02x%02x%02x", bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]); - - for (i = 0; i < 5; i++) - { - for (j = 0; j < 8; j++) - { - if (bksv[i] & 0x01) - { - temp++; - } - bksv[i] >>= 1; - } - } - if (temp != 20) - return HDCP_KSV_ERR; - - for(i = 0; i < hdcp->invalidkey; i++) - { - invalidkey = hdcp->invalidkeys + i *5; - if(memcmp(bksv, invalidkey, 5) == 0) { - printk(KERN_ERR "HDCP: BKSV was revocated!!!\n"); - HDCPMskReg(temp, HDCP_CTRL1, m_BKSV_INVALID | m_ENCRYPT_ENABLE, v_BKSV_INVALID(1) | v_ENCRYPT_ENABLE(1)); - return HDCP_KSV_ERR; - } - } - HDCPMskReg(temp, HDCP_CTRL1, m_BKSV_VALID | m_ENCRYPT_ENABLE, v_BKSV_VALID(1) | v_ENCRYPT_ENABLE(1)); - return HDCP_OK; -} - -void rk2928_hdcp_interrupt(char *status1, char *status2) -{ - char interrupt1 = HDCPRdReg(HDCP_INT_STATUS1); - char interrupt2 = HDCPRdReg(HDCP_INT_STATUS2); - if(interrupt1) { - HDCPWrReg(HDCP_INT_STATUS1, interrupt1); - if(interrupt1 & m_INT_HDCP_ERR) - printk(KERN_INFO "HDCP: Error 0x%02x\n", HDCPRdReg(HDCP_ERROR)); - } - if(interrupt2) - HDCPWrReg(HDCP_INT_STATUS2, interrupt2); - - *status1 = interrupt1; - *status2 = interrupt2; -} \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi_hw.c deleted file mode 100755 index 191b21b59cfb..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi_hw.c +++ /dev/null @@ -1,469 +0,0 @@ -#include -#include -#include -#include "rk2928_hdmi.h" -#include "rk2928_hdmi_hw.h" - -static char edid_result = 0; -static bool analog_sync = 0; - -static inline void delay100us(void) -{ - msleep(1); -} - - -static void rk2928_hdmi_av_mute(bool enable) -{ - HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(enable) | v_VIDEO_MUTE(enable)); -} - -static void rk2928_hdmi_sys_power_up(void) -{ - hdmi_dbg(hdmi->dev,"%s \n",__FUNCTION__); - HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_ON | v_INT_POL_HIGH); -} -static void rk2928_hdmi_sys_power_down(void) -{ - hdmi_dbg(hdmi->dev,"%s \n",__FUNCTION__); - HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_OFF | v_INT_POL_HIGH); -} - - - -static void rk2928_hdmi_set_pwr_mode(int mode) -{ - hdmi_dbg(hdmi->dev,"%s \n",__FUNCTION__); - if(hdmi->pwr_mode == mode) - return; - switch(mode){ - case NORMAL: - rk2928_hdmi_sys_power_down(); - HDMIWrReg(0xe0, 0x0a); - HDMIWrReg(0xe1, 0x03); - HDMIWrReg(0xe2, 0x99); - HDMIWrReg(0xe3, 0x0f); - HDMIWrReg(0xe4, 0x00); - HDMIWrReg(0xec, 0x02); - HDMIWrReg(0xce, 0x00); - HDMIWrReg(0xce, 0x01); - rk2928_hdmi_av_mute(1); - rk2928_hdmi_sys_power_up(); - analog_sync = 1; - break; - case LOWER_PWR: - rk2928_hdmi_av_mute(0); - rk2928_hdmi_sys_power_down(); - HDMIWrReg(0xe0, 0x3a); - HDMIWrReg(0xe1, 0x00); - HDMIWrReg(0xe2, 0x00); - HDMIWrReg(0xe3, 0x00); - HDMIWrReg(0xe4, 0x03); - HDMIWrReg(0xec, 0x03); - break; - default: - hdmi_dbg(hdmi->dev,"unkown rk2928 hdmi pwr mode %d\n",mode); - } - hdmi->pwr_mode = mode; -} - - -int rk2928_hdmi_detect_hotplug(void) -{ - int value = HDMIRdReg(HDMI_STATUS); - - hdmi_dbg(hdmi->dev, "[%s] value %02x\n", __FUNCTION__, value); - value &= m_HOTPLUG; - if(value == m_HOTPLUG) - return HDMI_HPD_ACTIVED; - else if(value) - return HDMI_HPD_INSERT; - else - return HDMI_HPD_REMOVED; -} - -#define HDMI_SYS_FREG_CLK 11289600 -#define HDMI_SCL_RATE (100*1000) -#define HDMI_DDC_CONFIG (HDMI_SYS_FREG_CLK>>2)/HDMI_SCL_RATE -#define DDC_BUS_FREQ_L 0x4b -#define DDC_BUS_FREQ_H 0x4c - -int rk2928_hdmi_read_edid(int block, unsigned char *buff) -{ - int value, ret = -1, ddc_bus_freq = 0; - char interrupt = 0, trytime = 2; - unsigned long flags; - - hdmi_dbg(hdmi->dev, "[%s] block %d\n", __FUNCTION__, block); - spin_lock_irqsave(&hdmi->irq_lock, flags); - edid_result = 0; - spin_unlock_irqrestore(&hdmi->irq_lock, flags); - //Before Phy parameter was set, DDC_CLK is equal to PLLA freq which is 30MHz. - //Set DDC I2C CLK which devided from DDC_CLK to 100KHz. - - ddc_bus_freq = HDMI_DDC_CONFIG; - HDMIWrReg(DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); - HDMIWrReg(DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); - - // Enable edid interrupt - HDMIWrReg(INTERRUPT_MASK1, m_INT_HOTPLUG | m_INT_EDID_READY); - - while(trytime--) { - // Config EDID block and segment addr - HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80); - HDMIWrReg(EDID_SEGMENT_POINTER, block/2); - - value = 10; - while(value--) - { - spin_lock_irqsave(&hdmi->irq_lock, flags); - interrupt = edid_result; - edid_result = 0; - spin_unlock_irqrestore(&hdmi->irq_lock, flags); - if(interrupt & (m_INT_EDID_READY)) - break; - msleep(10); - } - hdmi_dbg(hdmi->dev, "[%s] edid read value %d\n", __FUNCTION__, value); - if(interrupt & m_INT_EDID_READY) - { - for(value = 0; value < HDMI_EDID_BLOCK_SIZE; value++) - buff[value] = HDMIRdReg(EDID_FIFO_ADDR); - ret = 0; - - hdmi_dbg(hdmi->dev, "[%s] edid read sucess\n", __FUNCTION__); -#ifdef HDMI_DEBUG - for(value = 0; value < 128; value++) { - printk("%02x ,", buff[value]); - if( (value + 1) % 16 == 0) - printk("\n"); - } -#endif - break; - }else - hdmi_err(hdmi->dev, "[%s] edid read error\n", __FUNCTION__); - - hdmi_dbg(hdmi->dev, "[%s] edid try times %d\n", __FUNCTION__, trytime); - msleep(100); - } - // Disable edid interrupt - HDMIWrReg(INTERRUPT_MASK1, m_INT_HOTPLUG); -// msleep(100); - return ret; -} - -static void rk2928_hdmi_config_avi(unsigned char vic, unsigned char output_color) -{ - int i; - char info[SIZE_AVI_INFOFRAME]; - - memset(info, 0, SIZE_AVI_INFOFRAME); - HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); - info[0] = 0x82; - info[1] = 0x02; - 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[6] = 0; - info[7] = vic; - info[8] = 0; - - // Calculate AVI InfoFrame ChecKsum - for (i = 4; i < SIZE_AVI_INFOFRAME; i++) - { - info[3] += info[i]; - } - info[3] = 0x100 - info[3]; - - for(i = 0; i < SIZE_AVI_INFOFRAME; i++) - HDMIWrReg(CONTROL_PACKET_ADDR + i, info[i]); -} - -static int rk2928_hdmi_config_video(struct hdmi_video_para *vpara) -{ - int value; - struct fb_videomode *mode; - - hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); - if(vpara == NULL) { - hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__); - return -1; - } - - if(hdmi->hdcp_power_off_cb) - hdmi->hdcp_power_off_cb(); - // Diable video and audio output - HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); - - // Input video mode is SDR RGB24bit, Data enable signal from external - HDMIWrReg(VIDEO_CONTRL1, v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | v_DE_EXTERNAL); - HDMIWrReg(VIDEO_CONTRL2, v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | (vpara->output_color & 0xFF)); - - // Set HDMI Mode - HDMIWrReg(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; - HDMIWrReg(VIDEO_CONTRL3, value); - - // Set ext video -#if 1 - HDMIWrReg(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); - return -ENOENT; - } - hdmi->tmdsclk = mode->pixclock; -#else - value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode); - if(mode->sync & FB_SYNC_HOR_HIGH_ACT) - value |= v_HSYNC_POLARITY(1); - if(mode->sync & FB_SYNC_VERT_HIGH_ACT) - value |= v_VSYNC_POLARITY(1); - HDMIWrReg(VIDEO_TIMING_CTL, value); - - value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len; - HDMIWrReg(VIDEO_EXT_HTOTAL_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); - - value = mode->left_margin + mode->right_margin + mode->hsync_len; - HDMIWrReg(VIDEO_EXT_HBLANK_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); - - value = mode->left_margin + mode->hsync_len; - HDMIWrReg(VIDEO_EXT_HDELAY_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); - - value = mode->hsync_len; - HDMIWrReg(VIDEO_EXT_HDURATION_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); - - value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len; - HDMIWrReg(VIDEO_EXT_VTOTAL_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); - - value = mode->upper_margin + mode->vsync_len + mode->lower_margin; - HDMIWrReg(VIDEO_EXT_VBLANK, value & 0xFF); - - 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; - - HDMIWrReg(VIDEO_EXT_VDELAY, value & 0xFF); - - value = mode->vsync_len; - HDMIWrReg(VIDEO_EXT_VDURATION, value & 0xFF); -#endif - - if(vpara->output_mode == OUTPUT_HDMI) { - rk2928_hdmi_config_avi(vpara->vic, vpara->output_color); - hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); - } - else { - hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__); - } - - if(hdmi->tmdsclk >= 148500000) { - HDMIWrReg(0xe3, 0x4f); - } - else { - HDMIWrReg(0xe3, 0x0f); - } - return 0; -} - -static void rk2928_hdmi_config_aai(void) -{ - int i; - char info[SIZE_AUDIO_INFOFRAME]; - - memset(info, 0, SIZE_AUDIO_INFOFRAME); - - info[0] = 0x84; - info[1] = 0x01; - info[2] = 0x0A; - - info[3] = info[0] + info[1] + info[2]; - for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++) - info[3] += info[i]; - - info[3] = 0x100 - info[3]; - - HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI); - for(i = 0; i < SIZE_AUDIO_INFOFRAME; i++) - HDMIWrReg(CONTROL_PACKET_ADDR + i, info[i]); -} - -static int rk2928_hdmi_config_audio(struct hdmi_audio *audio) -{ - int rate, N, channel, mclk_fs; - - if(audio->channel < 3) - channel = I2S_CHANNEL_1_2; - else if(audio->channel < 5) - channel = I2S_CHANNEL_3_4; - 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; - } - - //set_audio source I2S - HDMIWrReg(AUDIO_CTRL1, 0x00); //internal CTS, disable down sample, i2s input, disable MCLK - HDMIWrReg(AUDIO_SAMPLE_RATE, rate); - HDMIWrReg(AUDIO_I2S_MODE, v_I2S_MODE(I2S_STANDARD) | v_I2S_CHANNEL(channel) ); - HDMIWrReg(AUDIO_I2S_MAP, 0x00); - HDMIWrReg(AUDIO_I2S_SWAPS_SPDIF, 0); // no swap - - //Set N value - HDMIWrReg(AUDIO_N_H, (N >> 16) & 0x0F); - HDMIWrReg(AUDIO_N_M, (N >> 8) & 0xFF); - HDMIWrReg(AUDIO_N_L, N & 0xFF); - rk2928_hdmi_config_aai(); - - return 0; -} - -void rk2928_hdmi_control_output(int enable) -{ - char mutestatus = 0; - - if(enable) { - if(hdmi->pwr_mode == LOWER_PWR) - rk2928_hdmi_set_pwr_mode(NORMAL); - mutestatus = HDMIRdReg(AV_MUTE); - if(mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) { - HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); - rk2928_hdmi_sys_power_up(); - rk2928_hdmi_sys_power_down(); - rk2928_hdmi_sys_power_up(); - if(analog_sync){ - HDMIWrReg(0xce, 0x00); - delay100us(); - HDMIWrReg(0xce, 0x01); - analog_sync = 0; - } - } - } - else { - HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); - } -} - -int rk2928_hdmi_removed(void) -{ - - dev_printk(KERN_INFO , hdmi->dev , "Removed.\n"); - rk2928_hdmi_set_pwr_mode(LOWER_PWR); - - return HDMI_ERROR_SUCESS; -} - - -irqreturn_t hdmi_irq(int irq, void *priv) -{ - char interrupt1 = 0; - unsigned long flags; - spin_lock_irqsave(&hdmi->irq_lock,flags); - interrupt1 = HDMIRdReg(INTERRUPT_STATUS1); - HDMIWrReg(INTERRUPT_STATUS1, interrupt1); -#if 1 - hdmi_dbg(hdmi->dev, "[%s] interrupt1 %02x \n",\ - __FUNCTION__, interrupt1); -#endif - if(interrupt1 & m_INT_HOTPLUG ){ - if(hdmi->state == HDMI_SLEEP) - hdmi->state = WAIT_HOTPLUG; - if(hdmi->pwr_mode == LOWER_PWR) - rk2928_hdmi_set_pwr_mode(NORMAL); - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); - }else if(interrupt1 & m_INT_EDID_READY) { - edid_result = interrupt1; - }else if(hdmi->state == HDMI_SLEEP) { - hdmi_dbg(hdmi->dev, "hdmi return to sleep mode\n"); - rk2928_hdmi_set_pwr_mode(LOWER_PWR); - } -#if 0 - if(hdmi->hdcp_irq_cb) - hdmi->hdcp_irq_cb(interrupt2); -#endif - spin_unlock_irqrestore(&hdmi->irq_lock,flags); - return IRQ_HANDLED; -} - -static void rk2928_hdmi_reset(void) -{ - writel_relaxed(0x00010001,RK2928_CRU_BASE+ 0x128); - msleep(100); - writel_relaxed(0x00010000, RK2928_CRU_BASE + 0x128); - rk2928_hdmi_set_pwr_mode(LOWER_PWR); -} - -int rk2928_hdmi_initial(void) -{ - int rc = HDMI_ERROR_SUCESS; - - hdmi->pwr_mode = NORMAL; - hdmi->remove = rk2928_hdmi_removed ; - hdmi->control_output = rk2928_hdmi_control_output; - hdmi->config_video = rk2928_hdmi_config_video; - hdmi->config_audio = rk2928_hdmi_config_audio; - hdmi->detect_hotplug = rk2928_hdmi_detect_hotplug; - hdmi->read_edid = rk2928_hdmi_read_edid; - - rk2928_hdmi_reset(); - - if(hdmi->hdcp_power_on_cb) - rc = hdmi->hdcp_power_on_cb(); - - return rc; -} diff --git a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi_hw.h deleted file mode 100755 index aa4fa1510d69..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk2928/rk2928_hdmi_hw.h +++ /dev/null @@ -1,248 +0,0 @@ -#ifndef _RK2928_HDMI_HW_H -#define _RK2928_HDMI_HW_H - -enum PWR_MODE{ - NORMAL, - LOWER_PWR, -}; -enum { - OUTPUT_DVI = 0, - OUTPUT_HDMI - }; -#define SYS_CTRL 0x00 - #define m_INT_POL (1 << 0) - #define m_POWER (1 << 1) - #define m_REG_CLK_SOURCE (1 << 2) - #define v_INT_POL_HIGH 1 - #define v_INT_POL_LOW 0 - #define v_PWR_ON (0 << 1) - #define v_PWR_OFF (1 << 1) - #define v_REG_CLK_SOURCE_TMDS (0 << 2) - #define v_REG_CLK_SOURCE_IIS (1 << 2) -#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 AUDIO_I2S_SWAPS_SPDIF 0x3a - #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_96K 0x3000 -#define N_192K 0x6000 - -#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 DDC_CLK_L 0x4b -#define DDC_CLK_H 0x4c - -#define EDID_SEGMENT_POINTER 0x4d -#define EDID_WORD_ADDR 0x4e -#define EDID_FIFO_OFFSET 0x4f -#define EDID_FIFO_ADDR 0x50 - -/* CONTROL_PACKET_BUF_INDEX */ -#define CONTROL_PACKET_BUF_INDEX 0x9f -enum { - INFOFRAME_AVI = 0x06, - INFOFRAME_AAI = 0x08 -}; -#define CONTROL_PACKET_ADDR 0xa0 - - -#define SIZE_AVI_INFOFRAME 0x11 // 14 bytes -#define SIZE_AUDIO_INFOFRAME 0x0F // 15 bytes -enum { - AVI_COLOR_MODE_RGB = 0, - AVI_COLOR_MODE_YCBCR422, - AVI_COLOR_MODE_YCBCR444 -}; -enum { - AVI_COLORIMETRY_NO_DATA = 0, - AVI_COLORIMETRY_SMPTE_170M, - AVI_COLORIMETRY_ITU709, - AVI_COLORIMETRY_EXTENDED -}; -enum { - AVI_CODED_FRAME_ASPECT_NO_DATA, - AVI_CODED_FRAME_ASPECT_4_3, - AVI_CODED_FRAME_ASPECT_16_9 -}; -enum { - ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME = 0x08, - ACTIVE_ASPECT_RATE_4_3, - ACTIVE_ASPECT_RATE_16_9, - ACTIVE_ASPECT_RATE_14_9 -}; - -#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 << 6) - #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_DRIVER 0xe1 - #define v_MAIN_DRIVER(n) (n << 4) - #define v_PRE_DRIVER(n) (n << 2) - #define v_TX_ENABLE(n) (n << 1) - -#define PHY_PRE_EMPHASIS 0xe2 - #define v_PRE_EMPHASIS(n) (n << 4) - #define v_TMDS_PWRDOWN(n) (n) - -#define PHY_PLL_TEST 0xe3 -#define PHY_BANDGAP_PWR 0xe4 - #define v_BANDGAP_PWR_DOWN 0x03 - #define v_BANDGAP_PWR_UP 0 - -#define PHY_PLL_CTRL 0xe5 - #define v_PLL_DISABLE(n) (n << 4) - #define v_PLL_RESET(n) (n << 3) - #define v_TMDS_RESET(n) (n << 2) - -#define PHY_PLL_LDO_PWR 0xe7 - #define v_LDO_PWR_DOWN(n) (n << 2) - -#define HDMIRdReg(addr) readl_relaxed(hdmi->regbase + (addr) * 0x04) -#define HDMIWrReg(addr, val) writel_relaxed((val), hdmi->regbase + (addr) * 0x04) -#define HDMIMskReg(temp, addr, msk, val) \ - temp = readl_relaxed(hdmi->regbase + (addr) * 0x04) & (0xFF - (msk)) ; \ - writel_relaxed(temp | ( (val) & (msk) ), hdmi->regbase + (addr) * 0x04); - -extern int rk2928_hdmi_initial(void); - -#endif diff --git a/drivers/video/rockchip/hdmi/chips/rk30/Kconfig b/drivers/video/rockchip/hdmi/chips/rk30/Kconfig deleted file mode 100755 index 27edf4102d3d..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/Kconfig +++ /dev/null @@ -1 +0,0 @@ -source "drivers/video/rockchip/hdmi/chips/rk30/hdcp/Kconfig" \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/chips/rk30/Makefile b/drivers/video/rockchip/hdmi/chips/rk30/Makefile deleted file mode 100755 index 0704c997140b..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for HDMI linux kernel module. -# - -ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG - -obj-$(CONFIG_HDMI_RK30) += rk30_hdmi_hw.o rk30_hdmi.o -obj-$(CONFIG_HDCP_RK30) += hdcp/ diff --git a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/Kconfig b/drivers/video/rockchip/hdmi/chips/rk30/hdcp/Kconfig deleted file mode 100755 index 1bb3c3a24f56..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -config HDCP_RK30 - bool "RK30 HDCP support" - depends on LCDC_RK30 && HDMI_RK30 - default n - help - HDCP Interface. This adds the High Definition Content Protection Interface. - See http://www.digital-cp.com/ for HDCP specification. - -config HDCP_RK30_DEBUG - bool "RK30 HDCP Debugging" - depends on HDCP_RK30 - default n - help - Enableds verbose debugging the the HDCP drivers diff --git a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/Makefile b/drivers/video/rockchip/hdmi/chips/rk30/hdcp/Makefile deleted file mode 100755 index 108b67ca134e..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for HDCP linux kernel module. -# - -ccflags-$(CONFIG_HDCP_RK30_DEBUG) = -DDEBUG -DHDCP_DEBUG - -obj-$(CONFIG_HDCP_RK30) += hdcp.o -hdcp-y := rk30_hdcp.o rk30_hdmi_hdcp.o diff --git a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/rk30_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk30/hdcp/rk30_hdcp.c deleted file mode 100755 index c0411214854b..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/rk30_hdcp.c +++ /dev/null @@ -1,634 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "../rk30_hdmi.h" -#include "../rk30_hdmi_hw.h" -#include "rk30_hdmi_hdcp.h" - -static struct hdcp *hdcp = NULL; - -static void hdcp_work_queue(struct work_struct *work); - -/*----------------------------------------------------------------------------- - * Function: hdcp_submit_work - *----------------------------------------------------------------------------- - */ -struct delayed_work *hdcp_submit_work(int event, int delay) -{ - struct hdcp_delayed_work *work; - - HDCP_DBG("%s event %04x delay %d", __FUNCTION__, event, delay); - - work = kmalloc(sizeof(struct hdcp_delayed_work), GFP_ATOMIC); - - if (work) { - INIT_DELAYED_WORK(&work->work, hdcp_work_queue); - work->event = event; - queue_delayed_work(hdcp->workqueue, - &work->work, - msecs_to_jiffies(delay)); - } else { - printk(KERN_WARNING "HDCP: Cannot allocate memory to " - "create work\n"); - return 0; - } - - return &work->work; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_cancel_work - *----------------------------------------------------------------------------- - */ -static void hdcp_cancel_work(struct delayed_work **work) -{ - int ret = 0; - - return; - if (*work) { - ret = cancel_delayed_work(*work); - if (ret != 1) { - ret = cancel_work_sync(&((*work)->work)); - printk(KERN_INFO "Canceling work failed - " - "cancel_work_sync done %d\n", ret); - } - kfree(*work); - *work = 0; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_failure - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_failure(void) -{ - HDCP_DBG("%s hdcp->retry_cnt %d \n", __FUNCTION__, hdcp->retry_cnt); - if (hdcp->hdmi_state == HDMI_STOPPED) { - return; - } - - rk30_hdcp_disable(hdcp); - rk30_hdmi_control_output(false); - - hdcp_cancel_work(&hdcp->pending_wq_event); - - if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) { - if (hdcp->retry_cnt < HDCP_INFINITE_REAUTH) { - hdcp->retry_cnt--; - printk(KERN_INFO "HDCP: authentication failed - " - "retrying, attempts=%d\n", - hdcp->retry_cnt); - } else - printk(KERN_INFO "HDCP: authentication failed - " - "retrying\n"); - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - - hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT, - HDCP_REAUTH_DELAY); - } else { - printk(KERN_INFO "HDCP: authentication failed - " - "HDCP disabled\n"); - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } - -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_start_authentication - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_start_authentication(void) -{ - int status = HDCP_OK; - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - - HDCP_DBG("HDCP: authentication start"); - - status = rk30_hdcp_start_authentication(hdcp); - - if (status != HDCP_OK) { - HDCP_DBG("HDCP: authentication failed"); - hdcp_wq_authentication_failure(); - } else { - hdcp->hdcp_state = HDCP_AUTHENTICATION_1ST; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_1st - *----------------------------------------------------------------------------- - */ -static int hdcp_wq_authentication_1st(void) -{ - int status = HDCP_OK; - - HDCP_DBG("1st authen start"); - - status = rk30_hdcp_authentication_1st(hdcp); - - if (status == -HDCP_DDC_ERROR) - hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_START_1ST, 1000); - else if (status != HDCP_OK) { - printk(KERN_INFO "HDCP: 1st authen failed %d", status); -// hdcp->retry_cnt = 0; - hdcp_wq_authentication_failure(); - } - else { - HDCP_DBG("HDCP: 1st Authentication successful"); - hdcp->hdcp_state = HDCP_WAIT_R0_DELAY; -// hdcp.auth_state = HDCP_STATE_AUTH_1ST_STEP; - } - return HDCP_OK; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_check_r0 - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_check_r0(void) -{ - int status = rk30_hdcp_lib_step1_r0_check(hdcp); - - if (status == -HDCP_CANCELLED_AUTH) { - HDCP_DBG("Authentication step 1/R0 cancelled."); - return; - } else if (status < 0) - hdcp_wq_authentication_failure(); - else { - if (hdcp_lib_check_repeater_bit_in_tx(hdcp)) { - /* Repeater */ - printk(KERN_INFO "HDCP: authentication step 1 " - "successful - Repeater\n"); - - hdcp->hdcp_state = HDCP_WAIT_KSV_LIST; -// hdcp.auth_state = HDCP_STATE_AUTH_2ND_STEP; - - hdcp->pending_wq_event = - hdcp_submit_work(HDCP_AUTH_START_2ND, 0); - - } else { - /* Receiver */ - printk(KERN_INFO "HDCP: authentication step 1 " - "successful - Receiver\n"); - - hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - } - } -} -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_check_bksv - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_step2_authentication(void) -{ - int status = HDCP_OK; - - HDCP_DBG("%s", __FUNCTION__); - - status = rk30_hdcp_authentication_2nd(hdcp); - - if (status == -HDCP_CANCELLED_AUTH) { - HDCP_DBG("Authentication step 2nd cancelled."); - return; - } - else if (status < 0) { - printk(KERN_INFO "HDCP: step2 authentication failed"); - hdcp_wq_authentication_failure(); - } - else { - HDCP_DBG("HDCP: step2 authentication successful"); - - hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_3rd - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_3rd(void) -{ - int status = rk30_hdcp_lib_step3_r0_check(hdcp); - - if (status == -HDCP_CANCELLED_AUTH) { - HDCP_DBG("Authentication step 3/Ri cancelled."); - return; - } else if (status < 0) - hdcp_wq_authentication_failure(); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_disable - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_disable(int event) -{ - printk(KERN_INFO "HDCP: disabled"); - - hdcp_cancel_work(&hdcp->pending_wq_event); - rk30_hdcp_disable(hdcp); - if(event == HDCP_DISABLE_CTL) { - hdcp->hdcp_state = HDCP_DISABLED; - if(hdcp->hdmi_state == HDMI_STARTED) - rk30_hdmi_control_output(true); - } - else if(event == HDCP_STOP_FRAME_EVENT) - hdcp->hdcp_state = HDCP_ENABLE_PENDING; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_work_queue - *----------------------------------------------------------------------------- - */ -static void hdcp_work_queue(struct work_struct *work) -{ - struct hdcp_delayed_work *hdcp_w = - container_of(work, struct hdcp_delayed_work, work.work); - int event = hdcp_w->event; - - mutex_lock(&hdcp->lock); - - HDCP_DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d", - jiffies_to_msecs(jiffies), - hdcp->hdmi_state, - hdcp->hdcp_state, - (event & 0xFF00) >> 8, - event & 0xFF); - - if(event == HDCP_STOP_FRAME_EVENT) { - hdcp->hdmi_state = HDMI_STOPPED; - } - - if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) { - hdcp_wq_disable(event); - } - - if (event & HDCP_WORKQUEUE_SRC) - hdcp->pending_wq_event = 0; - - /* First handle HDMI state */ - if (event == HDCP_START_FRAME_EVENT) { - hdcp->pending_start = 0; - hdcp->hdmi_state = HDMI_STARTED; - if(hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times; - } - - /**********************/ - /* HDCP state machine */ - /**********************/ - switch (hdcp->hdcp_state) { - case HDCP_DISABLED: - /* HDCP enable control or re-authentication event */ - if (event == HDCP_ENABLE_CTL) { - if(hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times; - if (hdcp->hdmi_state == HDMI_STARTED) - hdcp_wq_start_authentication(); - else - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } - break; - - case HDCP_ENABLE_PENDING: - /* HDMI start frame event */ - if (event == HDCP_START_FRAME_EVENT) - hdcp_wq_start_authentication(); - - break; - - case HDCP_AUTHENTICATION_START: - /* Re-authentication */ - if (event == HDCP_AUTH_REATT_EVENT) - hdcp_wq_start_authentication(); - - break; - - case HDCP_AUTHENTICATION_1ST: - if(event == HDCP_AUTH_START_1ST) - hdcp_wq_authentication_1st(); - break; - - case HDCP_WAIT_R0_DELAY: - if(event == HDCP_R0_EXP_EVENT) - hdcp_wq_check_r0(); - break; - - case HDCP_WAIT_KSV_LIST: - /* KSV failure */ - if (event == HDCP_FAIL_EVENT) { - printk(KERN_INFO "HDCP: KSV switch failure\n"); - - hdcp_wq_authentication_failure(); - } - /* KSV list ready event */ - else if (event == HDCP_AUTH_START_2ND) - hdcp_wq_step2_authentication(); - break; - - case HDCP_LINK_INTEGRITY_CHECK: - /* Ri failure */ - if (event == HDCP_FAIL_EVENT) { - printk(KERN_INFO "HDCP: Ri check failure\n"); - hdcp_wq_authentication_failure(); - } - else if(event == HDCP_RI_EXP_EVENT) - hdcp_wq_authentication_3rd(); - break; - - default: - printk(KERN_WARNING "HDCP: error - unknow HDCP state\n"); - break; - } - - kfree(hdcp_w); - if(event == HDCP_STOP_FRAME_EVENT) - complete(&hdcp->complete); - - mutex_unlock(&hdcp->lock); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_start_frame_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_start_frame_cb(void) -{ - HDCP_DBG("hdcp_start_frame_cb()"); - - /* Cancel any pending work */ - if (hdcp->pending_start) - hdcp_cancel_work(&hdcp->pending_start); - if (hdcp->pending_wq_event) - hdcp_cancel_work(&hdcp->pending_wq_event); - hdcp->pending_disable = 0; - hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT, - HDCP_ENABLE_DELAY); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_irq_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_irq_cb(int interrupt) -{ - rk30_hdcp_irq(hdcp); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_on_cb - *----------------------------------------------------------------------------- - */ -static int hdcp_power_on_cb(void) -{ - HDCP_DBG("%s", __FUNCTION__); - return rk30_hdcp_load_key2mem(hdcp, hdcp->keys); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_off_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_power_off_cb(void) -{ - HDCP_DBG("%s", __FUNCTION__); - if(!hdcp->enable) - return; - - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - hdcp->pending_disable = 1; - init_completion(&hdcp->complete); - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0)) - wait_for_completion_interruptible_timeout(&hdcp->complete, - msecs_to_jiffies(2000)); -} - -// Load HDCP key to external HDCP memory -static void hdcp_load_keys_cb(const struct firmware *fw, void *context) -{ - if (!fw) { - pr_err("HDCP: failed to load keys\n"); - return; - } - - if(fw->size < HDCP_KEY_SIZE) { - pr_err("HDCP: firmware wrong size %d\n", fw->size); - return; - } - - hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL); - if(hdcp->keys == NULL) { - pr_err("HDCP: can't allocated space for keys\n"); - return; - } - - memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE); - - rk30_hdcp_load_key2mem(hdcp, hdcp->keys); - printk(KERN_INFO "HDCP: loaded hdcp key success\n"); - - if(fw->size > HDCP_KEY_SIZE) { - HDCP_DBG("%s invalid key size %d", __FUNCTION__, fw->size - HDCP_KEY_SIZE); - if((fw->size - HDCP_KEY_SIZE) % 5) { - pr_err("HDCP: failed to load invalid keys\n"); - return; - } - hdcp->invalidkeys = kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL); - if(hdcp->invalidkeys == NULL) { - pr_err("HDCP: can't allocated space for invalid keys\n"); - return; - } - memcpy(hdcp->invalidkeys, fw->data + HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE); - hdcp->invalidkey = (fw->size - HDCP_KEY_SIZE)/5; - printk(KERN_INFO "HDCP: loaded hdcp invalid key success\n"); - } -} - -static ssize_t hdcp_enable_read(struct device *device, - struct device_attribute *attr, char *buf) -{ - int enable = 0; - - if(hdcp) - enable = hdcp->enable; - - return snprintf(buf, PAGE_SIZE, "%d\n", enable); -} - -static ssize_t hdcp_enable_write(struct device *device, - struct device_attribute *attr, const char *buf, size_t count) -{ - int enable; - - if(hdcp == NULL) - return -EINVAL; - - sscanf(buf, "%d", &enable); - if(hdcp->enable != enable) - { - /* Post event to workqueue */ - if(enable) { - if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0) - return -EFAULT; - } - else { - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0) - return -EFAULT; - } - hdcp->enable = enable; - } - return count; -} - -static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, hdcp_enable_read, hdcp_enable_write); - -static ssize_t hdcp_trytimes_read(struct device *device, - struct device_attribute *attr, char *buf) -{ - int trytimes = 0; - - if(hdcp) - trytimes = hdcp->retry_times; - - return snprintf(buf, PAGE_SIZE, "%d\n", trytimes); -} - -static ssize_t hdcp_trytimes_wrtie(struct device *device, - struct device_attribute *attr, const char *buf, size_t count) -{ - int trytimes; - - if(hdcp == NULL) - return -EINVAL; - - sscanf(buf, "%d", &trytimes); - if(hdcp->retry_times != trytimes) - hdcp->retry_times = trytimes; - - return count; -} - - -static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR, hdcp_trytimes_read, hdcp_trytimes_wrtie); - - -static struct miscdevice mdev; - -static int __init rk30_hdcp_init(void) -{ - int ret; - - HDCP_DBG("[%s] %u", __FUNCTION__, jiffies_to_msecs(jiffies)); - - hdcp = kmalloc(sizeof(struct hdcp), GFP_KERNEL); - if(!hdcp) - { - printk(KERN_ERR ">>HDCP: kmalloc fail!"); - ret = -ENOMEM; - goto error0; - } - memset(hdcp, 0, sizeof(struct hdcp)); - mutex_init(&hdcp->lock); - - mdev.minor = MISC_DYNAMIC_MINOR; - mdev.name = "hdcp"; - mdev.mode = 0666; - if (misc_register(&mdev)) { - printk(KERN_ERR "HDCP: Could not add character driver\n"); - ret = HDMI_ERROR_FALSE; - goto error1; - } - ret = device_create_file(mdev.this_device, &dev_attr_enable); - if(ret) - { - printk(KERN_ERR "HDCP: Could not add sys file enable\n"); - ret = -EINVAL; - goto error2; - } - - ret = device_create_file(mdev.this_device, &dev_attr_trytimes); - if(ret) - { - printk(KERN_ERR "HDCP: Could not add sys file trytimes\n"); - ret = -EINVAL; - goto error3; - } - - hdcp->workqueue = create_singlethread_workqueue("hdcp"); - if (hdcp->workqueue == NULL) { - printk(KERN_ERR "HDCP,: create workqueue failed.\n"); - goto error4; - } - - - ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, - "hdcp.keys", mdev.this_device, GFP_KERNEL, - hdcp, hdcp_load_keys_cb); - if (ret < 0) { - printk(KERN_ERR "HDCP: request_firmware_nowait failed: %d\n", ret); - goto error5; - } - - hdcp->hdmi = rk30_hdmi_register_hdcp_callbacks( hdcp_start_frame_cb, - hdcp_irq_cb, - hdcp_power_on_cb, - hdcp_power_off_cb); - - HDCP_DBG("%s success %u", __FUNCTION__, jiffies_to_msecs(jiffies)); - return 0; - -error5: - destroy_workqueue(hdcp->workqueue); -error4: - device_remove_file(mdev.this_device, &dev_attr_trytimes); -error3: - device_remove_file(mdev.this_device, &dev_attr_enable); -error2: - misc_deregister(&mdev); -error1: - if(hdcp->keys) - kfree(hdcp->keys); - if(hdcp->invalidkeys) - kfree(hdcp->invalidkeys); - kfree(hdcp); -error0: - return ret; -} - -static void __exit rk30_hdcp_exit(void) -{ - if(hdcp) { - mutex_lock(&hdcp->lock); - rk30_hdmi_register_hdcp_callbacks(0, 0, 0, 0); - device_remove_file(mdev.this_device, &dev_attr_enable); - misc_deregister(&mdev); - destroy_workqueue(hdcp->workqueue); - if(hdcp->keys) - kfree(hdcp->keys); - if(hdcp->invalidkeys) - kfree(hdcp->invalidkeys); - mutex_unlock(&hdcp->lock); - kfree(hdcp); - } -} - -//module_init(rk30_hdcp_init); -device_initcall_sync(rk30_hdcp_init); -module_exit(rk30_hdcp_exit); \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/rk30_hdmi_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk30/hdcp/rk30_hdmi_hdcp.c deleted file mode 100755 index 294d9cfc3e48..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/rk30_hdmi_hdcp.c +++ /dev/null @@ -1,633 +0,0 @@ -#include -#include -#include -#include -#include "../rk30_hdmi.h" -#include "../rk30_hdmi_hw.h" -#include "rk30_hdmi_hdcp.h" - -static int an_ready = 0, sha_ready = 0, i2c_ack = 9; - -/*----------------------------------------------------------------------------- - * Function: hdcp_lib_check_ksv - *----------------------------------------------------------------------------- - */ -static int hdcp_lib_check_ksv(uint8_t ksv[5]) -{ - int i, j; - int zero = 0, one = 0; - - for (i = 0; i < 5; i++) { - /* Count number of zero / one */ - for (j = 0; j < 8; j++) { - if (ksv[i] & (0x01 << j)) - one++; - else - zero++; - } - } - - if (one == zero) - return 0; - else - return -1; -} - -static void rk30_hdcp_write_mem(int addr_8, char value) -{ - int temp; - int addr_32 = addr_8 - addr_8%4; - int shift = (addr_8%4) * 8; - - temp = HDMIRdReg(addr_32); - temp &= ~(0xff << shift); - temp |= value << shift; -// printk("temp is %08x\n", temp); - HDMIWrReg(addr_32, temp); -} - -int rk30_hdcp_load_key2mem(struct hdcp *hdcp, struct hdcp_keys *key) -{ - int i; - - if(key == NULL) return HDMI_ERROR_FALSE; - - HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV); - - for(i = 0; i < 7; i++) - rk30_hdcp_write_mem(HDCP_RAM_KEY_KSV1 + i, key->KSV[i]); - for(i = 0; i < 7; i++) - rk30_hdcp_write_mem(HDCP_RAM_KEY_KSV2 + i, key->KSV[i]); - for(i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) - rk30_hdcp_write_mem(HDCP_RAM_KEY_PRIVATE + i, key->DeviceKey[i]); - for(i = 0; i < HDCP_KEY_SHA_SIZE; i++) - rk30_hdcp_write_mem(HDCP_RAM_KEY_PRIVATE + HDCP_PRIVATE_KEY_SIZE + i, key->sha1[i]); - - HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV | 0x20); - return HDCP_OK; -} - -void rk30_hdcp_disable(struct hdcp *hdcp) -{ - int temp; - - // Diable Encrypt - HDMIMskReg(temp, HDCP_CTRL, m_HDCP_FRAMED_ENCRYPED, v_HDCP_FRAMED_ENCRYPED(0)); - - // Diable HDCP Interrupt - HDMIWrReg(SOFT_HDCP_INT_MASK1, 0x00); - HDMIWrReg(SOFT_HDCP_INT_MASK2, 0x00); - - // Stop and Reset HDCP - HDMIWrReg(SOFT_HDCP_CTRL1, 0x00); -} - -static int rk30_hdcp_load_key(struct hdcp *hdcp) -{ - int value, temp = 0; - - if(hdcp->keys == NULL) { - pr_err("[%s] HDCP key not loaded.\n", __FUNCTION__); - return HDCP_KEY_ERR; - } - - value = HDMIRdReg(HDCP_KEY_MEM_CTRL); - //Check HDCP key loaded from external HDCP memory - while((value & (m_KSV_VALID | m_KEY_VALID | m_KEY_READY)) != (m_KSV_VALID | m_KEY_VALID | m_KEY_READY)) { - if(temp > 10) { - pr_err("[%s] loaded hdcp key is incorrectable %02x\n", __FUNCTION__, value & 0xFF); - return HDCP_KEY_ERR; - } - //Load HDCP Key from external HDCP memory - HDMIWrReg(HDCP_KEY_ACCESS_CTRL2, m_LOAD_HDCP_KEY); - msleep(1); - value = HDMIRdReg(HDCP_KEY_MEM_CTRL); - temp++; - } - - return HDCP_OK; -} - -static int rk30_hdcp_ddc_read(struct hdcp *hdcp, u16 no_bytes, u8 addr, u8 *pdata) -{ - int i, temp; - - i2c_ack = 0; - HDMIMskReg(temp, SOFT_HDCP_INT_MASK2, m_I2C_ACK|m_I2C_NO_ACK, 0xC0); - HDMIWrReg(HDCP_DDC_ACCESS_LENGTH, no_bytes); - HDMIWrReg(HDCP_DDC_OFFSET_ADDR, addr); - HDMIWrReg(HDCP_DDC_CTRL, m_DDC_READ); - - while(1) { - if(i2c_ack & 0xc0) { - break; - } - msleep(100); - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - } - - HDMIMskReg(temp, SOFT_HDCP_INT_MASK2, m_I2C_ACK|m_I2C_NO_ACK, 0x00); - if(i2c_ack & m_I2C_NO_ACK) - return -HDCP_DDC_ERROR; - - if(i2c_ack & m_I2C_ACK) { - for(i = 0; i < no_bytes; i++) - pdata[i] = HDMIRdReg(HDCP_DDC_READ_BUFF + i * 4); - } - - return HDCP_OK; -} - -static int rk30_hdcp_ddc_write(struct hdcp *hdcp, u16 no_bytes, u8 addr, u8 *pdata) -{ - int i, temp; - - for(i = 0; i < no_bytes; i++) - HDMIWrReg(HDCP_DDC_WRITE_BUFF + i * 4, pdata[i]); - - i2c_ack = 0; - HDMIMskReg(temp, SOFT_HDCP_INT_MASK2, m_I2C_ACK|m_I2C_NO_ACK, 0xC0); - HDMIWrReg(HDCP_DDC_ACCESS_LENGTH, no_bytes); - HDMIWrReg(HDCP_DDC_OFFSET_ADDR, addr); - HDMIWrReg(HDCP_DDC_CTRL, m_DDC_WRITE); - - while(1) { - if(i2c_ack & 0xc0) { - break; - } - msleep(100); - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - } - HDMIMskReg(temp, SOFT_HDCP_INT_MASK2, m_I2C_ACK|m_I2C_NO_ACK, 0x00); - if(i2c_ack & m_I2C_NO_ACK) - return -HDCP_DDC_ERROR; - - return HDCP_OK; -} - -int rk30_hdcp_start_authentication(struct hdcp *hdcp) -{ - int rc, temp; - struct hdmi* hdmi = hdcp->hdmi; - - rc = rk30_hdcp_load_key(hdcp); - if(rc != HDCP_OK) - return rc; - - // Config DDC Clock - temp = (hdmi->tmdsclk/HDCP_DDC_CLK)/4; - HDMIWrReg(DDC_BUS_FREQ_L, temp & 0xFF); - HDMIWrReg(DDC_BUS_FREQ_H, (temp >> 8) & 0xFF); - - // Enable Software HDCP INT - HDMIWrReg(INTR_MASK2, 0x00); - HDMIWrReg(SOFT_HDCP_INT_MASK1, m_SF_MODE_READY); - HDMIWrReg(SOFT_HDCP_INT_MASK2, 0x00); - - // Diable Encrypt - HDMIMskReg(temp, HDCP_CTRL, m_HDCP_FRAMED_ENCRYPED, v_HDCP_FRAMED_ENCRYPED(0)); - - // Enable Software HDCP - HDMIWrReg(SOFT_HDCP_CTRL1, v_SOFT_HDCP_AUTH_EN(1)); - - return HDCP_OK; -} - -static int rk30_hdcp_generate_an(struct hdcp *hdcp, uint8_t ksv[8]) -{ - int temp; - - HDCP_DBG("%s", __FUNCTION__); - - an_ready = 0; - HDMIMskReg(temp, SOFT_HDCP_INT_MASK1, (1 << 4), (1 << 4)); - HDMIWrReg(SOFT_HDCP_CTRL1, v_SOFT_HDCP_AUTH_EN(1) | v_SOFT_HDCP_PREP_AN(1)); - - while(1) { - if(an_ready) - break; - msleep(100); - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - } - HDMIMskReg(temp, SOFT_HDCP_INT_MASK1, (1 << 4), 0); - for(temp = 0; temp < 8; temp++) - ksv[temp] = HDMIRdReg(HDCP_AN_BUFF + temp * 4); - return HDCP_OK; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_lib_read_aksv - *----------------------------------------------------------------------------- - */ -static void rk30_hdcp_read_aksv(struct hdcp *hdcp, u8 *ksv_data) -{ - u8 i; - int temp; - - // Load AKSV to Reg - HDMIMskReg(temp, HDCP_KEY_MEM_CTRL, (1 << 4), (1 << 4)); - - for (i = 0; i < 5; i++) { - ksv_data[i] = HDMIRdReg(HDCP_AKSV_BUFF + i * 4); - } -} - -int rk30_hdcp_authentication_1st(struct hdcp *hdcp) -{ - /* HDCP authentication steps: - * 1) Read Bksv - check validity (is HDMI Rx supporting HDCP ?) - * 2) Initializes HDCP (CP reset release) - * 3) Read Bcaps - is HDMI Rx a repeater ? - * *** First part authentication *** - * 4) Read Bksv - check validity (is HDMI Rx supporting HDCP ?) - * 5) Generates An - * 6) DDC: Writes An, Aksv - * 7) DDC: Write Bksv - */ - uint8_t an_ksv_data[8]; - uint8_t rx_type; - uint8_t trytimes = 5; - int temp, status; - /* Generate An */ - status = rk30_hdcp_generate_an(hdcp, an_ksv_data); - if(status < 0) - return status; - HDCP_DBG("AN: %02x %02x %02x %02x %02x %02x %02x %02x", an_ksv_data[0], an_ksv_data[1], - an_ksv_data[2], an_ksv_data[3], - an_ksv_data[4], an_ksv_data[5], - an_ksv_data[6], an_ksv_data[7]); - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - /* DDC: Write An */ - status = rk30_hdcp_ddc_write(hdcp, DDC_AN_LEN, DDC_AN_ADDR , an_ksv_data); - if (status < 0) - return status; - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - /* Read AKSV from IP: (HDCP AKSV register) */ - rk30_hdcp_read_aksv(hdcp, an_ksv_data); - - HDCP_DBG("AKSV: %02x %02x %02x %02x %02x", an_ksv_data[0], an_ksv_data[1], - an_ksv_data[2], an_ksv_data[3], - an_ksv_data[4]); - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - if (hdcp_lib_check_ksv(an_ksv_data)) { - printk(KERN_INFO "HDCP: AKSV error (number of 0 and 1)\n"); - return -HDCP_AKSV_ERROR; - } - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - /* DDC: Write AKSV */ - status = rk30_hdcp_ddc_write(hdcp, DDC_AKSV_LEN, DDC_AKSV_ADDR, an_ksv_data); - if (status < 0) - return status; - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - /* Read BCAPS to determine if HDCP RX is a repeater */ - status = rk30_hdcp_ddc_read(hdcp, DDC_BCAPS_LEN, DDC_BCAPS_ADDR, &rx_type); - if (status < 0) - return status; - - HDCP_DBG("bcaps is %02x", rx_type); - - HDMIWrReg(SOFT_HDCP_BCAPS, rx_type); - - if(rx_type & m_REPEATER) { - HDCP_DBG("Downstream device is a repeater"); - HDMIMskReg(temp, SOFT_HDCP_CTRL1, m_SOFT_HDCP_REPEATER, v_SOFT_HDCP_REPEATER(1)); - } - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - /* DDC: Read BKSV from RX */ - while(trytimes--) { - status = rk30_hdcp_ddc_read(hdcp, DDC_BKSV_LEN, DDC_BKSV_ADDR, an_ksv_data); - if (status < 0) - return status; - - HDCP_DBG("BKSV: %02x %02x %02x %02x %02x", an_ksv_data[0], an_ksv_data[1], - an_ksv_data[2], an_ksv_data[3], - an_ksv_data[4]); - - if (hdcp_lib_check_ksv(an_ksv_data) == 0) - break; - else { - HDCP_DBG("BKSV error (number of 0 and 1)"); - } - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - } - if(trytimes == 0) - return -HDCP_BKSV_ERROR; - - for(trytimes = 0; trytimes < 5; trytimes++) - HDMIWrReg(HDCP_BKSV_BUFF + trytimes * 4, an_ksv_data[trytimes]); - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - HDMIMskReg(temp, SOFT_HDCP_INT_MASK1, (1 << 6), (1 << 6)); - HDMIMskReg(temp, SOFT_HDCP_CTRL1, m_SOFT_HDCP_GEN_RI, v_SOFT_HDCP_GEN_RI(1)); - return HDCP_OK; -} - -static int rk30_hdcp_r0_check(struct hdcp *hdcp) -{ - u8 ro_rx[2], ro_tx[2]; - int status; - - HDCP_DBG("%s()", __FUNCTION__); - - HDMIMskReg(status, SOFT_HDCP_INT_MASK1, (1 << 6), 0); - - /* DDC: Read Ri' from RX */ - status = rk30_hdcp_ddc_read(hdcp, DDC_Ri_LEN, DDC_Ri_ADDR , (u8 *)&ro_rx); - if (status < 0) - return status; - - /* Read Ri in HDCP IP */ - ro_tx[0] = HDMIRdReg(HDCP_RI_BUFF); - - ro_tx[1] = HDMIRdReg(HDCP_RI_BUFF + 4); - - /* Compare values */ - HDCP_DBG("ROTX: %x%x RORX:%x%x", ro_tx[0], ro_tx[1], ro_rx[0], ro_rx[1]); - - if ((ro_rx[0] == ro_tx[0]) && (ro_rx[1] == ro_tx[1])) - return HDCP_OK; - else - return -HDCP_AUTH_FAILURE; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_lib_check_repeater_bit_in_tx - *----------------------------------------------------------------------------- - */ -u8 hdcp_lib_check_repeater_bit_in_tx(struct hdcp *hdcp) -{ - return (HDMIRdReg(HDCP_BCAPS) & m_REPEATER); -} - -/*----------------------------------------------------------------------------- - * Function: rk30_hdcp_lib_step1_r0_check - *----------------------------------------------------------------------------- - */ -int rk30_hdcp_lib_step1_r0_check(struct hdcp *hdcp) -{ - int status = HDCP_OK, temp; - - /* HDCP authentication steps: - * 1) DDC: Read M0' - * 2) Compare M0 and M0' - * if Rx is a receiver: switch to authentication step 3 - * 3) Enable encryption / auto Ri check / disable AV mute - * if Rx is a repeater: switch to authentication step 2 - * 3) Get M0 from HDMI IP and store it for further processing (V) - * 4) Enable encryption / auto Ri check / auto BCAPS RDY polling - * Disable AV mute - */ - - HDCP_DBG("hdcp_lib_step1_r0_check() %u", jiffies_to_msecs(jiffies)); - - status = rk30_hdcp_r0_check(hdcp); - if(status < 0) - return status; - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - if (hdcp_lib_check_repeater_bit_in_tx(hdcp)) { - - } else { - HDMIMskReg(temp, SOFT_HDCP_INT_MASK2, (1 << 4) | (1 << 5), (1 << 4) | (1 << 5)); - /* Receiver: enable encryption */ - HDMIMskReg(temp, HDCP_CTRL, m_HDCP_FRAMED_ENCRYPED, v_HDCP_FRAMED_ENCRYPED(1)); - HDMIMskReg(temp, SOFT_HDCP_CTRL1, m_SOFT_HDCP_AUTH_START, m_SOFT_HDCP_AUTH_START); - } - - return HDCP_OK; -} - -static int rk30_hdcp_read_ksvlist(struct hdcp *hdcp, int num) -{ - int i, temp; - uint8_t an_ksv_data[5]; - - i2c_ack = 0; - - HDCP_DBG("%s", __FUNCTION__); - - HDMIMskReg(temp, SOFT_HDCP_INT_MASK2, m_I2C_ACK|m_I2C_NO_ACK, 0xC0); - HDMIWrReg(HDCP_DDC_ACCESS_LENGTH, num * 5); - HDMIWrReg(HDCP_DDC_OFFSET_ADDR, DDC_KSV_FIFO_ADDR); - HDMIWrReg(HDCP_DDC_CTRL, m_DDC_READ | (1 << 2)); - - while(1) { - if(i2c_ack & 0xc0) { - break; - } - msleep(100); - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - } - - HDMIMskReg(temp, SOFT_HDCP_INT_MASK2, m_I2C_ACK|m_I2C_NO_ACK, 0x00); - if(i2c_ack & m_I2C_NO_ACK) - return -HDCP_DDC_ERROR; - - if(i2c_ack & m_I2C_ACK) { - for(i = 0; i < num * 5; i++) { - temp = HDMIRdReg(0x80 * 4); - an_ksv_data[i%5] = temp; - if((i+1) % 5 == 0) { - HDCP_DBG("BKSV: %02x %02x %02x %02x %02x", an_ksv_data[0], an_ksv_data[1], - an_ksv_data[2], an_ksv_data[3], - an_ksv_data[4]); - if (hdcp_lib_check_ksv(an_ksv_data)) - return -HDCP_AUTH_FAILURE; -// for(temp = 0; temp < 5; temp++) -// HDMIWrReg(HDCP_BKSV_BUFF + temp * 4, an_ksv_data[temp]); - } - } - } - return HDCP_OK; -} - -static int rk30_hdcp_check_sha(struct hdcp *hdcp) -{ - int temp, status; - uint8_t asha[4], bsha[4], i; - - HDCP_DBG("%s", __FUNCTION__); - - // Calculate SHA1 - HDMIMskReg(temp, SOFT_HDCP_INT_MASK1, (1 << 3), (1 << 3)); - HDMIMskReg(temp, SOFT_HDCP_CTRL1, m_SOFT_HDCP_CAL_SHA, v_SOFT_HDCP_CAL_SHA(1)); - - while(1) { - if(sha_ready) - break; - msleep(100); - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - } - - HDMIMskReg(temp, SOFT_HDCP_INT_MASK1, (1 << 3), 0); - - for(temp = 0; temp < 5; temp++) { - for(i = 0; i < 4; i++) { - HDMIWrReg(HDCP_SHA_INDEX, i); - asha[i] = HDMIRdReg(HDCP_SHA_BUF + 4 * temp); - } - HDCP_DBG("ASHA%d %02x %02x %02x %02x\n", temp, asha[0], asha[1], asha[2], asha[3]); - - status = rk30_hdcp_ddc_read(hdcp, DDC_V_LEN, DDC_V_ADDR + temp * 4, bsha); - if(status < 0) - return status; - - HDCP_DBG("BSHA%d %02x %02x %02x %02x\n", temp, bsha[0], bsha[1], bsha[2], bsha[3]); - - if( (asha[0] != bsha[0]) || (asha[1] != bsha[1]) || (asha[2] != bsha[2]) || (asha[3] != bsha[3]) ) - return -HDCP_AUTH_FAILURE; - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - - } - return HDCP_OK; -} - -/*----------------------------------------------------------------------------- - * Function: rk30_hdcp_authentication_2nd - *----------------------------------------------------------------------------- - */ -int rk30_hdcp_authentication_2nd(struct hdcp *hdcp) -{ - int status = HDCP_OK; - struct timeval ts_start, ts; - uint32_t delta = 0, num_dev; - uint8_t bstatus[2]; - - HDCP_DBG("\n%s", __FUNCTION__); - - do_gettimeofday(&ts_start); - while(delta <= 5000000) { - /* Poll BCAPS */ - status = rk30_hdcp_ddc_read(hdcp, DDC_BCAPS_LEN, DDC_BCAPS_ADDR, bstatus); - if( (status == HDCP_OK) && (bstatus[0] & (1 << 5)) ) - break; - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - do_gettimeofday(&ts); - delta = (ts.tv_sec - ts_start.tv_sec) * 1000000 + (ts.tv_usec - ts_start.tv_usec); - msleep(100); - } - if(delta > 5000000) { - HDCP_DBG("Poll BKSV list out of time"); - return -HDCP_BKSVLIST_TIMEOUT; - } - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - status = rk30_hdcp_ddc_read(hdcp, DDC_BSTATUS_LEN, DDC_BSTATUS_ADDR, bstatus); - if(status < 0) - return status; - - HDCP_DBG("bstatus %02x %02x\n", bstatus[1], bstatus[0]); - - if( bstatus[0] & (1 << 7) ) { - HDCP_DBG("MAX_DEVS_EXCEEDED"); - return -HDCP_AUTH_FAILURE; - } - - if( bstatus[1] & (1 << 3) ) { - HDCP_DBG("MAX_CASCADE_EXCEEDED"); - return -HDCP_AUTH_FAILURE; - } - - num_dev = bstatus[0] & 0x7F; - if( num_dev > (MAX_DOWNSTREAM_DEVICE_NUM)) { - HDCP_DBG("Out of MAX_DOWNSTREAM_DEVICE_NUM"); - return -HDCP_AUTH_FAILURE; - } - - HDMIWrReg(HDCP_BSTATUS_BUFF, bstatus[0]); - HDMIWrReg(HDCP_BSTATUS_BUFF + 4, bstatus[1]); - - HDMIWrReg(HDCP_NUM_DEV, num_dev); - - // Read KSV List - if(num_dev) { - status = rk30_hdcp_read_ksvlist(hdcp, num_dev); - if(status < 0) - return status; - } - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - status = rk30_hdcp_check_sha(hdcp); - if(status < 0) - return status; - - if (hdcp->pending_disable) - return -HDCP_CANCELLED_AUTH; - - HDMIMskReg(status, SOFT_HDCP_INT_MASK2, (1 << 4) | (1 << 5), (1 << 4) | (1 << 5)); - /* Receiver: enable encryption */ - HDMIMskReg(status, HDCP_CTRL, m_HDCP_FRAMED_ENCRYPED, v_HDCP_FRAMED_ENCRYPED(1)); - HDMIMskReg(status, SOFT_HDCP_CTRL1, m_SOFT_HDCP_AUTH_START, m_SOFT_HDCP_AUTH_START); - return HDCP_OK; -} - -/*----------------------------------------------------------------------------- - * Function: rk30_hdcp_lib_step3_r0_check - *----------------------------------------------------------------------------- - */ -int rk30_hdcp_lib_step3_r0_check(struct hdcp *hdcp) -{ - return rk30_hdcp_r0_check(hdcp); -} - -void rk30_hdcp_irq(struct hdcp *hdcp) -{ - int soft_int1, soft_int2; - - soft_int1 = HDMIRdReg(INTR_STATUS3); - soft_int2 = HDMIRdReg(INTR_STATUS4); - HDMIWrReg(INTR_STATUS3, soft_int1); - HDMIWrReg(INTR_STATUS4, soft_int2); - HDCP_DBG("soft_int1 %x soft_int2 %x\n", soft_int1, soft_int2); - if(soft_int1 & m_SF_MODE_READY) - hdcp_submit_work(HDCP_AUTH_START_1ST, 0); - if(soft_int1 & m_SOFT_HDCP_AN_READY) - an_ready = 1; - if(soft_int1 & m_SOFT_HDCP_SHA_READY) - sha_ready = 1; - if(soft_int1 & m_SOFT_HDCP_RI_READY) - hdcp->pending_wq_event = - hdcp_submit_work(HDCP_R0_EXP_EVENT, - HDCP_R0_DELAY); - if(soft_int2 & 0xc0) - i2c_ack = soft_int2 & 0xc0; - if(soft_int2 & m_SOFT_HDCP_RI_SAVED) - hdcp->pending_wq_event = - hdcp_submit_work(HDCP_RI_EXP_EVENT, - 0); -} \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/rk30_hdmi_hdcp.h b/drivers/video/rockchip/hdmi/chips/rk30/hdcp/rk30_hdmi_hdcp.h deleted file mode 100755 index d3183e993c8a..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/hdcp/rk30_hdmi_hdcp.h +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef __RK30_HDMI_HDCP_H__ -#define __RK30_HDMI_HDCP_H__ - -/***************************/ -/* Definitions */ -/***************************/ - -/* Status / error codes */ -enum { - HDCP_OK, - HDCP_KEY_ERR, - HDCP_DDC_ERROR, - HDCP_AUTH_FAILURE, - HDCP_AKSV_ERROR, - HDCP_BKSV_ERROR, - HDCP_CANCELLED_AUTH, - HDCP_BKSVLIST_TIMEOUT, -}; - -/* Delays */ -#define HDCP_ENABLE_DELAY 300 -#define HDCP_REAUTH_DELAY 100 -#define HDCP_R0_DELAY 120 -#define HDCP_KSV_TIMEOUT_DELAY 5000 -/***********************/ -/* HDCP DDC addresses */ -/***********************/ - -#define DDC_BKSV_ADDR 0x00 -#define DDC_Ri_ADDR 0x08 -#define DDC_AKSV_ADDR 0x10 -#define DDC_AN_ADDR 0x18 -#define DDC_V_ADDR 0x20 -#define DDC_BCAPS_ADDR 0x40 -#define DDC_BSTATUS_ADDR 0x41 -#define DDC_KSV_FIFO_ADDR 0x43 - -#define DDC_BKSV_LEN 5 -#define DDC_Ri_LEN 2 -#define DDC_AKSV_LEN 5 -#define DDC_AN_LEN 8 -#define DDC_V_LEN 4//20 -#define DDC_BCAPS_LEN 1 -#define DDC_BSTATUS_LEN 2 - -/* Event source */ -#define HDCP_SRC_SHIFT 8 -#define HDCP_IOCTL_SRC (0x1 << HDCP_SRC_SHIFT) -#define HDCP_HDMI_SRC (0x2 << HDCP_SRC_SHIFT) -#define HDCP_IRQ_SRC (0x4 << HDCP_SRC_SHIFT) -#define HDCP_WORKQUEUE_SRC (0x8 << HDCP_SRC_SHIFT) - -/* Event */ -#define HDCP_ENABLE_CTL (HDCP_IOCTL_SRC | 0) -#define HDCP_DISABLE_CTL (HDCP_IOCTL_SRC | 1) -#define HDCP_START_FRAME_EVENT (HDCP_HDMI_SRC | 2) -#define HDCP_STOP_FRAME_EVENT (HDCP_HDMI_SRC | 3) -#define HDCP_FAIL_EVENT (HDCP_IRQ_SRC | 4) -#define HDCP_AUTH_PASS_EVENT (HDCP_IRQ_SRC | 5) -#define HDCP_AUTH_START_1ST (HDCP_IRQ_SRC | 6) -#define HDCP_RI_EXP_EVENT (HDCP_IRQ_SRC | 7) -#define HDCP_AUTH_REATT_EVENT (HDCP_WORKQUEUE_SRC | 8) -#define HDCP_R0_EXP_EVENT (HDCP_WORKQUEUE_SRC | 9) -#define HDCP_AUTH_START_2ND (HDCP_WORKQUEUE_SRC | 10) - -/* Key size */ -#define HDCP_KEY_SIZE 308 - -/* Authentication retry times */ -#define HDCP_INFINITE_REAUTH 0x100 - -/* Max downstream device number */ -#define MAX_DOWNSTREAM_DEVICE_NUM 1 - -enum hdcp_states { - HDCP_DISABLED, - HDCP_ENABLE_PENDING, - HDCP_AUTHENTICATION_START, - HDCP_AUTHENTICATION_1ST, - HDCP_WAIT_R0_DELAY, - HDCP_WAIT_KSV_LIST, - HDCP_LINK_INTEGRITY_CHECK, -}; - -enum hdmi_states { - HDMI_STOPPED, - HDMI_STARTED -}; - -#define HDCP_PRIVATE_KEY_SIZE 280 -#define HDCP_KEY_SHA_SIZE 20 -#define HDCP_DDC_CLK 100000 - -struct hdcp_keys{ - u8 KSV[8]; - u8 DeviceKey[HDCP_PRIVATE_KEY_SIZE]; - u8 sha1[HDCP_KEY_SHA_SIZE]; -}; - -struct hdcp_delayed_work { - struct delayed_work work; - int event; -}; - -struct hdcp { - int enable; - int retry_times; - struct hdcp_keys *keys; - int invalidkey; - char *invalidkeys; - struct mutex lock; - struct completion complete; - struct workqueue_struct *workqueue; - - enum hdmi_states hdmi_state; - enum hdcp_states hdcp_state; - - struct delayed_work *pending_start; - struct delayed_work *pending_wq_event; - int retry_cnt; - int pending_disable; - struct hdmi* hdmi; -}; - -#define SOFT_HDCP_INT_MASK1 0x96 * 4 - #define m_SF_MODE_READY (1 << 7) - -#define SOFT_HDCP_INT_MASK2 0x97 * 4 - #define m_I2C_ACK (1 << 7) - #define m_I2C_NO_ACK (1 << 6) - -#define SOFT_HDCP_INT1 0x98 * 4 - #define m_SOFT_HDCP_READY (1 << 7) - #define m_SOFT_HDCP_RI_READY (1 << 6) - #define m_SOFT_HDCP_AN_READY (1 << 4) - #define m_SOFT_HDCP_SHA_READY (1 << 3) - -#define SOFT_HDCP_INT2 0x99 * 4 - #define m_SOFT_HDCP_RI_SAVED (1 << 5) - #define m_SOFT_HDCP_PJ_SAVED (1 << 4) - -#define SOFT_HDCP_CTRL1 0x9A * 4 - #define m_SOFT_HDCP_AUTH_EN (1 << 7) // enable software hdcp - #define m_SOFT_HDCP_AUTH_START (1 << 5) - #define m_SOFT_HDCP_PREP_AN (1 << 4) - #define m_SOFT_HDCP_REPEATER (1 << 2) - #define m_SOFT_HDCP_GEN_RI (1 << 1) - #define m_SOFT_HDCP_CAL_SHA (1 << 0) - #define v_SOFT_HDCP_AUTH_EN(n) (n << 7) - #define v_SOFT_HDCP_PREP_AN(n) (n << 4) - #define v_SOFT_HDCP_REPEATER(n) (n << 2) - #define v_SOFT_HDCP_GEN_RI(n) (n << 1) - #define v_SOFT_HDCP_CAL_SHA(n) (n << 0) - -#define HDCP_DDC_ACCESS_LENGTH 0x9E * 4 -#define HDCP_DDC_OFFSET_ADDR 0xA0 * 4 -#define HDCP_DDC_CTRL 0xA1 * 4 - #define m_DDC_READ (1 << 0) - #define m_DDC_WRITE (1 << 1) - -#define SOFT_HDCP_BCAPS 0xE0 * 4 - -#define HDCP_DDC_READ_BUFF 0xA2 * 4 -#define HDCP_DDC_WRITE_BUFF 0xA7 * 4 -#define HDCP_AN_BUFF 0xE8 * 4 -#define HDCP_AKSV_BUFF 0xBF * 4 -#define HDCP_BKSV_BUFF 0xE3 * 4 -#define HDCP_RI_BUFF 0xD9 * 4 -#define HDCP_BSTATUS_BUFF 0xE1 * 4 - -#define HDCP_NUM_DEV 0xDC * 4 -#define HDCP_SHA_BUF 0xB9 * 4 -#define HDCP_SHA_INDEX 0xD8 * 4 - -#ifdef HDCP_DEBUG -#define HDCP_DBG(format, ...) \ - printk(KERN_INFO "HDCP: " format "\n", ## __VA_ARGS__) -#else -#define HDCP_DBG(format, ...) -#endif - -extern struct delayed_work *hdcp_submit_work(int event, int delay); -extern void rk30_hdcp_disable(struct hdcp *hdcp); -extern int rk30_hdcp_start_authentication(struct hdcp *hdcp); -extern int rk30_hdcp_check_bksv(struct hdcp *hdcp); -extern int rk30_hdcp_load_key2mem(struct hdcp *hdcp, struct hdcp_keys *key); -extern int rk30_hdcp_authentication_1st(struct hdcp *hdcp); -extern int rk30_hdcp_authentication_2nd(struct hdcp *hdcp); -extern void rk30_hdcp_irq(struct hdcp *hdcp); -extern int rk30_hdcp_lib_step1_r0_check(struct hdcp *hdcp); -extern int rk30_hdcp_lib_step3_r0_check(struct hdcp *hdcp); -extern u8 hdcp_lib_check_repeater_bit_in_tx(struct hdcp *hdcp); -#endif /* __RK30_HDMI_HDCP_H__ */ \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi.c deleted file mode 100755 index 85d68db20346..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi.c +++ /dev/null @@ -1,300 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "rk30_hdmi.h" -#include "rk30_hdmi_hw.h" - -struct hdmi *hdmi = NULL; - -extern irqreturn_t hdmi_irq(int irq, void *priv); -extern void hdmi_work(struct work_struct *work); -extern struct rk_lcdc_driver * rk_get_lcdc_drv(char *name); -extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent); -extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi); - -struct hdmi* rk30_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)) -{ - if(hdmi == 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; - - return hdmi; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void hdmi_early_suspend(struct early_suspend *h) -{ - hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state); - // When HDMI 1.1V and 2.5V power off, DDC channel will be pull down, current is produced - // from VCC_IO which is pull up outside soc. We need to switch DDC IO to GPIO. - rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME, GPIO0A_GPIO0A2); - rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME, GPIO0A_GPIO0A1); - flush_delayed_work(&hdmi->delay_work); - mutex_lock(&hdmi->enable_mutex); - hdmi->suspend = 1; - if(!hdmi->enable) { - mutex_unlock(&hdmi->enable_mutex); - return; - } - disable_irq(hdmi->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); - return; -} - -static void hdmi_early_resume(struct early_suspend *h) -{ - hdmi_dbg(hdmi->dev, "hdmi exit early resume\n"); - mutex_lock(&hdmi->enable_mutex); - - rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME, GPIO0A_HDMI_I2C_SDA); - rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME, GPIO0A_HDMI_I2C_SCL); - - hdmi->suspend = 0; - rk30_hdmi_initial(); - if(hdmi->enable) { - enable_irq(hdmi->irq); - } - mutex_unlock(&hdmi->enable_mutex); - return; -} -#endif - -static inline void hdmi_io_remap(void) -{ - unsigned int value; - - // Remap HDMI IO Pin - rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME, GPIO0A_HDMI_I2C_SDA); - rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME, GPIO0A_HDMI_I2C_SCL); - rk30_mux_api_set(GPIO0A0_HDMIHOTPLUGIN_NAME, GPIO0A_HDMI_HOT_PLUG_IN); - - // Select LCDC0 as video source and enabled. - value = (HDMI_SOURCE_DEFAULT << 14) | (1 << 30); - writel(value, GRF_SOC_CON0 + RK30_GRF_BASE); -} - -static int __devinit rk30_hdmi_probe (struct platform_device *pdev) -{ - int ret; - struct resource *res; - struct resource *mem; - - hdmi = kmalloc(sizeof(struct hdmi), GFP_KERNEL); - if(!hdmi) - { - dev_err(&pdev->dev, ">>rk30 hdmi kmalloc fail!"); - return -ENOMEM; - } - memset(hdmi, 0, sizeof(struct hdmi)); - 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; - goto err0; - } - hdmi->xscale = 95; - hdmi->yscale = 95; - - hdmi->hclk = clk_get(NULL,"hclk_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; - } - - - 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; - } - - ret = rk30_hdmi_initial(); - if(ret != HDMI_ERROR_SUCESS) - goto err1; - - hdmi_io_remap(); - hdmi_sys_init(); - - 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 - - hdmi_register_display_sysfs(hdmi, NULL); - #ifdef CONFIG_SWITCH - hdmi->switch_hdmi.name="hdmi"; - switch_dev_register(&(hdmi->switch_hdmi)); - #endif - - spin_lock_init(&hdmi->irq_lock); - mutex_init(&hdmi->enable_mutex); - - /* 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); - ret = -ENXIO; - goto err2; - } - - /* request the IRQ */ - ret = request_irq(hdmi->irq, hdmi_irq, 0, dev_name(&pdev->dev), hdmi); - if (ret) - { - dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret); - goto err2; - } - - hdmi_dbg(hdmi->dev, "rk30 hdmi probe sucess.\n"); - return 0; -err2: - #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); - #endif - iounmap((void*)hdmi->regbase); -err1: - release_mem_region(res->start,(res->end - res->start) + 1); - clk_disable(hdmi->hclk); -err0: - hdmi_dbg(hdmi->dev, "rk30 hdmi probe error.\n"); - kfree(hdmi); - hdmi = NULL; - return ret; -} - -static int __devexit rk30_hdmi_remove(struct platform_device *pdev) -{ - if(hdmi) { - mutex_lock(&hdmi->enable_mutex); - if(!hdmi->suspend && hdmi->enable) - disable_irq(hdmi->irq); - mutex_unlock(&hdmi->enable_mutex); - free_irq(hdmi->irq, NULL); - flush_workqueue(hdmi->workqueue); - destroy_workqueue(hdmi->workqueue); - #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); - #endif - iounmap((void*)hdmi->regbase); - release_mem_region(hdmi->regbase_phy, hdmi->regsize_phy); - clk_disable(hdmi->hclk); - 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); - } - kfree(hdmi); - hdmi = NULL; - } - printk(KERN_INFO "rk30 hdmi removed.\n"); - return 0; -} - -static void rk30_hdmi_shutdown(struct platform_device *pdev) -{ - if(hdmi) { - #ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&hdmi->early_suspend); - #endif - } - printk(KERN_INFO "rk30 hdmi shut down.\n"); -} - -static struct platform_driver rk30_hdmi_driver = { - .probe = rk30_hdmi_probe, - .remove = __devexit_p(rk30_hdmi_remove), - .driver = { - .name = "rk30-hdmi", - .owner = THIS_MODULE, - }, - .shutdown = rk30_hdmi_shutdown, -}; - -static int __init rk30_hdmi_init(void) -{ - return platform_driver_register(&rk30_hdmi_driver); -} - -static void __exit rk30_hdmi_exit(void) -{ - platform_driver_unregister(&rk30_hdmi_driver); -} - - -//fs_initcall(rk30_hdmi_init); -device_initcall_sync(rk30_hdmi_init); -module_exit(rk30_hdmi_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi.h b/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi.h deleted file mode 100755 index ae72f2b47bcf..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __RK30_HDMI_H__ -#define __RK30_HDMI_H__ - -#include "../../rk_hdmi.h" - -#if defined(CONFIG_HDMI_SOURCE_LCDC1) -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC1 -#else -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC0 -#endif - -extern struct hdmi* rk30_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)); -#endif /* __RK30_HDMI_H__ */ diff --git a/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi_hw.c deleted file mode 100755 index 8afa7e91d5fd..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi_hw.c +++ /dev/null @@ -1,667 +0,0 @@ -#include -#include -#include -#include "rk30_hdmi.h" -#include "rk30_hdmi_hw.h" - -static char edid_result = 0; - -static inline void delay100us(void) -{ - udelay(100); -} - -int rk30_hdmi_initial(void) -{ - int rc = HDMI_ERROR_SUCESS; - - hdmi->pwr_mode = PWR_SAVE_MODE_A; - hdmi->remove = rk30_hdmi_removed ; - hdmi->control_output = rk30_hdmi_control_output; - hdmi->config_video = rk30_hdmi_config_video; - hdmi->config_audio = rk30_hdmi_config_audio; - hdmi->detect_hotplug = rk30_hdmi_detect_hotplug; - hdmi->read_edid = rk30_hdmi_read_edid; - // internal hclk = hdmi_hclk/20 - HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV); - - if(hdmi->hdcp_power_on_cb) - rc = hdmi->hdcp_power_on_cb(); - - return rc; -} - -static void rk30_hdmi_set_pwr_mode(int mode) -{ - if(hdmi->pwr_mode == mode) - return; - hdmi_dbg(hdmi->dev, "[%s] mode %d\n", __FUNCTION__, mode); - switch(mode) - { - case PWR_SAVE_MODE_A: - HDMIWrReg(SYS_CTRL, 0x10); - break; - case PWR_SAVE_MODE_B: - HDMIWrReg(SYS_CTRL, 0x20); - break; - case PWR_SAVE_MODE_D: - // reset PLL A&B - HDMIWrReg(SYS_CTRL, 0x4C); - delay100us(); - // release PLL A reset - HDMIWrReg(SYS_CTRL, 0x48); - delay100us(); - // release PLL B reset - HDMIWrReg(SYS_CTRL, 0x40); - break; - case PWR_SAVE_MODE_E: - HDMIWrReg(SYS_CTRL, 0x80); - break; - } - hdmi->pwr_mode = mode; - if(mode != PWR_SAVE_MODE_A) - msleep(10); - hdmi_dbg(hdmi->dev, "[%s] curmode %02x\n", __FUNCTION__, HDMIRdReg(SYS_CTRL)); -} - -int rk30_hdmi_detect_hotplug(void) -{ - int value = HDMIRdReg(HPD_MENS_STA); - - hdmi_dbg(hdmi->dev, "[%s] value %02x\n", __FUNCTION__, value); - #if 0 - // When HPD and TMDS_CLK was high, HDMI is actived. - value &= m_HOTPLUG_STATUS | m_MSEN_STATUS; - if(value == (m_HOTPLUG_STATUS | m_MSEN_STATUS) ) - return HDMI_HPD_ACTIVED; - else if(value) - return HDMI_HPD_INSERT; - else - return HDMI_HPD_REMOVED; - #else - // When HPD was high, HDMI is actived. - if(value & m_HOTPLUG_STATUS) - return HDMI_HPD_ACTIVED; - else if(value & m_MSEN_STATUS) - return HDMI_HPD_INSERT; - else - return HDMI_HPD_REMOVED; - #endif -} - -#define HDMI_EDID_DDC_CLK 90000 -int rk30_hdmi_read_edid(int block, unsigned char *buff) -{ - int value, ret = -1, ddc_bus_freq = 0; - char interrupt = 0, trytime = 2; - unsigned long flags; - - hdmi_dbg(hdmi->dev, "[%s] block %d\n", __FUNCTION__, block); - spin_lock_irqsave(&hdmi->irq_lock, flags); - edid_result = 0; - spin_unlock_irqrestore(&hdmi->irq_lock, flags); - //Before Phy parameter was set, DDC_CLK is equal to PLLA freq which is 30MHz. - //Set DDC I2C CLK which devided from DDC_CLK to 100KHz. - ddc_bus_freq = (30000000/HDMI_EDID_DDC_CLK)/4; - HDMIWrReg(DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); - HDMIWrReg(DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); - - // Enable edid interrupt - HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS | m_INT_EDID_ERR | m_INT_EDID_READY); - - while(trytime--) { - // Config EDID block and segment addr - HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80); - HDMIWrReg(EDID_SEGMENT_POINTER, block/2); - - value = 100; - while(value--) - { - spin_lock_irqsave(&hdmi->irq_lock, flags); - interrupt = edid_result; - edid_result = 0; - spin_unlock_irqrestore(&hdmi->irq_lock, flags); - if(interrupt & (m_INT_EDID_ERR | m_INT_EDID_READY)) - break; - msleep(10); - } - hdmi_dbg(hdmi->dev, "[%s] edid read value %d\n", __FUNCTION__, value); - if(interrupt & m_INT_EDID_READY) - { - for(value = 0; value < HDMI_EDID_BLOCK_SIZE; value++) - buff[value] = HDMIRdReg(DDC_READ_FIFO_ADDR); - ret = 0; - - hdmi_dbg(hdmi->dev, "[%s] edid read sucess\n", __FUNCTION__); -#ifdef HDMI_DEBUG - for(value = 0; value < 128; value++) { - printk("%02x ,", buff[value]); - if( (value + 1) % 16 == 0) - printk("\n"); - } -#endif - break; - } - if(interrupt & m_INT_EDID_ERR) - hdmi_err(hdmi->dev, "[%s] edid read error\n", __FUNCTION__); - - hdmi_dbg(hdmi->dev, "[%s] edid try times %d\n", __FUNCTION__, trytime); - msleep(100); - } - // Disable edid interrupt - HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS); - return ret; -} - -static inline void rk30_hdmi_config_phy_reg(int reg, int value) -{ - HDMIWrReg(reg, value); - HDMIWrReg(SYS_CTRL, 0x2C); - delay100us(); - HDMIWrReg(SYS_CTRL, 0x20); - msleep(1); -} - -static void rk30_hdmi_config_phy(unsigned char vic) -{ - HDMIWrReg(DEEP_COLOR_MODE, 0x22); // tmds frequency same as input dlck - rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B); - switch(vic) - { - case HDMI_1920x1080p_60Hz: - case HDMI_1920x1080p_50Hz: - rk30_hdmi_config_phy_reg(0x158, 0x0E); - rk30_hdmi_config_phy_reg(0x15c, 0x00); - rk30_hdmi_config_phy_reg(0x160, 0x60); - rk30_hdmi_config_phy_reg(0x164, 0x00); - rk30_hdmi_config_phy_reg(0x168, 0xDA); - rk30_hdmi_config_phy_reg(0x16c, 0xA1); - rk30_hdmi_config_phy_reg(0x170, 0x0e); - rk30_hdmi_config_phy_reg(0x174, 0x22); - rk30_hdmi_config_phy_reg(0x178, 0x00); - break; - - case HDMI_1920x1080i_60Hz: - case HDMI_1920x1080i_50Hz: - case HDMI_1280x720p_60Hz: - case HDMI_1280x720p_50Hz: - rk30_hdmi_config_phy_reg(0x158, 0x06); - rk30_hdmi_config_phy_reg(0x15c, 0x00); - rk30_hdmi_config_phy_reg(0x160, 0x60); - rk30_hdmi_config_phy_reg(0x164, 0x00); - rk30_hdmi_config_phy_reg(0x168, 0xCA); - rk30_hdmi_config_phy_reg(0x16c, 0xA3); - rk30_hdmi_config_phy_reg(0x170, 0x0e); - rk30_hdmi_config_phy_reg(0x174, 0x20); - rk30_hdmi_config_phy_reg(0x178, 0x00); - 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: - rk30_hdmi_config_phy_reg(0x158, 0x02); - rk30_hdmi_config_phy_reg(0x15c, 0x00); - rk30_hdmi_config_phy_reg(0x160, 0x60); - rk30_hdmi_config_phy_reg(0x164, 0x00); - rk30_hdmi_config_phy_reg(0x168, 0xC2); - rk30_hdmi_config_phy_reg(0x16c, 0xA2); - rk30_hdmi_config_phy_reg(0x170, 0x0e); - rk30_hdmi_config_phy_reg(0x174, 0x20); - rk30_hdmi_config_phy_reg(0x178, 0x00); - break; - default: - hdmi_err(hdmi->dev, "not support such vic %d\n", vic); - break; - } -} - -static void rk30_hdmi_config_avi(unsigned char vic, unsigned char output_color) -{ - int i, clolorimetry, aspect_ratio; - char info[SIZE_AVI_INFOFRAME]; - - memset(info, 0, SIZE_AVI_INFOFRAME); - HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); - info[0] = 0x82; - info[1] = 0x02; - info[2] = 0x0D; - info[3] = info[0] + info[1] + info[2]; - - if(output_color == VIDEO_OUTPUT_YCBCR444) - info[4] = (AVI_COLOR_MODE_YCBCR444 << 5); - else if(output_color == VIDEO_OUTPUT_YCBCR422) - info[4] = (AVI_COLOR_MODE_YCBCR422 << 5); - else - info[4] = (AVI_COLOR_MODE_RGB << 5); - info[4] |= (1 << 4); //Enable active format data bits is present in info[2] - - switch(vic) - { - case HDMI_720x480i_60Hz_4_3: - case HDMI_720x576i_50Hz_4_3: - case HDMI_720x480p_60Hz_4_3: - case HDMI_720x576p_50Hz_4_3: - aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3; - clolorimetry = AVI_COLORIMETRY_SMPTE_170M; - break; - case HDMI_720x480i_60Hz_16_9: - case HDMI_720x576i_50Hz_16_9: - case HDMI_720x480p_60Hz_16_9: - case HDMI_720x576p_50Hz_16_9: - aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9; - clolorimetry = AVI_COLORIMETRY_SMPTE_170M; - break; - default: - aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9; - clolorimetry = AVI_COLORIMETRY_ITU709; - } - - if(output_color == VIDEO_OUTPUT_RGB444) - clolorimetry = AVI_COLORIMETRY_NO_DATA; - - info[5] = (clolorimetry << 6) | (aspect_ratio << 4) | ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME; - info[6] = 0; - info[7] = vic; - info[8] = 0; - - // Calculate AVI InfoFrame ChecKsum - for (i = 4; i < SIZE_AVI_INFOFRAME; i++) - { - info[3] += info[i]; - } - info[3] = 0x100 - info[3]; - - for(i = 0; i < SIZE_AVI_INFOFRAME; i++) - HDMIWrReg(CONTROL_PACKET_HB0 + i*4, info[i]); -} - -static char coeff_csc[][24] = { - //G B R Bias - { //CSC_RGB_0_255_TO_ITU601_16_235 - 0x11, 0xb6, 0x02, 0x0b, 0x10, 0x55, 0x00, 0x80, //Cr - 0x02, 0x59, 0x01, 0x32, 0x00, 0x75, 0x00, 0x10, //Y - 0x11, 0x5b, 0x10, 0xb0, 0x02, 0x0b, 0x00, 0x80, //Cb - }, - { //CSC_RGB_0_255_TO_ITU709_16_235 - 0x11, 0xdb, 0x02, 0x0b, 0x10, 0x30, 0x00, 0x80, //Cr - 0x02, 0xdc, 0x00, 0xda, 0x00, 0x4a, 0x00, 0x10, //Y - 0x11, 0x93, 0x10, 0x78, 0x02, 0x0b, 0x00, 0x80, //Cb - }, - //Y Cr Cb Bias - { //CSC_ITU601_16_235_TO_RGB_16_235 - 0x04, 0x00, 0x05, 0x7c, 0x00, 0x00, 0x02, 0xaf, //R - 0x04, 0x00, 0x12, 0xcb, 0x11, 0x58, 0x00, 0x84, //G - 0x04, 0x00, 0x00, 0x00, 0x06, 0xee, 0x02, 0xde, //B - }, - { //CSC_ITU709_16_235_TO_RGB_16_235 - 0x04, 0x00, 0x06, 0x29, 0x00, 0x00, 0x02, 0xc5, //R - 0x04, 0x00, 0x11, 0xd6, 0x10, 0xbb, 0x00, 0x52, //G - 0x04, 0x00, 0x00, 0x00, 0x07, 0x44, 0x02, 0xe8, //B - }, - { //CSC_ITU601_16_235_TO_RGB_0_255 - 0x04, 0xa8, 0x05, 0x7c, 0x00, 0x00, 0x02, 0xc2, //R - 0x04, 0xa8, 0x12, 0xcb, 0x11, 0x58, 0x00, 0x72, //G - 0x04, 0xa8, 0x00, 0x00, 0x06, 0xee, 0x02, 0xf0, //B - }, - { //CSC_ITU709_16_235_TO_RGB_0_255 - 0x04, 0xa8, 0x06, 0x29, 0x00, 0x00, 0x02, 0xd8, //R - 0x04, 0xa8, 0x11, 0xd6, 0x10, 0xbb, 0x00, 0x40, //G - 0x04, 0xa8, 0x00, 0x00, 0x07, 0x44, 0x02, 0xfb, //B - }, - -}; - -static void rk30_hdmi_config_csc(struct hdmi_video_para *vpara) -{ - int i, mode; - char *coeff = NULL; - - if( ((vpara->input_color == VIDEO_INPUT_COLOR_RGB) && (vpara->output_color == VIDEO_OUTPUT_RGB444)) || - ((vpara->input_color != VIDEO_INPUT_COLOR_RGB) && (vpara->output_color != VIDEO_OUTPUT_RGB444) )) - { - return; - } - switch(vpara->vic) - { - case HDMI_720x480i_60Hz_4_3: - case HDMI_720x576i_50Hz_4_3: - case HDMI_720x480p_60Hz_4_3: - case HDMI_720x576p_50Hz_4_3: - case HDMI_720x480i_60Hz_16_9: - case HDMI_720x576i_50Hz_16_9: - case HDMI_720x480p_60Hz_16_9: - case HDMI_720x576p_50Hz_16_9: - if(vpara->input_color == VIDEO_INPUT_COLOR_RGB) - mode = CSC_RGB_0_255_TO_ITU601_16_235; - else if(vpara->output_mode == OUTPUT_HDMI) - mode = CSC_ITU601_16_235_TO_RGB_16_235; - else - mode = CSC_ITU601_16_235_TO_RGB_0_255; - break; - default: - if(vpara->input_color == VIDEO_INPUT_COLOR_RGB) - mode = CSC_RGB_0_255_TO_ITU709_16_235; - else if(vpara->output_mode == OUTPUT_HDMI) - mode = CSC_ITU709_16_235_TO_RGB_16_235; - else - mode = CSC_ITU709_16_235_TO_RGB_0_255; - break; - } - - coeff = coeff_csc[mode]; - - HDMIWrReg(CSC_CONFIG1, v_CSC_MODE(CSC_MODE_MANUAL) | v_CSC_BRSWAP_DIABLE(1)); - - for(i = 0; i < 24; i++) - HDMIWrReg(CSC_PARA_C0_H + i*4, coeff[i]); - - HDMIWrReg(AV_CTRL2, v_CSC_ENABLE(1)); -} - -int rk30_hdmi_config_video(struct hdmi_video_para *vpara) -{ - int value; - struct fb_videomode *mode; - - hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); - if(vpara == NULL) { - hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__); - return -1; - } - if(hdmi->pwr_mode == PWR_SAVE_MODE_E) - rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D); - if(hdmi->pwr_mode == PWR_SAVE_MODE_D || hdmi->pwr_mode == PWR_SAVE_MODE_A) - rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B); - - if(hdmi->hdcp_power_off_cb) - hdmi->hdcp_power_off_cb(); - - // Input video mode is RGB24bit, Data enable signal from external - HDMIMskReg(value, AV_CTRL1, m_INPUT_VIDEO_MODE | m_DE_SIGNAL_SELECT, \ - v_INPUT_VIDEO_MODE(vpara->input_mode) | EXTERNAL_DE) - HDMIMskReg(value, VIDEO_CTRL1, m_VIDEO_OUTPUT_MODE | m_VIDEO_INPUT_DEPTH | m_VIDEO_INPUT_COLOR_MODE, \ - v_VIDEO_OUTPUT_MODE(vpara->output_color) | v_VIDEO_INPUT_DEPTH(VIDEO_INPUT_DEPTH_8BIT) | vpara->input_color) - HDMIWrReg(DEEP_COLOR_MODE, 0x20); - // color space convert - rk30_hdmi_config_csc(vpara); - // Set HDMI Mode - HDMIWrReg(HDCP_CTRL, v_HDMI_DVI(vpara->output_mode)); - - // Set ext video - 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); - return -ENOENT; - } - hdmi->tmdsclk = mode->pixclock; - - if( (vpara->vic == HDMI_720x480p_60Hz_4_3) || (vpara->vic == HDMI_720x480p_60Hz_16_9) ) - value = v_VSYNC_OFFSET(6); - else - value = v_VSYNC_OFFSET(0); - value |= v_EXT_VIDEO_ENABLE(1) | v_INTERLACE(mode->vmode); - if(mode->sync & FB_SYNC_HOR_HIGH_ACT) - value |= v_HSYNC_POLARITY(1); - if(mode->sync & FB_SYNC_VERT_HIGH_ACT) - value |= v_VSYNC_POLARITY(1); - HDMIWrReg(EXT_VIDEO_PARA, value); - value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len; - HDMIWrReg(EXT_VIDEO_PARA_HTOTAL_L, value & 0xFF); - HDMIWrReg(EXT_VIDEO_PARA_HTOTAL_H, (value >> 8) & 0xFF); - - value = mode->left_margin + mode->right_margin + mode->hsync_len; - HDMIWrReg(EXT_VIDEO_PARA_HBLANK_L, value & 0xFF); - HDMIWrReg(EXT_VIDEO_PARA_HBLANK_H, (value >> 8) & 0xFF); - - value = mode->left_margin + mode->hsync_len; - HDMIWrReg(EXT_VIDEO_PARA_HDELAY_L, value & 0xFF); - HDMIWrReg(EXT_VIDEO_PARA_HDELAY_H, (value >> 8) & 0xFF); - - value = mode->hsync_len; - HDMIWrReg(EXT_VIDEO_PARA_HSYNCWIDTH_L, value & 0xFF); - HDMIWrReg(EXT_VIDEO_PARA_HSYNCWIDTH_H, (value >> 8) & 0xFF); - - value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len; - HDMIWrReg(EXT_VIDEO_PARA_VTOTAL_L, value & 0xFF); - HDMIWrReg(EXT_VIDEO_PARA_VTOTAL_H, (value >> 8) & 0xFF); - - value = mode->upper_margin + mode->vsync_len + mode->lower_margin; - HDMIWrReg(EXT_VIDEO_PARA_VBLANK_L, value & 0xFF); - - 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; - - HDMIWrReg(EXT_VIDEO_PARA_VDELAY, value & 0xFF); - - value = mode->vsync_len; - HDMIWrReg(EXT_VIDEO_PARA_VSYNCWIDTH, value & 0xFF); - - if(vpara->output_mode == OUTPUT_HDMI) { - rk30_hdmi_config_avi(vpara->vic, vpara->output_color); - hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); - } - else { - hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__); - } - - rk30_hdmi_config_phy(vpara->vic); - rk30_hdmi_control_output(0); - return 0; -} - -static void rk30_hdmi_config_aai(void) -{ - int i; - char info[SIZE_AUDIO_INFOFRAME]; - - memset(info, 0, SIZE_AUDIO_INFOFRAME); - - info[0] = 0x84; - info[1] = 0x01; - info[2] = 0x0A; - - info[3] = info[0] + info[1] + info[2]; - for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++) - info[3] += info[i]; - - info[3] = 0x100 - info[3]; - - HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI); - for(i = 0; i < SIZE_AUDIO_INFOFRAME; i++) - HDMIWrReg(CONTROL_PACKET_HB0 + i*4, info[i]); -} - -int rk30_hdmi_config_audio(struct hdmi_audio *audio) -{ - int value, rate, N; - char word_length, channel; - - if(audio->channel < 3) - channel = I2S_CHANNEL_1_2; - else if(audio->channel < 5) - channel = I2S_CHANNEL_3_4; - 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; - break; - case HDMI_AUDIO_FS_44100: - rate = AUDIO_441K; - N = N_441K; - break; - case HDMI_AUDIO_FS_48000: - rate = AUDIO_48K; - N = N_48K; - break; - case HDMI_AUDIO_FS_88200: - rate = AUDIO_882K; - N = N_882K; - break; - case HDMI_AUDIO_FS_96000: - rate = AUDIO_96K; - N = N_96K; - break; - case HDMI_AUDIO_FS_176400: - rate = AUDIO_1764K; - N = N_1764K; - break; - case HDMI_AUDIO_FS_192000: - rate = AUDIO_192K; - N = N_192K; - break; - default: - hdmi_err(hdmi->dev, "[%s] not support such sample rate %d\n", __FUNCTION__, audio->rate); - return -ENOENT; - } -// switch(audio->word_length) -// { -// case HDMI_AUDIO_WORD_LENGTH_16bit: -// word_length = 0x02; -// break; -// case HDMI_AUDIO_WORD_LENGTH_20bit: -// word_length = 0x0a; -// break; -// case HDMI_AUDIO_WORD_LENGTH_24bit: -// word_length = 0x0b; -// break; -// default: -// hdmi_err(hdmi->dev, "[%s] not support such word length %d\n", __FUNCTION__, audio->word_length); -// return -ENOENT; -// } - //set_audio_if I2S - HDMIWrReg(AUDIO_CTRL1, 0x00); //internal CTS, disable down sample, i2s input, disable MCLK - HDMIWrReg(AUDIO_CTRL2, 0x40); - HDMIWrReg(I2S_AUDIO_CTRL, v_I2S_MODE(I2S_MODE_STANDARD) | v_I2S_CHANNEL(channel) ); - HDMIWrReg(I2S_INPUT_SWAP, 0x00); //no swap - HDMIMskReg(value, AV_CTRL1, m_AUDIO_SAMPLE_RATE, v_AUDIO_SAMPLE_RATE(rate)) -// HDMIWrReg(SRC_NUM_AUDIO_LEN, word_length); - - //Set N value 6144, fs=48kHz - HDMIWrReg(N_1, N & 0xFF); - HDMIWrReg(N_2, (N >> 8) & 0xFF); - HDMIWrReg(LR_SWAP_N3, (N >> 16) & 0x0F); - - rk30_hdmi_config_aai(); - return 0; -} - -static void rk30_hdmi_audio_reset(void) -{ - int value; - - HDMIMskReg(value, VIDEO_SETTING2, m_AUDIO_RESET, AUDIO_CAPTURE_RESET) - msleep(1); - HDMIMskReg(value, VIDEO_SETTING2, m_AUDIO_RESET, 0) -} - -void rk30_hdmi_control_output(int enable) -{ - hdmi_dbg(hdmi->dev, "[%s] %d\n", __FUNCTION__, enable); - if(enable == 0) { - HDMIWrReg(VIDEO_SETTING2, 0x03); - } - else { - if(hdmi->pwr_mode == PWR_SAVE_MODE_B) { - // Switch to power save mode_d - rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D); - } - if(hdmi->pwr_mode == PWR_SAVE_MODE_D) { - // Switch to power save mode_e - rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_E); - } - HDMIWrReg(VIDEO_SETTING2, 0x00); - rk30_hdmi_audio_reset(); - } -} - -int rk30_hdmi_removed(void) -{ - if(hdmi->pwr_mode == PWR_SAVE_MODE_E) - { - HDMIWrReg(VIDEO_SETTING2, 0x00); - rk30_hdmi_audio_reset(); - rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D); - } - if(hdmi->pwr_mode == PWR_SAVE_MODE_D) - rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B); - if(hdmi->pwr_mode == PWR_SAVE_MODE_B && hdmi->state == HDMI_SLEEP) - { - HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS); - HDMIWrReg(INTR_MASK2, 0); - HDMIWrReg(INTR_MASK3, 0); - HDMIWrReg(INTR_MASK4, 0); - // Disable color space convertion - HDMIWrReg(AV_CTRL2, v_CSC_ENABLE(0)); - HDMIWrReg(CSC_CONFIG1, v_CSC_MODE(CSC_MODE_AUTO) | v_CSC_BRSWAP_DIABLE(1)); - if(hdmi->hdcp_power_off_cb) - hdmi->hdcp_power_off_cb(); - rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_A); - } - dev_printk(KERN_INFO , hdmi->dev , "Removed.\n"); - return HDMI_ERROR_SUCESS; -} - - -irqreturn_t hdmi_irq(int irq, void *priv) -{ - char interrupt1 = 0, interrupt2 = 0, interrupt3 = 0, interrupt4 = 0; - - if(hdmi->pwr_mode == PWR_SAVE_MODE_A) - { - HDMIWrReg(SYS_CTRL, 0x20); - hdmi->pwr_mode = PWR_SAVE_MODE_B; - - hdmi_dbg(hdmi->dev, "hdmi irq wake up\n"); - // HDMI was inserted when system is sleeping, irq was triggered only once - // when wake up. So we need to check hotplug status. - if(HDMIRdReg(HPD_MENS_STA) & (m_HOTPLUG_STATUS | m_MSEN_STATUS)) { - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); - } - } - else - { - interrupt1 = HDMIRdReg(INTR_STATUS1); - interrupt2 = HDMIRdReg(INTR_STATUS2); - interrupt3 = HDMIRdReg(INTR_STATUS3); - interrupt4 = HDMIRdReg(INTR_STATUS4); - HDMIWrReg(INTR_STATUS1, interrupt1); -// HDMIWrReg(INTR_STATUS2, interrupt2); -// HDMIWrReg(INTR_STATUS3, interrupt3); -// HDMIWrReg(INTR_STATUS4, interrupt4); -#if 0 - hdmi_dbg(hdmi->dev, "[%s] interrupt1 %02x interrupt2 %02x interrupt3 %02x interrupt4 %02x\n",\ - __FUNCTION__, interrupt1, interrupt2, interrupt3, interrupt4); -#endif - if(interrupt1 & (m_INT_HOTPLUG | m_INT_MSENS)) - { - if(hdmi->state == HDMI_SLEEP) - hdmi->state = WAIT_HOTPLUG; - interrupt1 &= ~(m_INT_HOTPLUG | m_INT_MSENS); - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); - } - else if(interrupt1 & (m_INT_EDID_READY | m_INT_EDID_ERR)) { - spin_lock(&hdmi->irq_lock); - edid_result = interrupt1; - spin_unlock(&hdmi->irq_lock); - } -// else if(hdmi->state == HDMI_SLEEP) { -// RK30DBG( "hdmi return to sleep mode\n"); -// HDMIWrReg(SYS_CTRL, 0x10); -// rk30_hdmi->pwr_mode = PWR_SAVE_MODE_A; -// } - if(hdmi->hdcp_irq_cb) - hdmi->hdcp_irq_cb(interrupt2); - } - return IRQ_HANDLED; -} - diff --git a/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi_hw.h deleted file mode 100755 index c42f0614b942..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk30/rk30_hdmi_hw.h +++ /dev/null @@ -1,422 +0,0 @@ -#ifndef __RK30_HDMI_HW_H__ -#define __RK30_HDMI_HW_H__ - -/* HDMI_SYS_CONTROL */ -#define SYS_CTRL 0x0 - -enum { - PWR_SAVE_MODE_A = 1, - PWR_SAVE_MODE_B = 2, - PWR_SAVE_MODE_D = 4, - PWR_SAVE_MODE_E = 8 -}; -#define m_PWR_SAVE_MODE 0xF0 -#define v_PWR_SAVE_MODE(n) (n << 4) -#define PLL_B_RESET (1 << 3) - -#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 LR_SWAP_N3 0x04 -#define N_2 0x08 -#define N_1 0x0c - -#define AUDIO_CTRL1 0x28 -#define AUDIO_CTRL2 0x2c -#define I2S_AUDIO_CTRL 0x30 -enum { - I2S_MODE_STANDARD = 0, - I2S_MODE_RIGHT_JUSTIFIED, - I2S_MODE_LEFT_JUSTIFIED -}; -#define v_I2S_MODE(n) n -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 ) - -#define I2S_INPUT_SWAP 0x40 - -#define SRC_NUM_AUDIO_LEN 0x50 - -/* HDMI_AV_CTRL1*/ -#define AV_CTRL1 0x54 -enum { - AUDIO_32K = 0x3, - AUDIO_441K = 0x0, - AUDIO_48K = 0x2, - AUDIO_882K = 0x8, - AUDIO_96K = 0xa, - AUDIO_1764K = 0xc, - AUDIO_192K = 0xe, -}; -#define m_AUDIO_SAMPLE_RATE 0xF0 -#define v_AUDIO_SAMPLE_RATE(n) (n << 4) -#define m_INPUT_VIDEO_MODE (7 << 1) -#define v_INPUT_VIDEO_MODE(n) (n << 1) -enum { - INTERNAL_DE = 0, - EXTERNAL_DE -}; -#define m_DE_SIGNAL_SELECT (1 << 0) - -/* HDMI_AV_CTRL2 */ -#define AV_CTRL2 0xec -#define m_CSC_ENABLE (1 << 0) -#define v_CSC_ENABLE(n) (n) - -/* HDMI_VIDEO_CTRL1 */ -#define VIDEO_CTRL1 0x58 - -#define m_VIDEO_OUTPUT_MODE (0x3 << 6) -#define v_VIDEO_OUTPUT_MODE(n) (n << 6) -enum { - VIDEO_INPUT_DEPTH_12BIT = 0, - VIDEO_INPUT_DEPTH_10BIT = 0x1, - VIDEO_INPUT_DEPTH_8BIT = 0x3 -}; -#define m_VIDEO_INPUT_DEPTH (3 << 4) -#define v_VIDEO_INPUT_DEPTH(n) (n << 4) -enum { - VIDEO_EMBEDDED_SYNC_LOCATION_0 = 0, - VIDEO_EMBEDDED_SYNC_LOCATION_1, - VIDEO_EMBEDDED_SYNC_LOCATION_2 -}; -#define m_VIDEO_EMBEDDED_SYNC_LOCATION (3 << 2) -#define VIDEO_EMBEDDED_SYNC_LOCATION(n) (n << 2) -#define m_VIDEO_INPUT_COLOR_MODE (1 << 0) - -/* DEEP_COLOR_MODE */ -#define DEEP_COLOR_MODE 0x5c -enum{ - TMDS_CLOCK_MODE_8BIT = 0, - TMDS_CLOKK_MODE_10BIT, - TMDS_CLOKK_MODE_12BIT -}; -#define TMDS_CLOCK_MODE_MASK 0x3 << 6 -#define TMDS_CLOCK_MODE(n) (n) << 6 - -/* VIDEO_CTRL2 */ -#define VIDEO_SETTING2 0x114 -#define m_UNMUTE (1 << 7) -#define m_MUTE (1 << 6) -#define m_AUDIO_RESET (1 << 2) -#define m_NOT_SEND_AUDIO (1 << 1) -#define m_NOT_SEND_VIDEO (1 << 0) -#define AV_UNMUTE (1 << 7) // Unmute video and audio, send normal video and audio data -#define AV_MUTE (1 << 6) // Mute video and audio, send black video data and silent audio data -#define AUDIO_CAPTURE_RESET (1 << 2) // Reset audio process logic, only available in pwr_e mode. -#define NOT_SEND_AUDIO (1 << 1) // Send silent audio data -#define NOT_SEND_VIDEO (1 << 0) // Send black video data - -/* Color Space Convertion Parameter*/ -#define CSC_PARA_C0_H 0x60 -#define CSC_PARA_C0_L 0x64 -#define CSC_PARA_C1_H 0x68 -#define CSC_PARA_C1_L 0x6c -#define CSC_PARA_C2_H 0x70 -#define CSC_PARA_C2_L 0x74 -#define CSC_PARA_C3_H 0x78 -#define CSC_PARA_C3_L 0x7c -#define CSC_PARA_C4_H 0x80 -#define CSC_PARA_C4_L 0x84 -#define CSC_PARA_C5_H 0x88 -#define CSC_PARA_C5_L 0x8c -#define CSC_PARA_C6_H 0x90 -#define CSC_PARA_C6_L 0x94 -#define CSC_PARA_C7_H 0x98 -#define CSC_PARA_C7_L 0x9c -#define CSC_PARA_C8_H 0xa0 -#define CSC_PARA_C8_L 0xa4 -#define CSC_PARA_C9_H 0xa8 -#define CSC_PARA_C9_L 0xac -#define CSC_PARA_C10_H 0xac -#define CSC_PARA_C10_L 0xb4 -#define CSC_PARA_C11_H 0xb8 -#define CSC_PARA_C11_L 0xbc - -#define CSC_CONFIG1 0x34c -#define m_CSC_MODE (1 << 7) -#define m_CSC_COEF_MODE (0xF << 3) //Only used in auto csc mode -#define m_CSC_STATUS (1 << 2) -#define m_CSC_VID_SELECT (1 << 1) -#define m_CSC_BRSWAP_DIABLE (1) - -enum { - CSC_MODE_MANUAL = 0, - CSC_MODE_AUTO -}; -#define v_CSC_MODE(n) (n << 7) -enum { - COE_SDTV_LIMITED_RANGE = 0x08, - COE_SDTV_FULL_RANGE = 0x04, - COE_HDTV_60Hz = 0x2, - COE_HDTV_50Hz = 0x1 -}; -#define v_CSC_COE_MODE(n) (n << 3) -enum { - CSC_INPUT_VID_5_19 = 0, - CSC_INPUT_VID_28_29 -}; -#define v_CSC_VID_SELECT(n) (n << 1) -#define v_CSC_BRSWAP_DIABLE(n) (n) - -/* CONTROL_PACKET_BUF_INDEX */ -#define CONTROL_PACKET_BUF_INDEX 0x17c -enum { - INFOFRAME_AVI = 0x06, - INFOFRAME_AAI = 0x08 -}; -#define CONTROL_PACKET_HB0 0x180 -#define CONTROL_PACKET_HB1 0x184 -#define CONTROL_PACKET_HB2 0x188 -#define CONTROL_PACKET_PB_ADDR 0x18c -#define SIZE_AVI_INFOFRAME 0x11 // 17 bytes -#define SIZE_AUDIO_INFOFRAME 0x0F // 15 bytes -enum { - AVI_COLOR_MODE_RGB = 0, - AVI_COLOR_MODE_YCBCR422, - AVI_COLOR_MODE_YCBCR444 -}; -enum { - AVI_COLORIMETRY_NO_DATA = 0, - AVI_COLORIMETRY_SMPTE_170M, - AVI_COLORIMETRY_ITU709, - AVI_COLORIMETRY_EXTENDED -}; -enum { - AVI_CODED_FRAME_ASPECT_NO_DATA, - AVI_CODED_FRAME_ASPECT_4_3, - AVI_CODED_FRAME_ASPECT_16_9 -}; -enum { - ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME = 0x08, - ACTIVE_ASPECT_RATE_4_3, - ACTIVE_ASPECT_RATE_16_9, - ACTIVE_ASPECT_RATE_14_9 -}; - -/* External Video Parameter Setting*/ -#define EXT_VIDEO_PARA 0xC0 -#define m_VSYNC_OFFSET (0xF << 4) -#define m_VSYNC_POLARITY (1 << 3) -#define m_HSYNC_POLARITY (1 << 2) -#define m_INTERLACE (1 << 1) -#define m_EXT_VIDEO_ENABLE (1 << 0) - -#define v_VSYNC_OFFSET(n) (n << 4) -#define v_VSYNC_POLARITY(n) (n << 3) -#define v_HSYNC_POLARITY(n) (n << 2) -#define v_INTERLACE(n) (n << 1) -#define v_EXT_VIDEO_ENABLE(n) (n << 0) - -#define EXT_VIDEO_PARA_HTOTAL_L 0xC4 -#define EXT_VIDEO_PARA_HTOTAL_H 0xC8 -#define EXT_VIDEO_PARA_HBLANK_L 0xCC -#define EXT_VIDEO_PARA_HBLANK_H 0xD0 -#define EXT_VIDEO_PARA_HDELAY_L 0xD4 -#define EXT_VIDEO_PARA_HDELAY_H 0xD8 -#define EXT_VIDEO_PARA_HSYNCWIDTH_L 0xDC -#define EXT_VIDEO_PARA_HSYNCWIDTH_H 0xE0 - -#define EXT_VIDEO_PARA_VTOTAL_L 0xE4 -#define EXT_VIDEO_PARA_VTOTAL_H 0xE8 -#define EXT_VIDEO_PARA_VBLANK_L 0xF4 -#define EXT_VIDEO_PARA_VDELAY 0xF8 -#define EXT_VIDEO_PARA_VSYNCWIDTH 0xFC - -#define PHY_PLL_SPEED 0x158 - #define v_TEST_EN(n) (n << 6) - #define v_PLLA_BYPASS(n) (n << 4) - #define v_PLLB_SPEED(n) (n << 2) - #define v_PLLA_SPEED(n) (n) - enum { - PLL_SPEED_LOWEST = 0, - PLL_SPEED_MIDLOW, - PLL_SPEED_MIDHIGH, - PLL_SPEED_HIGHEST - }; - -#define PHY_PLL_17 0x15c // PLL A & B config bit 17 - #define v_PLLA_BIT17(n) (n << 2) - #define v_PLLB_BIT17(n) (n << 1) - -#define PHY_BGR 0x160 - #define v_BGR_DISCONNECT(n) (n << 7) - #define v_BGR_V_OFFSET(n) (n << 4) - #define v_BGR_I_OFFSET(n) (n) - -#define PHY_PLLA_1 0x164 -#define PHY_PLLA_2 0x168 -#define PHY_PLLB_1 0x16c -#define PHY_PLLB_2 0x170 - -#define PHY_DRIVER_PREEMPHASIS 0x174 - #define v_TMDS_SWING(n) (n << 4) - #define v_PRE_EMPHASIS(n) (n) - -#define PHY_PLL_16_AML 0x178 // PLL A & B config bit 16 and AML control - #define v_PLLA_BIT16(n) (n << 5) - #define v_PLLB_BIT16(n) (n << 4) - #define v_AML(n) (n) - -/* Interrupt Setting */ -#define INTR_MASK1 0x248 -#define INTR_STATUS1 0x250 - #define m_INT_HOTPLUG (1 << 7) - #define m_INT_MSENS (1 << 6) - #define m_INT_VSYNC (1 << 5) - #define m_INT_AUDIO_FIFO_FULL (1 << 4) - #define m_INT_EDID_READY (1 << 2) - #define m_INT_EDID_ERR (1 << 1) -#define INTR_MASK2 0x24c -#define INTR_STATUS2 0x254 - #define m_INT_HDCP_ERR (1 << 7) // HDCP error detected - #define m_INT_BKSV_RPRDY (1 << 6) // BKSV list ready from repeater - #define m_INT_BKSV_RCRDY (1 << 5) // BKSV list ready from receiver - #define m_INT_AUTH_DONE (1 << 4) // HDCP authentication done - #define m_INT_AUTH_READY (1 << 3) // HDCP authentication ready -#define INTR_MASK3 0x258 -#define INTR_STATUS3 0x260 - -#define INTR_MASK4 0x25c -#define INTR_STATUS4 0x264 - -#define DDC_READ_FIFO_ADDR 0x200 -#define DDC_BUS_FREQ_L 0x204 -#define DDC_BUS_FREQ_H 0x208 -#define DDC_BUS_CTRL 0x2dc -#define DDC_I2C_LEN 0x278 -#define DDC_I2C_OFFSET 0x280 -#define DDC_I2C_CTRL 0x284 -#define DDC_I2C_READ_BUF0 0x288 -#define DDC_I2C_READ_BUF1 0x28c -#define DDC_I2C_READ_BUF2 0x290 -#define DDC_I2C_READ_BUF3 0x294 -#define DDC_I2C_WRITE_BUF0 0x298 -#define DDC_I2C_WRITE_BUF1 0x29c -#define DDC_I2C_WRITE_BUF2 0x2a0 -#define DDC_I2C_WRITE_BUF3 0x2a4 -#define DDC_I2C_WRITE_BUF4 0x2ac -#define DDC_I2C_WRITE_BUF5 0x2b0 -#define DDC_I2C_WRITE_BUF6 0x2b4 - -#define EDID_SEGMENT_POINTER 0x310 -#define EDID_WORD_ADDR 0x314 -#define EDID_FIFO_ADDR 0x318 - -#define HPD_MENS_STA 0x37c -#define m_HOTPLUG_STATUS (1 << 7) -#define m_MSEN_STATUS (1 << 6) - -/* HDCP_CTRL */ -#define HDCP_CTRL 0x2bc - enum { - OUTPUT_DVI = 0, - OUTPUT_HDMI - }; - #define m_HDCP_AUTH_START (1 << 7) // start hdcp - #define m_HDCP_BKSV_PASS (1 << 6) // bksv valid - #define m_HDCP_BKSV_FAILED (1 << 5) // bksv invalid - #define m_HDCP_FRAMED_ENCRYPED (1 << 4) - #define m_HDCP_AUTH_STOP (1 << 3) // stop hdcp - #define m_HDCP_ADV_CIPHER (1 << 2) // advanced cipher mode - #define m_HDMI_DVI (1 << 1) - #define m_HDCP_RESET (1 << 0) // reset hdcp - #define v_HDCP_AUTH_START(n) (n << 7) - #define v_HDCP_BKSV_PASS(n) (n << 6) - #define v_HDCP_BKSV_FAILED(n) (n << 5) - #define v_HDCP_FRAMED_ENCRYPED(n) (n << 4) - #define v_HDCP_AUTH_STOP(n) (n << 3) - #define v_HDCP_ADV_CIPHER(n) (n << 2) - #define v_HDMI_DVI(n) (n << 1) - #define v_HDCP_RESET(n) (n << 0) -#define HDCP_CTRL2 0x340 - -/* HDCP Key Memory Access Control */ -#define HDCP_KEY_ACCESS_CTRL1 0x338 -#define HDCP_KEY_ACCESS_CTRL2 0x33c - #define m_LOAD_FACSIMILE_HDCP_KEY (1 << 1) - #define m_LOAD_HDCP_KEY (1 << 0) -/* HDCP Key Memory Control */ -#define HDCP_KEY_MEM_CTRL 0x348 - #define m_USE_KEY1 (1 << 6) - #define m_USE_KEY2 (1 << 5) - #define m_LOAD_AKSV (1 << 4) - #define m_KSV_SELECTED (1 << 3) - #define m_KSV_VALID (1 << 2) - #define m_KEY_VALID (1 << 1) - #define m_KEY_READY (1 << 0) - #define v_USE_KEY1(n) (n << 6) - #define v_USE_KEY2(n) (n << 5) - #define v_LOAD_AKSV(n) (n << 4) - -/* HDCP B device capacity */ -#define HDCP_BCAPS 0x2f8 - #define m_HDMI_RECEIVED (1 << 7) //If HDCP receiver support HDMI, this bit must be 1. - #define m_REPEATER (1 << 6) - #define m_KSV_FIFO_READY (1 << 5) - #define m_DDC_FAST (1 << 4) - #define m_1_1_FEATURE (1 << 1) - #define m_FAST_REAUTHENTICATION (1 << 0) //For HDMI, this function is supported whether this bit is enabled or not. - -/* HDCP KSV Value */ -#define HDCP_KSV_BYTE0 0x2fc -#define HDCP_KSV_BYTE1 0x300 -#define HDCP_KSV_BYTE2 0x304 -#define HDCP_KSV_BYTE3 0x308 -#define HDCP_KSV_BYTE4 0x30c - -/* HDCP error status */ -#define HDCP_ERROR 0x320 - -/* HDCP 100 ms timer */ -#define HDCP_TIMER_100MS 0x324 -/* HDCP 5s timer */ -#define HDCP_TIMER_5S 0x328 - -/* HDCP Key ram address */ -#define HDCP_RAM_KEY_KSV1 0x400 -#define HDCP_RAM_KEY_KSV2 0x407 -#define HDCP_RAM_KEY_PRIVATE 0x40e -#define HDCP_KEY_LENGTH 0x13C - - -#define HDCP_ENABLE_HW_AUTH // Enable hardware authentication mode -#define HDMI_INTERANL_CLK_DIV 0x19 - -#define HDMIRdReg(addr) __raw_readl(hdmi->regbase + addr) -#define HDMIWrReg(addr, val) __raw_writel((val), hdmi->regbase + addr); -#define HDMIMskReg(temp, addr, msk, val) \ - temp = __raw_readl(hdmi->regbase + addr) & (0xFF - (msk)) ; \ - __raw_writel(temp | ( (val) & (msk) ), hdmi->regbase + addr); - - - -/* Color Space Convertion Mode */ -enum { - CSC_RGB_0_255_TO_ITU601_16_235 = 0, //RGB 0-255 input to YCbCr 16-235 output according BT601 - CSC_RGB_0_255_TO_ITU709_16_235, //RGB 0-255 input to YCbCr 16-235 output accroding BT709 - CSC_ITU601_16_235_TO_RGB_16_235, //YCbCr 16-235 input to RGB 16-235 output according BT601 - CSC_ITU709_16_235_TO_RGB_16_235, //YCbCr 16-235 input to RGB 16-235 output according BT709 - CSC_ITU601_16_235_TO_RGB_0_255, //YCbCr 16-235 input to RGB 0-255 output according BT601 - CSC_ITU709_16_235_TO_RGB_0_255 //YCbCr 16-235 input to RGB 0-255 output according BT709 -}; - -extern int rk30_hdmi_initial(void); -extern int rk30_hdmi_detect_hotplug(void); -extern int rk30_hdmi_read_edid(int block, unsigned char *buff); -extern int rk30_hdmi_removed(void); -extern int rk30_hdmi_config_video(struct hdmi_video_para *vpara); -extern int rk30_hdmi_config_audio(struct hdmi_audio *audio); -extern void rk30_hdmi_control_output(int enable); - -#endif diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/Kconfig b/drivers/video/rockchip/hdmi/chips/rk3036/Kconfig deleted file mode 100755 index 7c210a7a61e9..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -config HDCP_RK3036 - bool "RK3036 HDCP support" - default n - help - HDCP Interface. This adds the High Definition Content Protection Interface. - See http://www.digital-cp.com/ for HDCP specification. - -config HDCP_RK3036_DEBUG - bool "RK3036 HDCP Debugging" - depends on HDCP_RK3036 - default n - help - Enableds verbose debugging the the HDCP drivers - -config CEC_RK3036 - bool "RK3036 CEC support" - default n - help - CEC Interface. This adds the HDMI CEC Interface. diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/Makefile b/drivers/video/rockchip/hdmi/chips/rk3036/Makefile deleted file mode 100755 index 0766e060d776..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for HDMI linux kernel module. -# - -ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG -ccflags-$(CONFIG_HDCP_RK616_DEBUG) = -DHDCP_DEBUG - -obj-$(CONFIG_HDMI_RK3036) += rk3036_hdmi_hw.o rk3036_hdmi.o -obj-$(CONFIG_HDCP_RK3036) += rk3036_hdmi_hdcp.o rk3036_hdcp.o -obj-$(CONFIG_CEC_RK3036) += rk3036_hdmi_cec.o diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdcp.c deleted file mode 100755 index 0ca77446de89..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdcp.c +++ /dev/null @@ -1,585 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rk3036_hdmi.h" -#include "rk3036_hdcp.h" - -struct hdcp *hdcp = NULL; - -static void hdcp_work_queue(struct work_struct *work); - -#define AUTH_TIMEOUT (2*HZ) -static struct timer_list auth_timer; -static int timer_state; - -/*----------------------------------------------------------------------------- - * Function: hdcp_submit_work - *----------------------------------------------------------------------------- - */ -static struct delayed_work *hdcp_submit_work(int event, int delay) -{ - struct hdcp_delayed_work *work; - - DBG("%s event %04x delay %d\n", __func__, event, delay); - work = kmalloc(sizeof(*work), GFP_ATOMIC); - - if (work) { - INIT_DELAYED_WORK(&work->work, hdcp_work_queue); - work->event = event; - queue_delayed_work(hdcp->workqueue, - &work->work, - msecs_to_jiffies(delay)); - } else { - HDCP_WARN("HDCP:Cannot allocate memory to create work\n"); - return 0; - } - - return &work->work; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_cancel_work - *----------------------------------------------------------------------------- - */ -static void hdcp_cancel_work(struct delayed_work **work) -{ - int ret = 0; - - if (*work) { - ret = cancel_delayed_work(*work); - if (ret != 1) { - ret = cancel_work_sync(&((*work)->work)); - HDCP_WARN("Canceling sync work failed %d\n", ret); - } - kfree(*work); - *work = 0; - } -} - -/*----------------------------------------------------------------------------- - * Function: auth_timer_func - *----------------------------------------------------------------------------- - */ -static void auth_timer_func(unsigned long data) -{ - HDCP_WARN("hdcp auth 2 second timeout\n"); - if (hdcp->auth_state == 0) { - mod_timer(&auth_timer, jiffies + AUTH_TIMEOUT); - if ((hdcp->hdcp_state != HDCP_DISABLED) && - (hdcp->hdcp_state != HDCP_ENABLE_PENDING)) { - if (is_1b_03_test()) - return; - hdcp_submit_work(HDCP_FAIL_EVENT, 0); - } - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_failure - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_failure(void) -{ - if (hdcp->hdmi_state == HDMI_STOPPED) - return; - - rk3036_hdcp_disable(); -/* - rk3036_hdmi_control_output(false); - */ - rk3036_set_colorbar(1); - hdcp_cancel_work(&hdcp->pending_wq_event); - if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) { - if (hdcp->retry_cnt <= HDCP_INFINITE_REAUTH) { - hdcp->retry_cnt--; - HDCP_WARN("authentication failed attempts=%d\n", - hdcp->retry_cnt); - } else - HDCP_WARN("authentication failed retrying\n"); - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - - if (hdcp->auth_state == 1 && timer_state == 0) { - DBG("add auth timer\n"); - hdcp->auth_state = 0; - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - auth_timer.expires = jiffies + AUTH_TIMEOUT; - add_timer(&auth_timer); - timer_state = 1; - } - - hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT, - HDCP_REAUTH_DELAY); - } else { - HDCP_WARN("authentication failed HDCP disabled\n"); - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - - if (timer_state == 1) { - DBG("delete auth timer\n"); - del_timer_sync(&auth_timer); - timer_state = 0; - } - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_start_authentication - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_start_authentication(void) -{ - int status = HDCP_OK; - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - DBG("HDCP: authentication start\n"); - status = rk3036_hdcp_start_authentication(); - if (status != HDCP_OK) { - DBG("HDCP: authentication failed\n"); - hdcp_wq_authentication_failure(); - } else { - /*hdcp->hdcp_state = HDCP_WAIT_KSV_LIST;*/ - hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - } -} -#if 0 -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_check_bksv - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_check_bksv(void) -{ - int status = HDCP_OK; - - DBG("Check BKSV start"); - status = rk3036_hdcp_check_bksv(); - if (status != HDCP_OK) { - HDCP_WARN("HDCP: Check BKSV failed"); - hdcp->retry_cnt = 0; - hdcp_wq_authentication_failure(); - } else { - DBG("HDCP: Check BKSV successful"); - hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - /* Restore retry counter */ - if (hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times; - } -} -#endif -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_sucess - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_sucess(void) -{ - hdcp->auth_state = 1; - if (timer_state == 1) { - DBG("delete auth timer\n"); - timer_state = 0; - del_timer_sync(&auth_timer); - } -/* - rk616_hdmi_control_output(true); - */ - rk3036_set_colorbar(0); - HDCP_WARN("HDCP: authentication pass\n"); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_disable - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_disable(int event) -{ - HDCP_WARN("HDCP: disabled\n"); - - hdcp_cancel_work(&hdcp->pending_wq_event); - rk3036_hdcp_disable(); - if (event == HDCP_DISABLE_CTL) { - hdcp->hdcp_state = HDCP_DISABLED; - if (hdcp->hdmi_state == HDMI_STARTED) - rk3036_set_colorbar(0); - } else if (event == HDCP_STOP_FRAME_EVENT) { - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_work_queue - *----------------------------------------------------------------------------- - */ -static void hdcp_work_queue(struct work_struct *work) -{ - struct hdcp_delayed_work *hdcp_w = - container_of(work, struct hdcp_delayed_work, work.work); - int event = hdcp_w->event; - - mutex_lock(&hdcp->lock); - DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d\n", - jiffies_to_msecs(jiffies), - hdcp->hdmi_state, - hdcp->hdcp_state, - (event & 0xFF00) >> 8, - event & 0xFF); - - if (event == HDCP_STOP_FRAME_EVENT) - hdcp->hdmi_state = HDMI_STOPPED; - if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) - hdcp_wq_disable(event); - if (event & HDCP_WORKQUEUE_SRC) - hdcp->pending_wq_event = 0; - /* First handle HDMI state */ - if (event == HDCP_START_FRAME_EVENT) { - hdcp->pending_start = 0; - hdcp->hdmi_state = HDMI_STARTED; - } - - /**********************/ - /* HDCP state machine */ - /**********************/ - switch (hdcp->hdcp_state) { - case HDCP_DISABLED: - /* HDCP enable control or re-authentication event */ - if (event == HDCP_ENABLE_CTL) { - /*if (hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times;*/ - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - if (hdcp->hdmi_state == HDMI_STARTED) - hdcp_wq_start_authentication(); - else - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } - break; - case HDCP_ENABLE_PENDING: - /* HDMI start frame event */ - if (event == HDCP_START_FRAME_EVENT) - hdcp_wq_start_authentication(); - break; - case HDCP_AUTHENTICATION_START: - /* Re-authentication */ - if (event == HDCP_AUTH_REATT_EVENT) - hdcp_wq_start_authentication(); - break; -#if 0 - case HDCP_WAIT_KSV_LIST: - /* KSV failure */ - if (event == HDCP_FAIL_EVENT) { - HDCP_WARN("HDCP: KSV switch failure\n"); - hdcp_wq_authentication_failure(); - } - /* KSV list ready event */ - else if (event == HDCP_KSV_LIST_RDY_EVENT) - hdcp_wq_check_bksv(); - break; -#endif - case HDCP_LINK_INTEGRITY_CHECK: - /* authentication failure */ - if (event == HDCP_FAIL_EVENT) { - HDCP_WARN("HDCP: Ri check failure\n"); - hdcp_wq_authentication_failure(); - } else if (event == HDCP_AUTH_PASS_EVENT) - hdcp_wq_authentication_sucess(); - break; - default: - HDCP_WARN("HDCP: error - unknow HDCP state\n"); - break; - } - kfree(hdcp_w); - if (event == HDCP_STOP_FRAME_EVENT) - complete(&hdcp->complete); - mutex_unlock(&hdcp->lock); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_start_frame_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_start_frame_cb(void) -{ - DBG("hdcp_start_frame_cb()\n"); - - /* Cancel any pending work */ - if (hdcp->pending_start) - hdcp_cancel_work(&hdcp->pending_start); - if (hdcp->pending_wq_event) - hdcp_cancel_work(&hdcp->pending_wq_event); - - if (timer_state == 0) { - DBG("add auth timer\n"); - auth_timer.expires = jiffies + AUTH_TIMEOUT; - add_timer(&auth_timer); - timer_state = 1; - } - - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT, - HDCP_ENABLE_DELAY); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_irq_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_irq_cb(int status) -{ - char interrupt1; - char interrupt2; - - rk3036_hdcp_interrupt(&interrupt1, &interrupt2); - DBG("%s 0x%02x 0x%02x\n", __func__, interrupt1, interrupt2); - if (interrupt1 & m_INT_HDCP_ERR) { - if ((hdcp->hdcp_state != HDCP_DISABLED) && - (hdcp->hdcp_state != HDCP_ENABLE_PENDING)) - hdcp_submit_work(HDCP_FAIL_EVENT, 0); - } -/* - else if (interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE)) - hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0); - */ - else if (interrupt1 & m_INT_AUTH_SUCCESS) - hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_on_cb - *----------------------------------------------------------------------------- - */ -static int hdcp_power_on_cb(void) -{ - DBG("%s", __func__); - return rk3036_hdcp_load_key2mem(hdcp->keys); - return HDCP_OK; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_off_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_power_off_cb(void) -{ - DBG("%s\n", __func__); - if (timer_state == 1) { - DBG("delete auth timer\n"); - timer_state = 0; - del_timer_sync(&auth_timer); - } - hdcp->auth_state = 0; - - if (!hdcp->enable) - return; - rk3036_hdcp_stop_authentication(); - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - init_completion(&hdcp->complete); - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0)) - wait_for_completion_interruptible_timeout(&hdcp->complete, - msecs_to_jiffies(5000)); -} - -/* - * Load HDCP key to external HDCP memory - */ -static void hdcp_load_keys_cb(const struct firmware *fw, void *context) -{ - if (!fw) { - pr_err("HDCP: failed to load keys\n"); - return; - } - if (fw->size < HDCP_KEY_SIZE) { - pr_err("HDCP: firmware wrong size %d\n", fw->size); - return; - } - hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL); - if (hdcp->keys == NULL) { - pr_err("HDCP: can't allocated space for keys\n"); - return; - } - memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE); - HDCP_WARN("HDCP: load hdcp key success\n"); - - if (fw->size > HDCP_KEY_SIZE) { - DBG("%s invalid key size %d\n", __func__, - fw->size - HDCP_KEY_SIZE); - if ((fw->size - HDCP_KEY_SIZE) % 5) { - pr_err("HDCP: failed to load invalid keys\n"); - return; - } - hdcp->invalidkeys = - kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL); - if (hdcp->invalidkeys == NULL) { - pr_err("HDCP: can't allocated space for invalid keys\n"); - return; - } - memcpy(hdcp->invalidkeys, fw->data + - HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE); - hdcp->invalidkey = (fw->size - HDCP_KEY_SIZE)/5; - HDCP_WARN("HDCP: loaded hdcp invalid key success\n"); - } -} - -static ssize_t hdcp_enable_read(struct device *device, - struct device_attribute *attr, - char *buf) -{ - int enable = 0; - - if (hdcp) - enable = hdcp->enable; - return snprintf(buf, PAGE_SIZE, "%d\n", enable); -} - -static ssize_t hdcp_enable_write(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) -{ - int enable; - - if (hdcp == NULL) - return -EINVAL; - sscanf(buf, "%d", &enable); - if (hdcp->enable != enable) { - /* Post event to workqueue */ - if (enable) { - if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0) - return -EFAULT; - } else { - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0) - return -EFAULT; - } - hdcp->enable = enable; - } - return count; -} - -static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, - hdcp_enable_read, hdcp_enable_write); - -static ssize_t hdcp_trytimes_read(struct device *device, - struct device_attribute *attr, - char *buf) -{ - int trytimes = 0; - - if (hdcp) - trytimes = hdcp->retry_times; - return snprintf(buf, PAGE_SIZE, "%d\n", trytimes); -} - -static ssize_t hdcp_trytimes_wrtie(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) -{ - int trytimes; - - if (hdcp == NULL) - return -EINVAL; - sscanf(buf, "%d", &trytimes); - if (hdcp->retry_times != trytimes) - hdcp->retry_times = trytimes; - return count; -} - - -static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR, - hdcp_trytimes_read, hdcp_trytimes_wrtie); -static struct miscdevice mdev; - -static int __init rk3036_hdcp_init(void) -{ - int ret; - - DBG("[%s] %u\n", __func__, jiffies_to_msecs(jiffies)); - hdcp = kmalloc(sizeof(struct hdcp), GFP_KERNEL); - if (!hdcp) { - HDCP_WARN(">>HDCP: kmalloc fail!\n"); - ret = -ENOMEM; - goto error0; - } - memset(hdcp, 0, sizeof(struct hdcp)); - mutex_init(&hdcp->lock); - mdev.minor = MISC_DYNAMIC_MINOR; - mdev.name = "hdcp"; - mdev.mode = 0666; - if (misc_register(&mdev)) { - HDCP_WARN("HDCP: Could not add character driver\n"); - ret = HDMI_ERROR_FALSE; - goto error1; - } - ret = device_create_file(mdev.this_device, &dev_attr_enable); - if (ret) { - HDCP_WARN("HDCP: Could not add sys file enable\n"); - ret = -EINVAL; - goto error2; - } - ret = device_create_file(mdev.this_device, &dev_attr_trytimes); - if (ret) { - HDCP_WARN("HDCP: Could not add sys file trytimes\n"); - ret = -EINVAL; - goto error3; - } - hdcp->workqueue = create_singlethread_workqueue("hdcp"); - if (hdcp->workqueue == NULL) { - HDCP_WARN("HDCP,: create workqueue failed.\n"); - goto error4; - } - ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, - "hdcp.keys", mdev.this_device, - GFP_KERNEL, hdcp, - hdcp_load_keys_cb); - if (ret < 0) { - HDCP_WARN("HDCP: request_firmware_nowait failed: %d\n", ret); - goto error5; - } - - rk3036_hdmi_register_hdcp_callbacks(hdcp_start_frame_cb, - hdcp_irq_cb, - hdcp_power_on_cb, - hdcp_power_off_cb); - - init_timer(&auth_timer); - auth_timer.data = 0; - auth_timer.function = auth_timer_func; - DBG("%s success %u\n", __func__, jiffies_to_msecs(jiffies)); - return 0; -error5: - destroy_workqueue(hdcp->workqueue); -error4: - device_remove_file(mdev.this_device, &dev_attr_trytimes); -error3: - device_remove_file(mdev.this_device, &dev_attr_enable); -error2: - misc_deregister(&mdev); -error1: - kfree(hdcp->keys); - kfree(hdcp->invalidkeys); - kfree(hdcp); -error0: - return ret; -} - -static void __exit rk3036_hdcp_exit(void) -{ - device_remove_file(mdev.this_device, &dev_attr_enable); - misc_deregister(&mdev); - kfree(hdcp->keys); - kfree(hdcp->invalidkeys); - kfree(hdcp); -} - -/* module_init(rk3036_hdcp_init); */ -late_initcall_sync(rk3036_hdcp_init); -module_exit(rk3036_hdcp_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdcp.h b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdcp.h deleted file mode 100755 index 57c3126d4ddd..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdcp.h +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef __RK3036_HDCP_H__ -#define __RK3036_HDCP_H__ - -/***************************/ -/* Definitions */ -/***************************/ - -/* Status / error codes */ -#define HDCP_OK 0 -#define HDCP_KEY_ERR 1 -#define HDCP_KSV_ERR 2 -#define HDCP_KEY_VALID 3 -#define HDCP_KEY_INVALID 4 - -/* Delays */ -#define HDCP_ENABLE_DELAY 300 -#define HDCP_REAUTH_DELAY 100 - -/* Event source */ -#define HDCP_SRC_SHIFT 8 -#define HDCP_IOCTL_SRC (0x1 << HDCP_SRC_SHIFT) -#define HDCP_HDMI_SRC (0x2 << HDCP_SRC_SHIFT) -#define HDCP_IRQ_SRC (0x4 << HDCP_SRC_SHIFT) -#define HDCP_WORKQUEUE_SRC (0x8 << HDCP_SRC_SHIFT) - -/* Event */ -#define HDCP_ENABLE_CTL (HDCP_IOCTL_SRC | 0) -#define HDCP_DISABLE_CTL (HDCP_IOCTL_SRC | 1) -#define HDCP_START_FRAME_EVENT (HDCP_HDMI_SRC | 2) -#define HDCP_STOP_FRAME_EVENT (HDCP_HDMI_SRC | 3) -#define HDCP_KSV_LIST_RDY_EVENT (HDCP_IRQ_SRC | 4) -#define HDCP_FAIL_EVENT (HDCP_IRQ_SRC | 5) -#define HDCP_AUTH_PASS_EVENT (HDCP_IRQ_SRC | 6) -#define HDCP_AUTH_REATT_EVENT (HDCP_WORKQUEUE_SRC | 7) - -/* Key size */ -#define HDCP_KEY_SIZE 308 - -/* HDCP DDC Clock */ -#define HDCP_DDC_CLK 100000 - -/* Authentication retry times */ -#define HDCP_INFINITE_REAUTH 0x100 - -/* HDCP Regs */ -#define HDCP_CTRL1 0x52 - #define m_AUTH_START (1 << 7) - #define m_BKSV_VALID (1 << 6) - #define m_BKSV_INVALID (1 << 5) - #define m_ENCRYPT_ENABLE (1 << 4) - #define m_AUTH_STOP (1 << 3) - #define m_ADVANED_ENABLE (1 << 2) - #define m_HDMI_DVI (1 << 1) - #define m_HDCP_RESET (1 << 0) - - #define v_AUTH_START(n) (n << 7) - #define v_BKSV_VALID(n) (n << 6) - #define v_BKSV_INVALID(n) (n << 5) - #define v_ENCRYPT_ENABLE(n) (n << 4) - #define v_AUTH_STOP(n) (n << 3) - #define v_ADVANED_ENABLE(n) (n << 2) - #define v_HDMI_DVI(n) (n << 1) - #define v_HDCP_RESET(n) (n << 0) - -#define HDCP_CTRL2 0x53 - #define m_DISABLE_127_CHECK (1 << 7) - #define m_SKIP_BKSV_CHECK (1 << 6) - #define m_ENABLE_PJ_CHECK (1 << 5) - #define m_DISABLE_DEVICE_NUMBER_CHECK (1 << 4) - #define m_DELAY_RI_1_CLK (1 << 3) - #define m_USE_PRESET_AN (1 << 2) - #define m_KEY_COMBINATION (3 << 0) - - #define v_DISABLE_127_CHECK(n) (n << 7) - #define v_SKIP_BKSV_CHECK(n) (n << 6) - #define v_ENABLE_PJ_CHECK(n) (n << 5) - #define v_DISABLE_DEVICE_NUMBER_CHECK(n)(n << 4) - #define v_DELAY_RI_1_CLK(n) (n << 3) - #define v_USE_PRESET_AN(n) (n << 2) - #define v_KEY_COMBINATION(n) (n << 0) - -#define HDCP_KEY_STATUS 0x54 - #define m_KEY_READY (1 << 0) - -#define HDCP_CTRL_SOFT 0x57 - #define m_DISABLE_127_CHECK (1 << 7) - #define m_SKIP_BKSV_CHECK (1 << 6) - #define m_NOT_AUTHENTICATED (1 << 5) - #define m_ENCRYPTED (1 << 4) - #define m_ADVANCED_CIPHER (1 << 3) - -#define HDCP_BCAPS_RX 0x58 -#define HDCP_TIMER_100MS 0x63 -#define HDCP_TIMER_5S 0x64 -#define HDCP_ERROR 0x65 - #define m_DDC_NO_ACK (1 << 3) - #define m_PJ_MISMACH (1 << 2) - #define m_RI_MISMACH (1 << 1) - #define m_BKSV_WRONG (1 << 0) - -#define HDCP_KSV_BYTE0 0x66 -#define HDCP_KSV_BYTE1 0x67 -#define HDCP_KSV_BYTE2 0x68 -#define HDCP_KSV_BYTE3 0x69 -#define HDCP_KSV_BYTE4 0x6a - -#define HDCP_AN_SEED 0x6c - -#define HDCP_BCAPS_TX 0x80 -#define HDCP_BSTATE_0 0x81 -#define HDCP_BSTATE_1 0x82 - -#define HDCP_KEY_FIFO 0x98 - -#define HDCP_INT_MASK1 0xc2 -#define HDCP_INT_STATUS1 0xc3 - #define m_INT_HDCP_ERR (1 << 7) - #define m_INT_BKSV_READY (1 << 6) - #define m_INT_BKSV_UPDATE (1 << 5) - #define m_INT_AUTH_SUCCESS (1 << 4) - #define m_INT_AUTH_READY (1 << 3) - -#define HDCP_INT_MASK2 0xc4 -#define HDCP_INT_STATUS2 0xc5 - #define m_INT_SOFT_MODE_READY (1 << 7) - #define m_INT_AUTH_M0_REDAY (1 << 6) - #define m_INT_1st_FRAME_ARRIVE (1 << 5) - #define m_INT_AN_READY (1 << 4) - #define m_INT_ENCRYPTED (1 << 2) - #define m_INT_NOT_ENCRYPTED_AVMUTE (1 << 1) - #define m_INT_NOT_ENCRYPTED_AVUNMUTE (1 << 0) - -enum hdcp_states { - HDCP_DISABLED, - HDCP_ENABLE_PENDING, - HDCP_AUTHENTICATION_START, - HDCP_WAIT_KSV_LIST, - HDCP_LINK_INTEGRITY_CHECK, -}; - -enum hdmi_states { - HDMI_STOPPED, - HDMI_STARTED -}; - -#define HDCP_PRIVATE_KEY_SIZE 280 -#define HDCP_KEY_SHA_SIZE 20 - -struct hdcp_keys { - u8 ksv[8]; - u8 devicekey[HDCP_PRIVATE_KEY_SIZE]; - u8 sha1[HDCP_KEY_SHA_SIZE]; -}; - -struct hdcp_delayed_work { - struct delayed_work work; - int event; -}; - -struct hdcp { - int enable; - int retry_times; - struct hdcp_keys *keys; - int invalidkey; - char *invalidkeys; - struct mutex lock; - struct completion complete; - struct workqueue_struct *workqueue; - - enum hdmi_states hdmi_state; - enum hdcp_states hdcp_state; - - struct delayed_work *pending_start; - struct delayed_work *pending_wq_event; - int retry_cnt; - int auth_state; -}; - -extern struct hdcp *hdcp; - -#ifdef HDCP_DEBUG -#define DBG(format, ...) \ - printk(KERN_INFO "HDCP: " format "\n", ## __VA_ARGS__) -#else -#define DBG(format, ...) -#endif - -#if 1 -#define HDCP_WARN(x...) printk(KERN_INFO x) -#else -#define I2S_DBG(x...) do { } while (0) -#endif - -extern void rk3036_hdcp_disable(void); -extern int rk3036_hdcp_start_authentication(void); -extern int rk3036_hdcp_check_bksv(void); -extern int rk3036_hdcp_load_key2mem(struct hdcp_keys *key); -extern void rk3036_hdcp_interrupt(char *status1, char *status2); -extern void rk3036_set_colorbar(int enable); -extern int rk3036_hdcp_stop_authentication(void); -extern int is_1b_03_test(void); -#endif /* __rk3036_HDCP_H__ */ diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c deleted file mode 100755 index e705565ef845..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c +++ /dev/null @@ -1,546 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#if defined(CONFIG_DEBUG_FS) -#include -#include -#include -#endif - -#include "rk3036_hdmi.h" -#include "rk3036_hdmi_hw.h" - -struct rk_hdmi_device *hdmi_dev; - -#if defined(CONFIG_DEBUG_FS) -static int rk3036_hdmi_reg_show(struct seq_file *s, void *v) -{ - int i = 0; - u32 val = 0; - - seq_puts(s, "\n\n>>>rk3036_ctl reg"); - for (i = 0; i < 16; i++) - seq_printf(s, " %2x", i); - - 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>>>rk3036_ctl %2x:", i); - seq_printf(s, " %02x", val); - - } - seq_puts(s, - "\n-----------------------------------------------------------------\n"); - - return 0; -} - -static ssize_t rk3036_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_drv->dev, "it is no hdmi reg\n"); - return count; - } - dev_info(hdmi_drv->dev, "/**********rk3036 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 rk3036_hdmi_reg_open(struct inode *inode, struct file *file) -{ - return single_open(file, rk3036_hdmi_reg_show, NULL); -} - -static const struct file_operations rk3036_hdmi_reg_fops = { - .owner = THIS_MODULE, - .open = rk3036_hdmi_reg_open, - .read = seq_read, - .write = rk3036_hdmi_reg_write, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - -static int rk3036_hdmi_clk_enable(struct rk_hdmi_device *hdmi_dev) -{ - struct hdmi *hdmi_drv; - hdmi_drv = &hdmi_dev->driver; - - if (!hdmi_dev->clk_on) { - if(hdmi_drv->data->soc_type == HDMI_SOC_RK312X) { - clk_prepare_enable(hdmi_dev->pd); - } - 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 rk3036_hdmi_clk_disable(struct rk_hdmi_device *hdmi_dev) -{ - struct hdmi *hdmi_drv; - hdmi_drv = &hdmi_dev->driver; - - if (hdmi_dev->clk_on) { - spin_lock(&hdmi_dev->reg_lock); - hdmi_dev->clk_on = 0; - spin_unlock(&hdmi_dev->reg_lock); - if(hdmi_drv->data->soc_type == HDMI_SOC_RK312X) { - clk_disable_unprepare(hdmi_dev->pd); - } - clk_disable_unprepare(hdmi_dev->hclk); - } - - return 0; -} - -int rk3036_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)) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - if (hdmi_drv == NULL) - return HDMI_ERROR_FALSE; - - 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; -} - -int rk3036_hdmi_register_cec_callbacks(void (*cec_irq)(void), - void (*cec_set_device_pa)(int addr), - int (*cec_enumerate)(void)) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - if (hdmi_drv == NULL) - return HDMI_ERROR_FALSE; - - hdmi_drv->cec_irq = cec_irq; - hdmi_drv->cec_set_device_pa = cec_set_device_pa; - hdmi_drv->cec_enumerate = cec_enumerate; - - return HDMI_ERROR_SUCESS; -} - -static void rk3036_hdmi_early_suspend(void) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - 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); - if (!hdmi_drv->suspend) { - 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_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); - rk3036_hdmi_clk_disable(hdmi_dev); - } -} - -static void rk3036_hdmi_early_resume(void) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - hdmi_dbg(hdmi_drv->dev, "hdmi exit early resume\n"); - - mutex_lock(&hdmi_drv->enable_mutex); - if (hdmi_drv->suspend) { - hdmi_drv->suspend = 0; - rk3036_hdmi_clk_enable(hdmi_dev); - rk3036_hdmi_initial(hdmi_drv); - if (hdmi_drv->enable && hdmi_drv->irq) { - enable_irq(hdmi_drv->irq); - rk3036_hdmi_irq(hdmi_drv); - } - - queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, - msecs_to_jiffies(10)); - } - mutex_unlock(&hdmi_drv->enable_mutex); -} - -static int rk3036_hdmi_fb_event_notify(struct notifier_block *self, - unsigned long action, void *data) -{ - 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: - rk3036_hdmi_early_suspend(); - break; - } - } else if (action == FB_EVENT_BLANK) { - switch (blank_mode) { - case FB_BLANK_UNBLANK: - rk3036_hdmi_early_resume(); - break; - default: - break; - } - } - - return NOTIFY_OK; -} - -static struct notifier_block rk3036_hdmi_fb_notifier = { - .notifier_call = rk3036_hdmi_fb_event_notify, -}; - - -static void rk3036_delay_work_func(struct work_struct *work) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - if (hdmi_drv->suspend == 0) { - if (hdmi_drv->enable == 1) - rk3036_hdmi_irq(hdmi_drv); - if (hdmi_drv->irq == 0) - queue_delayed_work(hdmi_drv->workqueue, &hdmi_dev->rk3036_delay_work, - msecs_to_jiffies(100)); - } -} - -static irqreturn_t rk3036_hdmi_irq_func(int irq, void *dev_id) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - if ((hdmi_drv->suspend == 0) && (hdmi_drv->enable == 1)) { - hdmi_dbg(hdmi_drv->dev, - "line = %d, rk3036_hdmi_irq_func irq triggered.\n", - __LINE__); - rk3036_hdmi_irq(hdmi_drv); - } - - return IRQ_HANDLED; -} - -static int rk3036_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_id = screen.lcdc_id;//for box,hdmi is primary - - 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 = rk3036_hdmi_initial(hdmi_drv); - - hdmi_drv_register(hdmi_drv); - return ret; -} - -static struct rk_hdmi_drvdata rk3036_hdmi_drvdata = { - .soc_type = HDMI_SOC_RK3036, -}; - -static struct rk_hdmi_drvdata rk312x_hdmi_drvdata = { - .soc_type = HDMI_SOC_RK312X, -}; - -#if defined(CONFIG_OF) -static const struct of_device_id rk3036_hdmi_of_match[] = { - {.compatible = "rockchip,rk3036-hdmi", - .data = (void *)&rk3036_hdmi_drvdata, }, - {.compatible = "rockchip,rk312x-hdmi", - .data = (void *)&rk312x_hdmi_drvdata,}, - {} -}; - -MODULE_DEVICE_TABLE(of, rk3036_hdmi_of_match); -#endif - -static int rk3036_hdmi_probe(struct platform_device *pdev) -{ - int ret; - struct hdmi *hdmi_drv; - struct resource *res; - const struct of_device_id *match; - struct device_node *node = pdev->dev.of_node; - - hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(struct rk_hdmi_device), - GFP_KERNEL); - if (!hdmi_dev) { - dev_err(&pdev->dev, ">>rk3036_hdmi kmalloc fail!"); - return -ENOMEM; - } - - hdmi_drv = &hdmi_dev->driver; - hdmi_drv->dev = &pdev->dev; - platform_set_drvdata(pdev, hdmi_dev); - spin_lock_init(&hdmi_dev->reg_lock); - - match = of_match_node(rk3036_hdmi_of_match, node); - hdmi_drv->data = (struct rk_hdmi_drvdata*)match->data; - dev_info(hdmi_drv->dev, "%s,type=%d\n", - __func__,hdmi_drv->data->soc_type); - - -#ifdef CONFIG_SWITCH - hdmi_drv->switch_hdmi.name = "hdmi"; - switch_dev_register(&(hdmi_drv->switch_hdmi)); -#endif - hdmi_register_display_sysfs(hdmi_drv, NULL); - fb_register_client(&rk3036_hdmi_fb_notifier); - - hdmi_drv->workqueue = create_singlethread_workqueue("hdmi"); - INIT_DELAYED_WORK(&(hdmi_drv->delay_work), hdmi_work); - INIT_DELAYED_WORK(&hdmi_dev->rk3036_delay_work, rk3036_delay_work_func); - - /* enable clk */ - if(hdmi_drv->data->soc_type == HDMI_SOC_RK312X) { - hdmi_dev->pd = devm_clk_get(hdmi_drv->dev, "pd_hdmi"); - if (IS_ERR(hdmi_dev->pd)) { - dev_err(hdmi_drv->dev, "Unable to get hdmi pd\n"); - ret = -ENXIO; - goto err1; - } - } - 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; - } - rk3036_hdmi_clk_enable(hdmi_dev); /* enable clk may move to irq func */ - hdmi_dev->hclk_rate = clk_get_rate(hdmi_dev->hclk); - /* request and remap iomem */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(hdmi_drv->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; - } - if (rk3036_hdmi_drv_init(hdmi_drv)) - goto err0; - - /* get the IRQ */ - hdmi_drv->irq = platform_get_irq(pdev, 0); - if (hdmi_drv->irq <= 0) { - dev_err(hdmi_drv->dev, "failed to get hdmi irq resource (%d).\n", - hdmi_drv->irq); - hdmi_drv->irq = 0; - } else { - /* request the IRQ */ - ret = devm_request_irq(hdmi_drv->dev, hdmi_drv->irq, - rk3036_hdmi_irq_func, 0, - dev_name(hdmi_drv->dev), hdmi_drv); - if (ret) { - dev_err(hdmi_drv->dev, "hdmi request_irq failed (%d)\n", - ret); - goto err2; - } - } - -#if defined(CONFIG_DEBUG_FS) - hdmi_dev->debugfs_dir = debugfs_create_dir("rk3036", NULL); - if (IS_ERR(hdmi_dev->debugfs_dir)) { - dev_err(hdmi_drv->dev, - "failed to create debugfs dir for rk3036!\n"); - } else { - debugfs_create_file("hdmi", S_IRUSR, - hdmi_dev->debugfs_dir, hdmi_drv, - &rk3036_hdmi_reg_fops); - } - -#endif - - queue_delayed_work(hdmi_drv->workqueue, &hdmi_dev->rk3036_delay_work, - msecs_to_jiffies(0)); - dev_info(hdmi_drv->dev, "rk3036 hdmi probe success.\n"); - - return 0; - -err2: - rk3036_hdmi_clk_disable(hdmi_dev); -err1: - fb_unregister_client(&rk3036_hdmi_fb_notifier); - hdmi_unregister_display_sysfs(hdmi_drv); -#ifdef CONFIG_SWITCH - switch_dev_unregister(&(hdmi_drv->switch_hdmi)); -#endif - -err0: - hdmi_dbg(hdmi_drv->dev, "rk3036 hdmi probe error.\n"); - kfree(hdmi_dev); - hdmi_dev = NULL; - return ret; -} - -static int rk3036_hdmi_remove(struct platform_device *pdev) -{ - 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_drv->switch_hdmi)); -#endif - hdmi_unregister_display_sysfs(hdmi_drv); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&hdmi_drv->early_suspend); -#endif - 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); - } - - hdmi_dbg(hdmi_drv->dev, "rk3036 hdmi removed.\n"); - kfree(hdmi_dev); - hdmi_dev = NULL; - } - - return 0; -} - -static void rk3036_hdmi_shutdown(struct platform_device *pdev) -{ - struct rk_hdmi_device *hdmi_dev = platform_get_drvdata(pdev); - struct hdmi *hdmi_drv = NULL; - - if (hdmi_dev) { - hdmi_drv = &hdmi_dev->driver; -#ifdef CONFIG_HAS_EARLYSUSPEND - 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); - if (hdmi_drv->hotplug == HDMI_HPD_ACTIVED) - rk3036_hdmi_control_output(hdmi_drv, 0); - rk3036_hdmi_clk_disable(hdmi_dev); - } - hdmi_dbg(hdmi_drv->dev, "rk3036 hdmi shut down.\n"); -} - - -static struct platform_driver rk3036_hdmi_driver = { - .probe = rk3036_hdmi_probe, - .remove = rk3036_hdmi_remove, - .driver = { - .name = "rk3036-hdmi", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(rk3036_hdmi_of_match), - }, - .shutdown = rk3036_hdmi_shutdown, -}; - -static int __init rk3036_hdmi_init(void) -{ - return platform_driver_register(&rk3036_hdmi_driver); -} - -static void __exit rk3036_hdmi_exit(void) -{ - platform_driver_unregister(&rk3036_hdmi_driver); -} - -module_init(rk3036_hdmi_init); -module_exit(rk3036_hdmi_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.h b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.h deleted file mode 100755 index 15de55767060..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __RK3036_HDMI_H__ -#define __RK3036_HDMI_H__ - -#include "../../rk_hdmi.h" - -enum { - INPUT_IIS, - INPUT_SPDIF -}; - - -#if defined(CONFIG_SND_RK_SOC_HDMI_SPDIF) -#define HDMI_CODEC_SOURCE_SELECT INPUT_SPDIF -#else -#define HDMI_CODEC_SOURCE_SELECT INPUT_IIS -#endif - -extern void rk3036_hdmi_control_output(struct hdmi *hdmi, int enable); -extern int rk3036_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)); -extern int rk3036_hdmi_register_cec_callbacks(void (*cec_irq)(void), - void (*cec_set_device_pa)(int addr), - int (*cec_enumerate)(void)); - - -extern struct rk_hdmi_device *hdmi_dev; - -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 rk3036_delay_work; - struct work_struct rk3036_irq_work_struct; - struct dentry *debugfs_dir; - unsigned int hclk_rate; -}; - -#endif /* __RK3036_HDMI_H__ */ diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_cec.c b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_cec.c deleted file mode 100755 index 89337e6483db..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_cec.c +++ /dev/null @@ -1,459 +0,0 @@ -#include "rk3036_hdmi.h" -#include "rk3036_hdmi_hw.h" -#include "rk3036_hdmi_cec.h" - -static cec_t cec; -static char la_player[3] = {CEC_LOGADDR_PLAYBACK1, - CEC_LOGADDR_PLAYBACK2, - CEC_LOGADDR_PLAYBACK3}; - -static int cec_read_frame(cec_framedata_t *frame) -{ - int i, length,val; - char *data = (char *)frame;//modify by hjc - if(frame == NULL) - return -1; - - hdmi_readl(hdmi_dev, CEC_RX_LENGTH, &length); - hdmi_writel(hdmi_dev, CEC_RX_OFFSET, 0); - - printk("CEC: %s length is %d\n", __FUNCTION__, length); - for(i = 0; i < length; i++) { - hdmi_readl(hdmi_dev, CEC_DATA, &val); - data[i] = val; - printk("%02x\n", data[i]); - } - return 0; -} - -static int cec_send_frame(cec_framedata_t *frame) -{ - int i; - - CECDBG("CEC: TX srcdestaddr %02x opcode %02x ", - frame->srcdestaddr, frame->opcode); - if(frame->argcount) { - CECDBG("args:"); - for(i = 0; i < frame->argcount; i++) { - CECDBG("%02x ", frame->args[i]); - } - } - CECDBG("\n"); - - hdmi_writel(hdmi_dev, CEC_TX_OFFSET, 0); - hdmi_writel(hdmi_dev, CEC_DATA, frame->srcdestaddr); - hdmi_writel(hdmi_dev, CEC_DATA, frame->opcode); - - for(i = 0; i < frame->argcount; i++) - hdmi_writel(hdmi_dev, CEC_DATA, frame->args[i]); - - hdmi_writel(hdmi_dev, CEC_TX_LENGTH, frame->argcount + 2); - - /*Wait for bus free*/ - cec.busfree = 1; - hdmi_writel(hdmi_dev, CEC_CTRL, m_BUSFREETIME_ENABLE); - CECDBG("start wait bus free\n"); - if(wait_event_interruptible_timeout(cec.wait, cec.busfree == 0, msecs_to_jiffies(17))) { - return -1; - } - CECDBG("end wait bus free,start tx,busfree=%d\n",cec.busfree); - /*Start TX*/ - cec.tx_done = 0; - hdmi_writel(hdmi_dev, CEC_CTRL, m_BUSFREETIME_ENABLE|m_START_TX); - if(wait_event_interruptible_timeout(cec.wait, cec.tx_done != 0, msecs_to_jiffies(100))) - hdmi_writel(hdmi_dev, CEC_CTRL, 0); - CECDBG("end tx,tx_done=%d\n",cec.tx_done); - if (cec.tx_done == 1) { - cec.tx_done = 0;//hjc add ,need? - return 0; - } else - return -1; -} - -static int cec_send_message(char opcode, char dest) -{ - cec_framedata_t cecframe; - CECDBG("CEC: cec_send_message\n"); - - cecframe.opcode = opcode; - cecframe.srcdestaddr = MAKE_SRCDEST(cec.address_logic, dest); - cecframe.argcount = 0; - return cec_send_frame(&cecframe); -} - -static void cec_send_feature_abort ( cec_framedata_t *pcpi, char reason ) -{ - cec_framedata_t cecFrame; - CECDBG("CEC: cec_send_feature_abort\n"); - - if (( pcpi->srcdestaddr & 0x0F) != CEC_LOGADDR_UNREGORBC ) - { - cecFrame.opcode = CECOP_FEATURE_ABORT; - cecFrame.srcdestaddr = MAKE_SRCDEST( cec.address_logic, (pcpi->srcdestaddr & 0xF0) >> 4 ); - cecFrame.args[0] = pcpi->opcode; - cecFrame.args[1] = reason; - cecFrame.argcount = 2; - cec_send_frame( &cecFrame ); - } -} - -static void cec_send_active_source(void) -{ - cec_framedata_t cecframe; - - CECDBG("CEC: start_active_source\n"); - cecframe.opcode = CECOP_ACTIVE_SOURCE; - cecframe.srcdestaddr = MAKE_SRCDEST( cec.address_logic, CEC_LOGADDR_UNREGORBC); - cecframe.args[0] = (cec.address_phy & 0xFF00) >> 8; /* [Physical Address]*/ - cecframe.args[1] = (cec.address_phy & 0x00FF); /* [Physical Address]*/ - cecframe.argcount = 2; - cec_send_frame( &cecframe ); -} - -static void start_active_source(void) -{ - int i; - CECDBG("CEC: start_active_source\n"); - /* GPIO simulate CEC timing may be not correct, so we try more times.*/ - /*send image view on first*/ - for(i = 0; i < 1; i++) { - if(cec_send_message(CECOP_IMAGE_VIEW_ON,CEC_LOGADDR_TV) == 0) { - cec_send_active_source(); - } - } -} - -static void cec_handle_inactive_source ( cec_framedata_t *pcpi ) -{ - -} - -static void cec_handle_feature_abort( cec_framedata_t *pcpi ) -{ - -} - -static bool validate_cec_message(cec_framedata_t *pcpi) -{ - char parametercount = 0; - bool countok = true; - CECDBG("CEC: validate_cec_message,opcode=%d\n",pcpi->opcode); - - /* Determine required parameter count */ - switch (pcpi->opcode) - { - case CECOP_IMAGE_VIEW_ON: - case CECOP_TEXT_VIEW_ON: - case CECOP_STANDBY: - case CECOP_GIVE_PHYSICAL_ADDRESS: - case CECOP_GIVE_DEVICE_POWER_STATUS: - case CECOP_GET_MENU_LANGUAGE: - case CECOP_GET_CEC_VERSION: - parametercount = 0; - break; - case CECOP_REPORT_POWER_STATUS: // power status*/ - case CECOP_CEC_VERSION: // cec version*/ - parametercount = 1; - break; - case CECOP_INACTIVE_SOURCE: // physical address*/ - case CECOP_FEATURE_ABORT: // feature opcode / abort reason*/ - case CECOP_ACTIVE_SOURCE: // physical address*/ - parametercount = 2; - break; - case CECOP_REPORT_PHYSICAL_ADDRESS: // physical address / device type*/ - case CECOP_DEVICE_VENDOR_ID: // vendor id*/ - parametercount = 3; - break; - case CECOP_SET_OSD_NAME: // osd name (1-14 bytes)*/ - case CECOP_SET_OSD_STRING: // 1 + x display control / osd string (1-13 bytes)*/ - parametercount = 1; // must have a minimum of 1 operands*/ - break; - case CECOP_ABORT: - break; - case CECOP_ARC_INITIATE: - break; - case CECOP_ARC_REPORT_INITIATED: - break; - case CECOP_ARC_REPORT_TERMINATED: - break; - - case CECOP_ARC_REQUEST_INITIATION: - break; - case CECOP_ARC_REQUEST_TERMINATION: - break; - case CECOP_ARC_TERMINATE: - break; - default: - break; - } - - /* Test for correct parameter count. */ - - if (pcpi->argcount < parametercount) { - CECDBG("CEC: pcpi->argcount[%d] < parametercount[%d]\n", - pcpi->argcount,parametercount); - countok = false; - } - return(countok ); -} - -static bool cec_rx_msg_handler_last(cec_framedata_t *pcpi) -{ - bool isdirectaddressed; - cec_framedata_t cecFrame; - - CECDBG("CEC: cec_rx_msg_handler_last,opcode=%d\n",pcpi->opcode); - isdirectaddressed = !((pcpi->srcdestaddr & 0x0F) == CEC_LOGADDR_UNREGORBC); - - if (validate_cec_message(pcpi)) {/* If invalid message, ignore it, but treat it as handled*/ - if (isdirectaddressed) { - switch (pcpi->opcode) { - case CECOP_FEATURE_ABORT: - cec_handle_feature_abort(pcpi); - break; - case CECOP_IMAGE_VIEW_ON: /*In our case, respond the same to both these messages*/ - case CECOP_TEXT_VIEW_ON: - break; - case CECOP_STANDBY: /* Direct and Broadcast*/ - /* Setting this here will let the main task know */ - /* (via SI_CecGetPowerState) and at the same time */ - /* prevent us from broadcasting a STANDBY message */ - /* of our own when the main task responds by */ - /* calling SI_CecSetPowerState( STANDBY ); */ - cec.powerstatus = CEC_POWERSTATUS_STANDBY; - break; - case CECOP_INACTIVE_SOURCE: - cec_handle_inactive_source(pcpi); - break; - case CECOP_GIVE_PHYSICAL_ADDRESS: - /* TV responds by broadcasting its Physical Address: 0.0.0.0 */ - cecFrame.opcode = CECOP_REPORT_PHYSICAL_ADDRESS; - cecFrame.srcdestaddr = MAKE_SRCDEST(cec.address_logic, - CEC_LOGADDR_UNREGORBC); - cecFrame.args[0] = (cec.address_phy&0xFF00)>>8; /* [Physical Address]*/ - cecFrame.args[1] = (cec.address_phy&0x00FF); /*[Physical Address]*/ - cecFrame.args[2] = cec.address_logic;/*CEC_LOGADDR_PLAYBACK1;//2011.08.03 CEC_LOGADDR_TV; // [Device Type] = 0 = TV*/ - cecFrame.argcount = 3; - cec_send_frame(&cecFrame); - break; - case CECOP_GIVE_DEVICE_POWER_STATUS: - /* TV responds with power status. */ - cecFrame.opcode = CECOP_REPORT_POWER_STATUS; - cecFrame.srcdestaddr = MAKE_SRCDEST(cec.address_logic, (pcpi->srcdestaddr & 0xF0) >> 4); - cecFrame.args[0] = cec.powerstatus; - cecFrame.argcount = 1; - cec_send_frame(&cecFrame); - break; - case CECOP_GET_MENU_LANGUAGE: - /* TV Responds with a Set Menu language command. */ - cecFrame.opcode = CECOP_SET_MENU_LANGUAGE; - cecFrame.srcdestaddr = CEC_LOGADDR_UNREGORBC; - cecFrame.args[0] = 'e'; /* [language code see iso/fdis 639-2]*/ - cecFrame.args[1] = 'n'; /* [language code see iso/fdis 639-2]*/ - cecFrame.args[2] = 'g'; /* [language code see iso/fdis 639-2]*/ - cecFrame.argcount = 3; - cec_send_frame(&cecFrame); - break; - case CECOP_GET_CEC_VERSION: - /* TV responds to this request with it's CEC version support. */ - cecFrame.srcdestaddr = MAKE_SRCDEST(cec.address_logic, (pcpi->srcdestaddr & 0xF0) >> 4); - cecFrame.opcode = CECOP_CEC_VERSION; - cecFrame.args[0] = 0x04; /* Report CEC1.3a*/ - cecFrame.argcount = 1; - cec_send_frame(&cecFrame); - break; - case CECOP_REPORT_POWER_STATUS: /* Someone sent us their power state.*/ - /*l_sourcePowerStatus = pcpi->args[0]; - Let NEW SOURCE task know about it. - if (l_cecTaskState.task == SI_CECTASK_NEWSOURCE) { - l_cecTaskState.cpiState = CPI_RESPONSE; - }*/ - break; - /* Do not reply to directly addressed 'Broadcast' msgs. */ - case CECOP_ACTIVE_SOURCE: - case CECOP_REPORT_PHYSICAL_ADDRESS: /*A physical address was broadcast -- ignore it.*/ - case CECOP_REQUEST_ACTIVE_SOURCE: /*We are not a source, so ignore this one.*/ - case CECOP_ROUTING_CHANGE: /*We are not a downstream switch, so ignore this one.*/ - case CECOP_ROUTING_INFORMATION: /*We are not a downstream switch, so ignore this one.*/ - case CECOP_SET_STREAM_PATH: /*We are not a source, so ignore this one.*/ - case CECOP_SET_MENU_LANGUAGE: /*As a TV, we can ignore this message*/ - case CECOP_DEVICE_VENDOR_ID: - break; - case CECOP_ABORT: /*Send Feature Abort for all unsupported features.*/ - default: - cec_send_feature_abort(pcpi, CECAR_UNRECOG_OPCODE); - break; - } - } else { - /* Respond to broadcast messages. */ - switch (pcpi->opcode) { - case CECOP_STANDBY: - - /* Setting this here will let the main task know */ - /* (via SI_CecGetPowerState) and at the same time */ - /* prevent us from broadcasting a STANDBY message */ - /* of our own when the main task responds by */ - /* calling SI_CecSetPowerState( STANDBY ); */ - - cec.powerstatus = CEC_POWERSTATUS_STANDBY; - break; - - case CECOP_ACTIVE_SOURCE: - /*CecHandleActiveSource( pcpi );*/ - break; - case CECOP_REPORT_PHYSICAL_ADDRESS: - /*CecHandleReportPhysicalAddress( pcpi );*/ - break; - /* Do not reply to 'Broadcast' msgs that we don't need. */ - case CECOP_REQUEST_ACTIVE_SOURCE: /*We are not a source, so ignore this one.*/ - /*SI_StartActiveSource(0,0);//2011.08.03*/ - break; - case CECOP_ROUTING_CHANGE: /*We are not a downstream switch, so ignore this one.*/ - case CECOP_ROUTING_INFORMATION: /*We are not a downstream switch, so ignore this one.*/ - case CECOP_SET_STREAM_PATH: /*We are not a source, so ignore this one.*/ - case CECOP_SET_MENU_LANGUAGE: /*As a TV, we can ignore this message*/ - break; - } - } - } - return 0; -} - -static void cec_work_func(struct work_struct *work) -{ - struct cec_delayed_work *cec_w = - container_of(work, struct cec_delayed_work, work.work); - cec_framedata_t cecFrame; - CECDBG(KERN_WARNING "CEC: cec_work_func,event=%d\n",cec_w->event); - switch(cec_w->event) - { - case EVENT_ENUMERATE: - break; - case EVENT_RX_FRAME: - memset(&cecFrame, 0, sizeof(cec_framedata_t)); - cec_read_frame(&cecFrame); - cec_rx_msg_handler_last(&cecFrame); - break; - default: - break; - } - - if(cec_w->data) - kfree(cec_w->data); - kfree(cec_w); -} - -static void cec_submit_work(int event, int delay, void *data) -{ - struct cec_delayed_work *work; - - CECDBG("%s event %04x delay %d", __func__, event, delay); - work = kmalloc(sizeof(struct cec_delayed_work), GFP_ATOMIC); - - if (work) { - INIT_DELAYED_WORK(&work->work, cec_work_func); - work->event = event; - work->data = data; - queue_delayed_work(cec.workqueue, - &work->work, - msecs_to_jiffies(delay)); - } else { - CECDBG(KERN_WARNING "CEC: GPIO CEC: Cannot allocate memory to " - "create work\n");; - } -} - -int cec_enumerate(void) -{ - /*for(i = 0; i < 3; i++) { - if(Cec_Ping(la_player[i]) == 1) { - cec.address_logic = la_player[i]; - break; - } - } - if(i == 3) - return -1; - //Broadcast our physical address. - GPIO_CecSendMessage(CECOP_GET_MENU_LANGUAGE,CEC_LOGADDR_TV); - msleep(100);*/ - CECDBG("CEC: %s\n", __func__); - cec.address_logic = la_player[0]; - hdmi_writel(hdmi_dev, CEC_LOGICADDR, cec.address_logic); - start_active_source(); - return 0; -} - -void cec_set_device_pa(int addr) -{ - CECDBG("CEC: Physical Address is %02x", addr); - cec.address_phy = addr; -} - -void rk3036_cec_isr(void) -{ - int tx_isr = 0, rx_isr = 0; - hdmi_readl(hdmi_dev, CEC_TX_INT, &tx_isr); - hdmi_readl(hdmi_dev, CEC_RX_INT, &rx_isr); - - CECDBG("CEC: rk3036_cec_isr:tx_isr %02x rx_isr %02x\n\n", tx_isr, rx_isr); - - hdmi_writel(hdmi_dev, CEC_TX_INT, tx_isr); - hdmi_writel(hdmi_dev, CEC_RX_INT, rx_isr); - - if (tx_isr & m_TX_BUSNOTFREE) { - cec.busfree = 0; - CECDBG("CEC: m_TX_BUSNOTFREE,busfree=%d\n",cec.busfree); - } else if (tx_isr & m_TX_DONE) { - cec.tx_done = 1; - CECDBG("CEC: m_TX_DONE,busfree=%d\n",cec.tx_done); - } else { - cec.tx_done = -1; - CECDBG("CEC: else:busfree=%d\n",cec.tx_done); - } - - wake_up_interruptible_all(&cec.wait); - if(rx_isr & m_RX_DONE) - cec_submit_work(EVENT_RX_FRAME, 0, NULL); -} - - -static int __init rk3036_cec_init(void) -{ - CECDBG(KERN_ERR "CEC: rk3036_cec_init start.\n"); - memset(&cec, 0, sizeof(cec_t)); - cec.workqueue = create_singlethread_workqueue("cec"); - if (cec.workqueue == NULL) { - CECDBG(KERN_ERR "CEC: GPIO CEC: create workqueue failed.\n"); - return -1; - } - init_waitqueue_head(&cec.wait); - - /*Fref = Fsys / ((register 0xd4 + 1)*(register 0xd5 + 1))*/ - /*Fref = 0.5M, Fsys = 74.25M*/ - hdmi_writel(hdmi_dev, CEC_CLK_H, 11); - hdmi_writel(hdmi_dev, CEC_CLK_L, 11); - - /*Set bus free time to 16.8ms*/ - hdmi_writel(hdmi_dev, CEC_BUSFREETIME_L, 0xd0); - hdmi_writel(hdmi_dev, CEC_BUSFREETIME_H, 0x20); - - /*Enable TX/RX INT*/ - hdmi_writel(hdmi_dev, CEC_TX_INT, 0xFF); - hdmi_writel(hdmi_dev, CEC_RX_INT, 0xFF); - - rk3036_hdmi_register_cec_callbacks(rk3036_cec_isr, - cec_set_device_pa, - cec_enumerate); - - CECDBG(KERN_ERR "CEC: rk3036_cec_init sucess\n"); - - return 0; -} - -static void __exit rk3036_cec_exit(void) -{ - kfree(&cec); -} - -late_initcall_sync(rk3036_cec_init); -module_exit(rk3036_cec_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_cec.h b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_cec.h deleted file mode 100755 index e9f6cf2a4d72..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_cec.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef __RK3036_CEC_H__ -#define __RK3036_CEC_H__ - -typedef enum -{ - CEC_LOGADDR_TV = 0x00, - CEC_LOGADDR_RECDEV1 = 0x01, - CEC_LOGADDR_RECDEV2 = 0x02, - CEC_LOGADDR_TUNER1 = 0x03, /* STB1 in Spev v1.3*/ - CEC_LOGADDR_PLAYBACK1 = 0x04, /* DVD1 in Spev v1.3*/ - CEC_LOGADDR_AUDSYS = 0x05, - CEC_LOGADDR_TUNER2 = 0x06, /* STB2 in Spec v1.3*/ - CEC_LOGADDR_TUNER3 = 0x07, /* STB3 in Spec v1.3*/ - CEC_LOGADDR_PLAYBACK2 = 0x08, /* DVD2 in Spec v1.3*/ - CEC_LOGADDR_RECDEV3 = 0x09, - CEC_LOGADDR_TUNER4 = 0x0A, /* RES1 in Spec v1.3*/ - CEC_LOGADDR_PLAYBACK3 = 0x0B, /* RES2 in Spec v1.3*/ - CEC_LOGADDR_RES3 = 0x0C, - CEC_LOGADDR_RES4 = 0x0D, - CEC_LOGADDR_FREEUSE = 0x0E, - CEC_LOGADDR_UNREGORBC = 0x0F -} cec_log_addr_t; - -typedef enum /* CEC Messages*/ -{ - CECOP_FEATURE_ABORT = 0x00, - CECOP_IMAGE_VIEW_ON = 0x04, - CECOP_TUNER_STEP_INCREMENT = 0x05, /* N/A*/ - CECOP_TUNER_STEP_DECREMENT = 0x06, /* N/A*/ - CECOP_TUNER_DEVICE_STATUS = 0x07, /* N/A*/ - CECOP_GIVE_TUNER_DEVICE_STATUS = 0x08, /* N/A*/ - CECOP_RECORD_ON = 0x09, /* N/A*/ - CECOP_RECORD_STATUS = 0x0A, /* N/A*/ - CECOP_RECORD_OFF = 0x0B, /* N/A*/ - CECOP_TEXT_VIEW_ON = 0x0D, - CECOP_RECORD_TV_SCREEN = 0x0F, /* N/A*/ - CECOP_GIVE_DECK_STATUS = 0x1A, - CECOP_DECK_STATUS = 0x1B, - CECOP_SET_MENU_LANGUAGE = 0x32, - CECOP_CLEAR_ANALOGUE_TIMER = 0x33, /* Spec 1.3A*/ - CECOP_SET_ANALOGUE_TIMER = 0x34, /* Spec 1.3A*/ - CECOP_TIMER_STATUS = 0x35, /* Spec 1.3A*/ - CECOP_STANDBY = 0x36, - CECOP_PLAY = 0x41, - CECOP_DECK_CONTROL = 0x42, - CECOP_TIMER_CLEARED_STATUS = 0x43, /* Spec 1.3A*/ - CECOP_USER_CONTROL_PRESSED = 0x44, - CECOP_USER_CONTROL_RELEASED = 0x45, - CECOP_GIVE_OSD_NAME = 0x46, - CECOP_SET_OSD_NAME = 0x47, - CECOP_SET_OSD_STRING = 0x64, - CECOP_SET_TIMER_PROGRAM_TITLE = 0x67, /* Spec 1.3A*/ - CECOP_SYSTEM_AUDIO_MODE_REQUEST = 0x70, /* Spec 1.3A*/ - CECOP_GIVE_AUDIO_STATUS = 0x71, /* Spec 1.3A*/ - CECOP_SET_SYSTEM_AUDIO_MODE = 0x72, /* Spec 1.3A*/ - CECOP_REPORT_AUDIO_STATUS = 0x7A, /* Spec 1.3A*/ - CECOP_GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D, /* Spec 1.3A*/ - CECOP_SYSTEM_AUDIO_MODE_STATUS = 0x7E, /* Spec 1.3A*/ - CECOP_ROUTING_CHANGE = 0x80, - CECOP_ROUTING_INFORMATION = 0x81, - CECOP_ACTIVE_SOURCE = 0x82, - CECOP_GIVE_PHYSICAL_ADDRESS = 0x83, - CECOP_REPORT_PHYSICAL_ADDRESS = 0x84, - CECOP_REQUEST_ACTIVE_SOURCE = 0x85, - CECOP_SET_STREAM_PATH = 0x86, - CECOP_DEVICE_VENDOR_ID = 0x87, - CECOP_VENDOR_COMMAND = 0x89, - CECOP_VENDOR_REMOTE_BUTTON_DOWN = 0x8A, - CECOP_VENDOR_REMOTE_BUTTON_UP = 0x8B, - CECOP_GIVE_DEVICE_VENDOR_ID = 0x8C, - CECOP_MENU_REQUEST = 0x8D, - CECOP_MENU_STATUS = 0x8E, - CECOP_GIVE_DEVICE_POWER_STATUS = 0x8F, - CECOP_REPORT_POWER_STATUS = 0x90, - CECOP_GET_MENU_LANGUAGE = 0x91, - CECOP_SELECT_ANALOGUE_SERVICE = 0x92, /* Spec 1.3A N/A*/ - CECOP_SELECT_DIGITAL_SERVICE = 0x93, /* N/A*/ - CECOP_SET_DIGITAL_TIMER = 0x97, /* Spec 1.3A*/ - CECOP_CLEAR_DIGITAL_TIMER = 0x99, /* Spec 1.3A*/ - CECOP_SET_AUDIO_RATE = 0x9A, /* Spec 1.3A*/ - CECOP_INACTIVE_SOURCE = 0x9D, /* Spec 1.3A*/ - CECOP_CEC_VERSION = 0x9E, /* Spec 1.3A*/ - CECOP_GET_CEC_VERSION = 0x9F, /* Spec 1.3A*/ - CECOP_VENDOR_COMMAND_WITH_ID = 0xA0, /* Spec 1.3A*/ - CECOP_CLEAR_EXTERNAL_TIMER = 0xA1, /* Spec 1.3A*/ - CECOP_SET_EXTERNAL_TIMER = 0xA2, /* Spec 1.3A*/ - CDCOP_HEADER = 0xF8, - CECOP_ABORT = 0xFF, - - CECOP_REPORT_SHORT_AUDIO = 0xA3, /* Spec 1.4*/ - CECOP_REQUEST_SHORT_AUDIO = 0xA4, /* Spec 1.4*/ - - CECOP_ARC_INITIATE = 0xC0, - CECOP_ARC_REPORT_INITIATED = 0xC1, - CECOP_ARC_REPORT_TERMINATED = 0xC2, - - CECOP_ARC_REQUEST_INITIATION = 0xC3, - CECOP_ARC_REQUEST_TERMINATION = 0xC4, - CECOP_ARC_TERMINATE = 0xC5, -} cec_opcode_t; - -typedef enum /* Operands for Opcode*/ -{ - CECAR_UNRECOG_OPCODE = 0x00, - CECAR_NOT_CORRECT_MODE, - CECAR_CANT_PROVIDE_SOURCE, - CECAR_INVALID_OPERAND, - CECAR_REFUSED -} cec_abor_reason_t; - -enum /* Operands for Opcode*/ -{ - CEC_POWERSTATUS_ON = 0x00, - CEC_POWERSTATUS_STANDBY = 0x01, - CEC_POWERSTATUS_STANDBY_TO_ON = 0x02, - CEC_POWERSTATUS_ON_TO_STANDBY = 0x03, -}; - -enum { - EVENT_RX_FRAME, - EVENT_ENUMERATE, -}; - -#define MAKE_SRCDEST( src, dest) (( src << 4) | dest ) - -#define MAX_CMD_SIZE 16 - -typedef struct -{ - char srcdestaddr; /*Source in upper nybble, dest in lower nybble*/ - char opcode; - char args[ MAX_CMD_SIZE ]; - char argcount; - char nextframeargcount; -} cec_framedata_t; - -struct cec_delayed_work { - struct delayed_work work; - int event; - void *data; -}; - -typedef struct -{ - struct workqueue_struct *workqueue; - wait_queue_head_t wait; - int busfree; - int tx_done; - int address_phy; - int address_logic; - int powerstatus; -} cec_t; - -//#define DEBUG -#ifdef DEBUG -#define CECDBG(format, ...) \ - printk(KERN_INFO format, ## __VA_ARGS__) -#else -#define CECDBG(format, ...) -#endif -#endif diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hdcp.c deleted file mode 100755 index b28dd0e2578d..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hdcp.c +++ /dev/null @@ -1,286 +0,0 @@ -#include -#include "rk3036_hdmi.h" -#include "rk3036_hdmi_hw.h" -#include "rk3036_hdcp.h" -int is_1b_03_test(void) -{ - int reg_value; - int reg_val_1; - - hdmi_readl(hdmi_dev, 0x58, ®_value); - hdmi_readl(hdmi_dev, 0xc3, ®_val_1); - - if (reg_value != 0) { - if ((reg_val_1 & 0x40) == 0) - return 1; - } - return 0; -} - -void rk3036_set_colorbar(int enable) -{ - static int display_mask; - int reg_value; - int tmds_clk; - - tmds_clk = hdmi_dev->driver.tmdsclk; - if (enable) { - if (!display_mask) { - if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) { - hdmi_readl(hdmi_dev, SYS_CTRL, ®_value); - hdmi_msk_reg(hdmi_dev, SYS_CTRL, - m_REG_CLK_SOURCE, - v_REG_CLK_SOURCE_SYS); - hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00); - hdmi_writel(hdmi_dev, SYS_CTRL, reg_value); - } else { - hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00); - } - display_mask = 1; - } - } else { - if (display_mask) { - if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) { - hdmi_readl(hdmi_dev, SYS_CTRL, ®_value); - hdmi_msk_reg(hdmi_dev, SYS_CTRL, - m_REG_CLK_SOURCE, - v_REG_CLK_SOURCE_SYS); - hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10); - hdmi_writel(hdmi_dev, SYS_CTRL, reg_value); - } else { - hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10); - } - display_mask = 0; - } - } -} - -void rk3036_hdcp_disable(void) -{ - int reg_value; - int tmds_clk; - - tmds_clk = hdmi_dev->driver.tmdsclk; - if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) { - hdmi_readl(hdmi_dev, SYS_CTRL, ®_value); - hdmi_msk_reg(hdmi_dev, SYS_CTRL, - m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS); - } - - /* Diable HDCP Interrupt*/ - hdmi_writel(hdmi_dev, HDCP_INT_MASK1, 0x00); - /* Stop and Reset HDCP*/ - hdmi_msk_reg(hdmi_dev, HDCP_CTRL1, - m_AUTH_START | m_AUTH_STOP | m_HDCP_RESET, - v_AUTH_START(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1)); - - if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) - hdmi_writel(hdmi_dev, SYS_CTRL, reg_value); -} - -int rk3036_hdcp_key_check(struct hdcp_keys *key) -{ - int i = 0; - - DBG("HDCP: check hdcp key\n"); - /*check 40 private key */ - for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) { - if (key->devicekey[i] != 0x00) - return HDCP_KEY_VALID; - } - /*check aksv*/ - for (i = 0; i < 5; i++) { - if (key->ksv[i] != 0x00) - return HDCP_KEY_VALID; - } - - return HDCP_KEY_INVALID; -} -int rk3036_hdcp_load_key2mem(struct hdcp_keys *key) -{ - int i; - - DBG("HDCP: rk3036_hdcp_load_key2mem start\n"); - /* Write 40 private key*/ - for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) - hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->devicekey[i]); - /* Write 1st aksv*/ - for (i = 0; i < 5; i++) - hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->ksv[i]); - /* Write 2nd aksv*/ - for (i = 0; i < 5; i++) - hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->ksv[i]); - DBG("HDCP: rk3036_hdcp_load_key2mem end\n"); - return HDCP_OK; -} - -int rk3036_hdcp_start_authentication(void) -{ - int temp; - int retry = 0; - int tmds_clk; - - tmds_clk = hdmi_dev->driver.tmdsclk; - if (hdcp->keys == NULL) { - HDCP_WARN("HDCP: key is not loaded\n"); - return HDCP_KEY_ERR; - } - if (rk3036_hdcp_key_check(hdcp->keys) == HDCP_KEY_INVALID) { - HDCP_WARN("loaded HDCP key is incorrect\n"); - return HDCP_KEY_ERR; - } - if (tmds_clk > (HDMI_SYS_FREG_CLK << 2)) { - /*Select TMDS CLK to configure regs*/ - hdmi_msk_reg(hdmi_dev, SYS_CTRL, - m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS); - } else { - hdmi_msk_reg(hdmi_dev, SYS_CTRL, - m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS); - } - hdmi_writel(hdmi_dev, HDCP_TIMER_100MS, 0x28); - hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp); - while ((temp & m_KEY_READY) == 0) { - if (retry > 1000) { - HDCP_WARN("HDCP: loaded key error\n"); - return HDCP_KEY_ERR; - } - rk3036_hdcp_load_key2mem(hdcp->keys); - msleep(1); - hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp); - retry++; - } - /*Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b)*/ - retry = hdmi_dev->hclk_rate/(HDCP_DDC_CLK << 2); - hdmi_writel(hdmi_dev, DDC_CLK_L, retry & 0xFF); - hdmi_writel(hdmi_dev, DDC_CLK_H, (retry >> 8) & 0xFF); - hdmi_writel(hdmi_dev, HDCP_CTRL2, 0x67); - /*Enable interrupt*/ - hdmi_writel(hdmi_dev, HDCP_INT_MASK1, - m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE | - m_INT_AUTH_SUCCESS | m_INT_AUTH_READY); - hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x00); - /*Start authentication*/ - hdmi_msk_reg(hdmi_dev, HDCP_CTRL1, - m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE | - m_AUTH_STOP | m_HDCP_RESET, - v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) | - v_ADVANED_ENABLE(0) | v_AUTH_STOP(0) | v_HDCP_RESET(0)); - - if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) { - hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, - v_REG_CLK_SOURCE_TMDS); - } - return HDCP_OK; -} - -int rk3036_hdcp_stop_authentication(void) -{ - hdmi_msk_reg(hdmi_dev, SYS_CTRL, - m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS); - hdmi_writel(hdmi_dev, DDC_CLK_L, 0x1c); - hdmi_writel(hdmi_dev, DDC_CLK_H, 0x00); - hdmi_writel(hdmi_dev, HDCP_CTRL2, 0x08); - hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x06); - hdmi_writel(hdmi_dev, HDCP_CTRL1, 0x02); - return 0; - /*hdmi_writel(HDCP_CTRL1, 0x0a);*/ -} -#if 0 -int rk3036_hdcp_check_bksv(void) -{ - int i, j; - char temp = 0, bksv[5]; - char *invalidkey; - - for (i = 0; i < 5; i++) { - hdmi_readl(HDCP_KSV_BYTE0 + (4 - i), &temp); - bksv[i] = temp & 0xFF; - } - DBG("bksv is 0x%02x%02x%02x%02x%02x", - bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]); - - temp = 0; - for (i = 0; i < 5; i++) { - for (j = 0; j < 8; j++) { - if (bksv[i] & 0x01) - temp++; - bksv[i] >>= 1; - } - } - if (temp != 20) - return HDCP_KSV_ERR; - for (i = 0; i < hdcp->invalidkey; i++) { - invalidkey = hdcp->invalidkeys + i*5; - if (memcmp(bksv, invalidkey, 5) == 0) { - HDCP_WARN("HDCP:BKSV was revocated!\n"); - hdmi_msk_reg(HDCP_CTRL1, m_BKSV_INVALID | m_ENCRYPT_ENABLE, - v_BKSV_INVALID(1) | v_ENCRYPT_ENABLE(1)); - return HDCP_KSV_ERR; - } - } - hdmi_msk_reg(HDCP_CTRL1, m_BKSV_VALID | m_ENCRYPT_ENABLE, - v_BKSV_VALID(1) | v_ENCRYPT_ENABLE(1)); - return HDCP_OK; -} -#endif - -int rk3036_hdcp_error(int value) -{ - if (value & 0x80) - HDCP_WARN("Timed out waiting for downstream repeater\n"); - else if (value & 0x40) - HDCP_WARN("Too many devices connected to repeater tree\n"); - else if (value & 0x20) - HDCP_WARN("SHA-1 hash check of BKSV list failed\n"); - else if (value & 0x10) - HDCP_WARN("SHA-1 hash check of BKSV list failed\n"); - else if (value & 0x08) - HDCP_WARN("DDC channels no acknowledge\n"); - else if (value & 0x04) - HDCP_WARN("Pj mismatch\n"); - else if (value & 0x02) - HDCP_WARN("Ri mismatch\n"); - else if (value & 0x01) - HDCP_WARN("Bksv is wrong\n"); - else - return 0; - return 1; -} -void rk3036_hdcp_interrupt(char *status1, char *status2) -{ - int interrupt1 = 0; - int interrupt2 = 0; - int temp = 0; - int tmds_clk; - - tmds_clk = hdmi_dev->driver.tmdsclk; - hdmi_readl(hdmi_dev, HDCP_INT_STATUS1, &interrupt1); - hdmi_readl(hdmi_dev, HDCP_INT_STATUS2, &interrupt2); - - if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) - hdmi_msk_reg(hdmi_dev, SYS_CTRL, - m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS); - - if (interrupt1) { - hdmi_writel(hdmi_dev, HDCP_INT_STATUS1, interrupt1); - if (interrupt1 & m_INT_HDCP_ERR) { - hdmi_readl(hdmi_dev, HDCP_ERROR, &temp); - HDCP_WARN("HDCP: Error reg 0x65 = 0x%02x\n", temp); - rk3036_hdcp_error(temp); - hdmi_writel(hdmi_dev, HDCP_ERROR, temp); - } - } - if (interrupt2) - hdmi_writel(hdmi_dev, HDCP_INT_STATUS2, interrupt2); - - *status1 = interrupt1; - *status2 = interrupt2; - - if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) - hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, - v_REG_CLK_SOURCE_TMDS); -/* - hdmi_readl(HDCP_ERROR, &temp); - DBG("HDCP: Error reg 0x65 = 0x%02x\n", temp); -*/ -} diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.c deleted file mode 100755 index 3228b52d7eed..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.c +++ /dev/null @@ -1,887 +0,0 @@ -#include -#include -#include -#include -#include "rk3036_hdmi.h" -#include "rk3036_hdmi_hw.h" -static unsigned int rk3036_hdmi_support_vic[] = { - HDMI_720X480P_60HZ_VIC, - HDMI_720X480I_60HZ_VIC, - HDMI_720X576P_50HZ_VIC, - HDMI_720X576I_50HZ_VIC, - HDMI_1280X720P_50HZ_VIC, - HDMI_1280X720P_60HZ_VIC, - HDMI_1920X1080P_50HZ_VIC, - HDMI_1920X1080I_50HZ_VIC, - HDMI_1920X1080P_60HZ_VIC, - HDMI_1920X1080I_60HZ_VIC -}; -static int __maybe_unused rk3036_hdmi_show_reg(struct hdmi *hdmi_drv) -{ - int i = 0; - u32 val = 0; - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); - - printk("\n>>>rk3036_ctl reg"); - for (i = 0; i < 16; i++) - printk(" %2x", i); - - printk("\n-----------------------------------------------------------------"); - - for (i = 0; i <= PHY_PRE_DIV_RATIO; i++) { - hdmi_readl(hdmi_dev, i, &val); - if (i % 16 == 0) - printk("\n>>>rk3036_ctl %2x:", i); - printk(" %02x", val); - } - printk("\n-----------------------------------------------------------------\n"); - - return 0; -} - -static inline void delay100us(void) -{ - msleep(1); -} - -static void rk3036_hdmi_av_mute(struct hdmi *hdmi_drv, bool enable) -{ - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); - if (enable) { - hdmi_msk_reg(hdmi_dev, AV_MUTE, - m_AVMUTE_CLEAR | m_AVMUTE_ENABLE, - v_AVMUTE_CLEAR(0) | v_AVMUTE_ENABLE(1)); - } else { - hdmi_msk_reg(hdmi_dev, AV_MUTE, - m_AVMUTE_CLEAR | m_AVMUTE_ENABLE, - v_AVMUTE_CLEAR(1) | v_AVMUTE_ENABLE(0)); - } - hdmi_writel(hdmi_dev, PACKET_SEND_AUTO, m_PACKET_GCP_EN); -} - -static void rk3036_hdmi_sys_power(struct hdmi *hdmi_drv, bool enable) -{ - 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 rk3036_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode) -{ - 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_drv->pwr_mode, mode); - rk3036_hdmi_sys_power(hdmi_drv, false); - if (hdmi_drv->data->soc_type == HDMI_SOC_RK3036) { - hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x6f); - hdmi_writel(hdmi_dev, PHY_DRIVER, 0xbb); - } - else if (hdmi_drv->data->soc_type == HDMI_SOC_RK312X) { - hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x5f); - hdmi_writel(hdmi_dev, PHY_DRIVER, 0xaa); - } - hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x15); - hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x14); - hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x10); - hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x0f); - hdmi_writel(hdmi_dev, 0xce, 0x00); - hdmi_writel(hdmi_dev, 0xce, 0x01); - rk3036_hdmi_sys_power(hdmi_drv, true); - break; - case LOWER_PWR: - hdmi_dbg(hdmi_drv->dev, - "%s change pwr_mode LOWER_PWR pwr_mode = %d, mode = %d\n", - __func__, hdmi_drv->pwr_mode, mode); - rk3036_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, 0x17); - break; - default: - hdmi_dbg(hdmi_drv->dev, "unkown rk3036 hdmi pwr mode %d\n", - mode); - } - - hdmi_drv->pwr_mode = mode; -} - -int rk3036_hdmi_detect_hotplug(struct hdmi *hdmi_drv) -{ - int value = 0; - 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) - return HDMI_HPD_ACTIVED; - else if (value) - return HDMI_HPD_INSERT; - else - return HDMI_HPD_REMOVED; -} -int rk3036_hdmi_insert(struct hdmi *hdmi_drv) -{ - rk3036_hdmi_set_pwr_mode(hdmi_drv, NORMAL); - return 0; -} - - -int rk3036_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; - 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_dev->hclk_rate >> 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_EDID_READY); - - for (trytime = 0; trytime < 10; trytime++) { - checksum = 0; - 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); - - printk("0x%02x ", c); -#endif - } - - if ((checksum & 0xff) == 0) { - ret = 0; - hdmi_dbg(hdmi_drv->dev, - "[%s] edid read sucess\n", __func__); - break; - } - } - } - /*close edid irq*/ - hdmi_writel(hdmi_dev, INTERRUPT_MASK1, 0); - /* clear EDID interrupt reg */ - hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, - m_INT_EDID_READY); - - enable_irq(hdmi_drv->irq); - - return ret; -} - -static const char coeff_csc[][24] = { - /*YUV2RGB:601 SD mode(Y[16:235],UV[16:240],RGB[0:255]): - R = 1.164*Y +1.596*V - 204 - G = 1.164*Y - 0.391*U - 0.813*V + 154 - B = 1.164*Y + 2.018*U - 258*/ - { - 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc, - 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a, - 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02}, - - /*YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]): - R = Y + 1.402*V - 248 - G = Y - 0.344*U - 0.714*V + 135 - B = Y + 1.772*U - 227*/ - { - 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8, - 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87, - 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3}, - /*YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]): - R = 1.164*Y +1.793*V - 248 - G = 1.164*Y - 0.213*U - 0.534*V + 77 - B = 1.164*Y + 2.115*U - 289*/ - { - 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8, - 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d, - 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21}, - /*RGB2YUV:601 SD mode: - Cb = -0.291G - 0.148R + 0.439B + 128 - Y = 0.504G + 0.257R + 0.098B + 16 - Cr = -0.368G + 0.439R - 0.071B + 128*/ - { - /*0x11, 0x78, 0x01, 0xc1, 0x10, 0x48, 0x00, 0x80, - 0x02, 0x04, 0x01, 0x07, 0x00, 0x64, 0x00, 0x10, - 0x11, 0x29, 0x10, 0x97, 0x01, 0xc1, 0x00, 0x80*/ - - /*0x11,0x4b,0x01,0x8a,0x10,0x3f,0x00,0x80, - 0x01,0xbb,0x00,0xe2,0x00,0x56,0x00,0x1d, - 0x11,0x05,0x10,0x85,0x01,0x8a,0x00,0x80*/ - - 0x11,0x5f,0x01,0x82,0x10,0x23,0x00,0x80, - 0x02,0x1c,0x00,0xa1,0x00,0x36,0x00,0x1e, - 0x11,0x29,0x10,0x59,0x01,0x82,0x00,0x80 - }, - - /*RGB2YUV:709 HD mode: - Cb = - 0.338G - 0.101R + 0.439B + 128 - Y = 0.614G + 0.183R + 0.062B + 16 - Cr = - 0.399G + 0.439R - 0.040B + 128*/ - { - 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80, - 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10, - 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80 - }, - /*RGB[0:255]2RGB[16:235]: - R' = R x (235-16)/255 + 16; - G' = G x (235-16)/255 + 16; - B' = B x (235-16)/255 + 16;*/ - { - 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10, - 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10}, -}; -static int rk3036_hdmi_video_csc(struct hdmi *hdmi_drv, - struct hdmi_video_para *vpara) -{ - int value,i,csc_mode,c0_c2_change,auto_csc,csc_enable; - const char *coeff = NULL; - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); - /* Enable or disalbe color space convert */ - hdmi_dbg(hdmi_drv->dev, "[%s] input_color=%d,output_color=%d\n", - __func__, vpara->input_color, vpara->output_color); - if (vpara->input_color == vpara->output_color) { - if ((vpara->input_color >= VIDEO_INPUT_COLOR_YCBCR444) || - ((vpara->input_color == VIDEO_INPUT_COLOR_RGB) && - (vpara->color_limit_range == COLOR_LIMIT_RANGE_0_255))) { - value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1); - hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); - hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, - m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, - v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) | - v_VIDEO_C0_C2_EXCHANGE(C0_C2_CHANGE_DISABLE)); - return 0; - } else if ((vpara->input_color == VIDEO_INPUT_COLOR_RGB) && - (vpara->color_limit_range == COLOR_LIMIT_RANGE_16_235)) { - csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT; - auto_csc = AUTO_CSC_DISABLE; - c0_c2_change = C0_C2_CHANGE_DISABLE; - csc_enable = v_CSC_ENABLE; - } - } - - switch (vpara->vic) { - case HDMI_720x480i_60Hz_4_3: - case HDMI_720x576i_50Hz_4_3: - case HDMI_720x480p_60Hz_4_3: - case HDMI_720x576p_50Hz_4_3: - case HDMI_720x480i_60Hz_16_9: - case HDMI_720x576i_50Hz_16_9: - case HDMI_720x480p_60Hz_16_9: - case HDMI_720x576p_50Hz_16_9: - if (vpara->input_color == VIDEO_INPUT_COLOR_RGB - && vpara->output_color >= VIDEO_OUTPUT_YCBCR444) { - csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT; - auto_csc = AUTO_CSC_DISABLE; - c0_c2_change = C0_C2_CHANGE_DISABLE; - csc_enable = v_CSC_ENABLE; - } else if (vpara->input_color >= VIDEO_OUTPUT_YCBCR444 - && vpara->output_color == VIDEO_OUTPUT_RGB444) { -#ifdef AUTO_DEFINE_CSC - csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT; - auto_csc = AUTO_CSC_ENABLE; - c0_c2_change = C0_C2_CHANGE_DISABLE; - csc_enable = v_CSC_DISABLE; -#else - csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT; - auto_csc = AUTO_CSC_DISABLE; - c0_c2_change = C0_C2_CHANGE_ENABLE; - csc_enable = v_CSC_ENABLE; -#endif - } - break; - default: - if (vpara->input_color == VIDEO_INPUT_COLOR_RGB - && vpara->output_color >= VIDEO_OUTPUT_YCBCR444) { - csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT; - auto_csc = AUTO_CSC_DISABLE; - c0_c2_change = C0_C2_CHANGE_DISABLE; - csc_enable = v_CSC_ENABLE; - } else if (vpara->input_color >= VIDEO_OUTPUT_YCBCR444 - && vpara->output_color == VIDEO_OUTPUT_RGB444) { -#ifdef AUTO_DEFINE_CSC - csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT; - auto_csc = AUTO_CSC_ENABLE; - c0_c2_change = C0_C2_CHANGE_DISABLE; - csc_enable = v_CSC_DISABLE; -#else - csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;//CSC_ITU709_16_235_TO_RGB_0_255_8BIT; - auto_csc = AUTO_CSC_DISABLE; - c0_c2_change = C0_C2_CHANGE_ENABLE; - csc_enable = v_CSC_ENABLE; -#endif - } - break; - } - - coeff = coeff_csc[csc_mode]; - for (i = 0; i < 24; i++) { - hdmi_writel(hdmi_dev, VIDEO_CSC_COEF+i, coeff[i]); - } - - value = v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1); - hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); - hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, - m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, - v_VIDEO_AUTO_CSC(auto_csc) | v_VIDEO_C0_C2_EXCHANGE(c0_c2_change)); - -#if 0 - if (vpara->input_color != vpara->output_color) { - if(vpara->input_color == VIDEO_INPUT_COLOR_RGB) {/*rgb2yuv*/ - coeff = coeff_csc[3]; - for (i = 0; i < 24; i++) { - hdmi_writel(hdmi_dev, VIDEO_CSC_COEF+i, coeff[i]); - } - - value = v_SOF_DISABLE | v_CSC_ENABLE; - hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); - hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, - m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, - v_VIDEO_AUTO_CSC(0) | v_VIDEO_C0_C2_EXCHANGE(1)); - } else {/*yuv2rgb*/ -#ifdef AUTO_DEFINE_CSC - value = v_SOF_DISABLE | v_CSC_DISABLE; - hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); - hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, - m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, - v_VIDEO_AUTO_CSC(1) | v_VIDEO_C0_C2_EXCHANGE(1)); -#else - if(hdmi_drv->lcdc->cur_screen->mode.xres <= 576)/*x <= 576,REC-601*/ { - coeff = coeff_csc[0]; - printk("xres<=576,xres=%d\n",hdmi_drv->lcdc->cur_screen->mode.xres); - } else/*x > 576,REC-709*/{ - coeff = coeff_csc[2]; - printk("xres>576,xres=%d\n",hdmi_drv->lcdc->cur_screen->mode.xres); - } - for (i = 0; i < 24; i++) { - hdmi_writel(hdmi_dev, VIDEO_CSC_COEF+i, coeff[i]); - } - - value = v_SOF_DISABLE | v_CSC_ENABLE; - hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); - hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, - m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, - v_VIDEO_AUTO_CSC(0) | v_VIDEO_C0_C2_EXCHANGE(0)); -#endif - } - } else { - if(vpara->input_color == VIDEO_INPUT_COLOR_RGB) {/*rgb[0:255]->rbg[16:235]*/ - coeff = coeff_csc[5]; - for (i = 0; i < 24; i++) { - hdmi_writel(hdmi_dev, VIDEO_CSC_COEF+i, coeff[i]); - } - - value = v_SOF_DISABLE | v_CSC_ENABLE; - hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); - hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, - m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, - v_VIDEO_AUTO_CSC(0) | v_VIDEO_C0_C2_EXCHANGE(1)); - } else { - value = v_SOF_DISABLE; - hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); - hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, - m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, - v_VIDEO_AUTO_CSC(0) | v_VIDEO_C0_C2_EXCHANGE(1)); - } - } -#endif - return 0; -} - -static void rk3036_hdmi_config_avi(struct hdmi *hdmi_drv, - unsigned char vic, unsigned char output_color) -{ - int i; - int avi_color_mode; - 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(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); - info[0] = 0x82; - info[1] = 0x02; - info[2] = 0x0D; - info[3] = info[0] + info[1] + info[2]; - - if (output_color == VIDEO_OUTPUT_RGB444) - avi_color_mode = AVI_COLOR_MODE_RGB; - else if(output_color == VIDEO_OUTPUT_YCBCR444) - avi_color_mode = AVI_COLOR_MODE_YCBCR444; - else if(output_color == VIDEO_OUTPUT_YCBCR422) - avi_color_mode = AVI_COLOR_MODE_YCBCR422; - - info[4] = (avi_color_mode << 5); - 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; - if ((vic == HDMI_720X480I_60HZ_VIC) || (vic == HDMI_720X576I_50HZ_VIC)) - info[8] = 1; - else - info[8] = 0; - - /* Calculate AVI InfoFrame ChecKsum */ - for (i = 4; i < SIZE_AVI_INFOFRAME; i++) - info[3] += info[i]; - - info[3] = 0x100 - info[3]; - - for (i = 0; i < SIZE_AVI_INFOFRAME; i++) - hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]); -} - -static int rk3036_hdmi_config_video(struct hdmi *hdmi_drv, - struct hdmi_video_para *vpara) -{ - struct fb_videomode *mode; - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); - int val; - - hdmi_dbg(hdmi_drv->dev, "[%s]\n", __func__); - - if (vpara == NULL) { - hdmi_err(hdmi_drv->dev, "[%s] input parameter error\n", - __func__); - return -1; - } - - if (hdmi_drv->data->soc_type == HDMI_SOC_RK3036) { - vpara->input_color = VIDEO_INPUT_COLOR_RGB; - /*vpara->output_color = VIDEO_OUTPUT_RGB444;*//*rk3036 vop only can output rgb fmt*/ - } else if (hdmi_drv->data->soc_type == HDMI_SOC_RK312X) { - /* rk3128 vop can output yuv444 fmt */ - /*if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444) - vpara->output_color = VIDEO_OUTPUT_YCBCR444; - else - vpara->output_color = VIDEO_OUTPUT_RGB444;*/ - } - -/* if (hdmi_drv->pwr_mode == LOWER_PWR) - rk3036_hdmi_set_pwr_mode(hdmi_drv, NORMAL); -*/ - /* Disable video and audio output */ - hdmi_msk_reg(hdmi_dev, AV_MUTE, - m_AUDIO_MUTE | m_VIDEO_BLACK, - v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); - - /* 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); - val = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | - v_VIDEO_OUTPUT_FORMAT(vpara->output_color & 0x3) | - v_VIDEO_INPUT_CSP(vpara->input_color && 0x1); - hdmi_writel(hdmi_dev, VIDEO_CONTRL2,val); - - /* Set HDMI Mode */ - hdmi_writel(hdmi_dev, HDCP_CTRL, v_HDMI_DVI(vpara->output_mode)); - - /* Enable or disalbe color space convert */ - rk3036_hdmi_video_csc(hdmi_drv, vpara); - - /* Set ext video timing */ -#if 1 - hdmi_writel(hdmi_dev, VIDEO_TIMING_CTL, 0); - mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); - if (mode == NULL) { - hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __func__, - vpara->vic); - return -ENOENT; - } - hdmi_drv->tmdsclk = mode->pixclock; -#else - value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode); - if (mode->sync & FB_SYNC_HOR_HIGH_ACT) - value |= v_HSYNC_POLARITY(1); - if (mode->sync & FB_SYNC_VERT_HIGH_ACT) - value |= v_VSYNC_POLARITY(1); - 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(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(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(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(hdmi_dev, VIDEO_EXT_VBLANK, value & 0xFF); - - 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(hdmi_dev, VIDEO_EXT_VDELAY, value & 0xFF); - - value = mode->vsync_len; - hdmi_writel(hdmi_dev, VIDEO_EXT_VDURATION, value & 0xFF); -#endif - if (vpara->output_mode == OUTPUT_HDMI) { - rk3036_hdmi_config_avi(hdmi_drv, vpara->vic, - vpara->output_color); - hdmi_dbg(hdmi_drv->dev, "[%s] sucess output HDMI.\n", __func__); - } else { - hdmi_dbg(hdmi_drv->dev, "[%s] sucess output DVI.\n", __func__); - } - - /* 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); - - return 0; -} - -static void rk3036_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]; - for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++) - info[3] += info[i]; - - info[3] = 0x100 - info[3]; - - 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 rk3036_hdmi_config_audio(struct hdmi *hdmi_drv, - struct hdmi_audio *audio) -{ - int rate, N, channel, mclk_fs; - 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) - channel = I2S_CHANNEL_3_4; - 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_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(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(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); - rk3036_hdmi_config_aai(hdmi_drv); - - return 0; -} - -void rk3036_hdmi_control_output(struct hdmi *hdmi_drv, int enable) -{ - int mutestatus = 0; - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); - if (hdmi_drv->uboot_logo) { - hdmi_drv->uboot_logo = 0; - return; - } - - if (enable) { - if (hdmi_drv->pwr_mode == LOWER_PWR) - rk3036_hdmi_set_pwr_mode(hdmi_drv, NORMAL); - - rk3036_hdmi_sys_power(hdmi_drv, true); - rk3036_hdmi_sys_power(hdmi_drv, false); - delay100us(); - rk3036_hdmi_sys_power(hdmi_drv, true); - hdmi_writel(hdmi_dev, 0xce, 0x00); - delay100us(); - hdmi_writel(hdmi_dev, 0xce, 0x01); - - hdmi_readl(hdmi_dev, AV_MUTE, &mutestatus); - if (mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) { - hdmi_msk_reg(hdmi_dev, AV_MUTE, - m_AUDIO_MUTE | m_VIDEO_BLACK, - v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); - } - rk3036_hdmi_av_mute(hdmi_drv, 0); - } else { - hdmi_msk_reg(hdmi_dev, AV_MUTE, - m_AUDIO_MUTE | m_VIDEO_BLACK, - v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); - rk3036_hdmi_av_mute(hdmi_drv, 1); - msleep(100); - rk3036_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR); - } -} - -int rk3036_hdmi_removed(struct hdmi *hdmi_drv) -{ - dev_info(hdmi_drv->dev, "Removed.\n"); - if (hdmi_drv->hdcp_power_off_cb) - hdmi_drv->hdcp_power_off_cb(); - rk3036_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR); - - return HDMI_ERROR_SUCESS; -} - -void rk3036_hdmi_irq(struct hdmi *hdmi_drv) -{ - u32 interrupt = 0; - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); - hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &interrupt); - if(interrupt) { - hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt); - dev_info(hdmi_drv->dev, "Clear edid irq.\n"); - } - - hdmi_readl(hdmi_dev, HDMI_STATUS, &interrupt); - if(interrupt) { - hdmi_writel(hdmi_dev, HDMI_STATUS, interrupt); - } - if (interrupt & m_INT_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(20)); - - }/*plug out*/ - - if (hdmi_drv->hdcp_irq_cb) - hdmi_drv->hdcp_irq_cb(0); - if (hdmi_drv->cec_irq) - hdmi_drv->cec_irq(); -} - -static void rk3036_hdmi_reset(struct hdmi *hdmi_drv) -{ - u32 val = 0; - u32 msk = 0; - 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(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(hdmi_dev, SYS_CTRL, msk, val); - - rk3036_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR); -} -static int rk3036_hdmi_debug(struct hdmi *hdmi_drv,int cmd) -{ - switch(cmd) { - case 0: - printk("%s[%d]:cmd=%d\n",__func__,__LINE__,cmd); - rk3036_hdmi_irq(hdmi_drv); - break; - case 1: - printk("%s[%d]:cmd=%d\n",__func__,__LINE__,cmd); - break; - default: - printk("%s[%d]:cmd=%d\n",__func__,__LINE__,cmd); - break; - } - return 0; -} - -static struct rk_hdmi_drv_ops hdmi_drv_ops = { - .hdmi_debug = rk3036_hdmi_debug, -}; - -int rk3036_hdmi_initial(struct hdmi *hdmi_drv) -{ - int rc = HDMI_ERROR_SUCESS; - - hdmi_drv->pwr_mode = NORMAL; - hdmi_drv->remove = rk3036_hdmi_removed; - hdmi_drv->control_output = rk3036_hdmi_control_output; - hdmi_drv->config_video = rk3036_hdmi_config_video; - hdmi_drv->config_audio = rk3036_hdmi_config_audio; - hdmi_drv->detect_hotplug = rk3036_hdmi_detect_hotplug; - hdmi_drv->read_edid = rk3036_hdmi_read_edid; - hdmi_drv->insert = rk3036_hdmi_insert; - hdmi_drv->ops = &hdmi_drv_ops; - hdmi_drv->support_vic = rk3036_hdmi_support_vic; - hdmi_drv->support_vic_num = ARRAY_SIZE(rk3036_hdmi_support_vic); - - if (!hdmi_drv->uboot_logo) { - rk3036_hdmi_reset_pclk(); - rk3036_hdmi_reset(hdmi_drv); - } else { - hdmi_drv->hotplug = rk3036_hdmi_detect_hotplug(hdmi_drv); - if (hdmi_drv->hotplug == HDMI_HPD_REMOVED) { - rk3036_hdmi_removed(hdmi_drv); - hdmi_drv->state = HDMI_SLEEP; - hdmi_drv->lcdc->uboot_logo = 0; - hdmi_drv->uboot_logo = 0; - } - } - if (hdmi_drv->hdcp_power_on_cb) - rc = hdmi_drv->hdcp_power_on_cb(); - - return rc; -} diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.h deleted file mode 100755 index 6032b96cf317..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.h +++ /dev/null @@ -1,417 +0,0 @@ -#ifndef _RK3036_HDMI_HW_H -#define _RK3036_HDMI_HW_H - -#include -#include - -enum PWR_MODE { - NORMAL, - LOWER_PWR, -}; -enum { - OUTPUT_DVI = 0, - OUTPUT_HDMI -}; - -/* C0 C2 Change */ -enum { - C0_C2_CHANGE_ENABLE, /* enable c0 c2 change*/ - C0_C2_CHANGE_DISABLE /* disable c0 c2 change*/ -}; - -/* Auto CSC mode enable */ -enum { - AUTO_CSC_DISABLE, /* disable auto csc*/ - AUTO_CSC_ENABLE /* enable auto csc*/ -}; - - -/* Color Limit Range */ -enum { - COLOR_LIMIT_RANGE_0_255, /* Color Limit Range 0 To 255*/ - COLOR_LIMIT_RANGE_16_235, /* Color Limit Range 16 To 235*/ -}; -/* Color Space Convertion Mode */ -enum { - CSC_ITU601_16_235_TO_RGB_0_255_8BIT, /* YCbCr 16-235 input to RGB 0-255 output according BT601 that is 8bit clolor depth */ - CSC_ITU601_0_255_TO_RGB_0_255_8BIT, /* YCbCr 0-255 input to RGB 0-255 output according BT601 that is 8bit clolor depth */ - CSC_ITU709_16_235_TO_RGB_0_255_8BIT, /* YCbCr 16-235 input to RGB 0-255 output according BT709 that is 8bit clolor depth */ - CSC_RGB_0_255_TO_ITU601_16_235_8BIT, /* RGB 0-255 input to YCbCr 16-235 output according BT601 that is 8bit clolor depth */ - CSC_RGB_0_255_TO_ITU709_16_235_8BIT, /* RGB 0-255 input to YCbCr 16-235 output accroding BT709 that is 8bit clolor depth */ - CSC_RGB_0_255_TO_RGB_16_235_8BIT, /* RGB 0-255 input to RGB 16-235 output that is 8bit clolor depth */ -}; - - -#define AUTO_DEFINE_CSC -#ifdef RK616_USE_MCLK_12M -#define HDMI_SYS_FREG_CLK 12000000 -#else -#define HDMI_SYS_FREG_CLK 11289600 -#endif - -#define HDMI_SCL_RATE (100*1000) -#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 m_VIDEO_INPUT_CSP (1 << 0) -#define v_VIDEO_OUTPUT_FORMAT(n) (((n)&0x3) << 6) -#define v_VIDEO_INPUT_BITS(n) (n << 4) -#define v_VIDEO_INPUT_CSP(n) (n << 0) - -enum { - VIDEO_INPUT_12BITS = 0, - VIDEO_INPUT_10BITS, - VIDEO_INPUT_REVERT, - VIDEO_INPUT_8BITS -}; -#define VIDEO_CONTRL 0x03 -#define m_VIDEO_AUTO_CSC (1 << 7) -#define v_VIDEO_AUTO_CSC(n) (n << 7) -#define m_VIDEO_C0_C2_EXCHANGE (1 << 0) -#define v_VIDEO_C0_C2_EXCHANGE(n) (n << 0) - - -#define VIDEO_CONTRL3 0x04 -#define m_COLOR_DEPTH_NOT_INDICATED (1 << 4) -#define m_SOF (1 << 3) -#define m_COLOR_RANGE (1 << 2) -#define m_CSC (1 << 0) -#define v_COLOR_DEPTH_NOT_INDICATED(n) ((n) << 4) /*1: Force GCP CD[3:0] zero - 0: GCP CD[3:0] according - color depth*/ -#define v_SOF_ENABLE (0 << 3) -#define v_SOF_DISABLE (1 << 3) -#define v_COLOR_RANGE_FULL (1 << 2) -#define v_COLOR_RANGE_LIMITED (0 << 2) -#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_AVMUTE_CLEAR(n) (n << 7) -#define v_AVMUTE_ENABLE(n) (n << 6) -#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 VIDEO_CSC_COEF 0x18 - - -#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 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 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 DDC_CLK_L 0x4b -#define DDC_CLK_H 0x4c - -#define EDID_SEGMENT_POINTER 0x4d -#define EDID_WORD_ADDR 0x4e -#define EDID_FIFO_OFFSET 0x4f -#define EDID_FIFO_ADDR 0x50 - - -#define PACKET_SEND_MANUAL 0x9c -#define PACKET_SEND_AUTO 0x9d - #define m_PACKET_GCP_EN (1 << 7) -/* CONTROL_PACKET_BUF_INDEX */ -#define CONTROL_PACKET_BUF_INDEX 0x9f -enum { - INFOFRAME_AVI = 0x06, - INFOFRAME_AAI = 0x08 -}; -#define CONTROL_PACKET_ADDR 0xa0 - -#define SIZE_AVI_INFOFRAME 0x11 /* 14 bytes */ -#define SIZE_AUDIO_INFOFRAME 0x0F /* 15 bytes */ -enum { - AVI_COLOR_MODE_RGB = 0, - AVI_COLOR_MODE_YCBCR422, - AVI_COLOR_MODE_YCBCR444 -}; -enum { - AVI_COLORIMETRY_NO_DATA = 0, - AVI_COLORIMETRY_SMPTE_170M, - AVI_COLORIMETRY_ITU709, - AVI_COLORIMETRY_EXTENDED -}; -enum { - AVI_CODED_FRAME_ASPECT_NO_DATA, - AVI_CODED_FRAME_ASPECT_4_3, - AVI_CODED_FRAME_ASPECT_16_9 -}; -enum { - ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME = 0x08, - ACTIVE_ASPECT_RATE_4_3, - ACTIVE_ASPECT_RATE_16_9, - ACTIVE_ASPECT_RATE_14_9 -}; - -#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_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_MASK_INT_HOTPLUG (1 << 5) - #define m_INT_HOTPLUG (1 << 1) - - -#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 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 PHY_PRE_DIV_RATIO 0xed -#define v_PRE_DIV_RATIO(n) (n & 0x1f) - - -/*-----START----- HDMI CEC CTRL------START------*/ -#define CEC_CTRL 0xd0 - #define m_ADJUST_FOR_HISENSE (1 << 6) - #define m_REJECT_RX_BROADCAST (1 << 5) - #define m_BUSFREETIME_ENABLE (1 << 2) - #define m_REJECT_RX (1 << 1) - #define m_START_TX (1 << 0) - -#define CEC_DATA 0xd1 -#define CEC_TX_OFFSET 0xd2 -#define CEC_RX_OFFSET 0xd3 -#define CEC_CLK_H 0xd4 -#define CEC_CLK_L 0xd5 -#define CEC_TX_LENGTH 0xd6 -#define CEC_RX_LENGTH 0xd7 -#define CEC_TX_INT_MASK 0xd8 - #define m_TX_DONE (1 << 3) - #define m_TX_NOACK (1 << 2) - #define m_TX_BROADCAST_REJ (1 << 1) - #define m_TX_BUSNOTFREE (1 << 0) - -#define CEC_RX_INT_MASK 0xd9 - #define m_RX_LA_ERR (1 << 4) - #define m_RX_GLITCH (1 << 3) - #define m_RX_DONE (1 << 0) - -#define CEC_TX_INT 0xda -#define CEC_RX_INT 0xdb -#define CEC_BUSFREETIME_L 0xdc -#define CEC_BUSFREETIME_H 0xdd -#define CEC_LOGICADDR 0xde -/*------END------ HDMI CEC CTRL------END-------*/ - - -static inline int hdmi_readl(struct rk_hdmi_device *hdmi_dev, u16 offset, - u32 *val) -{ - int ret = 0; - - *val = readl_relaxed(hdmi_dev->regbase + (offset) * 0x04); - return ret; -} - -static inline int hdmi_writel(struct rk_hdmi_device *hdmi_dev, u16 offset, - u32 val) -{ - int ret = 0; - - writel_relaxed(val, hdmi_dev->regbase + (offset) * 0x04); - return ret; -} - -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_dev->regbase + (offset) * 0x04) & (0xFF - (msk)); - writel_relaxed(temp | ((val) & (msk)), hdmi_dev->regbase + (offset) * 0x04); - return ret; -} -static inline void rk3036_hdmi_reset_pclk(void) -{ - writel_relaxed(0x00010001, RK_CRU_VIRT + 0x128); - msleep(100); - writel_relaxed(0x00010000, RK_CRU_VIRT + 0x128); -} - -extern int rk3036_hdmi_initial(struct hdmi *hdmi); -extern void rk3036_hdmi_irq(struct hdmi *hdmi); - -#endif diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/Makefile b/drivers/video/rockchip/hdmi/chips/rk3288/Makefile deleted file mode 100644 index 35e382b58433..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3288/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for HDMI linux kernel module. -# - -ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG - -obj-$(CONFIG_HDMI_RK3288) += rk3288_hdmi_hw.o rk3288_hdmi.o -#obj-$(CONFIG_HDCP_RK3288) += hdcp/ diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c deleted file mode 100644 index 9cca081f5d96..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c +++ /dev/null @@ -1,579 +0,0 @@ -/* - * drivers/video/rockchip/hdmi/chips/rk3288/rk3188_hdmi.c - * - * Copyright (C) 2014 ROCKCHIP, Inc. - *Author:zwl - *This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_OF) -#include -#include -#endif -#if defined(CONFIG_DEBUG_FS) -#include -#include -#include -#endif - -#include "rk3288_hdmi_hw.h" -#include "rk3288_hdmi.h" - -#define grf_readl(offset) readl_relaxed(RK_GRF_VIRT + offset) -#define grf_writel(v, offset) \ -do { \ - writel_relaxed(v, RK_GRF_VIRT + offset); \ - dsb(); \ -} while (0) -#define HDMI_PD_ON (1 << 0) -#define HDMI_PCLK_ON (1 << 1) -#define HDMI_HDCPCLK_ON (1 << 2) - - -static struct rk3288_hdmi_device *hdmi_dev; - -#if defined(CONFIG_DEBUG_FS) -static const struct rk3288_hdmi_reg_table hdmi_reg_table[] = { - {IDENTIFICATION_BASE, CONFIG3_ID}, - {INTERRUPT_BASE, IH_MUTE}, - {VIDEO_SAMPLER_BASE, TX_BCBDATA1}, - {VIDEO_PACKETIZER_BASE, VP_MASK}, - {FRAME_COMPOSER_BASE, FC_DBGTMDS2}, - {HDMI_SOURCE_PHY_BASE, PHY_PLLCFGFREQ2}, - {I2C_MASTER_PHY_BASE, PHY_I2CM_SDA_HOLD}, - {AUDIO_SAMPLER_BASE, AHB_DMA_STPADDR_SET1_0}, - {MAIN_CONTROLLER_BASE, MC_SWRSTZREQ_2}, - {COLOR_SPACE_CONVERTER_BASE, CSC_SPARE_2}, - {HDCP_ENCRYPTION_ENGINE_BASE, HDCP_REVOC_LIST}, - {HDCP_BKSV_BASE, HDCPREG_BKSV4}, - {HDCP_AN_BASE, HDCPREG_AN7}, - {ENCRYPTED_DPK_EMBEDDED_BASE, HDCPREG_DPK6}, - {CEC_ENGINE_BASE, CEC_WKUPCTRL}, - {I2C_MASTER_BASE, I2CM_SCDC_UPDATE1}, -}; - -static int rk3288_hdmi_reg_show(struct seq_file *s, void *v) -{ - int i = 0, j = 0; - u32 val = 0; - - seq_puts(s, "\n>>>hdmi_ctl reg"); - for (i = 0; i < 16; i++) - seq_printf(s, " %2x", i); - - seq_puts(s, - "\n-----------------------------------------------------------------"); - - for (i = 0; i < ARRAY_SIZE(hdmi_reg_table); 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) - seq_printf(s, "\n>>>hdmi_ctl %2x:", j); - seq_printf(s, " %02x", val); - - } - } - seq_puts(s, - "\n-----------------------------------------------------------------\n"); - - return 0; -} - -static ssize_t rk3288_hdmi_reg_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - u32 reg; - u32 val; - char kbuf[25]; - - if (copy_from_user(kbuf, buf, count)) - return -EFAULT; - sscanf(kbuf, "%x%x", ®, &val); - if ((reg < 0) || (reg > I2CM_SCDC_UPDATE1)) { - dev_info(hdmi_dev->dev, "it is no hdmi reg\n"); - return count; - } - dev_info(hdmi_dev->dev, "/**********rk3288 hdmi reg config******/"); - dev_info(hdmi_dev->dev, "\n reg=%x val=%x\n", reg, val); - hdmi_writel(hdmi_dev, reg, val); - - return count; -} - -static int rk3288_hdmi_reg_open(struct inode *inode, struct file *file) -{ - struct rk3288_hdmi_device *hdmi_dev = inode->i_private; - - return single_open(file, rk3288_hdmi_reg_show, hdmi_dev); -} - -static const struct file_operations rk3288_hdmi_reg_fops = { - .owner = THIS_MODULE, - .open = rk3288_hdmi_reg_open, - .read = seq_read, - .write = rk3288_hdmi_reg_write, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - -struct hdmi *rk3288_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)) -{ - struct hdmi *hdmi_drv = NULL; - - if (hdmi_dev == NULL) - return NULL; - - hdmi_drv = &hdmi_dev->driver; - 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_drv; -} - -#ifdef HDMI_INT_USE_POLL -#define HDMI_POLL_MDELAY 100 -static void rk3288_poll_delay_work(struct work_struct *work) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - if (hdmi_drv->suspend == 0) { - if (hdmi_drv->enable == 1) - hdmi_irq(0, hdmi_drv); - - if (hdmi_dev->irq == 0) - queue_delayed_work(hdmi_drv->workqueue, - &hdmi_dev->delay_work, - msecs_to_jiffies(HDMI_POLL_MDELAY)); - } -} -#endif - -static int rk3288_hdmi_clk_enable(struct rk3288_hdmi_device *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); - hdmi_dev->clk_on |= HDMI_PD_ON; - } - - if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) { - if (hdmi_dev->pclk == NULL) { - hdmi_dev->pclk = - devm_clk_get(hdmi_dev->dev, "pclk_hdmi"); - if (IS_ERR(hdmi_dev->pclk)) { - dev_err(hdmi_dev->dev, - "Unable to get hdmi pclk\n"); - return -1; - } - } - clk_prepare_enable(hdmi_dev->pclk); - hdmi_dev->clk_on |= HDMI_PCLK_ON; - } - - if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) { - if (hdmi_dev->hdcp_clk == NULL) { - hdmi_dev->hdcp_clk = - devm_clk_get(hdmi_dev->dev, "hdcp_clk_hdmi"); - if (IS_ERR(hdmi_dev->hdcp_clk)) { - dev_err(hdmi_dev->dev, - "Unable to get hdmi hdcp_clk\n"); - return -1; - } - } - clk_prepare_enable(hdmi_dev->hdcp_clk); - hdmi_dev->clk_on |= HDMI_HDCPCLK_ON; - } - - return 0; -} - -static int rk3288_hdmi_clk_disable(struct rk3288_hdmi_device *hdmi_dev) -{ - 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); - hdmi_dev->clk_on &= ~HDMI_PD_ON; - } - - if ((hdmi_dev->clk_on & HDMI_PCLK_ON) && (hdmi_dev->pclk != NULL)) { - 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)) { - clk_disable_unprepare(hdmi_dev->hdcp_clk); - hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON; - } - - return 0; -} - -static int rk3288_hdmi_drv_init(struct hdmi *hdmi_drv) -{ - int ret = 0; - struct rk_screen screen; - - rk_fb_get_prmry_screen(&screen); - - /* hdmi is extend as default,TODO modify if hdmi is primary */ - hdmi_dev->lcdc_id = (screen.lcdc_id == 0) ? 1 : 0; - /* lcdc source select */ - grf_writel(HDMI_SEL_LCDC(hdmi_dev->lcdc_id), RK3288_GRF_SOC_CON6); - if (hdmi_dev->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); - - rk3288_hdmi_initial(hdmi_drv); - hdmi_sys_init(hdmi_drv); - hdmi_drv_register(hdmi_drv); - - return ret; -} - -static void rk3288_hdmi_early_suspend(void) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - if (hdmi_drv->suspend) - return; - - 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; - } - disable_irq(hdmi_drv->irq); - 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); - - /* iomux to gpio and pull down when suspend */ - pinctrl_select_state(hdmi_dev->dev->pins->p, - hdmi_dev->dev->pins->sleep_state); - rk3288_hdmi_clk_disable(hdmi_dev); - return; -} - -static void rk3288_hdmi_early_resume(void) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - if (!hdmi_drv->suspend) - return; - - hdmi_dbg(hdmi_drv->dev, "hdmi enter early resume\n"); - /* iomux to default state for hdmi use when resume */ - pinctrl_select_state(hdmi_dev->dev->pins->p, - hdmi_dev->dev->pins->default_state); - rk3288_hdmi_clk_enable(hdmi_dev); - mutex_lock(&hdmi_drv->enable_mutex); - hdmi_drv->suspend = 0; - rk3288_hdmi_initial(hdmi_drv); - if (hdmi_dev->irq == 0) { -#ifdef HDMI_INT_USE_POLL - queue_delayed_work(hdmi_drv->workqueue, &hdmi_dev->delay_work, - msecs_to_jiffies(5)); -#endif - } else if (hdmi_drv->enable) { - enable_irq(hdmi_drv->irq); - } - queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, - msecs_to_jiffies(10)); - mutex_unlock(&hdmi_drv->enable_mutex); - return; -} - -static int rk3288_hdmi_fb_event_notify(struct notifier_block *self, - unsigned long action, void *data) -{ - 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: - rk3288_hdmi_early_suspend(); - break; - } - } else if (action == FB_EVENT_BLANK) { - switch (blank_mode) { - case FB_BLANK_UNBLANK: - rk3288_hdmi_early_resume(); - break; - default: - break; - } - } - - return NOTIFY_OK; -} - -static struct notifier_block rk3288_hdmi_fb_notifier = { - .notifier_call = rk3288_hdmi_fb_event_notify, -}; - -#if defined(CONFIG_OF) -static int rk3288_hdmi_parse_dt(struct rk3288_hdmi_device *hdmi_dev) -{ - int val = 0; - struct device_node *np = hdmi_dev->dev->of_node; - - if (!of_property_read_u32(np, "rockchips,hdmi_audio_source", &val)) - hdmi_dev->driver.audio.type = val; - - return 0; -} - -static const struct of_device_id rk3288_hdmi_dt_ids[] = { - {.compatible = "rockchip,rk3288-hdmi",}, - {} -}; -#endif - -static int rk3288_hdmi_probe(struct platform_device *pdev) -{ - int ret; - struct resource *res; - struct hdmi *dev_drv = NULL; - - hdmi_dev = kzalloc(sizeof(struct rk3288_hdmi_device), GFP_KERNEL); - if (!hdmi_dev) { - dev_err(&pdev->dev, ">>rk3288_hdmi_device kzalloc fail!"); - return -ENOMEM; - } - - hdmi_dev->dev = &pdev->dev; - platform_set_drvdata(pdev, hdmi_dev); - mutex_init(&hdmi_dev->int_mutex); - - rk3288_hdmi_parse_dt(hdmi_dev); - /* TODO Daisen wait to add cec iomux */ - - /* enable pd and pclk and hdcp_clk */ - if (rk3288_hdmi_clk_enable(hdmi_dev) < 0) - goto err0; - - /* 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 err0; - } - hdmi_dev->regbase_phy = res->start; - hdmi_dev->regsize_phy = resource_size(res); - hdmi_dev->regbase = devm_ioremap_resource(hdmi_dev->dev, res); - if (IS_ERR(hdmi_dev->regbase)) { - ret = PTR_ERR(hdmi_dev->regbase); - dev_err(hdmi_dev->dev, "cannot ioremap registers,err=%d\n", - ret); - goto err0; - } - - /*init hdmi driver */ - dev_drv = &hdmi_dev->driver; - dev_drv->dev = &pdev->dev; - if (rk3288_hdmi_drv_init(dev_drv)) - goto err0; - - dev_drv->workqueue = create_singlethread_workqueue("hdmi"); - INIT_DELAYED_WORK(&(dev_drv->delay_work), hdmi_work); - - hdmi_register_display_sysfs(dev_drv, NULL); - -#ifdef CONFIG_SWITCH - dev_drv->switch_hdmi.name = "hdmi"; - switch_dev_register(&(dev_drv->switch_hdmi)); -#endif - - fb_register_client(&rk3288_hdmi_fb_notifier); - -#ifndef HDMI_INT_USE_POLL - /* get and request the IRQ */ - dev_drv->irq = platform_get_irq(pdev, 0); - if (dev_drv->irq <= 0) { - dev_err(hdmi_dev->dev, - "failed to get hdmi irq resource (%d).\n", - hdmi_dev->irq); - ret = -ENXIO; - goto err1; - } - - ret = - devm_request_irq(hdmi_dev->dev, dev_drv->irq, hdmi_irq, 0, - dev_name(hdmi_dev->dev), dev_drv); - if (ret) { - dev_err(hdmi_dev->dev, "hdmi request_irq failed (%d).\n", ret); - goto err1; - } -#else - hdmi_dev->irq = 0; - INIT_DELAYED_WORK(&hdmi_dev->delay_work, rk3288_poll_delay_work); - queue_delayed_work(dev_drv->workqueue, &hdmi_dev->delay_work, - msecs_to_jiffies(1)); -#endif - -#if defined(CONFIG_DEBUG_FS) - hdmi_dev->debugfs_dir = debugfs_create_dir("rk3288-hdmi", NULL); - if (IS_ERR(hdmi_dev->debugfs_dir)) { - dev_err(hdmi_dev->dev, - "failed to create debugfs dir for rk3288 hdmi!\n"); - } else { - debugfs_create_file("hdmi", S_IRUSR, hdmi_dev->debugfs_dir, - hdmi_dev, &rk3288_hdmi_reg_fops); - } -#endif - - dev_info(hdmi_dev->dev, "rk3288 hdmi probe sucess.\n"); - return 0; - -#ifndef HDMI_INT_USE_POLL -err1: -#endif - fb_unregister_client(&rk3288_hdmi_fb_notifier); -#ifdef CONFIG_SWITCH - switch_dev_unregister(&(dev_drv->switch_hdmi)); -#endif - hdmi_unregister_display_sysfs(dev_drv); - - /* - iounmap((void*)hdmi_dev->regbase); - release_mem_region(res->start, hdmi_dev->regsize_phy); - */ -err0: - rk3288_hdmi_clk_disable(hdmi_dev); - dev_info(hdmi_dev->dev, "rk3288 hdmi probe error.\n"); - kfree(hdmi_dev); - hdmi_dev = NULL; - return ret; -} - -static int rk3288_hdmi_remove(struct platform_device *pdev) -{ - struct rk3288_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) - disable_irq(hdmi_drv->irq); - mutex_unlock(&hdmi_drv->enable_mutex); - free_irq(hdmi_drv->irq, NULL); - - flush_workqueue(hdmi_drv->workqueue); - destroy_workqueue(hdmi_drv->workqueue); - - fb_unregister_client(&rk3288_hdmi_fb_notifier); - -#ifdef CONFIG_SWITCH - switch_dev_unregister(&(hdmi_drv->switch_hdmi)); -#endif - hdmi_unregister_display_sysfs(hdmi_drv); - - /* - iounmap((void*)hdmi_drv->regbase); - release_mem_region(hdmi_drv->regbase_phy, - hdmi_drv->regsize_phy); - */ - rk3288_hdmi_clk_disable(hdmi_dev); - fb_destroy_modelist(&hdmi_drv->edid.modelist); - kfree(hdmi_drv->edid.audio); - if (hdmi_drv->edid.specs) { - kfree(hdmi_drv->edid.specs->modedb); - kfree(hdmi_drv->edid.specs); - } - - kfree(hdmi_dev); - hdmi_dev = NULL; - } - dev_info(hdmi_dev->dev, "rk3288 hdmi removed.\n"); - return 0; -} - -static void rk3288_hdmi_shutdown(struct platform_device *pdev) -{ - -} - -static struct platform_driver rk3288_hdmi_driver = { - .probe = rk3288_hdmi_probe, - .remove = rk3288_hdmi_remove, - .driver = { - .name = "rk3288-hdmi", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(rk3288_hdmi_dt_ids), - }, - .shutdown = rk3288_hdmi_shutdown, -}; - -static int __init rk3288_hdmi_init(void) -{ - return platform_driver_register(&rk3288_hdmi_driver); -} - -static void __exit rk3288_hdmi_exit(void) -{ - platform_driver_unregister(&rk3288_hdmi_driver); -} - -device_initcall_sync(rk3288_hdmi_init); -module_exit(rk3288_hdmi_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.h b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.h deleted file mode 100644 index 41055d4e45ee..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __RK3288_HDMI_H__ -#define __RK3288_HDMI_H__ - -#include "../../rk_hdmi.h" - - -#define ENABLE 16 -#define HDMI_SEL_LCDC(x) ((((x)&1)<<4)|(1<<(4+ENABLE))) - -extern irqreturn_t hdmi_irq(int irq, void *priv); -extern struct hdmi *rk3288_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)); - - -#endif /* __RK3288_HDMI_H__ */ diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c deleted file mode 100755 index 4fce93bc457d..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c +++ /dev/null @@ -1,1416 +0,0 @@ -#include -#include -#include "rk3288_hdmi_hw.h" - -static unsigned int rk3288_hdmi_support_vic[] = { - HDMI_720X480P_60HZ_VIC, - HDMI_720X576P_50HZ_VIC, - HDMI_1280X720P_50HZ_VIC, - HDMI_1280X720P_60HZ_VIC, - HDMI_1920X1080P_50HZ_VIC, - HDMI_1920X1080P_60HZ_VIC, - HDMI_3840X2160P_24HZ_VIC, - HDMI_3840X2160P_25HZ_VIC, - HDMI_3840X2160P_30HZ_VIC, - HDMI_3840X2160P_50HZ_VIC, - HDMI_3840X2160P_60HZ_VIC -}; -static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = { /* opmode: 0:HDMI1.4 1:HDMI2.0 */ -/* pixclock pixrepet colordepth prepdiv tmdsmhl opmode fbdiv2 fbdiv1 ref_cntrl nctrl propctrl intctrl gmpctrl */ - {27000000, 0, HDMI_COLOR_DEPTH_8BIT, 0, 0, 0, 2, 3, 0, 3, 7, 0, 3}, - {27000000, 0, HDMI_COLOR_DEPTH_10BIT, 1, 0, 0, 5, 1, 0, 3, 3, 0, 0}, - {27000000, 0, HDMI_COLOR_DEPTH_12BIT, 2, 0, 0, 3, 3, 0, 3, 3, 0, 0}, - {27000000, 0, HDMI_COLOR_DEPTH_16BIT, 3, 0, 0, 2, 3, 0, 2, 5, 0, 1}, - {74250000, 0, HDMI_COLOR_DEPTH_8BIT, 0, 0, 0, 4, 3, 3, 2, 7, 0, 3}, - {74250000, 0, HDMI_COLOR_DEPTH_10BIT, 1, 0, 0, 5, 3, 3, 2, 7, 0, 2}, - {74250000, 0, HDMI_COLOR_DEPTH_12BIT, 2, 0, 0, 1, 2, 0, 1, 7, 0, 2}, - {74250000, 0, HDMI_COLOR_DEPTH_16BIT, 3, 0, 0, 1, 3, 0, 1, 7, 0, 2}, - {148500000, 0, HDMI_COLOR_DEPTH_8BIT, 0, 0, 0, 1, 1, 0, 1, 0, 0, 3}, - {148500000, 0, HDMI_COLOR_DEPTH_10BIT, 1, 0, 0, 5, 1, 3, 1, 7, 0, 3}, - {148500000, 0, HDMI_COLOR_DEPTH_12BIT, 2, 0, 0, 1, 2, 1, 0, 7, 0, 3}, - {148500000, 0, HDMI_COLOR_DEPTH_16BIT, 3, 0, 0, 1, 1, 0, 0, 7, 0, 3}, - {297000000, 0, HDMI_COLOR_DEPTH_8BIT, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3}, - {297000000, 0, HDMI_COLOR_DEPTH_10BIT, 1, 3, 1, 5, 0, 3, 0, 7, 0, 3}, - {297000000, 0, HDMI_COLOR_DEPTH_12BIT, 2, 3, 1, 1, 2, 2, 0, 7, 0, 3}, - {297000000, 0, HDMI_COLOR_DEPTH_16BIT, 3, 3, 1, 1, 1, 0, 0, 5, 0, 3}, - {594000000, 0, HDMI_COLOR_DEPTH_8BIT, 0, 3, 1, 1, 0, 0, 0, 3, 0, 3}, -}; - -const struct phy_mpll_config_tab *get_phy_mpll_tab(int pixClock, char pixRepet, - char colorDepth) -{ - int i; - - if (pixClock == 0) - return NULL; - - for (i = 0; i < ARRAY_SIZE(PHY_MPLL_TABLE); i++) { - if ((PHY_MPLL_TABLE[i].pix_clock == pixClock) - && (PHY_MPLL_TABLE[i].pix_repet == pixRepet) - && (PHY_MPLL_TABLE[i].color_depth == colorDepth)) - return &PHY_MPLL_TABLE[i]; - } - return NULL; -} - -static void rk3288_hdmi_av_mute(struct hdmi *hdmi_drv, int enable) -{ - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - hdmi_msk_reg(hdmi_dev, FC_GCP, m_FC_SET_AVMUTE, - v_FC_SET_AVMUTE(enable)); -#if 0 - /* audio mute priority: AVMUTE, sample flat, validity */ - /* AVMUTE also mutes video */ - value = enable ? 0xF : 0; - hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, m_AUD_PACK_SAMPFIT, - v_AUD_PACK_SAMPFIT(value)); -#endif -} - -static void rk3288_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode) -{ - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_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_writel(hdmi_dev, MC_CLKDIS, 0x00); - break; - case LOWER_PWR: - hdmi_writel(hdmi_dev, MC_CLKDIS, 0xff); - hdmi_msk_reg(hdmi_dev, PHY_CONF0, - m_TMDS_EN | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG, - v_TMDS_EN(0) | v_TXPWRON_SIG(0) | - v_ENHPD_RXSENSE_SIG(1)); - break; - default: - hdmi_dbg(hdmi_drv->dev, "unkown hdmi pwr mode %d\n", mode); - } - hdmi_drv->pwr_mode = mode; -} - -/* i2c master reset */ -void rk3288_hdmi_i2cm_reset(struct rk3288_hdmi_device *hdmi_dev) -{ - hdmi_msk_reg(hdmi_dev, I2CM_SOFTRSTZ, m_I2CM_SOFTRST, - v_I2CM_SOFTRST(0)); - udelay(100); -} - -void rk3288_hdmi_reset(struct hdmi *hdmi_drv) -{ - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0x00); - udelay(100); - hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xff); - hdmi_writel(hdmi_dev, MC_SWRSTZREQ_2, 0x00); - udelay(100); - hdmi_writel(hdmi_dev, MC_SWRSTZREQ_2, 0x01); - - rk3288_hdmi_i2cm_reset(hdmi_dev); -#if 1 - /* reset PHY */ - hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1)); - udelay(100); - hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0)); -#endif - - rk3288_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR); -} - -int rk3288_hdmi_detect_hotplug(struct hdmi *hdmi_drv) -{ - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - u32 value = hdmi_readl(hdmi_dev, PHY_STAT0); - - hdmi_dbg(hdmi_drv->dev, "[%s] reg%x value %02x\n", __func__, - PHY_STAT0, value); - - if ((value & m_PHY_HPD) || ((value & 0xf0) == 0xf0)) - return HDMI_HPD_ACTIVED; - else - return HDMI_HPD_REMOVED; -} - -int rk3288_hdmi_read_edid(struct hdmi *hdmi_drv, int block, unsigned char *buff) -{ - int i = 0, n = 0, index = 0, ret = -1, trytime = 2; - int offset = (block % 2) * 0x80; - int interrupt = 0; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - hdmi_dbg(hdmi_drv->dev, "[%s] block %d\n", __func__, block); - - /* Set DDC I2C CLK which devided from DDC_CLK to 100KHz */ - hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_0_ADDR, 0x7a); - hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_0_ADDR, 0x8d); - hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE, - v_I2CM_FAST_STD_MODE(STANDARD_MODE)); /* Set Standard Mode */ - - /* Enable I2C interrupt for reading edid */ - hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, - v_SCDC_READREQ_MUTE(0) | v_I2CM_DONE_MUTE(0) | - v_I2CM_ERR_MUTE(0)); - hdmi_msk_reg(hdmi_dev, I2CM_INT, m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0)); - hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, m_I2CM_NACK_MASK | m_I2CM_ARB_MASK, - v_I2CM_NACK_MASK(0) | v_I2CM_ARB_MASK(0)); - - hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR); - hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR); - hdmi_writel(hdmi_dev, I2CM_SEGPTR, block / 2); - while (trytime--) { - for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) { - hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8 * n); - /* enable extend sequential read operation */ - if (block == 0) - hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, - m_I2CM_RD8, v_I2CM_RD8(1)); - else - hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, - m_I2CM_RD8_EXT, v_I2CM_RD8_EXT(1)); - - i = 20; - while (i--) { - msleep(1); - interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0); - if (interrupt) - hdmi_writel(hdmi_dev, IH_I2CM_STAT0, - interrupt); - - if (interrupt & - (m_SCDC_READREQ | m_I2CM_DONE | - m_I2CM_ERROR)) - break; - msleep(4); - } - - if (interrupt & m_I2CM_DONE) { - for (index = 0; index < 8; index++) { - buff[8 * n + index] = - hdmi_readl(hdmi_dev, - I2CM_READ_BUFF0 + index); - } - - if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) { - ret = 0; - hdmi_dbg(hdmi_drv->dev, - "[%s] edid read sucess\n", - __func__); - -#ifdef HDMI_DEBUG - for (i = 0; i < 128; i++) { - printk("%02x ,", buff[i]); - if ((i + 1) % 16 == 0) - printk("\n"); - } -#endif - goto exit; - } - continue; - } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) { - hdmi_err(hdmi_drv->dev, - "[%s] edid read error\n", - __func__); - rk3288_hdmi_i2cm_reset(hdmi_dev); - break; - } - } - - hdmi_err(hdmi_drv->dev, "[%s] edid try times %d\n", - __func__, trytime); - msleep(100); - } - -exit: - /* Disable I2C interrupt */ - hdmi_msk_reg(hdmi_dev, IH_MUTE_I2CM_STAT0, - m_I2CM_DONE_MUTE | m_I2CM_ERR_MUTE, - v_I2CM_DONE_MUTE(1) | v_I2CM_ERR_MUTE(1)); - hdmi_msk_reg(hdmi_dev, I2CM_INT, m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(1)); - hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, m_I2CM_NACK_MASK | m_I2CM_ARB_MASK, - v_I2CM_NACK_MASK(1) | v_I2CM_ARB_MASK(1)); - return ret; -} - -static int rk3288_hdmi_video_forceOutput(struct hdmi *hdmi_drv, char enable) -{ - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEAUDIO, - v_FC_FORCEAUDIO(0)); - - if (enable) { /* Force output Blue */ - hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00); /*R*/ - hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00); /*G*/ - hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0xff); /*B*/ - hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEVIDEO, - v_FC_FORCEVIDEO(1)); - } else { - hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEVIDEO, - v_FC_FORCEVIDEO(0)); - hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00); /*R*/ - hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00); /*G*/ - hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x00); /*B*/ - } - - return 0; -} - -/* TODO Daisen wait to add support 3D */ -static int rk3288_hdmi_video_frameComposer(struct hdmi *hdmi_drv, - struct hdmi_video_para *vpara) -{ - int h_act = 0, v_act = 0; - int h_syncdelay = 0, v_syncdelay = 0; - int h_sync = 0, v_sync = 0; - int h_blank = 0, v_blank = 0; - int vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync; - int hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync; - int de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0; - struct fb_videomode *mode = NULL; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); - if (mode == NULL) { - hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __func__, - vpara->vic); - return -ENOENT; - } - - hdmi_drv->pixclock = mode->pixclock; - switch (vpara->color_depth) { - case HDMI_COLOR_DEPTH_8BIT: - hdmi_drv->tmdsclk = mode->pixclock; - break; - case HDMI_COLOR_DEPTH_10BIT: - hdmi_drv->tmdsclk = mode->pixclock * 10 / 8; - break; - case HDMI_COLOR_DEPTH_12BIT: - hdmi_drv->tmdsclk = mode->pixclock * 12 / 8; - break; - case HDMI_COLOR_DEPTH_16BIT: - hdmi_drv->tmdsclk = mode->pixclock * 2; - break; - default: - hdmi_drv->tmdsclk = mode->pixclock; - break; - } - - /* cfg to bypass hdcp data encrypt */ - hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_ENCRYPT_BYPASS | m_HDMI_DVI, - v_ENCRYPT_BYPASS(1) | v_HDMI_DVI(vpara->output_mode)); - hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, - m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL | - m_FC_HDMI_DVI | m_FC_INTERLACE_MODE, - v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) | - v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara-> - output_mode) | - v_FC_INTERLACE_MODE(mode->vmode)); - hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_VBLANK, - v_FC_VBLANK(mode->vmode)); - - h_act = mode->xres; - hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(h_act >> 8)); - hdmi_writel(hdmi_dev, FC_INHACTIV0, (h_act & 0xff)); - - v_act = mode->yres; - hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(v_act >> 8)); - hdmi_writel(hdmi_dev, FC_INVACTIV0, (v_act & 0xff)); - - h_blank = mode->hsync_len + mode->left_margin + mode->right_margin; - hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(h_blank >> 8)); - hdmi_writel(hdmi_dev, FC_INHBLANK0, (h_blank & 0xff)); - - v_blank = mode->vsync_len + mode->upper_margin + mode->lower_margin; - hdmi_writel(hdmi_dev, FC_INVBLANK, (v_blank & 0xff)); - - h_syncdelay = mode->right_margin; - hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1, - v_FC_HSYNCINDEAY1(h_syncdelay >> 8)); - hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (h_syncdelay & 0xff)); - - v_syncdelay = mode->lower_margin; - hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (v_syncdelay & 0xff)); - - h_sync = mode->hsync_len; - hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(h_sync >> 8)); - hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (h_sync & 0xff)); - - v_sync = mode->vsync_len; - hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (v_sync & 0xff)); - - /* Set the control period minimum duration - * (min. of 12 pixel clock cycles, refer to HDMI 1.4b specification) - */ - hdmi_writel(hdmi_dev, FC_CTRLDUR, 12); - hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32); -#if 0 - /* used for HDMI 2.0 TX TODO Daisen wait to modify HDCP KEEPOUT */ - if (hdmi_drv->tmdsclk > 340000000) { - hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_HDCP_KEEPOUT, - v_FC_HDCP_KEEPOUT(1)); - hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL, m_FC_SCRAMBLE_EN, - v_FC_SCRAMBLE_EN(1)); - } - - /* spacing < 256^2 * config / tmdsClock, spacing <= 50ms - * worst case: tmdsClock == 25MHz => config <= 19 - */ - hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, 1); - - /* Set PreambleFilter */ - for (i = 0; i < 3; i++) { - value = (i + 1) * 11; - if (i == 0) /* channel 0 */ - hdmi_writel(hdmi_dev, FC_CH0PREAM, value); - else if (i == 1) /* channel 1 */ - hdmi_writel(hdmi_dev, FC_CH1PREAM, value & 0x3f); - else if (i == 2) /* channel 2 */ - hdmi_writel(hdmi_dev, FC_CH2PREAM, value & 0x3f); - } -#endif - /* Set PixelRepetition:No pixel repetition */ - hdmi_writel(hdmi_dev, FC_PRCONF, - v_FC_PR_FACTOR(vpara->pixel_repet + 1)); - - return 0; -} - -static int rk3288_hdmi_video_packetizer(struct hdmi *hdmi_drv, - struct hdmi_video_para *vpara) -{ - unsigned char color_depth = 0; - unsigned char output_select = 0; - unsigned char remap_size = 0; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - if (vpara->output_color == VIDEO_OUTPUT_RGB444 - || vpara->output_color == VIDEO_OUTPUT_YCBCR444 - || vpara->output_color == VIDEO_OUTPUT_YCBCR420) { - - switch (vpara->color_depth) { - case HDMI_COLOR_DEPTH_8BIT: - color_depth = COLOR_DEPTH_24BIT; - output_select = OUT_FROM_8BIT_BYPASS; - break; - case HDMI_COLOR_DEPTH_10BIT: - color_depth = COLOR_DEPTH_30BIT; - output_select = OUT_FROM_PIXEL_PACKING; - break; - case HDMI_COLOR_DEPTH_12BIT: - color_depth = COLOR_DEPTH_36BIT; - output_select = OUT_FROM_PIXEL_PACKING; - break; - case HDMI_COLOR_DEPTH_16BIT: - color_depth = COLOR_DEPTH_48BIT; - output_select = OUT_FROM_PIXEL_PACKING; - break; - default: - color_depth = COLOR_DEPTH_24BIT; - output_select = OUT_FROM_8BIT_BYPASS; - break; - } - - /* Config Color Depth */ - hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_COLOR_DEPTH, - v_COLOR_DEPTH(color_depth)); - } else if (vpara->output_color == VIDEO_OUTPUT_YCBCR422) { - - switch (vpara->color_depth) { - case HDMI_COLOR_DEPTH_8BIT: - remap_size = YCC422_16BIT; - break; - case HDMI_COLOR_DEPTH_10BIT: - remap_size = YCC422_20BIT; - break; - case HDMI_COLOR_DEPTH_12BIT: - remap_size = YCC422_24BIT; - break; - default: - remap_size = YCC422_16BIT; - break; - } - - output_select = OUT_FROM_YCC422_REMAP; - /* Config remap size for the different color Depth */ - hdmi_msk_reg(hdmi_dev, VP_REMAP, m_YCC422_SIZE, - v_YCC422_SIZE(remap_size)); - } else { - hdmi_err(hdmi_drv->dev, "invalid output color type: %d", - vpara->output_color); - return -1; - } - - /* Config pixel repettion */ - hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR, - v_DESIRED_PR_FACTOR(vpara->pixel_repet)); - if (vpara->pixel_repet > 0) - hdmi_msk_reg(hdmi_dev, VP_CONF, m_PIXEL_REPET_EN | m_BYPASS_SEL, - v_PIXEL_REPET_EN(1) | v_BYPASS_SEL(0)); - else - hdmi_msk_reg(hdmi_dev, VP_CONF, m_PIXEL_REPET_EN | m_BYPASS_SEL, - v_PIXEL_REPET_EN(0) | v_BYPASS_SEL(1)); - - /* config output select */ - if (output_select == OUT_FROM_PIXEL_PACKING) { /* pixel packing */ - hdmi_msk_reg(hdmi_dev, VP_CONF, - m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN | - m_OUTPUT_SEL, - v_BYPASS_EN(0) | v_PIXEL_PACK_EN(1) | - v_YCC422_EN(0) | v_OUTPUT_SEL(output_select)); - } else if (output_select == OUT_FROM_YCC422_REMAP) { /* YCC422 */ - hdmi_msk_reg(hdmi_dev, VP_CONF, - m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN | - m_OUTPUT_SEL, - v_BYPASS_EN(0) | v_PIXEL_PACK_EN(0) | - v_YCC422_EN(1) | v_OUTPUT_SEL(output_select)); - } else if (output_select == OUT_FROM_8BIT_BYPASS || output_select == 3) { - /* bypass */ - hdmi_msk_reg(hdmi_dev, VP_CONF, - m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN | - m_OUTPUT_SEL, - v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) | - v_YCC422_EN(0) | v_OUTPUT_SEL(output_select)); - } -#if defined(HDMI_VIDEO_STUFFING) - /* YCC422 and pixel packing stuffing */ - hdmi_msk_reg(hdmi_dev, VP_STUFF, m_PR_STUFFING, v_PR_STUFFING(1)); - hdmi_msk_reg(hdmi_dev, VP_STUFF, m_YCC422_STUFFING | m_PP_STUFFING, - v_YCC422_STUFFING(1) | v_PP_STUFFING(1)); -#endif - return 0; -} - -int rk3288_hdmi_video_sampler(struct hdmi *hdmi_drv, - struct hdmi_video_para *vpara) -{ - int map_code = 0; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - if (vpara->input_color == VIDEO_INPUT_COLOR_RGB - || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444 - || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR420) { - - switch (vpara->color_depth) { - case HDMI_COLOR_DEPTH_8BIT: - map_code = VIDEO_RGB444_8BIT; - break; - case HDMI_COLOR_DEPTH_10BIT: - map_code = VIDEO_RGB444_10BIT; - break; - case HDMI_COLOR_DEPTH_12BIT: - map_code = VIDEO_RGB444_12BIT; - break; - case HDMI_COLOR_DEPTH_16BIT: - map_code = VIDEO_RGB444_16BIT; - break; - default: - map_code = VIDEO_RGB444_8BIT; - break; - } - map_code += - (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444) ? 8 : 0; - } else if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR422) { - /* YCC422 mapping is discontinued - only map 1 is supported */ - switch (vpara->color_depth) { - case HDMI_COLOR_DEPTH_8BIT: - map_code = VIDEO_YCBCR422_8BIT; - break; - case HDMI_COLOR_DEPTH_10BIT: - map_code = VIDEO_YCBCR422_10BIT; - break; - case HDMI_COLOR_DEPTH_12BIT: - map_code = VIDEO_YCBCR422_12BIT; - break; - default: - map_code = VIDEO_YCBCR422_8BIT; - break; - } - } else { - hdmi_err(hdmi_drv->dev, "invalid input color type: %d", - vpara->input_color); - return -1; - } - - /* Set Data enable signal from external - * and set video sample input mapping - */ - hdmi_msk_reg(hdmi_dev, TX_INVID0, m_INTERNAL_DE_GEN | m_VIDEO_MAPPING, - v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code)); - -#if defined(HDMI_VIDEO_STUFFING) - hdmi_writel(hdmi_dev, TX_GYDATA0, 0x00); - hdmi_writel(hdmi_dev, TX_GYDATA1, 0x00); - hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_GYDATA_STUFF, - v_GYDATA_STUFF(1)); - hdmi_writel(hdmi_dev, TX_RCRDATA0, 0x00); - hdmi_writel(hdmi_dev, TX_RCRDATA1, 0x00); - hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_RCRDATA_STUFF, - v_RCRDATA_STUFF(1)); - hdmi_writel(hdmi_dev, TX_BCBDATA0, 0x00); - hdmi_writel(hdmi_dev, TX_BCBDATA1, 0x00); - hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_BCBDATA_STUFF, - v_BCBDATA_STUFF(1)); -#endif - return 0; -} - -#ifdef HDMI_DEBUG -static int __maybe_unused rk3288_hdmi_read_phy(struct rk3288_hdmi_device *hdmi_dev, - int reg_addr) -{ - int trytime = 2, i = 0, op_status = 0; - int val = 0; - - while (trytime--) { - hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr); - hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_1, 0x00); - hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_0, 0x00); - hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_READ); - - i = 20; - while (i--) { - msleep(1); - op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0); - if (op_status) - hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0, - op_status); - - if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) { - break; - } - msleep(4); - } - - if (op_status & m_I2CMPHY_DONE) { - val = hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_1); - val = (val & 0xff) << 8; - val += (hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_0) & 0xff); - hdmi_dbg(hdmi_dev->dev, "phy_reg0x%02x: 0x%04x", - reg_addr, val); - return val; - } else { - hdmi_err(hdmi_dev->dev, - "[%s] operation error,trytime=%d\n", - __func__, trytime); - } - msleep(100); - } - - return -1; -} -#endif - -static int rk3288_hdmi_write_phy(struct rk3288_hdmi_device *hdmi_dev, - int reg_addr, int val) -{ - int trytime = 2, i = 0, op_status = 0; - - while (trytime--) { - hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr); - hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_1, (val >> 8) & 0xff); - hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_0, val & 0xff); - hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_WRITE); - - i = 20; - while (i--) { - msleep(1); - op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0); - if (op_status) - hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0, - op_status); - - if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) { - break; - } - msleep(4); - } - - if (op_status & m_I2CMPHY_DONE) { - return 0; - } else { - hdmi_err(hdmi_dev->dev, - "[%s] operation error,trytime=%d\n", - __func__, trytime); - } - msleep(100); - } - - return -1; -} - -int rk3288_hdmi_config_phy(struct hdmi *hdmi_drv, unsigned char pixel_repet, - unsigned char color_depth) -{ - int stat = 0, i = 0; - const struct phy_mpll_config_tab *phy_mpll = NULL; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - hdmi_msk_reg(hdmi_dev, PHY_I2CM_DIV, m_PHY_I2CM_FAST_STD, - v_PHY_I2CM_FAST_STD(0)); - - /* power on PHY */ - hdmi_writel(hdmi_dev, PHY_CONF0, 0x3a); - /* - hdmi_msk_reg(hdmi_dev, PHY_CONF0, m_PDDQ_SIG | m_TXPWRON_SIG, - v_PDDQ_SIG(1) | v_TXPWRON_SIG(0)); - */ - - /* reset PHY */ - hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1)); - msleep(5); - hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0)); - - /* Set slave address as PHY GEN2 address */ - hdmi_writel(hdmi_dev, PHY_I2CM_SLAVE, PHY_GEN2_ADDR); - - /* config the required PHY I2C register */ - phy_mpll = - get_phy_mpll_tab(hdmi_drv->pixclock, pixel_repet, color_depth); - if (phy_mpll) { - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_OPMODE_PLLCFG, - v_PREP_DIV(phy_mpll->prep_div) | - v_TMDS_CNTRL(phy_mpll->tmdsmhl_cntrl) | - v_OPMODE(phy_mpll->opmode) | - v_FBDIV2_CNTRL(phy_mpll->fbdiv2_cntrl) | - v_FBDIV1_CNTRL(phy_mpll->fbdiv1_cntrl) | - v_REF_CNTRL(phy_mpll->ref_cntrl) | - v_MPLL_N_CNTRL(phy_mpll->n_cntrl)); - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_PLLCURRCTRL, - v_MPLL_PROP_CNTRL(phy_mpll->prop_cntrl) | - v_MPLL_INT_CNTRL(phy_mpll->int_cntrl)); - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_PLLGMPCTRL, - v_MPLL_GMP_CNTRL(phy_mpll->gmp_cntrl)); - } - if (hdmi_drv->pixclock <= 74250000) { - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL, - v_OVERRIDE(1) | v_SLOPEBOOST(0) - | v_TX_SYMON(1) | v_TX_TRAON(0) | - v_TX_TRBON(0) | v_CLK_SYMON(1)); - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_TERM_RESIS, - v_TX_TERM(R100_Ohms)); - } else if (hdmi_drv->pixclock == 148500000) { - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL, - v_OVERRIDE(1) | v_SLOPEBOOST(3) - | v_TX_SYMON(1) | v_TX_TRAON(0) | - v_TX_TRBON(0) | v_CLK_SYMON(1)); - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_TERM_RESIS, - v_TX_TERM(R100_Ohms)); - } else if (hdmi_drv->pixclock == 297000000) { - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL, - v_OVERRIDE(1) | v_SLOPEBOOST(2) - | v_TX_SYMON(1) | v_TX_TRAON(0) | - v_TX_TRBON(0) | v_CLK_SYMON(1)); - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_TERM_RESIS, - v_TX_TERM(R100_Ohms)); - } else if (hdmi_drv->pixclock > 297000000) { - /* TODO Daisen wait to add and modify */ - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_TERM_RESIS, - v_TX_TERM(R13333_Ohms)); - } - - if (hdmi_drv->pixclock < 297000000) - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_VLEVCTRL, - v_SUP_TXLVL(20) | v_SUP_CLKLVL(19)); - else - rk3288_hdmi_write_phy(hdmi_dev, PHYTX_VLEVCTRL, - v_SUP_TXLVL(17) | v_SUP_CLKLVL(16)); - - /* power on PHY */ - hdmi_writel(hdmi_dev, PHY_CONF0, 0x6e); - /* - hdmi_msk_reg(hdmi_dev, PHY_CONF0, - m_PDDQ_SIG | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG, - v_PDDQ_SIG(0) | v_TXPWRON_SIG(1) | v_ENHPD_RXSENSE_SIG(1)); - */ - - /* check if the PHY PLL is locked */ -#define PHY_TIMEOUT 10000 - while (i++ < PHY_TIMEOUT) { - if ((i % 100) == 0) { - stat = hdmi_readl(hdmi_dev, PHY_STAT0); - if (stat & m_PHY_LOCK) { - break; - } - } - } - if ((stat & m_PHY_LOCK) == 0) { - stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK); - hdmi_err(hdmi_dev->dev, - "PHY PLL not locked: PCLK_ON=%d,TMDSCLK_ON=%d\n", - (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5); - return -1; - } - - return 0; -} - -int rk3288_hdmi_config_vsi(struct hdmi *hdmi_drv, unsigned char vic_3d, - unsigned char format, int auto_send) -{ - int i = 0; - unsigned char data[3] = { 0 }; - int id = 0x000c03; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - hdmi_dbg(hdmi_drv->dev, "[%s] vic %d format %d.\n", __func__, - vic_3d, format); - hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(0)); - hdmi_writel(hdmi_dev, FC_VSDIEEEID0, id & 0xff); - hdmi_writel(hdmi_dev, FC_VSDIEEEID1, (id >> 8) & 0xff); - hdmi_writel(hdmi_dev, FC_VSDIEEEID2, (id >> 16) & 0xff); - - data[0] = format << 5; /* PB4 --HDMI_Video_Format */ - switch (format) { - case HDMI_VIDEO_FORMAT_4Kx2K: - data[1] = vic_3d; /* PB5--HDMI_VIC */ - data[2] = 0; - break; - case HDMI_VIDEO_FORMAT_3D: - data[1] = vic_3d << 4; /* PB5--3D_Structure field */ - data[2] = 0; /* PB6--3D_Ext_Data field */ - break; - default: - data[1] = 0; - data[2] = 0; - break; - } - - for (i = 0; i < 3; i++) - hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]); - - if (auto_send) { - hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, - v_VSD_AUTO(auto_send)); - } else { - hdmi_msk_reg(hdmi_dev, FC_DATMAN, m_VSD_MAN, v_VSD_MAN(1)); - } - - return 0; -} - -static void rk3288_hdmi_config_avi(struct hdmi *hdmi_drv, unsigned char vic, - struct hdmi_video_para *vpara) -{ - unsigned char colorimetry, ext_colorimetry, aspect_ratio, y1y0; - unsigned char rgb_quan_range = AVI_QUANTIZATION_RANGE_DEFAULT; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - /* Set AVI infoFrame Data byte1 */ - if (vpara->output_color == VIDEO_OUTPUT_YCBCR444) - y1y0 = AVI_COLOR_MODE_YCBCR444; - else if (vpara->output_color == VIDEO_OUTPUT_YCBCR422) - y1y0 = AVI_COLOR_MODE_YCBCR422; - else if (vpara->output_color == VIDEO_OUTPUT_YCBCR420) - y1y0 = AVI_COLOR_MODE_YCBCR420; - else - y1y0 = AVI_COLOR_MODE_RGB; - - hdmi_msk_reg(hdmi_dev, FC_AVICONF0, m_FC_ACTIV_FORMAT | m_FC_RGC_YCC, - v_FC_RGC_YCC(y1y0) | v_FC_ACTIV_FORMAT(1)); - - /* Set AVI infoFrame Data byte2 */ - switch (vic) { - case HDMI_720x480i_60Hz_4_3: - case HDMI_720x576i_50Hz_4_3: - case HDMI_720x480p_60Hz_4_3: - case HDMI_720x576p_50Hz_4_3: - aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3; - colorimetry = AVI_COLORIMETRY_SMPTE_170M; - break; - case HDMI_720x480i_60Hz_16_9: - case HDMI_720x576i_50Hz_16_9: - case HDMI_720x480p_60Hz_16_9: - case HDMI_720x576p_50Hz_16_9: - aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9; - colorimetry = AVI_COLORIMETRY_SMPTE_170M; - break; - default: - aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9; - colorimetry = AVI_COLORIMETRY_ITU709; - } - - if (vpara->color_depth > HDMI_COLOR_DEPTH_8BIT) { - colorimetry = AVI_COLORIMETRY_EXTENDED; - ext_colorimetry = 6; - } else if (vpara->output_color == VIDEO_OUTPUT_RGB444) { - colorimetry = AVI_COLORIMETRY_NO_DATA; - ext_colorimetry = 0; - } - - hdmi_writel(hdmi_dev, FC_AVICONF1, - v_FC_COLORIMETRY(colorimetry) | - v_FC_PIC_ASPEC_RATIO(aspect_ratio) | - v_FC_ACT_ASPEC_RATIO - (ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME)); - - /* Set AVI infoFrame Data byte3 */ - hdmi_msk_reg(hdmi_dev, FC_AVICONF2, - m_FC_EXT_COLORIMETRY | m_FC_QUAN_RANGE, - v_FC_EXT_COLORIMETRY(ext_colorimetry) | - v_FC_QUAN_RANGE(rgb_quan_range)); - - /* Set AVI infoFrame Data byte4 */ - hdmi_writel(hdmi_dev, FC_AVIVID, (vic & 0xff)); - - /* Set AVI infoFrame Data byte5 */ - hdmi_msk_reg(hdmi_dev, FC_AVICONF3, m_FC_YQ | m_FC_CN, - v_FC_YQ(YQ_LIMITED_RANGE) | v_FC_CN(CN_GRAPHICS)); - -} - -static const char coeff_csc[][24] = { - /* G R B Bias */ - /* A1 | A2 | A3 | A4 | */ - /* B1 | B2 | B3 | B4 | */ - /* C1 | C2 | C3 | C4 | */ - { /* CSC_RGB_0_255_TO_RGB_16_235_8BIT */ - 0x1b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* G */ - 0x00, 0x00, 0x1b, 0x80, 0x00, 0x00, 0x00, 0x20, /* R */ - 0x00, 0x00, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x20, /* B */ - }, - { /* CSC_RGB_0_255_TO_RGB_16_235_10BIT */ - 0x1b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* G */ - 0x00, 0x00, 0x1b, 0x80, 0x00, 0x00, 0x00, 0x80, /* R */ - 0x00, 0x00, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x80, /* B */ - }, -#if 0 - { /* CSC_RGB_0_255_TO_ITU601_16_235_8BIT */ - 0x25, 0x91, 0x13, 0x23, 0x07, 0x4c, 0x00, 0x00, /* Y */ - 0xe5, 0x34, 0x20, 0x00, 0xfa, 0xcc, 0x02, 0x00, /* Cr */ - 0xea, 0xcd, 0xf5, 0x33, 0x20, 0x00, 0x02, 0x00, /* Cb */ - }, - { /* CSC_RGB_0_255_TO_ITU601_16_235_10BIT */ - 0x25, 0x91, 0x13, 0x23, 0x07, 0x4c, 0x00, 0x00, /* Y */ - 0xe5, 0x34, 0x20, 0x00, 0xfa, 0xcc, 0x08, 0x00, /* Cr */ - 0xea, 0xcd, 0xf5, 0x33, 0x20, 0x00, 0x08, 0x00, /* Cb */ - }, - { /* CSC_RGB_0_255_TO_ITU709_16_235_8BIT */ - 0x2d, 0xc6, 0x0d, 0x9b, 0x04, 0x9f, 0x00, 0x00, /* Y */ - 0xe2, 0xef, 0x20, 0x00, 0xfd, 0x11, 0x02, 0x00, /* Cr */ - 0xe7, 0x55, 0xf8, 0xab, 0x20, 0x00, 0x02, 0x00, /* Cb */ - }, - { /* CSC_RGB_0_255_TO_ITU709_16_235_10BIT */ - 0x2d, 0xc6, 0x0d, 0x9b, 0x04, 0x9f, 0x00, 0x00, /* Y */ - 0xe2, 0xef, 0x20, 0x00, 0xfd, 0x11, 0x08, 0x00, /* Cr */ - 0xe7, 0x55, 0xf8, 0xab, 0x20, 0x00, 0x08, 0x00, /* Cb */ - }, -#else - { /* CSC_RGB_0_255_TO_ITU601_16_235_8BIT */ - 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x00, 0x40, /* Y */ - 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x02, 0x00, /* Cr */ - 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x02, 0x00, /* Cb */ - }, - { /* CSC_RGB_0_255_TO_ITU601_16_235_10BIT */ - 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x01, 0x00, /* Y */ - 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x08, 0x00, /* Cr */ - 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x08, 0x00, /* Cb */ - }, - { /* CSC_RGB_0_255_TO_ITU709_16_235_8BIT */ - 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x00, 0x40, /* Y */ - 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x02, 0x00, /* Cr */ - 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x02, 0x00, /* Cb */ - }, - { /* CSC_RGB_0_255_TO_ITU709_16_235_10BIT */ - 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x01, 0x00, /* Y */ - 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x08, 0x00, /* Cr */ - 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x08, 0x00, /* Cb */ - }, -#endif - /* Y Cr Cb Bias */ - { /* CSC_ITU601_16_235_TO_RGB_0_255_8BIT */ - 0x20, 0x00, 0x69, 0x26, 0x74, 0xfd, 0x01, 0x0e, /* G */ - 0x20, 0x00, 0x2c, 0xdd, 0x00, 0x00, 0x7e, 0x9a, /* R */ - 0x20, 0x00, 0x00, 0x00, 0x38, 0xb4, 0x7e, 0x3b, /* B */ - }, - { /* CSC_ITU709_16_235_TO_RGB_0_255_8BIT */ - 0x20, 0x00, 0x71, 0x06, 0x7a, 0x02, 0x00, 0xa7, /* G */ - 0x20, 0x00, 0x32, 0x64, 0x00, 0x00, 0x7e, 0x6d, /* R */ - 0x20, 0x00, 0x00, 0x00, 0x3b, 0x61, 0x7e, 0x25, /* B */ - }, -}; - -static int rk3288_hdmi_video_csc(struct hdmi *hdmi_drv, - struct hdmi_video_para *vpara) -{ - int i, mode, interpolation, decimation, csc_scale; - const char *coeff = NULL; - unsigned char color_depth = 0; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - if ((vpara->input_color == vpara->output_color) - && (vpara->color_limit_range == 0)) { - hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL, m_FEED_THROUGH_OFF, - v_FEED_THROUGH_OFF(0)); - return 0; - } - - if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR422 && - (vpara->output_color == VIDEO_OUTPUT_RGB444 - || vpara->output_color == VIDEO_OUTPUT_YCBCR444)) { - interpolation = 1; - hdmi_msk_reg(hdmi_dev, CSC_CFG, m_CSC_INTPMODE, - v_CSC_INTPMODE(interpolation)); - } - - if ((vpara->input_color == VIDEO_INPUT_COLOR_RGB - || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444) - && vpara->output_color == VIDEO_OUTPUT_YCBCR422) { - decimation = 1; - hdmi_msk_reg(hdmi_dev, CSC_CFG, m_CSC_DECIMODE, - v_CSC_DECIMODE(decimation)); - } - - switch (vpara->vic) { - case HDMI_720x480i_60Hz_4_3: - case HDMI_720x576i_50Hz_4_3: - case HDMI_720x480p_60Hz_4_3: - case HDMI_720x576p_50Hz_4_3: - case HDMI_720x480i_60Hz_16_9: - case HDMI_720x576i_50Hz_16_9: - case HDMI_720x480p_60Hz_16_9: - case HDMI_720x576p_50Hz_16_9: - if (vpara->input_color == VIDEO_INPUT_COLOR_RGB - && vpara->output_color >= VIDEO_OUTPUT_YCBCR444) { - mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT; - csc_scale = 0; - } else if (vpara->input_color >= VIDEO_OUTPUT_YCBCR444 - && vpara->output_color == VIDEO_OUTPUT_RGB444) { - mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT; - csc_scale = 1; - } - break; - default: - if (vpara->input_color == VIDEO_INPUT_COLOR_RGB - && vpara->output_color >= VIDEO_OUTPUT_YCBCR444) { - mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT; - csc_scale = 0; - } else if (vpara->input_color >= VIDEO_OUTPUT_YCBCR444 - && vpara->output_color == VIDEO_OUTPUT_RGB444) { - mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT; - csc_scale = 1; - } - break; - } - - if ((vpara->input_color == VIDEO_INPUT_COLOR_RGB) - && (vpara->output_color == VIDEO_OUTPUT_RGB444) - && (vpara->color_limit_range == 1)) { - mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT; - csc_scale = 1; - } - - switch (vpara->color_depth) { - case HDMI_COLOR_DEPTH_8BIT: - color_depth = COLOR_DEPTH_24BIT; - break; - case HDMI_COLOR_DEPTH_10BIT: - color_depth = COLOR_DEPTH_30BIT; - mode += 1; - break; - case HDMI_COLOR_DEPTH_12BIT: - color_depth = COLOR_DEPTH_36BIT; - mode += 2; - break; - case HDMI_COLOR_DEPTH_16BIT: - color_depth = COLOR_DEPTH_48BIT; - mode += 3; - break; - default: - color_depth = COLOR_DEPTH_24BIT; - break; - } - - coeff = coeff_csc[mode]; - for (i = 0; i < 24; i++) { - hdmi_writel(hdmi_dev, CSC_COEF_A1_MSB + i, coeff[i]); - } - hdmi_msk_reg(hdmi_dev, CSC_SCALE, m_CSC_SCALE, v_CSC_SCALE(csc_scale)); - /* config CSC_COLOR_DEPTH */ - hdmi_msk_reg(hdmi_dev, CSC_SCALE, m_CSC_COLOR_DEPTH, - v_CSC_COLOR_DEPTH(color_depth)); - - /* enable CSC */ - hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL, m_FEED_THROUGH_OFF, - v_FEED_THROUGH_OFF(1)); - return 0; -} - -int rk3288_hdmi_config_video(struct hdmi *hdmi_drv, - struct hdmi_video_para *vpara) -{ - if (rk3288_hdmi_video_forceOutput(hdmi_drv, 1) < 0) - return -1; - if (rk3288_hdmi_video_frameComposer(hdmi_drv, vpara) < 0) - return -1; - if (rk3288_hdmi_video_packetizer(hdmi_drv, vpara) < 0) - return -1; - if (rk3288_hdmi_video_csc(hdmi_drv, vpara) < 0) - return -1; - if (rk3288_hdmi_video_sampler(hdmi_drv, vpara) < 0) - return -1; - - if (vpara->output_mode == OUTPUT_HDMI) { - rk3288_hdmi_config_avi(hdmi_drv, vpara->vic, vpara); - hdmi_dbg(hdmi_drv->dev, "[%s] sucess output HDMI.\n", - __func__); - - if (vpara->format_3d != 0) - rk3288_hdmi_config_vsi(hdmi_drv, vpara->format_3d, - HDMI_VIDEO_FORMAT_3D, 1); -#ifndef HDMI_VERSION_2 - else if ((vpara->vic > 92 && vpara->vic < 96) - || (vpara->vic == 98)) { - vpara->vic = (vpara->vic == 98) ? 4 : (96 - vpara->vic); - rk3288_hdmi_config_vsi(hdmi_drv, vpara->vic, - HDMI_VIDEO_FORMAT_4Kx2K, 1); - } -#endif - else - rk3288_hdmi_config_vsi(hdmi_drv, vpara->vic, - HDMI_VIDEO_FORMAT_NORMAL, 1); - } else { - hdmi_dbg(hdmi_drv->dev, "[%s] sucess output DVI.\n", - __func__); - } - - rk3288_hdmi_set_pwr_mode(hdmi_drv, NORMAL); - rk3288_hdmi_config_phy(hdmi_drv, vpara->pixel_repet, - vpara->color_depth); - return 0; -} - -static void rk3288_hdmi_config_aai(struct hdmi *hdmi_drv, - struct hdmi_audio *audio) -{ - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - /* Refer to CEA861-E Audio infoFrame */ - /* Set both Audio Channel Count and - * Audio Coding Type Refer to Stream Head for HDMI - */ - hdmi_msk_reg(hdmi_dev, FC_AUDICONF0, m_FC_CHN_CNT | m_FC_CODING_TYEP, - v_FC_CHN_CNT(0) | v_FC_CODING_TYEP(0)); - - /* Set both Audio Sample Size and - * Sample Frequency Refer to Stream Head for HDMI - */ - hdmi_msk_reg(hdmi_dev, FC_AUDICONF1, - m_FC_SAMPLE_SIZE | m_FC_SAMPLE_FREQ, - v_FC_SAMPLE_SIZE(0) | v_FC_SAMPLE_FREQ(0)); - - /* Set Channel Allocation */ - hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00); - - /* Set LFEPBL¡¢DOWN-MIX INH and LSV */ - hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00); -} - -int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio) -{ - int word_length = 0, channel = 0, mclk_fs; - unsigned int N = 0, CTS = 0; - unsigned char layout_value = 0; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - if (audio->channel < 3) - channel = I2S_CHANNEL_1_2; - else if (audio->channel < 5) - channel = I2S_CHANNEL_3_4; - else if (audio->channel < 7) - channel = I2S_CHANNEL_5_6; - else - channel = I2S_CHANNEL_7_8; - - switch (audio->rate) { - case HDMI_AUDIO_FS_32000: - mclk_fs = FS_256; - if (hdmi_drv->pixclock >= 594000000) - N = N_32K_HIGHCLK; - else if (hdmi_drv->pixclock == 297000000) - N = N_32K_MIDCLK; - else - N = N_32K_LOWCLK; - - /* div a num to avoid the value is exceed 2^32(int) */ - CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 32); - break; - case HDMI_AUDIO_FS_44100: - mclk_fs = FS_256; - if (hdmi_drv->pixclock >= 594000000) - N = N_441K_HIGHCLK; - else if (hdmi_drv->pixclock == 297000000) - N = N_441K_MIDCLK; - else - N = N_441K_LOWCLK; - - CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 100, 441); - break; - case HDMI_AUDIO_FS_48000: - mclk_fs = FS_256; - if (hdmi_drv->pixclock >= 594000000) /* FS_153.6 */ - N = N_48K_HIGHCLK; - else if (hdmi_drv->pixclock == 297000000) - N = N_48K_MIDCLK; - else - N = N_48K_LOWCLK; - - CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 48); - break; - case HDMI_AUDIO_FS_88200: - mclk_fs = FS_256; - if (hdmi_drv->pixclock >= 594000000) - N = N_882K_HIGHCLK; - else if (hdmi_drv->pixclock == 297000000) - N = N_882K_MIDCLK; - else - N = N_882K_LOWCLK; - - CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 100, 882); - break; - case HDMI_AUDIO_FS_96000: - mclk_fs = FS_256; - if (hdmi_drv->pixclock >= 594000000) /* FS_153.6 */ - N = N_96K_HIGHCLK; - else if (hdmi_drv->pixclock == 297000000) - N = N_96K_MIDCLK; - else - N = N_96K_LOWCLK; - - CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 96); - break; - case HDMI_AUDIO_FS_176400: - mclk_fs = FS_256; - if (hdmi_drv->pixclock >= 594000000) - N = N_1764K_HIGHCLK; - else if (hdmi_drv->pixclock == 297000000) - N = N_1764K_MIDCLK; - else - N = N_1764K_LOWCLK; - - CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 100, 1764); - break; - case HDMI_AUDIO_FS_192000: - mclk_fs = FS_256; - if (hdmi_drv->pixclock >= 594000000) /* FS_153.6 */ - N = N_192K_HIGHCLK; - else if (hdmi_drv->pixclock == 297000000) - N = N_192K_MIDCLK; - else - N = N_192K_LOWCLK; - - CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 192); - break; - default: - hdmi_err(hdmi_drv->dev, - "[%s] not support such sample rate %d\n", __func__, - audio->rate); - return -ENOENT; - } - - switch (audio->word_length) { - case HDMI_AUDIO_WORD_LENGTH_16bit: - word_length = I2S_16BIT_SAMPLE; - break; - case HDMI_AUDIO_WORD_LENGTH_20bit: - word_length = I2S_20BIT_SAMPLE; - break; - case HDMI_AUDIO_WORD_LENGTH_24bit: - word_length = I2S_24BIT_SAMPLE; - break; - default: - word_length = I2S_16BIT_SAMPLE; - } - - hdmi_dbg(hdmi_drv->dev, "rate = %d, tmdsclk = %d, N = %d, CTS = %d\n", - audio->rate, hdmi_drv->tmdsclk, N, CTS); - /* more than 2 channels => layout 1 else layout 0 - * TODO Daisen wait to modify - */ - layout_value = (audio->channel > 2) ? 1 : 0; - hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, m_AUD_PACK_LAYOUT, - v_AUD_PACK_LAYOUT(layout_value)); - - if (hdmi_drv->audio.type == INPUT_SPDIF) { - hdmi_msk_reg(hdmi_dev, AUD_CONF0, m_I2S_SEL, - v_I2S_SEL(AUDIO_SPDIF_GPA)); - hdmi_msk_reg(hdmi_dev, AUD_SPDIF1, m_SET_NLPCM | m_SPDIF_WIDTH, - v_SET_NLPCM(PCM_LINEAR) | - v_SPDIF_WIDTH(word_length)); - /* Mask fifo empty and full int and reset fifo */ - hdmi_msk_reg(hdmi_dev, AUD_SPDIFINT, - m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK, - v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1)); - hdmi_msk_reg(hdmi_dev, AUD_SPDIF0, m_SW_SAUD_FIFO_RST, - v_SW_SAUD_FIFO_RST(1)); - } else { - hdmi_msk_reg(hdmi_dev, AUD_CONF0, m_I2S_SEL | m_I2S_IN_EN, - v_I2S_SEL(AUDIO_I2S) | v_I2S_IN_EN(channel)); - hdmi_writel(hdmi_dev, AUD_CONF1, - v_I2S_MODE(I2S_STANDARD_MODE) | - v_I2S_WIDTH(word_length)); - /* Mask fifo empty and full int and reset fifo */ - hdmi_msk_reg(hdmi_dev, AUD_INT, - m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK, - v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1)); - hdmi_msk_reg(hdmi_dev, AUD_CONF0, m_SW_AUD_FIFO_RST, - v_SW_AUD_FIFO_RST(1)); - } - - hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS, m_LFS_FACTOR, - v_LFS_FACTOR(mclk_fs)); - - /* Set N value */ - hdmi_msk_reg(hdmi_dev, AUD_N3, m_AUD_N3, v_AUD_N3(N >> 16)); - hdmi_writel(hdmi_dev, AUD_N2, (N >> 8) & 0xff); - hdmi_writel(hdmi_dev, AUD_N1, N & 0xff); - /* Set CTS by manual */ - hdmi_msk_reg(hdmi_dev, AUD_CTS3, m_N_SHIFT | m_CTS_MANUAL | m_AUD_CTS3, - v_N_SHIFT(N_SHIFT_1) | v_CTS_MANUAL(1) | v_AUD_CTS3(CTS >> - 16)); - hdmi_writel(hdmi_dev, AUD_CTS2, (CTS >> 8) & 0xff); - hdmi_writel(hdmi_dev, AUD_CTS1, CTS & 0xff); - - hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE, - v_AUDCLK_DISABLE(0)); - rk3288_hdmi_config_aai(hdmi_drv, audio); - - return 0; -} - -void rk3288_hdmi_control_output(struct hdmi *hdmi_drv, int enable) -{ - hdmi_dbg(hdmi_drv->dev, "[%s] %d\n", __func__, enable); - if (enable == 0) { - rk3288_hdmi_av_mute(hdmi_drv, 1); - rk3288_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR); - } else { - if (hdmi_drv->pwr_mode == LOWER_PWR) - rk3288_hdmi_set_pwr_mode(hdmi_drv, NORMAL); - - /* disable blue screen transmission - * after turning on all necessary blocks - */ - rk3288_hdmi_video_forceOutput(hdmi_drv, 0); - rk3288_hdmi_av_mute(hdmi_drv, 0); - } -} - -int rk3288_hdmi_insert(struct hdmi *hdmi_drv) -{ - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - - /* report HPD state to HDCP (after configuration) */ - hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_RX_DETECT, v_RX_DETECT(1)); - - return 0; -} - -int rk3288_hdmi_removed(struct hdmi *hdmi_drv) -{ - rk3288_hdmi_control_output(hdmi_drv, 0); - dev_printk(KERN_INFO, hdmi_drv->dev, "Removed.\n"); - return 0; -} - -int rk3288_hdmi_initial(struct hdmi *hdmi_drv) -{ - int rc = HDMI_ERROR_SUCESS; - - hdmi_drv->pwr_mode = NORMAL; - hdmi_drv->insert = rk3288_hdmi_insert; - hdmi_drv->remove = rk3288_hdmi_removed; - hdmi_drv->control_output = rk3288_hdmi_control_output; - hdmi_drv->config_video = rk3288_hdmi_config_video; - hdmi_drv->config_audio = rk3288_hdmi_config_audio; - hdmi_drv->detect_hotplug = rk3288_hdmi_detect_hotplug; - hdmi_drv->read_edid = rk3288_hdmi_read_edid; - hdmi_drv->support_vic = rk3288_hdmi_support_vic; - hdmi_drv->support_vic_num = ARRAY_SIZE(rk3288_hdmi_support_vic); - - rk3288_hdmi_reset(hdmi_drv); - - if (hdmi_drv->hdcp_power_on_cb) - rc = hdmi_drv->hdcp_power_on_cb(); - - return rc; -} - -irqreturn_t hdmi_irq(int irq, void *priv) -{ - struct hdmi *hdmi_drv = (struct hdmi *)priv; - struct rk3288_hdmi_device *hdmi_dev = - container_of(hdmi_drv, struct rk3288_hdmi_device, driver); - int phy_int = 0, i2cm_int = 0, phy_i2cm_int = 0, cec_int = 0; - int aud_dma_int = 0; - - /* read interrupt */ - phy_int = hdmi_readl(hdmi_dev, IH_PHY_STAT0); - i2cm_int = hdmi_readl(hdmi_dev, IH_I2CM_STAT0); - phy_i2cm_int = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0); - cec_int = hdmi_readl(hdmi_dev, IH_CEC_STAT0); - aud_dma_int = hdmi_readl(hdmi_dev, IH_AHBDMAAUD_STAT0); - /* - hdcp_int = hdmi_readl(hdmi_dev, A_APIINTSTAT); - */ - - /* clear interrupt */ - hdmi_writel(hdmi_dev, IH_PHY_STAT0, phy_int); - hdmi_writel(hdmi_dev, IH_I2CM_STAT0, i2cm_int); - hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0, phy_i2cm_int); - hdmi_writel(hdmi_dev, IH_CEC_STAT0, cec_int); - hdmi_writel(hdmi_dev, IH_AHBDMAAUD_STAT0, aud_dma_int); - /* - hdmi_writel(hdmi_dev, A_APIINTCLR, hdcp_int); - */ - - /* HPD or RX_SENSE */ - if ((phy_int & m_HPD) || ((phy_int & 0x3c) == 0x3c)) { - if (hdmi_drv->state == HDMI_SLEEP) - hdmi_drv->state = WAIT_HOTPLUG; - queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, - msecs_to_jiffies(5)); - } - /* I2CM write or read result */ - if (i2cm_int & (m_SCDC_READREQ | m_I2CM_DONE | m_I2CM_ERROR)) { - /* spin_lock(&hdmi_drv->irq_lock); */ - hdmi_dev->i2cm_int = i2cm_int; - /* spin_unlock(&hdmi_drv->irq_lock); */ - } - /* PHY I2CM write or read result */ - if (phy_i2cm_int & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) { - /* mutex_lock(&hdmi_dev->int_mutex); */ - hdmi_dev->phy_i2cm_int = phy_i2cm_int; - /* mutex_unlock(&hdmi_dev->int_mutex); */ - } - /* CEC */ - if (cec_int) { - } - /* HDCP */ - if (hdmi_drv->hdcp_irq_cb) - hdmi_drv->hdcp_irq_cb(i2cm_int); - - return IRQ_HANDLED; -} diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h deleted file mode 100644 index 6d175c372a02..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h +++ /dev/null @@ -1,1481 +0,0 @@ -#ifndef _RK3288_HDMI_HW_H -#define _RK3288_HDMI_HW_H -#include "../../rk_hdmi.h" - -#define HDMI_INT_USE_POLL 1 /* TODO Daisen wait to modify */ - -enum PWR_MODE { - NORMAL, - LOWER_PWR, -}; -enum { - OUTPUT_DVI = 0, - OUTPUT_HDMI, -}; -enum { - INPUT_IIS, - INPUT_SPDIF -}; - -/* Color Space Convertion Mode */ -enum { - CSC_RGB_0_255_TO_RGB_16_235_8BIT, /* RGB 0-255 input to RGB 16-235 output that is 8bit clolor depth */ - CSC_RGB_0_255_TO_RGB_16_235_10BIT, /* RGB 0-255 input to RGB 16-235 output that is 8bit clolor depth */ - CSC_RGB_0_255_TO_ITU601_16_235_8BIT, /* RGB 0-255 input to YCbCr 16-235 output according BT601 that is 8bit clolor depth */ - CSC_RGB_0_255_TO_ITU601_16_235_10BIT, /* RGB 0-255 input to YCbCr 16-235 output according BT601 that is 10bit clolor depth */ - CSC_RGB_0_255_TO_ITU709_16_235_8BIT, /* RGB 0-255 input to YCbCr 16-235 output accroding BT709 that is 8bit clolor depth */ - CSC_RGB_0_255_TO_ITU709_16_235_10BIT, /* RGB 0-255 input to YCbCr 16-235 output accroding BT709 that is 10bit clolor depth */ - CSC_ITU601_16_235_TO_RGB_16_235_8BIT, /* YCbCr 16-235 input to RGB 16-235 output according BT601 that is 8bit clolor depth */ - CSC_ITU709_16_235_TO_RGB_16_235_8BIT, /* YCbCr 16-235 input to RGB 16-235 output according BT709 that is 8bit clolor depth */ - CSC_ITU601_16_235_TO_RGB_0_255_8BIT, /* YCbCr 16-235 input to RGB 0-255 output according BT601 that is 8bit clolor depth */ - CSC_ITU709_16_235_TO_RGB_0_255_8BIT /* YCbCr 16-235 input to RGB 0-255 output according BT709 that is 8bit clolor depth */ -}; - -/* VIC VIDEO FORMAT */ -enum { - HDMI_VIDEO_FORMAT_NORMAL = 0, - HDMI_VIDEO_FORMAT_4Kx2K, - HDMI_VIDEO_FORMAT_3D -}; - -#define HDMI_SCL_RATE (100*1000) -#define DDC_I2C_EDID_ADDR 0x50 /* 0xA0/2 = 0x50 */ -#define DDC_I2C_SEG_ADDR 0x30 /* 0x60/2 = 0x30 */ - -/* Register and Field Descriptions */ -/* Identification Registers */ -#define IDENTIFICATION_BASE 0x0000 - -#define DESIGN_ID 0x0000 -#define REVISION_ID 0x0001 -#define PRODUCT_ID0 0x0002 -#define PRODUCT_ID1 0x0003 - -#define CONFIG0_ID 0x0004 -#define m_PREPEN (1 << 7) -#define m_AUDSPDIF (1 << 5) -#define m_AUDI2S (1 << 4) -#define m_HDMI14 (1 << 3) -#define m_CSC (1 << 2) -#define m_CEC (1 << 1) -#define m_HDCP (1 << 0) - -#define CONFIG1_ID 0x0005 -#define m_HDMI20 (1 << 5) -#define m_CONFAPB (1 << 1) - -#define CONFIG2_ID 0x0006 -enum PHYTYPE { - HDMI_TX_PHY = 0x00, - HDMI_MHL_WITH_HEAC_PHY = 0xb2, - HDMI_MHL_PHY = 0xc2, - HDMI_3D_TX_WITH_HEAC_PHY = 0xe2, - HDMI_3D_TX_PHY = 0xf2 -}; - -#define CONFIG3_ID 0x0007 -#define m_AHB_AUD_DMA (1 << 1) -#define m_GP_AUD (1 << 0) - -/* Interrupt Registers */ -#define INTERRUPT_BASE 0x0100 - -#define IH_FC_STAT0 0x0100 -#define m_AUD_INFOFRAME (1 << 7) -#define m_AUD_CONTENT_PROTECT (1 << 6) -#define m_AUD_HBR (1 << 5) -#define m_AUD_SAMPLE (1 << 2) -#define m_AUD_CLK_REGEN (1 << 1) -#define m_NULL_PACKET (1 << 0) - -#define IH_FC_STAT1 0x0101 -#define m_GMD (1 << 7) -#define m_ISCR1 (1 << 6) -#define m_ISCR2 (1 << 5) -#define m_VSD (1 << 4) -#define m_SPD (1 << 3) -#define m_AVI_INFOFRAME (1 << 1) -#define m_GCP (1 << 0) - -#define IH_FC_STAT2 0x0102 -#define m_LOWPRIO_OVERFLOW (1 << 1) -#define m_HIGHPRIO_OVERFLOW (1 << 0) - -#define IH_AS_SATA0 0x0103 -#define m_FIFO_UNDERRUN (1 << 4) -#define m_FIFO_OVERRUN (1 << 3) -#define m_AUD_FIFO_UDFLOW_THR (1 << 2) -#define m_AUD_FIFO_UDFLOW (1 << 1) -#define m_AUD_FIFO_OVERFLOW (1 << 0) - -#define IH_PHY_STAT0 0x0104 -#define m_RX_SENSE3 (1 << 5) -#define m_RX_SENSE2 (1 << 4) -#define m_RX_SENSE1 (1 << 3) -#define m_RX_SENSE0 (1 << 2) -#define m_TX_PHY_LOCK (1 << 1) -#define m_HPD (1 << 0) - -#define IH_I2CM_STAT0 0x0105 -#define m_SCDC_READREQ (1 << 2) -#define m_I2CM_DONE (1 << 1) -#define m_I2CM_ERROR (1 << 0) - -#define IH_CEC_STAT0 0x0106 -#define m_WAKEUP (1 << 6) -#define m_ERR_FOLLOW (1 << 5) -#define m_ERR_INITIATOR (1 << 4) -#define m_ARB_LOST (1 << 3) -#define m_NACK (1 << 2) -#define m_EOM (1 << 1) -#define m_DONE (1 << 0) - -#define IH_VP_STAT0 0x0107 -#define m_FIFOFULL_REPET (1 << 7) -#define m_FIFOEMPTY_REPET (1 << 6) -#define m_FIFOFULL_PACK (1 << 5) -#define m_FIFOEMPTY_PACK (1 << 4) -#define m_FIFOFULL_REMAP (1 << 3) -#define m_FIFOEMPTY_REMAP (1 << 2) -#define m_FIFOFULL_BYPASS (1 << 1) -#define m_FIFOEMPTY_BYPASS (1 << 0) - -#define IH_I2CMPHY_STAT0 0x0108 -#define m_I2CMPHY_DONE (1 << 1) -#define m_I2CMPHY_ERR (1 << 0) - -#define IH_AHBDMAAUD_STAT0 0x0109 -#define m_AUDDMA_INT_BUFOVERRUN (1 << 6) -#define m_AUDDMA_INT_ERR (1 << 5) -#define m_AUDDMA_INT_LOST (1 << 4) -#define m_AUDDMA_INT_RETRYSPLIT (1 << 3) -#define m_AUDDMA_INT_DONE (1 << 2) -#define m_AUDDMA_INT_BUFFULL (1 << 1) -#define m_AUDDMA_INT_BUFEMPTY (1 << 0) - -#define IH_DECODE 0x0170 -#define m_IH_FC_STAT0 (1 << 7) -#define m_IH_FC_STAT1 (1 << 6) -#define m_IH_FC_STAT2_VP (1 << 5) -#define m_IH_AS_STAT0 (1 << 4) -#define m_IH_PHY (1 << 3) -#define m_IH_I2CM_STAT0 (1 << 2) -#define m_IH_CEC_STAT0 (1 << 1) -#define m_IH_AHBDMAAUD_STAT0 (1 << 0) - -#define IH_MUTE_FC_STAT0 0x0180 -#define m_AUDI_MUTE (1 << 7) -#define m_ACP_MUTE (1 << 6) -#define m_DST_MUTE (1 << 4) -#define m_OBA_MUTE (1 << 3) -#define m_AUDS_MUTE (1 << 2) -#define m_ACR_MUTE (1 << 1) -#define m_NULL_MUTE (1 << 0) - -#define IH_MUTE_FC_STAT1 0x0181 -#define m_GMD_MUTE (1 << 7) -#define m_ISCR1_MUTE (1 << 6) -#define m_ISCR2_MUTE (1 << 5) -#define m_VSD_MUTE (1 << 4) -#define m_SPD_MUTE (1 << 3) -#define m_AVI_MUTE (1 << 1) -#define m_GCP_MUTE (1 << 0) - -#define IH_MUTE_FC_STAT2 0x0182 -#define m_LPRIO_OVERFLOW_MUTE (1 << 1) -#define m_HPRIO_OVERFLOW_MUTE (1 << 0) - -#define IH_MUTE_AS_STAT0 0x0183 -#define m_FIFO_UNDERRUN_MUTE (1 << 4) -#define m_FIFO_OVERRUN_MUTE (1 << 3) -#define m_AUD_FIFO_UDF_THR_MUTE (1 << 2) -#define m_AUD_FIFO_UDF_MUTE (1 << 1) -#define m_AUD_FIFO_OVF_MUTE (1 << 0) - -#define IH_MUTE_PHY_STAT0 0x0184 -#define m_RX_SENSE3_MUTE (1 << 5) -#define m_RX_SENSE2_MUTE (1 << 4) -#define m_RX_SENSE1_MUTE (1 << 3) -#define m_RX_SENSE0_MUTE (1 << 2) -#define m_TX_PHY_LOCK_MUTE (1 << 1) -#define m_HPD_MUTE (1 << 0) - -#define IH_MUTE_I2CM_STAT0 0x0185 -#define m_SCDC_READREQ_MUTE (1 << 2) -#define v_SCDC_READREQ_MUTE(n) (((n)&0x01) << 2) -#define m_I2CM_DONE_MUTE (1 << 1) -#define v_I2CM_DONE_MUTE(n) (((n)&0x01) << 1) -#define m_I2CM_ERR_MUTE (1 << 0) -#define v_I2CM_ERR_MUTE(n) (((n)&0x01) << 0) - -#define IH_MUTE_CEC_STAT0 0x0186 -#define m_WAKEUP_MUTE (1 << 6) -#define m_ERR_FOLLOW_MUTE (1 << 5) -#define m_ERR_INITIATOR_MUTE (1 << 4) -#define m_ARB_LOST_MUTE (1 << 3) -#define m_NACK_MUTE (1 << 2) -#define m_EOM_MUTE (1 << 1) -#define m_DONE_MUTE (1 << 0) - -#define IH_MUTE_VP_STAT0 0x0187 -#define m_FIFOFULL_REP_MUTE (1 << 7) -#define m_FIFOEMPTY_REP_MUTE (1 << 6) -#define m_FIFOFULL_PACK_MUTE (1 << 5) -#define m_FIFOEMPTY_PACK_MUTE (1 << 4) -#define m_FIFOFULL_REMAP_MUTE (1 << 3) -#define m_FIFOEMPTY_REMAP_MUTE (1 << 2) -#define m_FIFOFULL_BYP_MUTE (1 << 1) -#define m_FIFOEMPTY_BYP_MUTE (1 << 0) - -#define IH_MUTE_I2CMPHY_STAT0 0x0188 -#define m_I2CMPHY_DONE_MUTE (1 << 1) -#define m_I2CMPHY_ERR_MUTE (1 << 0) - -#define IH_MUTE_AHBDMAAUD_STAT0 0x0189 -#define IH_MUTE 0x01ff - -/* Video Sampler Registers */ -#define VIDEO_SAMPLER_BASE 0x0200 - -#define TX_INVID0 0x0200 -#define m_INTERNAL_DE_GEN (1 << 7) -#define v_INTERNAL_DE_GEN(n) (((n)&0x01) << 7) -enum VIDEO_MODE { - VIDEO_RGB444_8BIT = 0x01, - VIDEO_RGB444_10BIT = 0x03, - VIDEO_RGB444_12BIT = 0x05, - VIDEO_RGB444_16BIT = 0x07, - VIDEO_YCBCR444_8BIT = 0x09, /* or YCbCr420 */ - VIDEO_YCBCR444_10BIT = 0x0b, /* or YCbCr420 */ - VIDEO_YCBCR444_12BIT = 0x0d, /* or YCbCr420 */ - VIDEO_YCBCR444_16BIT = 0x0f, /* or YCbCr420 */ - VIDEO_YCBCR422_12BIT = 0x12, - VIDEO_YCBCR422_10BIT = 0x14, - VIDEO_YCBCR422_8BIT = 0x16 -}; -#define m_VIDEO_MAPPING (0x1f << 0) -#define v_VIDEO_MAPPING(n) ((n)&0x1f) - -#define TX_INSTUFFING 0x0201 -#define m_BCBDATA_STUFF (1 << 2) -#define v_BCBDATA_STUFF(n) (((n)&0x01) << 2) -#define m_RCRDATA_STUFF (1 << 1) -#define v_RCRDATA_STUFF(n) (((n)&0x01) << 1) -#define m_GYDATA_STUFF (1 << 0) -#define v_GYDATA_STUFF(n) (((n)&0x01) << 0) - -#define TX_GYDATA0 0x0202 -#define TX_GYDATA1 0x0203 -#define TX_RCRDATA0 0x0204 -#define TX_RCRDATA1 0x0205 -#define TX_BCBDATA0 0x0206 -#define TX_BCBDATA1 0x0207 - -/* Video Packetizer Registers */ -#define VIDEO_PACKETIZER_BASE 0x0800 - -#define VP_STATUS 0x0800 -#define m_PACKING_PHASE (0x0f << 0) - -#define VP_PR_CD 0x0801 -enum COLOR_DEPTH { - COLOR_DEPTH_24BIT_DEFAULT = 0, - COLOR_DEPTH_24BIT = 0x04, - COLOR_DEPTH_30BIT, - COLOR_DEPTH_36BIT, - COLOR_DEPTH_48BIT -}; -#define m_COLOR_DEPTH (0x0f << 4) -#define v_COLOR_DEPTH(n) (((n)&0x0f) << 4) -enum PIXEL_REPET { - NO_PIXEL_REPET = 0, - PIXEL_SENT_2TIMES, - PIXEL_SENT_3TIMES, - PIXEL_SENT_4TIMES, - PIXEL_SENT_5TIMES, - PIXEL_SENT_6TIMES, - PIXEL_SENT_7TIMES, - PIXEL_SENT_8TIMES, - PIXEL_SENT_9TIMES, - PIXEL_SENT_10TIMES -}; -#define m_DESIRED_PR_FACTOR (0x0f << 0) -#define v_DESIRED_PR_FACTOR(n) (((n)&0x0f) << 0) - -#define VP_STUFF 0x0802 -#define m_IDEFAULT_PHASE (1 << 5) -#define v_IDEFAULT_PHASE(n) (((n)&0x01) << 5) -#define m_IFIX_PP_TO_LAST (1 << 4) -#define m_ICX_GOTO_P0_ST (1 << 3) -enum { - DIRECT_MODE = 0, - STUFFING_MODE -}; -#define m_YCC422_STUFFING (1 << 2) -#define v_YCC422_STUFFING(n) (((n)&0x01) << 2) -#define m_PP_STUFFING (1 << 1) -#define v_PP_STUFFING(n) (((n)&0x01) << 1) -#define m_PR_STUFFING (1 << 0) -#define v_PR_STUFFING(n) (((n)&0x01) << 0) - -#define VP_REMAP 0x0803 -enum YCC422_SIZE { - YCC422_16BIT = 0, - YCC422_20BIT, - YCC422_24BIT -}; -#define m_YCC422_SIZE (0x03 << 0) -#define v_YCC422_SIZE(n) (((n)&0x03) << 0) - -#define VP_CONF 0x0804 -#define m_BYPASS_EN (1 << 6) -#define v_BYPASS_EN(n) (((n)&0x01) << 6) -#define m_PIXEL_PACK_EN (1 << 5) -#define v_PIXEL_PACK_EN(n) (((n)&0x01) << 5) -#define m_PIXEL_REPET_EN (1 << 4) -#define v_PIXEL_REPET_EN(n) (((n)&0x01) << 4) -#define m_YCC422_EN (1 << 3) -#define v_YCC422_EN(n) (((n)&0x01) << 3) -#define m_BYPASS_SEL (1 << 2) -#define v_BYPASS_SEL(n) (((n)&0x01) << 2) -enum { - OUT_FROM_PIXEL_PACKING = 0, - OUT_FROM_YCC422_REMAP, - OUT_FROM_8BIT_BYPASS -}; -#define m_OUTPUT_SEL (0x03 << 0) -#define v_OUTPUT_SEL(n) ((n&0x03) << 0) - -#define VP_MASK 0x0807 -#define m_OINTFULL_REPET (1 << 7) -#define m_OINTEMPTY_REPET (1 << 6) -#define m_OINTFULL_PACK (1 << 5) -#define m_OINTEMPTY_PACK (1 << 4) -#define m_OINTFULL_REMAP (1 << 3) -#define m_OINTEMPTY_REMAP (1 << 2) -#define m_OINTFULL_BYPASS (1 << 1) -#define m_OINTEMPTY_BYPASS (1 << 0) - -/* Frame Composer Registers */ -#define FRAME_COMPOSER_BASE 0x1000 - -#define FC_INVIDCONF 0x1000 -#define m_FC_HDCP_KEEPOUT (1 << 7) -#define v_FC_HDCP_KEEPOUT(n) (((n)&0x01) << 7) -#define m_FC_VSYNC_POL (1 << 6) -#define v_FC_VSYNC_POL(n) (((n)&0x01) << 6) -#define m_FC_HSYNC_POL (1 << 5) -#define v_FC_HSYNC_POL(n) (((n)&0x01) << 5) -#define m_FC_DE_POL (1 << 4) -#define v_FC_DE_POL(n) (((n)&0x01) << 4) -#define m_FC_HDMI_DVI (1 << 3) -#define v_FC_HDMI_DVI(n) (((n)&0x01) << 3) -#define m_FC_VBLANK (1 << 1) -#define v_FC_VBLANK(n) (((n)&0x01) << 1) -#define m_FC_INTERLACE_MODE (1 << 0) -#define v_FC_INTERLACE_MODE(n) (((n)&0x01) << 0) - -#define FC_INHACTIV0 0x1001 - -#define FC_INHACTIV1 0x1002 -#define v_FC_HACTIVE1(n) ((n) & 0x3f) -#define m_FC_H_ACTIVE_13 (1 << 5) -#define v_FC_H_ACTIVE_13(n) (((n)&0x01) << 5) -#define m_FC_H_ACTIVE_12 (1 << 4) -#define v_FC_H_ACTIVE_12(n) (((n)&0x01) << 4) -#define m_FC_H_ACTIVE (0x0f << 0) -#define v_FC_H_ACTIVE(n) (((n)&0x0f) << 0) - -#define FC_INHBLANK0 0x1003 - -#define FC_INHBLANK1 0x1004 -#define v_FC_HBLANK1(n) ((n) & 0x1f) -#define m_FC_H_BLANK_12_11 (0x07 << 2) -#define v_FC_H_BLANK_12_11(n) (((n)&0x07) << 2) -#define m_FC_H_BLANK (0x03 << 0) -#define v_FC_H_BLANK(n) (((n)&0x03) << 0) - -#define FC_INVACTIV0 0x1005 - -#define FC_INVACTIV1 0x1006 -#define v_FC_VACTIVE1(n) ((n) & 0x1f) -#define m_FC_V_ACTIVE_12_11 (0x03 << 3) -#define v_FC_V_ACTIVE_12_11(n) (((n)&0x03) << 3) -#define m_FC_V_ACTIVE (0x07 << 0) -#define v_FC_V_ACTIVE(n) (((n)&0x07) << 0) - -#define FC_INVBLANK 0x1007 -#define FC_HSYNCINDELAY0 0x1008 - -#define FC_HSYNCINDELAY1 0x1009 -#define v_FC_HSYNCINDEAY1(n) ((n) & 0x1f) -#define m_FC_H_SYNCFP_12_11 (0x03 << 3) -#define v_FC_H_SYNCFP_12_11(n) (((n)&0x03) << 3) -#define m_FC_H_SYNCFP (0x07 << 0) -#define v_FC_H_SYNCFP(n) (((n)&0x07) << 0) - -#define FC_HSYNCINWIDTH0 0x100a - -#define FC_HSYNCINWIDTH1 0x100b -#define v_FC_HSYNCWIDTH1(n) ((n) & 0x03) -#define m_FC_HSYNC_9 (1 << 1) -#define v_FC_HSYNC_9(n) (((n)&0x01) << 1) -#define m_FC_HSYNC (1 << 0) -#define v_FC_HSYNC(n) (((n)&0x01) << 0) - -#define FC_VSYNCINDELAY 0x100c -#define FC_VSYNCINWIDTH 0x100d -#define FC_INFREQ0 0x100e -#define FC_INFREQ1 0x100f -#define FC_INFREQ2 0x1010 -#define FC_CTRLDUR 0x1011 -#define FC_EXCTRLDUR 0x1012 -#define FC_EXCTRLSPAC 0x1013 -#define FC_CH0PREAM 0x1014 -#define FC_CH1PREAM 0x1015 -#define FC_CH2PREAM 0x1016 - -#define FC_AVICONF3 0x1017 -enum YCC_QUAN_RANGE { - YQ_LIMITED_RANGE = 0, - YQ_FULL_RANGE, - RESERVED, -}; -#define m_FC_YQ (0x03 << 2) -#define v_FC_YQ(n) (((n)&0x03) << 2) -enum IT_CONTENT_TYPE { - CN_GRAPHICS = 0, - CN_PHOTO, - CN_CINEMA, - CN_GAME, -}; -#define m_FC_CN (0x03 << 0) -#define v_FC_CN(n) (((n)&0x03) << 0) - -#define FC_GCP 0x1018 -#define m_FC_DEFAULT_PHASE (1 << 2) -#define v_FC_DEFAULT_PHASE(n) (((n)&0x01) << 2) -#define m_FC_SET_AVMUTE (1 << 1) -#define v_FC_SET_AVMUTE(n) (((n)&0x01) << 1) -#define m_FC_CLR_AVMUTE (1 << 0) -#define v_FC_CLR_AVMUTE(n) (((n)&0x01) << 0) - -enum { - AVI_COLOR_MODE_RGB = 0, - AVI_COLOR_MODE_YCBCR422, - AVI_COLOR_MODE_YCBCR444, - AVI_COLOR_MODE_YCBCR420 -}; -enum { - AVI_COLORIMETRY_NO_DATA = 0, - AVI_COLORIMETRY_SMPTE_170M, - AVI_COLORIMETRY_ITU709, - AVI_COLORIMETRY_EXTENDED -}; -enum { - AVI_CODED_FRAME_ASPECT_NO_DATA, - AVI_CODED_FRAME_ASPECT_4_3, - AVI_CODED_FRAME_ASPECT_16_9 -}; -enum { - ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME = 0x08, - ACTIVE_ASPECT_RATE_4_3, - ACTIVE_ASPECT_RATE_16_9, - ACTIVE_ASPECT_RATE_14_9 -}; -enum { - AVI_QUANTIZATION_RANGE_DEFAULT = 0, - AVI_QUANTIZATION_RANGE_LIMITED, - AVI_QUANTIZATION_RANGE_FULL -}; - -#define FC_AVICONF0 0x1019 -#define m_FC_RGC_YCC_2 (1 << 7) /* use for HDMI2.0 TX */ -#define v_FC_RGC_YCC_2(n) (((n)&0x01) << 7) -#define m_FC_ACTIV_FORMAT (1 << 6) -#define v_FC_ACTIV_FORMAT(n) (((n)&0x01) << 6) -#define m_FC_SCAN_INFO (0x03 << 4) -#define v_FC_SCAN_INFO(n) (((n)&0x03) << 4) -#define m_FC_BAR_FORMAT (0x03 << 2) -#define v_FC_BAR_FORMAT(n) (((n)&0x03) << 2) -#define m_FC_RGC_YCC (0x03 << 0) -#define v_FC_RGC_YCC(n) (((n)&0x03) << 0) - -#define FC_AVICONF1 0x101a -#define m_FC_COLORIMETRY (0x03 << 6) -#define v_FC_COLORIMETRY(n) (((n)&0x03) << 6) -#define m_FC_PIC_ASPEC_RATIO (0x03 << 4) -#define v_FC_PIC_ASPEC_RATIO(n) (((n)&0x03) << 4) -#define m_FC_ACT_ASPEC_RATIO (0x0f << 0) -#define v_FC_ACT_ASPEC_RATIO(n) (((n)&0x0f) << 0) - -#define FC_AVICONF2 0x101b -#define m_FC_IT_CONTENT (1 << 7) -#define v_FC_IT_CONTENT(n) (((n)&0x01) << 7) -#define m_FC_EXT_COLORIMETRY (0x07 << 4) -#define v_FC_EXT_COLORIMETRY(n) (((n)&0x07) << 4) -#define m_FC_QUAN_RANGE (0x03 << 2) -#define v_FC_QUAN_RANGE(n) (((n)&0x03) << 2) -#define m_FC_NUN_PIC_SCALE (0x03 << 0) -#define v_FC_NUN_PIC_SCALE(n) (((n)&0x03) << 0) - -#define FC_AVIVID 0x101c -#define m_FC_AVIVID_H (1 << 7) /* use for HDMI2.0 TX */ -#define v_FC_AVIVID_H(n) (((n)&0x01) << 7) -#define m_FC_AVIVID (0x7f << 0) -#define v_FC_AVIVID(n) (((n)&0x7f) << 0) - -#define FC_AVIETB0 0x101d -#define FC_AVIETB1 0x101e -#define FC_AVISBB0 0x101f -#define FC_AVISBB1 0x1020 -#define FC_AVIELB0 0x1021 -#define FC_AVIELB1 0x1022 -#define FC_AVISRB0 0x1023 -#define FC_AVISRB1 0x1024 - -#define FC_AUDICONF0 0x1025 -#define m_FC_CHN_CNT (0x07 << 4) -#define v_FC_CHN_CNT(n) (((n)&0x07) << 4) -#define m_FC_CODING_TYEP (0x0f << 0) -#define v_FC_CODING_TYEP(n) (((n)&0x0f) << 0) - -#define FC_AUDICONF1 0x1026 -#define m_FC_SAMPLE_SIZE (0x03 << 4) -#define v_FC_SAMPLE_SIZE(n) (((n)&0x03) << 4) -#define m_FC_SAMPLE_FREQ (0x07 << 0) -#define v_FC_SAMPLE_FREQ(n) (((n)&0x07) << 0) - -#define FC_AUDICONF2 0x1027 - -#define FC_AUDICONF3 0x1028 -#define m_FC_LFE_PBL (0x03 << 5) /* only use for HDMI1.4 TX */ -#define v_FC_LFE_PBL(n) (((n)&0x03) << 5) -#define m_FC_DM_INH (1 << 4) -#define v_FC_DM_INH(n) (((n)&0x01) << 4) -#define m_FC_LSV (0x0f << 0) -#define v_FC_LSV(n) (((n)&0x0f) << 0) - -#define FC_VSDIEEEID2 0x1029 -#define FC_VSDSIZE 0x102a -#define FC_VSDIEEEID1 0x1030 -#define FC_VSDIEEEID0 0x1031 -#define FC_VSDPAYLOAD0 0x1032 /* 0~23 */ -#define FC_SPDVENDORNAME0 0x104a /* 0~7 */ -#define FC_SPDPRODUCTNAME0 0x1052 /* 0~15 */ -#define FC_SPDDEVICEINF 0x1062 - -#define FC_AUDSCONF 0x1063 -#define m_AUD_PACK_SAMPFIT (0x0f << 4) -#define v_AUD_PACK_SAMPFIT(n) (((n)&0x0f) << 4) -#define m_AUD_PACK_LAYOUT (1 << 0) -#define v_AUD_PACK_LAYOUT(n) (((n)&0x01) << 0) - -#define FC_AUDSSTAT 0x1064 -#define FC_AUDSV 0x1065 -#define FC_AUDSU 0x1066 -#define FC_AUDSCHNLS0 0x1067 /* 0~8 */ -#define FC_CTRLQHIGH 0x1073 -#define FC_CTRLQLOW 0x1074 -#define FC_ACP0 0x1075 -#define FC_ACP16 0x1082 /* 16~1 */ -#define FC_ISCR1_0 0x1092 -#define FC_ISCR1_16 0x1093 /* 16~1 */ -#define FC_ISCR2_15 0x10a3 /* 15~0 */ - -#define FC_DATAUTO0 0x10b3 -#define m_SPD_AUTO (1 << 4) -#define v_SPD_AUTO(n) (((n)&0x01) << 4) -#define m_VSD_AUTO (1 << 3) -#define v_VSD_AUTO(n) (((n)&0x01) << 3) -#define m_ISCR2_AUTO (1 << 2) -#define v_ISCR2_AUTO(n) (((n)&0x01) << 2) -#define m_ISCR1_AUTO (1 << 1) -#define v_ISCR1_AUTO(n) (((n)&0x01) << 1) -#define m_ACP_AUTO (1 << 0) -#define v_ACP_AUTO(n) (((n)&0x01) << 0) - -#define FC_DATAUTO1 0x10b4 -#define FC_DATAUTO2 0x10b5 - -#define FC_DATMAN 0x10b6 -#define m_SPD_MAN (1 << 4) -#define v_SPD_MAN(n) (((n)&0x01) << 4) -#define m_VSD_MAN (1 << 3) -#define v_VSD_MAN(n) (((n)&0x01) << 3) -#define m_ISCR2_MAN (1 << 2) -#define v_ISCR2_MAN(n) (((n)&0x01) << 2) -#define m_ISCR1_MAN (1 << 1) -#define v_ISCR1_MAN(n) (((n)&0x01) << 1) -#define m_ACP_MAN (1 << 0) -#define v_ACP_MAN(n) (((n)&0x01) << 0) - -#define FC_DATAUTO3 0x10b7 -#define FC_RDRB0 0x10b8 -#define FC_RDRB1 0x10b9 -#define FC_RDRB2 0x10ba -#define FC_RDRB3 0x10bb -#define FC_RDRB4 0x10bc -#define FC_RDRB5 0x10bd -#define FC_RDRB6 0x10be -#define FC_RDRB7 0x10bf -#define FC_MASK0 0x10d2 -#define FC_MASK1 0x10d6 -#define FC_MASK2 0x10da - -#define FC_PRCONF 0x10e0 -#define m_FC_PR_FACTOR (0x0f << 4) -#define v_FC_PR_FACTOR(n) (((n)&0x0f) << 4) - -#define FC_SCRAMBLER_CTRL 0x10e1 -#define m_FC_SCRAMBLE_UCP (1 << 4) -#define v_FC_SCRAMBLE_UCP(n) (((n)&0x01) << 4) -#define m_FC_SCRAMBLE_EN (1 << 0) -#define v_FC_SCRAMBLE_EN(n) (((n)&0x01) << 0) - -#define FC_GMD_STAT 0x1100 -#define FC_GMD_EN 0x1101 -#define FC_GMD_UP 0x1102 -#define FC_GMD_CONF 0x1103 -#define FC_GMD_HB 0x1104 -#define FC_GMD_PB0 0x1105 /* 0~27 */ - -#define FC_DBGFORCE 0x1200 -#define m_FC_FORCEAUDIO (1 << 4) -#define v_FC_FORCEAUDIO(n) (((n)&0x01) << 4) -#define m_FC_FORCEVIDEO (1 << 0) -#define v_FC_FORCEVIDEO(n) (((n)&0x01) << 0) - -#define FC_DBGAUD0CH0 0x1201 /* aud0~aud2 ch0 */ -#define FC_DBGAUD0CH1 0x1204 /* aud0~aud2 ch1 */ -#define FC_DBGAUD0CH2 0x1207 /* aud0~aud2 ch2 */ -#define FC_DBGAUD0CH3 0x120a /* aud0~aud2 ch3 */ -#define FC_DBGAUD0CH4 0x120d /* aud0~aud2 ch4 */ -#define FC_DBGAUD0CH5 0x1210 /* aud0~aud2 ch5 */ -#define FC_DBGAUD0CH6 0x1213 /* aud0~aud2 ch6 */ -#define FC_DBGAUD0CH7 0x1216 /* aud0~aud2 ch7 */ -#define FC_DBGTMDS0 0x1219 -#define FC_DBGTMDS1 0x121a -#define FC_DBGTMDS2 0x121b - -/* HDMI Source PHY Registers */ -#define HDMI_SOURCE_PHY_BASE 0x3000 - -#define PHY_CONF0 0x3000 -#define m_POWER_DOWN_EN (1 << 7) /* enable depend on PHY_GEN2=0 and PHY_EXTERNAL=0 */ -#define v_POWER_DOWN_EN(n) (((n)&0x01) << 7) -#define m_TMDS_EN (1 << 6) /* enable depend on PHY_GEN2=0 and PHY_EXTERNAL=0 */ -#define v_TMDS_EN(n) (((n)&0x01) << 6) -#define m_SVSRET_SIG (1 << 5) /* depend on PHY_MHL_COMB0=1 */ -#define v_SVSRET_SIG(n) (((n)&0x01) << 5) -#define m_PDDQ_SIG (1 << 4) /* depend on PHY_GEN2=1 or PHY_EXTERNAL=1 */ -#define v_PDDQ_SIG(n) (((n)&0x01) << 4) -#define m_TXPWRON_SIG (1 << 3) /* depend on PHY_GEN2=1 or PHY_EXTERNAL=1 */ -#define v_TXPWRON_SIG(n) (((n)&0x01) << 3) -#define m_ENHPD_RXSENSE_SIG (1 << 2) /* depend on PHY_GEN2=1 or PHY_EXTERNAL=1 */ -#define v_ENHPD_RXSENSE_SIG(n) (((n)&0x01) << 2) -#define m_SEL_DATAEN_POL (1 << 1) -#define v_SEL_DATAEN_POL(n) (((n)&0x01) << 1) -#define m_SEL_INTERFACE (1 << 0) -#define v_SEL_INTERFACE(n) (((n)&0x01) << 0) - -#define PHY_TST0 0x3001 -#define m_TEST_CLR_SIG (1 << 5) -#define m_TEST_EN_SIG (1 << 4) -#define m_TEST_CLK_SIG (1 << 0) - -#define PHY_TST1 0x3002 -#define PHY_TST2 0x3003 -#define PHY_STAT0 0x3004 -#define PHY_INI0 0x3005 -#define PHY_MASK 0x3006 -#define PHY_POL0 0x3007 -#define m_PHY_RX_SENSE3 (1 << 7) -#define v_PHY_TX_SENSE3(n) (((n)&0x01) << 7) -#define m_PHY_RX_SENSE2 (1 << 6) -#define v_PHY_TX_SENSE2(n) (((n)&0x01) << 6) -#define m_PHY_RX_SENSE1 (1 << 5) -#define v_PHY_TX_SENSE1(n) (((n)&0x01) << 5) -#define m_PHY_RX_SENSE0 (1 << 4) -#define v_PHY_TX_SENSE0(n) (((n)&0x01) << 4) -#define m_PHY_HPD (1 << 1) -#define v_PHY_HPD (((n)&0x01) << 1) -#define m_PHY_LOCK (1 << 0) -#define v_PHY_LOCK(n) (((n)&0x01) << 0) - -#define PHY_PCLFREQ0 0x3008 -#define PHY_PCLFREQ1 0x3009 -#define PHY_PLLCFGFREQ0 0x300a -#define PHY_PLLCFGFREQ1 0x300b -#define PHY_PLLCFGFREQ2 0x300c - -/* I2C Master PHY Registers */ -#define I2C_MASTER_PHY_BASE 0x3020 - -#define PHY_I2CM_SLAVE 0x3020 -#define PHY_GEN2_ADDR 0x69 -#define PHY_HEAC_ADDR 0x49 -#define PHY_I2C_SLAVE_ADDR 0x54 - -#define PHY_I2CM_ADDRESS 0x3021 -#define PHY_I2CM_DATAO_1 0x3022 -#define PHY_I2CM_DATAO_0 0x3023 -#define PHY_I2CM_DATAI_1 0x3024 -#define PHY_I2CM_DATAI_0 0x3025 - -#define PHY_I2CM_OPERATION 0x3026 -#define m_PHY_I2CM_WRITE (1 << 4) -#define m_PHY_I2CM_READ (1 << 0) - -#define PHY_I2CM_INT 0x3027 -#define m_PHY_I2CM_DONE_INT_POL (1 << 3) -#define v_PHY_I2CM_DONE_INT_POL(n) (((n)&0x01) << 3) -#define m_PHY_I2CM_DONE_MASK (1 << 2) -#define v_PHY_I2CM_DONE_MASK(n) (((n)&0x01) << 2) -#define m_PHY_I2CM_DONE_INT (1 << 1) -#define m_PHY_I2CM_DONE_STATUS (1 << 0) - -#define PHY_I2CM_CTLINT 0x3028 -#define m_PHY_I2CM_NACK_POL (1 << 7) -#define v_PHY_I2CM_NACK_POL(n) (((n)&0x01) << 7) -#define m_PHY_I2CM_NACK_MASK (1 << 6) -#define v_PHY_I2CM_NACK_MASK(n) (((n)&0x01) << 6) -#define m_PHY_I2CM_NACK_INT (1 << 5) -#define m_PHY_I2CM_NACK_STATUS (1 << 4) -#define m_PHY_I2CM_ARB_POL (1 << 3) -#define v_PHY_I2CM_ARB_POL(n) (((n)&0x01) << 3) -#define m_PHY_I2CM_ARB_MASK (1 << 2) -#define v_PHY_I2CM_ARB_MASK(n) (((n)&0x01) << 2) -#define m_PHY_I2CM_ARB_INT (1 << 1) -#define m_PHY_I2CM_ARB_STATUS (1 << 0) - -#define PHY_I2CM_DIV 0x3029 -#define m_PHY_I2CM_FAST_STD (1 << 3) -#define v_PHY_I2CM_FAST_STD(n) (((n)&0x01) << 3) - -#define PHY_I2CM_SOFTRSTZ 0x302a -#define m_PHY_I2CM_SOFTRST (1 << 0) -#define v_PHY_I2CM_SOFTRST(n) (((n)&0x01) << 0) - -#define PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b -#define PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c -#define PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d -#define PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e -#define PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f -#define PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030 -#define PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031 -#define PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032 -#define PHY_I2CM_SDA_HOLD 0x3033 - -/* Audio Sampler Registers */ -#define AUDIO_SAMPLER_BASE 0x3100 - -#define AUD_CONF0 0x3100 -#define m_SW_AUD_FIFO_RST (1 << 7) -#define v_SW_AUD_FIFO_RST(n) (((n)&0x01) << 7) -enum { - AUDIO_SPDIF_GPA = 0, - AUDIO_I2S -}; -#define m_I2S_SEL (1 << 5) -#define v_I2S_SEL(n) (((n)&0x01) << 5) -enum { - I2S_CHANNEL_1_2 = 1, - I2S_CHANNEL_3_4 = 3, - I2S_CHANNEL_5_6 = 7, - I2S_CHANNEL_7_8 = 0xf -}; -#define m_I2S_IN_EN (0x0f << 0) -#define v_I2S_IN_EN(n) (((n)&0x0f) << 0) - -#define AUD_CONF1 0x3101 -enum I2S_MODE { - I2S_STANDARD_MODE = 0, - I2S_RIGHT_JUSTIFIED_MODE, - I2S_LEFT_JUSTIFIED_MODE, - I2S_BURST_1_MODE, - I2S_BURST_2_MODE -}; -#define m_I2S_MODE (0x07 << 5) -#define v_I2S_MODE(n) (((n)&0x07) << 5) -enum I2S_WIDTH { - I2S_16BIT_SAMPLE = 16, - I2S_17BIT_SAMPLE, - I2S_18BIT_SAMPLE, - I2S_19BIT_SAMPLE, - I2S_20BIT_SAMPLE, - I2S_21BIT_SAMPLE, - I2S_22BIT_SAMPLE, - I2S_23BIT_SAMPLE, - I2S_24BIT_SAMPLE, -}; -#define m_I2S_WIDTH (0x1f << 0) -#define v_I2S_WIDTH(n) (((n)&0x1f) << 0) - -#define AUD_INT 0x3102 -#define AUD_SPDIFINT 0x3302 -#define m_FIFO_EMPTY_MASK (1 << 3) -#define v_FIFO_EMPTY_MASK(n) (((n)&0x01) << 3) -#define m_FIFO_FULL_MASK (1 << 2) -#define v_FIFO_FULL_MASK(n) (((n)&0x01) << 2) - -#define AUD_CONF2 0x3103 -#define m_NLPCM_EN (1 << 1) -#define v_NLPCM_EN(n) (((n)&0x01) << 1) -#define m_HBR_EN (1 << 0) -#define v_HBR_EN(n) (((n)&0x01) << 0) - -#define AUD_INT1 0x3104 -#define AUD_SPDIFINT1 0x3303 -#define m_FIFO_OVERRUN_MASK (1 << 4) -#define v_FIFO_OVERRUN_MASK(n) (((n)&0x01) << 4) - -/***************N-CTS Table**************/ -/* TMDS LOWCLK: <=148.5M */ -/* TMDS MIDCLK: 297M */ -/* TMDS HIGHCLK: 594M */ -#define N_32K_LOWCLK 0x1000 -#define N_32K_MIDCLK 0x0c00 -#define N_32K_HIGHCLK 0x0c00 -#define N_441K_LOWCLK 0x1880 -#define N_441K_MIDCLK 0x1260 -#define N_441K_HIGHCLK 0x24c0 -#define N_48K_LOWCLK 0x1800 -#define N_48K_MIDCLK 0x1400 -#define N_48K_HIGHCLK 0x1800 -#define N_882K_LOWCLK 0x3100 -#define N_882K_MIDCLK 0x24c0 -#define N_882K_HIGHCLK 0x4980 -#define N_96K_LOWCLK 0x3000 -#define N_96K_MIDCLK 0x2800 -#define N_96K_HIGHCLK 0x3000 -#define N_1764K_LOWCLK 0x6200 -#define N_1764K_MIDCLK 0x4980 -#define N_1764K_HIGHCLK 0x9300 -#define N_192K_LOWCLK 0x6000 -#define N_192K_MIDCLK 0x5000 -#define N_192K_HIGHCLK 0x6000 - -#define CALC_CTS(N, TMDSCLK, FS) (((N) / 32) * (TMDSCLK) / ((FS) * 4)) -/****************************************/ - -#define AUD_N1 0x3200 -#define AUD_N2 0x3201 - -#define AUD_N3 0x3202 -#define m_NCTS_ATOMIC_WR (1 << 7) -#define v_NCTS_ATOMIC_WR(n) (((n)&0x01) << 7) -#define m_AUD_N3 (0x0f << 0) -#define v_AUD_N3(n) (((n)&0x0f) << 0) - -#define AUD_CTS1 0x3203 -#define AUD_CTS2 0x3204 - -#define AUD_CTS3 0x3205 -enum { - N_SHIFT_1 = 0, - N_SHIFT_16, - N_SHIFT_32, - N_SHIFT_64, - N_SHIFT_128, - N_SHIFT_256, - N_SHIFT_OTHERS_128 -}; -#define m_N_SHIFT (0x07 << 5) -#define v_N_SHIFT(n) (((n)&0x07) << 5) -#define m_CTS_MANUAL (1 << 4) -#define v_CTS_MANUAL(n) (((n)&0x01) << 4) -#define m_AUD_CTS3 (0x0f << 0) -#define v_AUD_CTS3(n) (((n)&0x0f) << 0) - -#define AUD_INPUTCLKFS 0x3206 -enum { - FS_128 = 0, - FS_256, - FS_512, - FS_64 = 4, - FS_OTHERS_128 -}; -#define m_LFS_FACTOR (0x07 << 0) -#define v_LFS_FACTOR(n) (((n)&0x07) << 0) - -#define AUD_SPDIF0 0x3300 -#define m_SW_SAUD_FIFO_RST (1 << 7) -#define v_SW_SAUD_FIFO_RST(n) (((n)&0x01) << 7) - -#define AUD_SPDIF1 0x3301 -enum { - PCM_LINEAR = 0, - PCM_NONLINEAR -}; -#define m_SET_NLPCM (1 << 7) -#define v_SET_NLPCM(n) (((n)&0x01) << 7) -#define m_SPDIF_HBR_MODE (1 << 6) -#define v_SPDIF_HBR_MODE(n) (((n)&0x01) << 6) -#define m_SPDIF_WIDTH (0x1f << 0) -#define v_SPDIF_WIDTH(n) (((n)&0x1f) << 0) - -/* Generic Parallel Audio Interface Registers */ -#define GP_AUDIO_INTERFACE_BASE 0x3500 - -#define GP_CONF0 0x3500 -#define GP_CONF1 0x3501 -#define GP_CONF2 0x3502 -#define GP_MASK 0x3506 - -/* Audio DMA Registers */ -#define AUDIO_DMA_BASE 0x3600 - -#define AHB_DMA_CONF0 0x3600 -#define AHB_DMA_START 0x3601 -#define AHB_DMA_STOP 0x3602 -#define AHB_DMA_THRSLD 0x3603 -#define AHB_DMA_STRADDR_SET0_0 0x3604 /* 0~3 */ -#define AHB_DMA_STPADDR_SET0_0 0x3608 /* 0~3 */ -#define AHB_DMA_BSTADDR0 0x360c /* 0~3 */ -#define AHB_DMA_MBLENGTH0 0x3610 /* 0~3 */ -#define AHB_DMA_MASK 0x3614 -#define AHB_DMA_CONF1 0x3616 -#define AHB_DMA_BUFFMASK 0x3619 -#define AHB_DMA_MASK1 0x361b -#define AHB_DMA_STATUS 0x361c -#define AHB_DMA_CONF2 0x361d -#define AHB_DMA_STRADDR_SET1_0 0x3620 /* 0~3 */ -#define AHB_DMA_STPADDR_SET1_0 0x3624 /* 0~3 */ - -/* Main Controller Registers */ -#define MAIN_CONTROLLER_BASE 0x4000 - -#define MC_CLKDIS 0x4001 -#define m_HDCPCLK_DISABLE (1 << 6) -#define v_HDCPCLK_DISABLE(n) (((n)&0x01) << 6) -#define m_CECCLK_DISABLE (1 << 5) -#define v_CECCLK_DISABLE(n) (((n)&0x01) << 5) -#define m_CSCCLK_DISABLE (1 << 4) -#define v_CSCCLK_DISABLE(n) (((n)&0x01) << 4) -#define m_AUDCLK_DISABLE (1 << 3) -#define v_AUDCLK_DISABLE(n) (((n)&0x01) << 3) -#define m_PREPCLK_DISABLE (1 << 2) -#define v_PREPCLK_DISABLE(n) (((n)&0x01) << 2) -#define m_TMDSCLK_DISABLE (1 << 1) -#define v_TMDSCLK_DISABLE(n) (((n)&0x01) << 1) -#define m_PIXELCLK_DISABLE (1 << 0) -#define v_PIXELCLK_DISABLE(n) (((n)&0x01) << 0) - -#define MC_SWRSTZREQ 0x4002 -#define m_IGPA_SWRST (1 << 7) -#define v_IGPA_SWRST(n) (((n)&0x01) << 7) -#define m_CEC_SWRST (1 << 6) -#define v_CEC_SWRST(n) (((n)&0x01) << 6) -#define m_ISPDIF_SWRST (1 << 4) -#define v_ISPDIF_SWRST(n) (((n)&0x01) << 4) -#define m_II2S_SWRST (1 << 3) -#define v_II2S_SWRST(n) (((n)&0x01) << 3) -#define m_PREP_SWRST (1 << 2) -#define v_PREP_SWRST(n) (((n)&0x01) << 2) -#define m_TMDS_SWRST (1 << 1) -#define v_TMDS_SWRST(n) (((n)&0x01) << 1) -#define m_PIXEL_SWRST (1 << 0) -#define v_PIXEL_SWRST(n) (((n)&0x01) << 0) - -#define MC_OPCTRL 0x4003 -#define m_HDCP_BLOCK_BYP (1 << 0) -#define v_HDCP_BLOCK_BYP(n) (((n)&0x01) << 0) - -#define MC_FLOWCTRL 0x4004 -#define m_FEED_THROUGH_OFF (1 << 0) -#define v_FEED_THROUGH_OFF(n) (((n)&0x01) << 0) - -#define MC_PHYRSTZ 0x4005 -#define m_PHY_RSTZ (1 << 0) -#define v_PHY_RSTZ(n) (((n)&0x01) << 0) - -#define MC_LOCKONCLOCK 0x4006 -#define m_IGPACLK_ON (1 << 7) -#define v_IGPACLK_ON(n) (((n)&0x01) << 7) -#define m_PCLK_ON (1 << 6) -#define v_PCLK_ON(n) (((n)&0x01) << 6) -#define m_TMDSCLK_ON (1 << 5) -#define v_TMDSCLK_ON(n) (((n)&0x01) << 5) -#define m_PREPCLK_ON (1 << 4) -#define v_PREPCLK_ON(n) (((n)&0x01) << 4) -#define m_I2SCLK_ON (1 << 3) -#define v_I2SCLK_ON(n) (((n)&0x01) << 3) -#define m_SPDIFCLK_ON (1 << 2) -#define v_SPDIFCLK_ON(n) (((n)&0x01) << 2) -#define m_CECCLK_ON (1 << 0) -#define v_CECCLK_ON(n) (((n)&0x01) << 0) - -#define MC_HEACPHY_RST 0x4007 -#define m_HEAC_PHY_RST (1 << 0) -#define v_HEAC_PHY_RST(n) (((n)&0x01) << 0) - -#define MC_LOCKONCLOCK_2 0x4009 -#define m_AHB_AUD_DMA_CLK (1 << 0) -#define v_AHB_AUD_DMA_CLK(n) (((n)&0x01) << 0) - -#define MC_SWRSTZREQ_2 0x400a -#define m_AHB_AUD_DMA_RST (1 << 7) -#define v_AHB_AUD_DMA_RST(n) (((n)&0x01) << 7) - -/* Color Space Converter Registers */ -#define COLOR_SPACE_CONVERTER_BASE 0x4100 - -#define CSC_CFG 0x4100 -#define m_CSC_INTPMODE (0x03 << 4) -#define v_CSC_INTPMODE(n) (((n)&0x03) << 4) -#define m_CSC_DECIMODE (0x03 << 0) -#define v_CSC_DECIMODE(n) (((n)&0x03) << 0) - -#define CSC_SCALE 0x4101 -#define m_CSC_COLOR_DEPTH (0x0f << 4) -#define v_CSC_COLOR_DEPTH(n) (((n)&0x0f) << 4) -#define m_CSC_SCALE (0x03 << 0) -#define v_CSC_SCALE(n) (((n)&0x03) << 0) - -#define CSC_COEF_A1_MSB 0x4102 -#define CSC_COEF_A1_LSB 0x4103 -#define CSC_COEF_A2_MSB 0x4104 -#define CSC_COEF_A2_LSB 0x4105 -#define CSC_COEF_A3_MSB 0x4106 -#define CSC_COEF_A3_LSB 0x4107 -#define CSC_COEF_A4_MSB 0x4108 -#define CSC_COEF_A4_LSB 0x4109 -#define CSC_COEF_B1_MSB 0x410a -#define CSC_COEF_B1_LSB 0x410b -#define CSC_COEF_B2_MSB 0x410c -#define CSC_COEF_B2_LSB 0x410d -#define CSC_COEF_B3_MSB 0x410e -#define CSC_COEF_B3_LSB 0x410f -#define CSC_COEF_B4_MSB 0x4110 -#define CSC_COEF_B4_LSB 0x4111 -#define CSC_COEF_C1_MSB 0x4112 -#define CSC_COEF_C1_LSB 0x4113 -#define CSC_COEF_C2_MSB 0x4114 -#define CSC_COEF_C2_LSB 0x4115 -#define CSC_COEF_C3_MSB 0x4116 -#define CSC_COEF_C3_LSB 0x4117 -#define CSC_COEF_C4_MSB 0x4118 -#define CSC_COEF_C4_LSB 0x4119 -#define CSC_SPARE_1 0x411a -#define CSC_SPARE_2 0x411b - -/* HDCP Encryption Engine Registers */ -#define HDCP_ENCRYPTION_ENGINE_BASE 0x5000 - -#define A_HDCPCFG0 0x5000 -#define m_HDCP_ENHANCE_LIKE (1 << 7) -#define v_HDCP_ENHANCE_LIKE(n) (((n)&0x01) << 7) -#define m_I2C_FAST_MODE (1 << 6) -#define v_I2C_FAST_MODE(n) (((n)&0x01) << 6) -#define m_ENCRYPT_BYPASS (1 << 5) -#define v_ENCRYPT_BYPASS(n) (((n)&0x01) << 5) -#define m_SYNC_RI_CHECK (1 << 4) -#define v_SYNC_RI_CHECK(n) (((n)&0x01) << 4) -#define m_AVMUTE (1 << 3) -#define m_RX_DETECT (1 << 2) -#define v_RX_DETECT(n) (((n)&0x01) << 2) -#define m_FEATURE11_EN (1 << 1) -#define v_FEATURE11_EN(n) (((n)&0x01) << 1) -#define m_HDMI_DVI (1 << 0) -#define v_HDMI_DVI(n) (((n)&0x01) << 0) - -#define A_HDCPCFG1 0x5001 -#define m_HDCP_LOCK (1 << 4) -#define v_HDCP_LOCK(n) (((n)&0x01) << 4) -#define m_SHA1_CHECK_DISABLE (1 << 3) -#define v_SHA1_CHECK_DISBALE(n) (((n)&0x01) << 3) -#define m_PH2UPSHFTENC (1 << 2) -#define v_PH2UPSHFTENC(n) (((n)&0x01) << 2) -#define m_ENCRYPT_DISBALE (1 << 1) -#define v_ENCRYPT_DISBALE(n) (((n)&0x01) << 1) -#define m_HDCP_SW_RST (1 << 0) -#define v_HDCP_SW_RST(n) (((n)&0x01) << 0) - -#define A_HDCPOBS0 0x5002 -#define m_STATE_AUTH (0x0f << 4) -#define m_SUB_STATE_AUTH (0x07 << 1) -#define m_STATE_HDCP_ENGAGED (1 << 0) - -#define A_HDCPOBS1 0x5003 -#define m_STATE_OESS (0x07 << 3) -#define m_STATE_REVO (0x07 << 0) - -#define A_HDCPOBS2 0x5004 -#define m_STATE_CIPHER (0x07 << 3) -#define m_STATE_EESS (0x07 << 0) - -#define A_HDCPOBS3 0x5005 -#define m_BCAP_REPEATER (1 << 6) -#define m_BCAP_KSVFIFO_READY (1 << 5) -#define m_BCAP_FAST_I2C (1 << 4) -#define m_BCAP_HDMI_MODE (1 << 2) -#define m_BCAP_FEATURES11 (1 << 1) -#define m_BCAP_FAST_REAUTH (1 << 0) - -#define A_APIINTCLR 0x5006 -#define A_APIINTSTAT 0x5007 -#define A_APIINTMSK 0x5008 -#define m_HDCP_ENGAGED (1 << 7) -#define m_HDCP_FAILED (1 << 6) -#define m_HDCP_I2C_NOACK (1 << 4) -#define m_HDCP_LOST_ARBI (1 << 3) -#define m_KEEP_ERR_INT (1 << 2) -#define m_KSVSHA1_CALC_INT (1 << 1) -#define m_KSV_ACCESS_INT (1 << 0) -#define v_HDCP_ENGAGED(n) (((n)&0x01) << 7) -#define v_HDCP_FAILED(n) (((n)&0x01) << 6) -#define v_HDCP_I2C_NOACK(n) (((n)&0x01) << 4) -#define v_HDCP_LOST_ARBI(n) (((n)&0x01) << 3) -#define v_KEEP_ERR_INT(n) (((n)&0x01) << 1) -#define v_KSVSHA1_CALC_INT(n) (((n)&0x01) << 1) -#define v_KSV_ACCESS_INT(n) (((n)&0x01) << 0) - -#define A_VIDPOLCFG 0x5009 -#define m_UNENCRYT_CONF (0x03 << 5) -#define v_UNENCRYT_CONF(n) (((n)&0x03) << 5) -#define m_DATAEN_POL (1 << 4) -#define v_DATAEN_POL(n) (((n)&0x01) << 4) -#define m_VSYNC_POL (1 << 3) -#define v_VSYNC_POL(n) (((n)&0x01) << 3) -#define m_HSYNC_POL (1 << 1) -#define v_HSYNC_POL(n) (((n)&0x01) << 1) - -#define A_OESSWCFG 0x500a -#define A_COREVERLSB 0x5014 -#define A_COREVERMSB 0x5015 - -#define A_KSVMEMCTRL 0x5016 -#define m_SHA1_FAIL (1 << 3) -#define v_SHA1_FAIL(n) (((n)&0x01) << 3) -#define m_KSV_UPDATE (1 << 2) -#define v_KSV_UPDATE(n) (((n)&0x01) << 2) -#define m_KSV_MEM_ACCESS (1 << 1) -#define m_KSV_MEM_REQ (1 << 0) -#define v_KSV_MEM_REQ(n) (((n)&0x01) << 0) - -#define HDCP_BSTATUS_0 0x5020 -#define m_MAX_DEVS_EXCEEDED (1 << 7) -#define m_DEVICE_COUNT (0x7f << 0) - -#define HDCP_BSTATUS_1 0x5021 -#define HDCP_M0_0 0x5022 -#define HDCP_M0_1 0x5023 -#define HDCP_M0_2 0x5024 -#define HDCP_M0_3 0x5025 -#define HDCP_M0_4 0x5026 -#define HDCP_M0_5 0x5027 -#define HDCP_M0_6 0x5028 -#define HDCP_M0_7 0x5029 -#define HDCP_KSV 0x502a /* 0~634 */ -#define HDCP_VH 0x52a5 /* 0~19 */ -#define HDCP_REVOC_SIZE_0 0x52b9 -#define HDCP_REVOC_SIZE_1 0x52ba -#define HDCP_REVOC_LIST 0x52bb /* 0~5059 */ - -/* HDCP BKSV Registers */ -#define HDCP_BKSV_BASE 0x7800 - -#define HDCPREG_BKSV0 0x7800 -#define HDCPREG_BKSV1 0x7801 -#define HDCPREG_BKSV2 0x7802 -#define HDCPREG_BKSV3 0x7803 -#define HDCPREG_BKSV4 0x7804 - -/* HDCP AN Registers */ -#define HDCP_AN_BASE 0x7805 - -#define HDCPREG_ANCONF 0x7805 -#define m_OAN_BYPASS (1 << 0) -#define v_OAN_BYPASS(n) (((n)&0x01) << 0) - -#define HDCPREG_AN0 0x7806 -#define HDCPREG_AN1 0x7807 -#define HDCPREG_AN2 0x7808 -#define HDCPREG_AN3 0x7809 -#define HDCPREG_AN4 0x780a -#define HDCPREG_AN5 0x780b -#define HDCPREG_AN6 0x780c -#define HDCPREG_AN7 0x780d - -/* Encrypted DPK Embedded Storage Registers */ -#define ENCRYPTED_DPK_EMBEDDED_BASE 0x780e - -#define HDCPREG_RMCTL 0x780e -#define m_DPK_DECRYPT_EN (1 << 0) -#define v_DPK_DECRYPT_EN(n) (((n)&0x01) << 0) - -#define HDCPREG_RMSTS 0x780f -#define m_DPK_WR_OK_STS (1 << 6) -#define m_DPK_DATA_INDEX (0x3f << 6) - -#define HDCPREG_SEED0 0x7810 -#define HDCPREG_SEED1 0x7811 -#define HDCPREG_DPK0 0x7812 -#define HDCPREG_DPK1 0x7813 -#define HDCPREG_DPK2 0x7814 -#define HDCPREG_DPK3 0x7815 -#define HDCPREG_DPK4 0x7816 -#define HDCPREG_DPK5 0x7817 -#define HDCPREG_DPK6 0x7818 - -/* CEC Engine Registers */ -#define CEC_ENGINE_BASE 0x7d00 - -#define CEC_CTRL 0x7d00 -#define CEC_MASK 0x7d02 -#define CEC_ADDR_L 0x7d05 -#define CEC_ADDR_H 0x7d06 -#define CEC_TX_CNT 0x7d07 -#define CEC_RX_CNT 0x7d08 -#define CEC_TX_DATA0 0x7d10 /* txdata0~txdata15 */ -#define CEC_RX_DATA0 0x7d20 /* rxdata0~rxdata15 */ -#define CEC_LOCK 0x7d30 -#define CEC_WKUPCTRL 0x7d31 - -/* I2C Master Registers */ -#define I2C_MASTER_BASE 0x7e00 - -#define I2CM_SLAVE 0x7e00 -#define I2CM_ADDRESS 0x7e01 -#define I2CM_DATAO 0x7e02 -#define I2CM_DATAI 0x7e03 - -#define I2CM_OPERATION 0x7e04 -#define m_I2CM_WR (1 << 4) -#define v_I2CM_WR(n) (((n)&0x01) << 4) -#define m_I2CM_RD8_EXT (1 << 3) -#define v_I2CM_RD8_EXT(n) (((n)&0x01) << 3) -#define m_I2CM_RD8 (1 << 2) -#define v_I2CM_RD8(n) (((n)&0x01) << 2) -#define m_I2CM_RD_EXT (1 << 1) -#define v_I2CM_RD_EXT(n) (((n)&0x01) << 1) -#define m_I2CM_RD (1 << 0) -#define v_I2CM_RD(n) (((n)&0x01) << 0) - -#define I2CM_INT 0x7e05 -#define m_I2CM_RD_REQ_MASK (1 << 6) -#define v_I2CM_RD_REQ_MASK(n) (((n)&0x01) << 6) -#define m_I2CM_DONE_MASK (1 << 2) -#define v_I2CM_DONE_MASK(n) (((n)&0x01) << 2) - -#define I2CM_CTLINT 0x7e06 -#define m_I2CM_NACK_MASK (1 << 6) -#define v_I2CM_NACK_MASK(n) (((n)&0x01) << 6) -#define m_I2CM_ARB_MASK (1 << 2) -#define v_I2CM_ARB_MASK(n) (((n)&0x01) << 2) - -#define I2CM_DIV 0x7e07 -enum { - STANDARD_MODE = 0, - FAST_MODE -}; -#define m_I2CM_FAST_STD_MODE (1 << 3) -#define v_I2CM_FAST_STD_MODE(n) (((n)&0x01) << 3) - -#define I2CM_SEGADDR 0x7e08 -#define m_I2CM_SEG_ADDR (0x7f << 0) -#define v_I2CM_SEG_ADDR(n) (((n)&0x7f) << 0) - -#define I2CM_SOFTRSTZ 0x7e09 -#define m_I2CM_SOFTRST (1 << 0) -#define v_I2CM_SOFTRST(n) (((n)&0x01) << 0) - -#define I2CM_SEGPTR 0x7e0a -#define I2CM_SS_SCL_HCNT_1_ADDR 0x7e0b -#define I2CM_SS_SCL_HCNT_0_ADDR 0x7e0c -#define I2CM_SS_SCL_LCNT_1_ADDR 0x7e0d -#define I2CM_SS_SCL_LCNT_0_ADDR 0x7e0e -#define I2CM_FS_SCL_HCNT_1_ADDR 0x7e0f -#define I2CM_FS_SCL_HCNT_0_ADDR 0x7e10 -#define I2CM_FS_SCL_LCNT_1_ADDR 0x7e11 -#define I2CM_FS_SCL_LCNT_0_ADDR 0x7e12 -#define I2CM_SDA_HOLD 0x7e13 - -#define I2CM_SCDC_READ_UPDATE 0x7e14 -#define m_I2CM_UPRD_VSYNC_EN (1 << 5) -#define v_I2CM_UPRD_VSYNC_EN(n) (((n)&0x01) << 5) -#define m_I2CM_READ_REQ_EN (1 << 4) -#define v_I2CM_READ_REQ_EN(n) (((n)&0x01) << 4) -#define m_I2CM_READ_UPDATE (1 << 0) -#define v_I2CM_READ_UPDATE(n) (((n)&0x01) << 0) - -#define I2CM_READ_BUFF0 0x7e20 /* buff0~buff7 */ -#define I2CM_SCDC_UPDATE0 0x7e30 -#define I2CM_SCDC_UPDATE1 0x7e31 - -/* -* HDMI TX PHY Define Start -*/ -#define PHYTX_OPMODE_PLLCFG 0x06 -enum { - PREP_DIV_BY_2 = 0, /* 16 bits */ - PREP_DIV_BY_15, /* 12 bits */ - PREP_DIV_BY_125, /* 10 bits */ - PREP_DIV_BY_1, /* 8 bits */ -}; -#define m_PREP_DIV (0x03 << 13) -#define v_PREP_DIV(n) (((n)&0x03) << 13) -enum { - TMDS_DIV_BY_1 = 0, - TMDS_DIV_NOT_USED, - TMDS_DIV_BY_3, - TMDS_DIV_BY_4, -}; -#define m_TMDS_CNTRL (0x03 << 11) -#define v_TMDS_CNTRL(n) (((n)&0x03) << 11) -enum OPMODE { - OP_HDMI_14 = 0, - OP_HDMI_20, -}; -#define m_OPMODE (0x03 << 9) -#define v_OPMODE(n) (((n)&0x03) << 9) -enum { - FBDIV2_BY_1 = 1, - FBDIV2_BY_2, - FBDIV2_BY_3, - FBDIV2_BY_4, - FBDIV2_BY_5, - FBDIV2_BY_6, -}; -#define m_FBDIV2_CNTRL (0x07 << 6) -#define v_FBDIV2_CNTRL(n) (((n)&0x07) << 6) -enum { - FBDIV1_BY_1 = 0, - FBDIV1_BY_2, - FBDIV1_BY_3, - FBDIV1_BY_4, -}; -#define m_FBDIV1_CNTRL (0x03 << 4) -#define v_FBDIV1_CNTRL(n) (((n)&0x03) << 4) -enum { - REF_DIV_BY_1 = 0, - REF_DIV_BY_2, - REF_DIV_NOT_USED, - REF_DIV_BY_4, -}; -#define m_REF_CNTRL (0x03 << 2) -#define v_REF_CNTRL(n) (((n)&0x03) << 2) -#define m_MPLL_N_CNTRL (0x03 << 0) -#define v_MPLL_N_CNTRL(n) (((n)&0x03) << 0) - -#define PHYTX_CLKSYMCTRL 0x09 -#define v_OVERRIDE(n) (0x01 << 15) -#define m_SLOPEBOOST (0x03 << 4) -#define v_SLOPEBOOST(n) (((n)&0x03) << 4) -#define m_TX_SYMON (0x01 << 3) -#define v_TX_SYMON(n) (((n)&0x01) << 3) -#define m_TX_TRAON (0x01 << 2) -#define v_TX_TRAON(n) (((n)&0x01) << 2) -#define m_TX_TRBON (0x01 << 1) -#define v_TX_TRBON(n) (((n)&0x01) << 1) -#define m_CLK_SYMON (0x01 << 0) -#define v_CLK_SYMON(n) (((n)&0x01) << 0) - -#define PHYTX_VLEVCTRL 0x0e -#define m_SUP_TXLVL (0x1f << 5) -#define v_SUP_TXLVL(n) (((n)&0x1f) << 5) -#define m_SUP_CLKLVL (0x1f << 0) -#define v_SUP_CLKLVL(n) (((n)&0x1f) << 0) - -#define PHYTX_PLLCURRCTRL 0x10 -#define m_MPLL_PROP_CNTRL (0x07 << 3) -#define v_MPLL_PROP_CNTRL(n) (((n)&0x07) << 3) -#define m_MPLL_INT_CNTRL (0x07 << 0) -#define v_MPLL_INT_CNTRL(n) (((n)&0x07) << 0) - -#define PHYTX_PLLGMPCTRL 0x15 -#define m_MPLL_GMP_CNTRL (0x03 << 0) -#define v_MPLL_GMP_CNTRL(n) (((n)&0x03) << 0) - -enum TERM_RESIS { - R50_Ohms = 0, - R5714_Ohms, - R6667_Ohms, - R80_Ohms, - R100_Ohms, - R13333_Ohms, - R200_Ohms, - ROPEN_CIRCUIT, -}; -#define PHYTX_TERM_RESIS 0x19 -#define m_TX_TERM (0x07 << 0) -#define v_TX_TERM(n) (((n)&0x07) << 0) - -struct phy_mpll_config_tab { - u32 pix_clock; - u8 pix_repet; - u8 color_depth; - u16 prep_div; - u16 tmdsmhl_cntrl; - u16 opmode; - u32 fbdiv2_cntrl; - u16 fbdiv1_cntrl; - u16 ref_cntrl; - u16 n_cntrl; - u32 prop_cntrl; - u32 int_cntrl; - u16 gmp_cntrl; -}; - -/* -* HDMI TX PHY Define End -*/ - -struct rk3288_hdmi_reg_table { - int reg_base; - int reg_end; -}; - -struct rk3288_hdmi_device { - int irq; - void __iomem *regbase; - int regbase_phy; - int regsize_phy; - int lcdc_id; - int i2cm_int; - int phy_i2cm_int; - unsigned char clk_on; - struct mutex int_mutex; - struct device *dev; - struct clk *pd; - struct clk *pclk; /* HDMI AHP clk */ - struct clk *hdcp_clk; - struct hdmi driver; - struct dentry *debugfs_dir; -#ifdef HDMI_INT_USE_POLL - struct delayed_work delay_work; -#endif -}; - -static inline u32 hdmi_readl(struct rk3288_hdmi_device *hdmi_dev, u16 offset) -{ - return readl_relaxed(hdmi_dev->regbase + (offset) * 0x04); -} - -static inline int hdmi_writel(struct rk3288_hdmi_device *hdmi_dev, u16 offset, - u32 val) -{ - int ret = 0; - writel_relaxed(val, hdmi_dev->regbase + (offset) * 0x04); - return ret; -} - -static inline int hdmi_msk_reg(struct rk3288_hdmi_device *hdmi_dev, u16 offset, - u32 msk, u32 val) -{ - int ret = 0; - u32 temp; - temp = - readl_relaxed(hdmi_dev->regbase + (offset) * 0x04) & (0xFF - (msk)); - writel_relaxed(temp | ((val) & (msk)), - hdmi_dev->regbase + (offset) * 0x04); - return ret; -} - -int rk3288_hdmi_initial(struct hdmi *hdmi_drv); -void rk3288_hdmi_control_output(struct hdmi *hdmi_drv, int enable); -int rk3288_hdmi_config_phy(struct hdmi *hdmi_drv, unsigned char pixel_repet, - unsigned char color_depth); - -#endif diff --git a/drivers/video/rockchip/hdmi/chips/rk610/Kconfig b/drivers/video/rockchip/hdmi/chips/rk610/Kconfig deleted file mode 100755 index 389f127ae56e..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk610/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -config HDCP_RK610 - bool "RK610 HDCP support" - depends on HDMI_RK610 - default n - help - HDCP Interface. This adds the High Definition Content Protection Interface. - See http://www.digital-cp.com/ for HDCP specification. - -config HDCP_RK610_DEBUG - bool "RK610 HDCP Debugging" - depends on HDCP_RK610 - default n - help - Enableds verbose debugging the the HDCP drivers diff --git a/drivers/video/rockchip/hdmi/chips/rk610/Makefile b/drivers/video/rockchip/hdmi/chips/rk610/Makefile deleted file mode 100755 index 683fb21bec4b..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk610/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG -ccflags-$(CONFIG_HDCP_RK610_DEBUG) = -DHDCP_DEBUG - -obj-$(CONFIG_HDMI_RK610) += rk610_hdmi_hw.o rk610_hdmi.o -obj-$(CONFIG_HDCP_RK610) += rk610_hdmi_hdcp.o rk610_hdcp.o - diff --git a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdcp.c deleted file mode 100755 index 61207db705e9..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdcp.c +++ /dev/null @@ -1,563 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "rk610_hdmi.h" -#include "rk610_hdcp.h" - -struct hdcp *hdcp = NULL; - -static void hdcp_work_queue(struct work_struct *work); - -/*----------------------------------------------------------------------------- - * Function: hdcp_submit_work - *----------------------------------------------------------------------------- - */ -static struct delayed_work *hdcp_submit_work(int event, int delay) -{ - struct hdcp_delayed_work *work; - - DBG("%s event %04x delay %d", __FUNCTION__, event, delay); - - work = kmalloc(sizeof(struct hdcp_delayed_work), GFP_ATOMIC); - - if (work) { - INIT_DELAYED_WORK(&work->work, hdcp_work_queue); - work->event = event; - queue_delayed_work(hdcp->workqueue, - &work->work, - msecs_to_jiffies(delay)); - } else { - printk(KERN_WARNING "HDCP: Cannot allocate memory to " - "create work\n"); - return 0; - } - - return &work->work; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_cancel_work - *----------------------------------------------------------------------------- - */ -static void hdcp_cancel_work(struct delayed_work **work) -{ - int ret = 0; - - if (*work) { - ret = cancel_delayed_work(*work); - if (ret != 1) { - ret = cancel_work_sync(&((*work)->work)); - printk(KERN_INFO "Canceling work failed - " - "cancel_work_sync done %d\n", ret); - } - kfree(*work); - *work = 0; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_failure - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_failure(void) -{ - if (hdcp->hdmi_state == HDMI_STOPPED) { - return; - } - - rk610_hdcp_disable(); - rk610_hdmi_sys_enalbe_output(false); - - hdcp_cancel_work(&hdcp->pending_wq_event); - - if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) { - if (hdcp->retry_cnt < HDCP_INFINITE_REAUTH) { - hdcp->retry_cnt--; - printk(KERN_INFO "HDCP: authentication failed - " - "retrying, attempts=%d\n", - hdcp->retry_cnt); - } else - printk(KERN_INFO "HDCP: authentication failed - " - "retrying\n"); - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - - hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT, - HDCP_REAUTH_DELAY); - } else { - printk(KERN_INFO "HDCP: authentication failed - " - "HDCP disabled\n"); - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } - -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_start_authentication - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_start_authentication(void) -{ - int status = HDCP_OK; - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - - DBG("HDCP: authentication start"); - - status = rk610_hdcp_start_authentication(); - - if (status != HDCP_OK) { - DBG("HDCP: authentication failed"); - hdcp_wq_authentication_failure(); - } else { - hdcp->hdcp_state = HDCP_WAIT_KSV_LIST; -// hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_check_bksv - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_check_bksv(void) -{ - int status = HDCP_OK; - - DBG("Check BKSV start"); - - status = rk610_hdcp_check_bksv(); - - if (status != HDCP_OK) { - printk(KERN_INFO "HDCP: Check BKSV failed"); - hdcp->retry_cnt = 0; - hdcp_wq_authentication_failure(); - } - else { - DBG("HDCP: Check BKSV successful"); - - hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - - /* Restore retry counter */ - if(hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_sucess - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_sucess(void) -{ - rk610_hdmi_sys_enalbe_output(true); - printk(KERN_INFO "HDCP: authentication pass"); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_disable - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_disable(int event) -{ - printk(KERN_INFO "HDCP: disabled"); - - hdcp_cancel_work(&hdcp->pending_wq_event); - rk610_hdcp_disable(); - if(event == HDCP_DISABLE_CTL) { - hdcp->hdcp_state = HDCP_DISABLED; - if(hdcp->hdmi_state == HDMI_STARTED) - rk610_hdmi_sys_enalbe_output(true); - } - else if(event == HDCP_STOP_FRAME_EVENT) - hdcp->hdcp_state = HDCP_ENABLE_PENDING; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_work_queue - *----------------------------------------------------------------------------- - */ -static void hdcp_work_queue(struct work_struct *work) -{ - struct hdcp_delayed_work *hdcp_w = - container_of(work, struct hdcp_delayed_work, work.work); - int event = hdcp_w->event; - - mutex_lock(&hdcp->lock); - - DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d", - jiffies_to_msecs(jiffies), - hdcp->hdmi_state, - hdcp->hdcp_state, - (event & 0xFF00) >> 8, - event & 0xFF); - - if(event == HDCP_STOP_FRAME_EVENT) { - hdcp->hdmi_state = HDMI_STOPPED; - } - - if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) { - hdcp_wq_disable(event); - } - - if (event & HDCP_WORKQUEUE_SRC) - hdcp->pending_wq_event = 0; - - /* First handle HDMI state */ - if (event == HDCP_START_FRAME_EVENT) { - hdcp->pending_start = 0; - hdcp->hdmi_state = HDMI_STARTED; - } - - /**********************/ - /* HDCP state machine */ - /**********************/ - switch (hdcp->hdcp_state) { - case HDCP_DISABLED: - /* HDCP enable control or re-authentication event */ - if (event == HDCP_ENABLE_CTL) { - if(hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times; - if (hdcp->hdmi_state == HDMI_STARTED) - hdcp_wq_start_authentication(); - else - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } - break; - - case HDCP_ENABLE_PENDING: - /* HDMI start frame event */ - if (event == HDCP_START_FRAME_EVENT) - hdcp_wq_start_authentication(); - - break; - - case HDCP_AUTHENTICATION_START: - /* Re-authentication */ - if (event == HDCP_AUTH_REATT_EVENT) - hdcp_wq_start_authentication(); - - break; - - case HDCP_WAIT_KSV_LIST: - /* KSV failure */ - if (event == HDCP_FAIL_EVENT) { - printk(KERN_INFO "HDCP: KSV switch failure\n"); - - hdcp_wq_authentication_failure(); - } - /* KSV list ready event */ - else if (event == HDCP_KSV_LIST_RDY_EVENT) - hdcp_wq_check_bksv(); - break; - - case HDCP_LINK_INTEGRITY_CHECK: - /* Ri failure */ - if (event == HDCP_FAIL_EVENT) { - printk(KERN_INFO "HDCP: Ri check failure\n"); - hdcp_wq_authentication_failure(); - } - else if(event == HDCP_AUTH_PASS_EVENT) - hdcp_wq_authentication_sucess(); - break; - - default: - printk(KERN_WARNING "HDCP: error - unknow HDCP state\n"); - break; - } - - kfree(hdcp_w); - if(event == HDCP_STOP_FRAME_EVENT) - complete(&hdcp->complete); - - mutex_unlock(&hdcp->lock); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_start_frame_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_start_frame_cb(void) -{ - DBG("hdcp_start_frame_cb()"); - - /* Cancel any pending work */ - if (hdcp->pending_start) - hdcp_cancel_work(&hdcp->pending_start); - if (hdcp->pending_wq_event) - hdcp_cancel_work(&hdcp->pending_wq_event); - - hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT, - HDCP_ENABLE_DELAY); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_irq_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_irq_cb(int status) -{ - char interrupt1; - char interrupt2; - - rk610_hdcp_interrupt(&interrupt1, &interrupt2); - DBG("%s 0x%02x 0x%02x", __FUNCTION__, interrupt1, interrupt2); - if(interrupt1 & m_INT_HDCP_ERR) - { - if( (hdcp->hdcp_state != HDCP_DISABLED) && - (hdcp->hdcp_state != HDCP_ENABLE_PENDING) ) - { - hdcp_submit_work(HDCP_FAIL_EVENT, 0); - } - } - else if(interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE)) - hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0); - else if(interrupt1 & m_INT_AUTH_SUCCESS) - hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_on_cb - *----------------------------------------------------------------------------- - */ -static int hdcp_power_on_cb(void) -{ - DBG("%s", __FUNCTION__); -// return rk610_hdcp_load_key2mem(hdcp->keys); - return HDCP_OK; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_off_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_power_off_cb(void) -{ - DBG("%s", __FUNCTION__); - if(!hdcp->enable) - return; - - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - init_completion(&hdcp->complete); - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0)) - wait_for_completion_interruptible_timeout(&hdcp->complete, - msecs_to_jiffies(5000)); -} - -// Load HDCP key to external HDCP memory -static void hdcp_load_keys_cb(const struct firmware *fw, void *context) -{ - if (!fw) { - pr_err("HDCP: failed to load keys\n"); - return; - } - - if(fw->size < HDCP_KEY_SIZE) { - pr_err("HDCP: firmware wrong size %d\n", fw->size); - return; - } - - hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL); - if(hdcp->keys == NULL) { - pr_err("HDCP: can't allocated space for keys\n"); - return; - } - - memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE); - - printk(KERN_INFO "HDCP: load hdcp key success\n"); - - if(fw->size > HDCP_KEY_SIZE) { - DBG("%s invalid key size %d", __FUNCTION__, fw->size - HDCP_KEY_SIZE); - if((fw->size - HDCP_KEY_SIZE) % 5) { - pr_err("HDCP: failed to load invalid keys\n"); - return; - } - hdcp->invalidkeys = kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL); - if(hdcp->invalidkeys == NULL) { - pr_err("HDCP: can't allocated space for invalid keys\n"); - return; - } - memcpy(hdcp->invalidkeys, fw->data + HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE); - hdcp->invalidkey = (fw->size - HDCP_KEY_SIZE)/5; - printk(KERN_INFO "HDCP: loaded hdcp invalid key success\n"); - } -} - -static ssize_t hdcp_enable_read(struct device *device, - struct device_attribute *attr, char *buf) -{ - int enable = 0; - - if(hdcp) - enable = hdcp->enable; - - return snprintf(buf, PAGE_SIZE, "%d\n", enable); -} - -static ssize_t hdcp_enable_write(struct device *device, - struct device_attribute *attr, const char *buf, size_t count) -{ - int enable; - - if(hdcp == NULL) - return -EINVAL; - - sscanf(buf, "%d", &enable); - if(hdcp->enable != enable) - { - /* Post event to workqueue */ - if(enable) { - if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0) - return -EFAULT; - } - else { - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0) - return -EFAULT; - } - hdcp->enable = enable; - } - return count; -} - -static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, hdcp_enable_read, hdcp_enable_write); - -static ssize_t hdcp_trytimes_read(struct device *device, - struct device_attribute *attr, char *buf) -{ - int trytimes = 0; - - if(hdcp) - trytimes = hdcp->retry_times; - - return snprintf(buf, PAGE_SIZE, "%d\n", trytimes); -} - -static ssize_t hdcp_trytimes_wrtie(struct device *device, - struct device_attribute *attr, const char *buf, size_t count) -{ - int trytimes; - - if(hdcp == NULL) - return -EINVAL; - - sscanf(buf, "%d", &trytimes); - if(hdcp->retry_times != trytimes) - hdcp->retry_times = trytimes; - - return count; -} - - -static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR, hdcp_trytimes_read, hdcp_trytimes_wrtie); - - -static struct miscdevice mdev; - -static int __init rk610_hdcp_init(void) -{ - int ret; - - DBG("[%s] %u", __FUNCTION__, jiffies_to_msecs(jiffies)); - - hdcp = kmalloc(sizeof(struct hdcp), GFP_KERNEL); - if(!hdcp) - { - printk(KERN_ERR ">>HDCP: kmalloc fail!"); - ret = -ENOMEM; - goto error0; - } - memset(hdcp, 0, sizeof(struct hdcp)); - mutex_init(&hdcp->lock); - - mdev.minor = MISC_DYNAMIC_MINOR; - mdev.name = "hdcp"; - mdev.mode = 0666; - if (misc_register(&mdev)) { - printk(KERN_ERR "HDCP: Could not add character driver\n"); - ret = HDMI_ERROR_FALSE; - goto error1; - } - ret = device_create_file(mdev.this_device, &dev_attr_enable); - if(ret) - { - printk(KERN_ERR "HDCP: Could not add sys file enable\n"); - ret = -EINVAL; - goto error2; - } - - ret = device_create_file(mdev.this_device, &dev_attr_trytimes); - if(ret) - { - printk(KERN_ERR "HDCP: Could not add sys file trytimes\n"); - ret = -EINVAL; - goto error3; - } - - hdcp->workqueue = create_singlethread_workqueue("hdcp"); - if (hdcp->workqueue == NULL) { - printk(KERN_ERR "HDCP,: create workqueue failed.\n"); - goto error4; - } - - - ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, - "hdcp.keys", mdev.this_device, GFP_KERNEL, - hdcp, hdcp_load_keys_cb); - if (ret < 0) { - printk(KERN_ERR "HDCP: request_firmware_nowait failed: %d\n", ret); - goto error5; - } - - rk610_hdmi_register_hdcp_callbacks( hdcp_start_frame_cb, - hdcp_irq_cb, - hdcp_power_on_cb, - hdcp_power_off_cb); - - DBG("%s success %u", __FUNCTION__, jiffies_to_msecs(jiffies)); - return 0; - -error5: - destroy_workqueue(hdcp->workqueue); -error4: - device_remove_file(mdev.this_device, &dev_attr_trytimes); -error3: - device_remove_file(mdev.this_device, &dev_attr_enable); -error2: - misc_deregister(&mdev); -error1: - if(hdcp->keys) - kfree(hdcp->keys); - if(hdcp->invalidkeys) - kfree(hdcp->invalidkeys); - kfree(hdcp); -error0: - return ret; -} - -static void __exit rk610_hdcp_exit(void) -{ - device_remove_file(mdev.this_device, &dev_attr_enable); - misc_deregister(&mdev); - if(hdcp->keys) - kfree(hdcp->keys); - if(hdcp->invalidkeys) - kfree(hdcp->invalidkeys); - kfree(hdcp); -} - -module_init(rk610_hdcp_init); -module_exit(rk610_hdcp_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdcp.h b/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdcp.h deleted file mode 100755 index d7459a2c9b92..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdcp.h +++ /dev/null @@ -1,194 +0,0 @@ -#ifndef __RK610_HDCP_H__ -#define __RK610_HDCP_H__ - -/***************************/ -/* Definitions */ -/***************************/ - -/* Status / error codes */ -#define HDCP_OK 0 -#define HDCP_KEY_ERR 1 -#define HDCP_KSV_ERR 2 - -/* Delays */ -#define HDCP_ENABLE_DELAY 300 -#define HDCP_REAUTH_DELAY 100 - -/* Event source */ -#define HDCP_SRC_SHIFT 8 -#define HDCP_IOCTL_SRC (0x1 << HDCP_SRC_SHIFT) -#define HDCP_HDMI_SRC (0x2 << HDCP_SRC_SHIFT) -#define HDCP_IRQ_SRC (0x4 << HDCP_SRC_SHIFT) -#define HDCP_WORKQUEUE_SRC (0x8 << HDCP_SRC_SHIFT) - -/* Event */ -#define HDCP_ENABLE_CTL (HDCP_IOCTL_SRC | 0) -#define HDCP_DISABLE_CTL (HDCP_IOCTL_SRC | 1) -#define HDCP_START_FRAME_EVENT (HDCP_HDMI_SRC | 2) -#define HDCP_STOP_FRAME_EVENT (HDCP_HDMI_SRC | 3) -#define HDCP_KSV_LIST_RDY_EVENT (HDCP_IRQ_SRC | 4) -#define HDCP_FAIL_EVENT (HDCP_IRQ_SRC | 5) -#define HDCP_AUTH_PASS_EVENT (HDCP_IRQ_SRC | 6) -#define HDCP_AUTH_REATT_EVENT (HDCP_WORKQUEUE_SRC | 7) - -/* Key size */ -#define HDCP_KEY_SIZE 308 - -/* HDCP DDC Clock */ -#define HDCP_DDC_CLK 100000 - -/* Authentication retry times */ -#define HDCP_INFINITE_REAUTH 0x100 - -/* HDCP Regs */ -#define HDCP_CTRL1 0x52 - #define m_AUTH_START (1 << 7) - #define m_BKSV_VALID (1 << 6) - #define m_BKSV_INVALID (1 << 5) - #define m_ENCRYPT_ENABLE (1 << 4) - #define m_AUTH_STOP (1 << 3) - #define m_ADVANED_ENABLE (1 << 2) - #define m_HDMI_DVI (1 << 1) - #define m_HDCP_RESET (1 << 0) - - #define v_AUTH_START(n) (n << 7) - #define v_BKSV_VALID(n) (n << 6) - #define v_BKSV_INVALID(n) (n << 5) - #define v_ENCRYPT_ENABLE(n) (n << 4) - #define v_AUTH_STOP(n) (n << 3) - #define v_ADVANED_ENABLE(n) (n << 2) - #define v_HDMI_DVI(n) (n << 1) - #define v_HDCP_RESET(n) (n << 0) - -#define HDCP_CTRL2 0x53 - #define m_DISABLE_127_CHECK (1 << 7) - #define m_SKIP_BKSV_CHECK (1 << 6) - #define m_ENABLE_PJ_CHECK (1 << 5) - #define m_DISABLE_DEVICE_NUMBER_CHECK (1 << 4) - #define m_DELAY_RI_1_CLK (1 << 3) - #define m_USE_PRESET_AN (1 << 2) - #define m_KEY_COMBINATION (3 << 0) - - #define v_DISABLE_127_CHECK(n) (n << 7) - #define v_SKIP_BKSV_CHECK(n) (n << 6) - #define v_ENABLE_PJ_CHECK(n) (n << 5) - #define v_DISABLE_DEVICE_NUMBER_CHECK(n)(n << 4) - #define v_DELAY_RI_1_CLK(n) (n << 3) - #define v_USE_PRESET_AN(n) (n << 2) - #define v_KEY_COMBINATION(n) (n << 0) - -#define HDCP_KEY_STATUS 0x54 - #define m_KEY_READY (1 << 0) - -#define HDCP_CTRL_SOFT 0x57 - #define m_DISABLE_127_CHECK (1 << 7) - #define m_SKIP_BKSV_CHECK (1 << 6) - #define m_NOT_AUTHENTICATED (1 << 5) - #define m_ENCRYPTED (1 << 4) - #define m_ADVANCED_CIPHER (1 << 3) - -#define HDCP_BCAPS_RX 0x58 -#define HDCP_TIMER_100MS 0x63 -#define HDCP_TIMER_5S 0x64 -#define HDCP_ERROR 0x65 - #define m_DDC_NO_ACK (1 << 3) - #define m_PJ_MISMACH (1 << 2) - #define m_RI_MISMACH (1 << 1) - #define m_BKSV_WRONG (1 << 0) - -#define HDCP_KSV_BYTE0 0x66 -#define HDCP_KSV_BYTE1 0x67 -#define HDCP_KSV_BYTE2 0x68 -#define HDCP_KSV_BYTE3 0x69 -#define HDCP_KSV_BYTE4 0x6a - -#define HDCP_AN_SEED 0x6c - -#define HDCP_BCAPS_TX 0x80 -#define HDCP_BSTATE_0 0x81 -#define HDCP_BSTATE_1 0x82 - -#define HDCP_KEY_FIFO 0x98 - -#define HDCP_INT_MASK1 0xc2 -#define HDCP_INT_STATUS1 0xc3 - #define m_INT_HDCP_ERR (1 << 7) - #define m_INT_BKSV_READY (1 << 6) - #define m_INT_BKSV_UPDATE (1 << 5) - #define m_INT_AUTH_SUCCESS (1 << 4) - #define m_INT_AUTH_READY (1 << 3) - -#define HDCP_INT_MASK2 0xc4 -#define HDCP_INT_STATUS2 0xc5 - #define m_INT_SOFT_MODE_READY (1 << 7) - #define m_INT_AUTH_M0_REDAY (1 << 6) - #define m_INT_1st_FRAME_ARRIVE (1 << 5) - #define m_INT_AN_READY (1 << 4) - #define m_INT_ENCRYPTED (1 << 2) - #define m_INT_NOT_ENCRYPTED_AVMUTE (1 << 1) - #define m_INT_NOT_ENCRYPTED_AVUNMUTE (1 << 0) - -enum hdcp_states { - HDCP_DISABLED, - HDCP_ENABLE_PENDING, - HDCP_AUTHENTICATION_START, - HDCP_WAIT_KSV_LIST, - HDCP_LINK_INTEGRITY_CHECK, -}; - -enum hdmi_states { - HDMI_STOPPED, - HDMI_STARTED -}; - -#define HDCP_PRIVATE_KEY_SIZE 280 -#define HDCP_KEY_SHA_SIZE 20 - -struct hdcp_keys{ - u8 KSV[8]; - u8 DeviceKey[HDCP_PRIVATE_KEY_SIZE]; - u8 sha1[HDCP_KEY_SHA_SIZE]; -}; - -struct hdcp_delayed_work { - struct delayed_work work; - int event; -}; - -struct hdcp { - int enable; - int retry_times; - struct hdcp_keys *keys; - int invalidkey; - char *invalidkeys; - struct mutex lock; - struct completion complete; - struct workqueue_struct *workqueue; - - enum hdmi_states hdmi_state; - enum hdcp_states hdcp_state; - - struct delayed_work *pending_start; - struct delayed_work *pending_wq_event; - int retry_cnt; -}; - -extern struct hdcp *hdcp; - -#ifdef DBG -#undef DBG -#endif - -#ifdef HDCP_DEBUG -#define DBG(format, ...) \ - printk(KERN_INFO "HDCP: " format "\n", ## __VA_ARGS__) -#else -#define DBG(format, ...) -#endif - -extern void rk610_hdcp_disable(void); -extern int rk610_hdcp_start_authentication(void); -extern int rk610_hdcp_check_bksv(void); -extern int rk610_hdcp_load_key2mem(struct hdcp_keys *key); -extern void rk610_hdcp_interrupt(char *status1, char *status2); -#endif /* __RK610_HDCP_H__ */ \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi.c deleted file mode 100755 index 8952b399216b..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi.c +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "rk610_hdmi.h" - -struct rk610_hdmi_pdata *rk610_hdmi = NULL; -struct hdmi *hdmi=NULL; - -extern struct rk_lcdc_driver * rk_get_lcdc_drv(char *name); -extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent); -extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi); - -int rk610_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)) -{ - 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; - - return HDMI_ERROR_SUCESS; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void hdmi_early_suspend(struct early_suspend *h) -{ - hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state); - flush_delayed_work(&hdmi->delay_work); - mutex_lock(&hdmi->enable_mutex); - hdmi->suspend = 1; - if(!hdmi->enable) { - mutex_unlock(&hdmi->enable_mutex); - return; - } - - #ifdef HDMI_USE_IRQ - if(hdmi->irq) - disable_irq(hdmi->irq); - #endif - - 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); - return; -} - -static void hdmi_early_resume(struct early_suspend *h) -{ - hdmi_dbg(hdmi->dev, "hdmi exit early resume\n"); - mutex_lock(&hdmi->enable_mutex); - - hdmi->suspend = 0; - #ifdef HDMI_USE_IRQ - if(hdmi->enable && hdmi->irq) { - enable_irq(hdmi->irq); - } - #else - queue_delayed_work(rk610_hdmi->workqueue, &rk610_hdmi->delay_work, 100); - #endif - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); - mutex_unlock(&hdmi->enable_mutex); - return; -} -#endif - -static void rk610_irq_work_func(struct work_struct *work) -{ - if(hdmi->suspend == 0) { - if(hdmi->enable == 1) { - rk610_hdmi_interrupt(); - if(hdmi->hdcp_irq_cb) - hdmi->hdcp_irq_cb(0); - } - #ifndef HDMI_USE_IRQ - queue_delayed_work(rk610_hdmi->workqueue, &rk610_hdmi->delay_work, 50); - #endif - } -} - -#ifdef HDMI_USE_IRQ -static irqreturn_t rk610_irq(int irq, void *dev_id) -{ - printk(KERN_INFO "rk610 irq triggered.\n"); - schedule_work(&rk610_hdmi->irq_work); - return IRQ_HANDLED; -} -#endif - -static int rk610_hdmi_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id) -{ - int rc = 0; - - rk610_hdmi = kzalloc(sizeof(struct rk610_hdmi_pdata), GFP_KERNEL); - if(!rk610_hdmi) - { - dev_err(&client->dev, "no memory for state\n"); - return -ENOMEM; - } - rk610_hdmi->client = client; - i2c_set_clientdata(client, rk610_hdmi); - - hdmi = kmalloc(sizeof(struct hdmi), GFP_KERNEL); - if(!hdmi) - { - dev_err(&client->dev, "rk610 hdmi kmalloc fail!"); - goto err_kzalloc_hdmi; - } - memset(hdmi, 0, sizeof(struct hdmi)); - hdmi->dev = &client->dev; - - 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"); - rc = -ENXIO; - goto err_request_lcdc; - } - hdmi->xscale = 100; - hdmi->yscale = 100; - hdmi->insert = rk610_hdmi_sys_insert; - hdmi->remove = rk610_hdmi_sys_remove; - hdmi->control_output = rk610_hdmi_sys_enalbe_output; - hdmi->config_video = rk610_hdmi_sys_config_video; - hdmi->config_audio = rk610_hdmi_sys_config_audio; - hdmi->detect_hotplug = rk610_hdmi_sys_detect_hpd; - hdmi->read_edid = rk610_hdmi_sys_read_edid; - hdmi_sys_init(); - - 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 - - hdmi_register_display_sysfs(hdmi, NULL); - #ifdef CONFIG_SWITCH - hdmi->switch_hdmi.name="hdmi"; - switch_dev_register(&(hdmi->switch_hdmi)); - #endif - - spin_lock_init(&hdmi->irq_lock); - mutex_init(&hdmi->enable_mutex); - - rk610_hdmi_sys_init(); - -#ifdef HDMI_USE_IRQ - if(client->irq != INVALID_GPIO) { - INIT_WORK(&rk610_hdmi->irq_work, rk610_irq_work_func); - schedule_work(&rk610_hdmi->irq_work); - if((rc = gpio_request(client->irq, "hdmi gpio")) < 0) - { - dev_err(&client->dev, "fail to request gpio %d\n", client->irq); - goto err_request_lcdc; - } - hdmi->irq = gpio_to_irq(client->irq); - rk610_hdmi->gpio = client->irq; - gpio_pull_updown(client->irq, GPIOPullUp); - gpio_direction_input(client->irq); - if((rc = request_irq(hdmi->irq, rk610_irq, IRQF_TRIGGER_RISING, NULL, hdmi)) < 0) - { - dev_err(&client->dev, "fail to request hdmi irq\n"); - goto err_request_irq; - } - } - else -#else - { - rk610_hdmi->workqueue = create_singlethread_workqueue("rk610 irq"); - INIT_DELAYED_WORK(&(rk610_hdmi->delay_work), rk610_irq_work_func); - rk610_irq_work_func(NULL); - } -#endif - - dev_info(&client->dev, "rk610 hdmi i2c probe ok\n"); - - return 0; - -err_request_irq: - gpio_free(client->irq); -err_request_lcdc: - kfree(hdmi); - hdmi = NULL; -err_kzalloc_hdmi: - kfree(rk610_hdmi); - rk610_hdmi = NULL; - dev_err(&client->dev, "rk610 hdmi probe error\n"); - return rc; - -} - -static int __devexit rk610_hdmi_i2c_remove(struct i2c_client *client) -{ - hdmi_dbg(hdmi->dev, "%s\n", __func__); - 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); - #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); - #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); - } - kfree(hdmi); - hdmi = NULL; - } - return 0; -} - -static void rk610_hdmi_i2c_shutdown(struct i2c_client *client) -{ - if(hdmi) { - #ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&hdmi->early_suspend); - #endif - } - printk(KERN_INFO "rk610 hdmi shut down.\n"); -} - -static const struct i2c_device_id rk610_hdmi_id[] = { - { "rk610_hdmi", 0 }, - { } -}; - -static struct i2c_driver rk610_hdmi_i2c_driver = { - .driver = { - .name = "rk610_hdmi", - .owner = THIS_MODULE, - }, - .probe = rk610_hdmi_i2c_probe, - .remove = rk610_hdmi_i2c_remove, - .shutdown = rk610_hdmi_i2c_shutdown, - .id_table = rk610_hdmi_id, -}; - -static int __init rk610_hdmi_init(void) -{ - return i2c_add_driver(&rk610_hdmi_i2c_driver); -} - -static void __exit rk610_hdmi_exit(void) -{ - i2c_del_driver(&rk610_hdmi_i2c_driver); -} - -//module_init(rk610_hdmi_init); -device_initcall_sync(rk610_hdmi_init); -module_exit(rk610_hdmi_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi.h b/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi.h deleted file mode 100755 index 1a652e80702b..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __RK610_HDMI_H__ -#define __RK610_HDMI_H__ -#include "../../rk_hdmi.h" - -#if defined(CONFIG_HDMI_SOURCE_LCDC1) -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC1 -#else -#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC0 -#endif -//#define HDMI_USE_IRQ - -struct rk610_hdmi_pdata { - int gpio; - struct i2c_client *client; - struct delayed_work delay_work; - #ifdef HDMI_USE_IRQ - struct work_struct irq_work; - #else - struct workqueue_struct *workqueue; - #endif -}; - -extern struct rk610_hdmi_pdata *rk610_hdmi; - -extern int rk610_hdmi_sys_init(void); -extern void rk610_hdmi_interrupt(void); -extern int rk610_hdmi_sys_detect_hpd(void); -extern int rk610_hdmi_sys_insert(void); -extern int rk610_hdmi_sys_remove(void); -extern int rk610_hdmi_sys_read_edid(int block, unsigned char *buff); -extern int rk610_hdmi_sys_config_video(struct hdmi_video_para *vpara); -extern int rk610_hdmi_sys_config_audio(struct hdmi_audio *audio); -extern void rk610_hdmi_sys_enalbe_output(int enable); -extern int rk610_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)); -#endif diff --git a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi_hdcp.c deleted file mode 100755 index e690f715b596..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi_hdcp.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include "rk610_hdmi.h" -#include "rk610_hdmi_hw.h" -#include "rk610_hdcp.h" - -static char rk610_hdmi_i2c_read_reg(char reg) -{ - char val = 0; - - if(i2c_master_reg8_recv(rk610_hdmi->client, reg, &val, 1, 100*1000) > 0) - return val; - else { - printk(KERN_ERR "[%s] read reg %02x error\n", __FUNCTION__, reg); - return 0; - } -} -static char rk610_hdmi_i2c_write_reg(char reg, char val) -{ - if(i2c_master_reg8_send(rk610_hdmi->client, reg, &val, 1, 100*1000) > 0) - return 0; - else { - printk(KERN_ERR "[%s] write reg %02x error\n", __FUNCTION__, reg); - return -EINVAL; - } -} - -#define HDCPWrReg rk610_hdmi_i2c_write_reg -#define HDCPRdReg rk610_hdmi_i2c_read_reg -#define HDCPMskReg(temp, addr, msk, val) \ - temp = HDCPRdReg(addr) & (0xFF - (msk)) ; \ - HDCPWrReg(addr, temp | ( (val) & (msk) )); - -void rk610_hdcp_disable(void) -{ - char temp; - - // Diable HDCP Interrupt - HDCPWrReg(HDCP_INT_MASK1, 0x00); - // Stop and Reset HDCP - HDCPMskReg(temp, HDCP_CTRL1, m_ENCRYPT_ENABLE | m_AUTH_STOP | m_HDCP_RESET, - v_ENCRYPT_ENABLE(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1) ) -} - -int rk610_hdcp_load_key2mem(struct hdcp_keys *key) -{ - int i; - DBG("HDCP: rk610_hdcp_load_key2mem start"); - // Write 40 private key - for(i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) - HDCPWrReg(HDCP_KEY_FIFO, key->DeviceKey[i]); - - // Write 1st aksv - for(i = 0; i < 5; i++) - HDCPWrReg(HDCP_KEY_FIFO, key->KSV[i]); - - // Write 2nd aksv - for(i = 0; i < 5; i++) - HDCPWrReg(HDCP_KEY_FIFO, key->KSV[i]); - DBG("HDCP: rk610_hdcp_load_key2mem end"); - return HDCP_OK; -} - -int rk610_hdcp_start_authentication(void) -{ - char temp; - int retry = 0; - - if(hdcp->keys == NULL) { - printk(KERN_ERR "HDCP: key is not loaded\n"); - return HDCP_KEY_ERR; - } - - // Select TMDS CLK to configure regs - HDCPMskReg(temp, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS); - - temp = HDCPRdReg(HDCP_KEY_STATUS); - while( ( temp & m_KEY_READY) == 0 ) { - if(retry > 10) { - printk(KERN_ERR "HDCP: loaded key error\n"); - return HDCP_KEY_ERR; - } - rk610_hdcp_load_key2mem(hdcp->keys); - msleep(1); - temp = HDCPRdReg(HDCP_KEY_STATUS); - } - - // Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b) - DBG("TMDS frequency %d", hdmi->tmdsclk); - retry = hdmi->tmdsclk/(HDCP_DDC_CLK*4); - HDCPWrReg(DDC_CLK_L, retry & 0xFF); - HDCPWrReg(DDC_CLK_H, (retry >> 8) & 0xFF); - - HDCPWrReg(HDCP_CTRL2, 0x00); - - //Enable interrupt - HDCPWrReg(HDCP_INT_MASK1, m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE | m_INT_AUTH_SUCCESS | m_INT_AUTH_READY); -// HDCPWrReg(HDCP_INT_MASK2, 0xFF); - //Start authentication - HDCPMskReg(temp, HDCP_CTRL1, m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE, v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) | v_ADVANED_ENABLE(0)); - - return HDCP_OK; -} - -int rk610_hdcp_check_bksv(void) -{ - int i, j; - char temp = 0, bksv[5]; - char *invalidkey; - - for(i = 0; i < 5; i++) { - bksv[i] = HDCPRdReg(HDCP_KSV_BYTE0 + (4 - i)) & 0xFF; - } - DBG("bksv is 0x%02x%02x%02x%02x%02x", bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]); - - for (i = 0; i < 5; i++) - { - for (j = 0; j < 8; j++) - { - if (bksv[i] & 0x01) - { - temp++; - } - bksv[i] >>= 1; - } - } - if (temp != 20) - return HDCP_KSV_ERR; - - for(i = 0; i < hdcp->invalidkey; i++) - { - invalidkey = hdcp->invalidkeys + i *5; - if(memcmp(bksv, invalidkey, 5) == 0) { - printk(KERN_ERR "HDCP: BKSV was revocated!!!\n"); - HDCPMskReg(temp, HDCP_CTRL1, m_BKSV_INVALID | m_ENCRYPT_ENABLE, v_BKSV_INVALID(1) | v_ENCRYPT_ENABLE(1)); - return HDCP_KSV_ERR; - } - } - HDCPMskReg(temp, HDCP_CTRL1, m_BKSV_VALID | m_ENCRYPT_ENABLE, v_BKSV_VALID(1) | v_ENCRYPT_ENABLE(1)); - return HDCP_OK; -} - -void rk610_hdcp_interrupt(char *status1, char *status2) -{ - char interrupt1 = HDCPRdReg(HDCP_INT_STATUS1); - char interrupt2 = HDCPRdReg(HDCP_INT_STATUS2); - if(interrupt1) { - HDCPWrReg(HDCP_INT_STATUS1, interrupt1); - if(interrupt1 & m_INT_HDCP_ERR) - printk(KERN_INFO "HDCP: Error 0x%02x\n", HDCPRdReg(HDCP_ERROR)); - } - if(interrupt2) - HDCPWrReg(HDCP_INT_STATUS2, interrupt2); - - *status1 = interrupt1; - *status2 = interrupt2; -} \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi_hw.c deleted file mode 100755 index d472dddcaf50..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi_hw.c +++ /dev/null @@ -1,412 +0,0 @@ -#include -#include "rk610_hdmi.h" -#include "rk610_hdmi_hw.h" -#include - -static atomic_t edid_ready; - -static int rk610_hdmi_i2c_read_reg(char reg, char *val) -{ - if(i2c_master_reg8_recv(rk610_hdmi->client, reg, val, 1, 100*1000) > 0) - return 0; - else { - printk("[%s] reg %02x error\n", __FUNCTION__, reg); - return -EINVAL; - } -} -static int rk610_hdmi_i2c_write_reg(char reg, char val) -{ - return i2c_master_reg8_send(rk610_hdmi->client, reg, &val, 1, 100*1000) > 0? 0: -EINVAL; -} - -#define HDMIWrReg rk610_hdmi_i2c_write_reg - -int rk610_hdmi_sys_init(void) -{ - // System power power off - HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_OFF | v_INT_POL_HIGH); - - //Synchronize analog module. -// HDMIWrReg(PHY_SYNC, 0x00); -// HDMIWrReg(PHY_SYNC, 0x01); - - // set hdmi phy parameters - // driver mode - HDMIWrReg(PHY_DRIVER, v_MAIN_DRIVER(8)| v_PRE_DRIVER(0) | v_TX_ENABLE(0)); -// HDMIWrReg(PHY_PRE_EMPHASIS, 0x04); - HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(1)); //Driver power down - // pll mode - HDMIWrReg(0xe8, 0x10); - HDMIWrReg(0xe6, 0x2c); - - HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(1) | v_PLL_RESET(1) | v_TMDS_RESET(1)); - HDMIWrReg(PHY_PLL_LDO_PWR, v_LDO_PWR_DOWN(1)); - HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_DOWN); - - // Enable Hotplug interrupt - HDMIWrReg(INTERRUPT_MASK1, m_INT_HOTPLUG); - return HDMI_ERROR_SUCESS; -} - -void rk610_hdmi_interrupt() -{ - char interrupt = 0; - - if(rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &interrupt)) - return; - - HDMIWrReg(INTERRUPT_STATUS1, interrupt); - - if(interrupt) - HDMIWrReg(INTERRUPT_STATUS1, interrupt); - - if(interrupt & m_INT_HOTPLUG) { - hdmi_dbg(hdmi->dev, "%s interrupt %02x\n", __FUNCTION__, interrupt); - if(hdmi->state == HDMI_SLEEP) - hdmi->state = WAIT_HOTPLUG; - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); - } - else if(interrupt & m_INT_EDID_READY) { - atomic_set(&edid_ready, 1); - } -} - -int rk610_hdmi_sys_detect_hpd(void) -{ - char hdmi_status = 0; - - #ifdef HDMI_USE_IRQ - rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &hdmi_status); - HDMIWrReg(INTERRUPT_STATUS1, hdmi_status); - #endif - hdmi_status = 0; - rk610_hdmi_i2c_read_reg(HDMI_STATUS, &hdmi_status); -// printk("%s value is %02x\n", __FUNCTION__, hdmi_status); - if(hdmi_status) - return HDMI_HPD_ACTIVED; - else - return HDMI_HPD_REMOVED; -} - -#define SYSCLK 11289600 -#define DDC_CLK 100000 -int rk610_hdmi_sys_read_edid(int block, unsigned char *buff) -{ - char value; - int count, rc = HDMI_ERROR_EDID; - char hdmi_status = 0; - - // Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b) - // when reg00 select reg_clk equal to sys_clk which is equal - // to i2s clk, it gernerally is 11.2896MHz. - - count = SYSCLK/(DDC_CLK*4); - HDMIWrReg(DDC_CLK_L, count & 0xFF); - HDMIWrReg(DDC_CLK_H, (count >> 8) & 0xFF); - - // Enable EDID Interrupt -// edid_ready = 0; - atomic_set(&edid_ready, 0); - value = 0; - rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value); - value |= m_INT_EDID_READY; - HDMIWrReg(INTERRUPT_MASK1, value); - - // Reset FIFO offset - HDMIWrReg(EDID_FIFO_OFFSET, 0); - // Set EDID read addr. - HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80); - HDMIWrReg(EDID_SEGMENT_POINTER, block/2); - - count = 0; - while(count++ < 10) - { -#ifdef HDMI_USE_IRQ - value = atomic_read(&edid_ready); -#else - msleep(10); - rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &hdmi_status); - value = (hdmi_status & m_INT_EDID_READY); -#endif - if(value) - { - for(value = 0; value < 128; value++) - rk610_hdmi_i2c_read_reg(EDID_FIFO_ADDR, buff + value); - rc = HDMI_ERROR_SUCESS; - break; - } - msleep(100); - } - // Disable EDID interrupt. - value = 0; - rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value); - value &= ~m_INT_EDID_READY; - HDMIWrReg(INTERRUPT_MASK1, value); - return rc; -} - -static void rk610_hdmi_config_avi(unsigned char vic, unsigned char output_color) -{ - int i; - char info[SIZE_AVI_INFOFRAME]; - - memset(info, 0, SIZE_AVI_INFOFRAME); - HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); - info[0] = 0x82; - info[1] = 0x02; - 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[6] = 0; - info[7] = vic; - info[8] = 0; - - // Calculate AVI InfoFrame ChecKsum - for (i = 4; i < SIZE_AVI_INFOFRAME; i++) - { - info[3] += info[i]; - } - info[3] = 0x100 - info[3]; - - for(i = 0; i < SIZE_AVI_INFOFRAME; i++) - HDMIWrReg(CONTROL_PACKET_ADDR + i, info[i]); -} - -int rk610_hdmi_sys_config_video(struct hdmi_video_para *vpara) -{ - char value; - struct fb_videomode *mode; - - hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); - if(vpara == NULL) { - hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__); - return -1; - } - if(hdmi->hdcp_power_off_cb) - hdmi->hdcp_power_off_cb(); - // Diable video and audio output - HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); - - // Input video mode is SDR RGB24bit, Data enable signal from external - HDMIWrReg(VIDEO_CONTRL1, v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | v_DE_EXTERNAL); - HDMIWrReg(VIDEO_CONTRL2, v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | (vpara->output_color & 0xFF)); - - // Set HDMI Mode - HDMIWrReg(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; - HDMIWrReg(VIDEO_CONTRL3, value); - - #if 1 - HDMIWrReg(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); - return -ENOENT; - } - hdmi->tmdsclk = mode->pixclock; -#else - value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode); - if(mode->sync & FB_SYNC_HOR_HIGH_ACT) - value |= v_HSYNC_POLARITY(1); - if(mode->sync & FB_SYNC_VERT_HIGH_ACT) - value |= v_VSYNC_POLARITY(1); - HDMIWrReg(VIDEO_TIMING_CTL, value); - - value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len; - HDMIWrReg(VIDEO_EXT_HTOTAL_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); - - value = mode->left_margin + mode->right_margin + mode->hsync_len; - HDMIWrReg(VIDEO_EXT_HBLANK_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); - - value = mode->left_margin + mode->hsync_len; - HDMIWrReg(VIDEO_EXT_HDELAY_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); - - value = mode->hsync_len; - HDMIWrReg(VIDEO_EXT_HDURATION_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); - - value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len; - HDMIWrReg(VIDEO_EXT_VTOTAL_L, value & 0xFF); - HDMIWrReg(VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); - - value = mode->upper_margin + mode->vsync_len + mode->lower_margin; - HDMIWrReg(VIDEO_EXT_VBLANK, value & 0xFF); - - 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; - - HDMIWrReg(VIDEO_EXT_VDELAY, value & 0xFF); - - value = mode->vsync_len; - HDMIWrReg(VIDEO_EXT_VDURATION, value & 0xFF); - #endif - - if(vpara->output_mode == OUTPUT_HDMI) { - rk610_hdmi_config_avi(vpara->vic, vpara->output_color); - hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); - } - else { - hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__); - } - - // Power on TMDS - HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(0)); // TMDS power on - - // Enable TMDS - value = 0; - rk610_hdmi_i2c_read_reg(PHY_DRIVER, &value); - value |= v_TX_ENABLE(1); - HDMIWrReg(PHY_DRIVER, value); - - return 0; -} - -static void rk610_hdmi_config_aai(void) -{ - int i; - char info[SIZE_AUDIO_INFOFRAME]; - - memset(info, 0, SIZE_AUDIO_INFOFRAME); - - info[0] = 0x84; - info[1] = 0x01; - info[2] = 0x0A; - - info[3] = info[0] + info[1] + info[2]; - for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++) - info[3] += info[i]; - - info[3] = 0x100 - info[3]; - - HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI); - for(i = 0; i < SIZE_AUDIO_INFOFRAME; i++) - HDMIWrReg(CONTROL_PACKET_ADDR + i, info[i]); -} - -int rk610_hdmi_sys_config_audio(struct hdmi_audio *audio) -{ - int rate, N, channel, mclk_fs; - - if(audio->channel < 3) - channel = I2S_CHANNEL_1_2; - else if(audio->channel < 5) - channel = I2S_CHANNEL_3_4; - 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; - } - - //set_audio source I2S - HDMIWrReg(AUDIO_CTRL1, 0x00); //internal CTS, disable down sample, i2s input, disable MCLK - HDMIWrReg(AUDIO_SAMPLE_RATE, rate); - HDMIWrReg(AUDIO_I2S_MODE, v_I2S_MODE(I2S_STANDARD) | v_I2S_CHANNEL(channel) ); - HDMIWrReg(AUDIO_I2S_MAP, 0x00); - HDMIWrReg(AUDIO_I2S_SWAPS_SPDIF, 0); // no swap - - //Set N value - HDMIWrReg(AUDIO_N_H, (N >> 16) & 0x0F); - HDMIWrReg(AUDIO_N_M, (N >> 8) & 0xFF); - HDMIWrReg(AUDIO_N_L, N & 0xFF); - rk610_hdmi_config_aai(); - - return 0; -} - -void rk610_hdmi_sys_enalbe_output(int enable) -{ - char mutestatus = 0; - - if(enable) { - rk610_hdmi_i2c_read_reg(AV_MUTE, &mutestatus); - if(mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) { - HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); - HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_ON | v_INT_POL_HIGH); - HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_OFF | v_INT_POL_HIGH); - HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_ON | v_INT_POL_HIGH); - if(hdmi->hdcp_cb) - hdmi->hdcp_cb(); - } - } - else { - HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); - } -} - -int rk610_hdmi_sys_insert(void) -{ - hdmi_dbg(hdmi->dev, "%s \n", __FUNCTION__); - //Bring up analog module. - HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_UP); //BG power on - HDMIWrReg(PHY_PLL_LDO_PWR, 0x00); //PLL power on - msleep(1); - HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(0)); //Analog reset - return 0; -} - -int rk610_hdmi_sys_remove(void) -{ - hdmi_dbg(hdmi->dev, "%s \n", __FUNCTION__); - if(hdmi->hdcp_power_off_cb) - hdmi->hdcp_power_off_cb(); - HDMIWrReg(PHY_DRIVER, v_MAIN_DRIVER(8)| v_PRE_DRIVER(0) | v_TX_ENABLE(0)); - HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(1)); //Driver power down - HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(1) | v_PLL_RESET(1) | v_TMDS_RESET(1)); - HDMIWrReg(PHY_PLL_LDO_PWR, v_LDO_PWR_DOWN(1)); - HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_DOWN); - return 0; -} diff --git a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi_hw.h deleted file mode 100755 index 0e4cce913f74..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk610/rk610_hdmi_hw.h +++ /dev/null @@ -1,237 +0,0 @@ -#ifndef _RK610_HDMI_HW_H -#define _RK610_HDMI_HW_H - -enum { - OUTPUT_DVI = 0, - OUTPUT_HDMI - }; - -#define SYS_CTRL 0x00 - #define m_INT_POL (1 << 0) - #define m_POWER (1 << 1) - #define m_REG_CLK_SOURCE (1 << 2) - #define v_INT_POL_HIGH 1 - #define v_INT_POL_LOW 0 - #define v_PWR_ON (0 << 1) - #define v_PWR_OFF (1 << 1) - #define v_REG_CLK_SOURCE_TMDS (0 << 2) - #define v_REG_CLK_SOURCE_IIS (1 << 2) -#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 AUDIO_I2S_SWAPS_SPDIF 0x3a - #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_96K 0x3000 -#define N_192K 0x6000 - -#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 DDC_CLK_L 0x4b -#define DDC_CLK_H 0x4c - -#define EDID_SEGMENT_POINTER 0x4d -#define EDID_WORD_ADDR 0x4e -#define EDID_FIFO_OFFSET 0x4f -#define EDID_FIFO_ADDR 0x50 - -/* CONTROL_PACKET_BUF_INDEX */ -#define CONTROL_PACKET_BUF_INDEX 0x9f -enum { - INFOFRAME_AVI = 0x06, - INFOFRAME_AAI = 0x08 -}; -#define CONTROL_PACKET_ADDR 0xa0 - - -#define SIZE_AVI_INFOFRAME 0x11 // 14 bytes -#define SIZE_AUDIO_INFOFRAME 0x0F // 15 bytes -enum { - AVI_COLOR_MODE_RGB = 0, - AVI_COLOR_MODE_YCBCR422, - AVI_COLOR_MODE_YCBCR444 -}; -enum { - AVI_COLORIMETRY_NO_DATA = 0, - AVI_COLORIMETRY_SMPTE_170M, - AVI_COLORIMETRY_ITU709, - AVI_COLORIMETRY_EXTENDED -}; -enum { - AVI_CODED_FRAME_ASPECT_NO_DATA, - AVI_CODED_FRAME_ASPECT_4_3, - AVI_CODED_FRAME_ASPECT_16_9 -}; -enum { - ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME = 0x08, - ACTIVE_ASPECT_RATE_4_3, - ACTIVE_ASPECT_RATE_16_9, - ACTIVE_ASPECT_RATE_14_9 -}; - -#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 << 6) - #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_DRIVER 0xe1 - #define v_MAIN_DRIVER(n) (n << 4) - #define v_PRE_DRIVER(n) (n << 2) - #define v_TX_ENABLE(n) (n << 1) - -#define PHY_PRE_EMPHASIS 0xe2 - #define v_PRE_EMPHASIS(n) (n << 4) - #define v_TMDS_PWRDOWN(n) (n) - -#define PHY_PLL_TEST 0xe3 -#define PHY_BANDGAP_PWR 0xe4 - #define v_BANDGAP_PWR_DOWN 0x03 - #define v_BANDGAP_PWR_UP 0 - -#define PHY_PLL_CTRL 0xe5 - #define v_PLL_DISABLE(n) (n << 4) - #define v_PLL_RESET(n) (n << 3) - #define v_TMDS_RESET(n) (n << 2) - -#define PHY_PLL_LDO_PWR 0xe7 - #define v_LDO_PWR_DOWN(n) (n << 2) - -#endif \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/chips/rk616/Kconfig b/drivers/video/rockchip/hdmi/chips/rk616/Kconfig deleted file mode 100755 index 68cedb7eed0c..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk616/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -config HDCP_RK616 - bool "RK616 HDCP support" - depends on HDMI_RK616 || ARCH_RK3026 - default n - help - HDCP Interface. This adds the High Definition Content Protection Interface. - See http://www.digital-cp.com/ for HDCP specification. - -config HDCP_RK616_DEBUG - bool "RK616 HDCP Debugging" - depends on HDCP_RK616 - default n - help - Enableds verbose debugging the the HDCP drivers diff --git a/drivers/video/rockchip/hdmi/chips/rk616/Makefile b/drivers/video/rockchip/hdmi/chips/rk616/Makefile deleted file mode 100755 index 685f5cad6cc5..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk616/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for HDMI linux kernel module. -# - -ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG -ccflags-$(CONFIG_HDCP_RK616_DEBUG) = -DHDCP_DEBUG - -obj-$(CONFIG_HDMI_RK616) += rk616_hdmi_hw.o rk616_hdmi.o -obj-$(CONFIG_HDCP_RK616) += rk616_hdmi_hdcp.o rk616_hdcp.o diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdcp.c deleted file mode 100755 index 8b03fedf0f49..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdcp.c +++ /dev/null @@ -1,563 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "rk616_hdmi.h" -#include "rk616_hdcp.h" - -struct hdcp *hdcp = NULL; - -static void hdcp_work_queue(struct work_struct *work); - -/*----------------------------------------------------------------------------- - * Function: hdcp_submit_work - *----------------------------------------------------------------------------- - */ -static struct delayed_work *hdcp_submit_work(int event, int delay) -{ - struct hdcp_delayed_work *work; - - DBG("%s event %04x delay %d", __FUNCTION__, event, delay); - - work = kmalloc(sizeof(struct hdcp_delayed_work), GFP_ATOMIC); - - if (work) { - INIT_DELAYED_WORK(&work->work, hdcp_work_queue); - work->event = event; - queue_delayed_work(hdcp->workqueue, - &work->work, - msecs_to_jiffies(delay)); - } else { - printk(KERN_WARNING "HDCP: Cannot allocate memory to " - "create work\n"); - return 0; - } - - return &work->work; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_cancel_work - *----------------------------------------------------------------------------- - */ -static void hdcp_cancel_work(struct delayed_work **work) -{ - int ret = 0; - - if (*work) { - ret = cancel_delayed_work(*work); - if (ret != 1) { - ret = cancel_work_sync(&((*work)->work)); - printk(KERN_INFO "Canceling work failed - " - "cancel_work_sync done %d\n", ret); - } - kfree(*work); - *work = 0; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_failure - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_failure(void) -{ - if (hdcp->hdmi_state == HDMI_STOPPED) { - return; - } - - rk616_hdcp_disable(); - rk616_hdmi_control_output(false); - - hdcp_cancel_work(&hdcp->pending_wq_event); - - if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) { - if (hdcp->retry_cnt < HDCP_INFINITE_REAUTH) { - hdcp->retry_cnt--; - printk(KERN_INFO "HDCP: authentication failed - " - "retrying, attempts=%d\n", - hdcp->retry_cnt); - } else - printk(KERN_INFO "HDCP: authentication failed - " - "retrying\n"); - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - - hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT, - HDCP_REAUTH_DELAY); - } else { - printk(KERN_INFO "HDCP: authentication failed - " - "HDCP disabled\n"); - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } - -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_start_authentication - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_start_authentication(void) -{ - int status = HDCP_OK; - - hdcp->hdcp_state = HDCP_AUTHENTICATION_START; - - DBG("HDCP: authentication start"); - - status = rk616_hdcp_start_authentication(); - - if (status != HDCP_OK) { - DBG("HDCP: authentication failed"); - hdcp_wq_authentication_failure(); - } else { - hdcp->hdcp_state = HDCP_WAIT_KSV_LIST; -// hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_check_bksv - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_check_bksv(void) -{ - int status = HDCP_OK; - - DBG("Check BKSV start"); - - status = rk616_hdcp_check_bksv(); - - if (status != HDCP_OK) { - printk(KERN_INFO "HDCP: Check BKSV failed"); - hdcp->retry_cnt = 0; - hdcp_wq_authentication_failure(); - } - else { - DBG("HDCP: Check BKSV successful"); - - hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; - - /* Restore retry counter */ - if(hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times; - } -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_authentication_sucess - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_authentication_sucess(void) -{ - rk616_hdmi_control_output(true); - printk(KERN_INFO "HDCP: authentication pass"); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_wq_disable - *----------------------------------------------------------------------------- - */ -static void hdcp_wq_disable(int event) -{ - printk(KERN_INFO "HDCP: disabled"); - - hdcp_cancel_work(&hdcp->pending_wq_event); - rk616_hdcp_disable(); - if(event == HDCP_DISABLE_CTL) { - hdcp->hdcp_state = HDCP_DISABLED; - if(hdcp->hdmi_state == HDMI_STARTED) - rk616_hdmi_control_output(true); - } - else if(event == HDCP_STOP_FRAME_EVENT) - hdcp->hdcp_state = HDCP_ENABLE_PENDING; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_work_queue - *----------------------------------------------------------------------------- - */ -static void hdcp_work_queue(struct work_struct *work) -{ - struct hdcp_delayed_work *hdcp_w = - container_of(work, struct hdcp_delayed_work, work.work); - int event = hdcp_w->event; - - mutex_lock(&hdcp->lock); - - DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d", - jiffies_to_msecs(jiffies), - hdcp->hdmi_state, - hdcp->hdcp_state, - (event & 0xFF00) >> 8, - event & 0xFF); - - if(event == HDCP_STOP_FRAME_EVENT) { - hdcp->hdmi_state = HDMI_STOPPED; - } - - if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) { - hdcp_wq_disable(event); - } - - if (event & HDCP_WORKQUEUE_SRC) - hdcp->pending_wq_event = 0; - - /* First handle HDMI state */ - if (event == HDCP_START_FRAME_EVENT) { - hdcp->pending_start = 0; - hdcp->hdmi_state = HDMI_STARTED; - } - - /**********************/ - /* HDCP state machine */ - /**********************/ - switch (hdcp->hdcp_state) { - case HDCP_DISABLED: - /* HDCP enable control or re-authentication event */ - if (event == HDCP_ENABLE_CTL) { - if(hdcp->retry_times == 0) - hdcp->retry_cnt = HDCP_INFINITE_REAUTH; - else - hdcp->retry_cnt = hdcp->retry_times; - if (hdcp->hdmi_state == HDMI_STARTED) - hdcp_wq_start_authentication(); - else - hdcp->hdcp_state = HDCP_ENABLE_PENDING; - } - break; - - case HDCP_ENABLE_PENDING: - /* HDMI start frame event */ - if (event == HDCP_START_FRAME_EVENT) - hdcp_wq_start_authentication(); - - break; - - case HDCP_AUTHENTICATION_START: - /* Re-authentication */ - if (event == HDCP_AUTH_REATT_EVENT) - hdcp_wq_start_authentication(); - - break; - - case HDCP_WAIT_KSV_LIST: - /* KSV failure */ - if (event == HDCP_FAIL_EVENT) { - printk(KERN_INFO "HDCP: KSV switch failure\n"); - - hdcp_wq_authentication_failure(); - } - /* KSV list ready event */ - else if (event == HDCP_KSV_LIST_RDY_EVENT) - hdcp_wq_check_bksv(); - break; - - case HDCP_LINK_INTEGRITY_CHECK: - /* Ri failure */ - if (event == HDCP_FAIL_EVENT) { - printk(KERN_INFO "HDCP: Ri check failure\n"); - hdcp_wq_authentication_failure(); - } - else if(event == HDCP_AUTH_PASS_EVENT) - hdcp_wq_authentication_sucess(); - break; - - default: - printk(KERN_WARNING "HDCP: error - unknow HDCP state\n"); - break; - } - - kfree(hdcp_w); - if(event == HDCP_STOP_FRAME_EVENT) - complete(&hdcp->complete); - - mutex_unlock(&hdcp->lock); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_start_frame_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_start_frame_cb(void) -{ - DBG("hdcp_start_frame_cb()"); - - /* Cancel any pending work */ - if (hdcp->pending_start) - hdcp_cancel_work(&hdcp->pending_start); - if (hdcp->pending_wq_event) - hdcp_cancel_work(&hdcp->pending_wq_event); - - hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT, - HDCP_ENABLE_DELAY); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_irq_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_irq_cb(int status) -{ - char interrupt1; - char interrupt2; - - rk616_hdcp_interrupt(&interrupt1, &interrupt2); - DBG("%s 0x%02x 0x%02x", __FUNCTION__, interrupt1, interrupt2); - if(interrupt1 & m_INT_HDCP_ERR) - { - if( (hdcp->hdcp_state != HDCP_DISABLED) && - (hdcp->hdcp_state != HDCP_ENABLE_PENDING) ) - { - hdcp_submit_work(HDCP_FAIL_EVENT, 0); - } - } - else if(interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE)) - hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0); - else if(interrupt1 & m_INT_AUTH_SUCCESS) - hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0); -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_on_cb - *----------------------------------------------------------------------------- - */ -static int hdcp_power_on_cb(void) -{ - DBG("%s", __FUNCTION__); -// return rk616_hdcp_load_key2mem(hdcp->keys); - return HDCP_OK; -} - -/*----------------------------------------------------------------------------- - * Function: hdcp_power_off_cb - *----------------------------------------------------------------------------- - */ -static void hdcp_power_off_cb(void) -{ - DBG("%s", __FUNCTION__); - if(!hdcp->enable) - return; - - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - init_completion(&hdcp->complete); - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0)) - wait_for_completion_interruptible_timeout(&hdcp->complete, - msecs_to_jiffies(5000)); -} - -// Load HDCP key to external HDCP memory -static void hdcp_load_keys_cb(const struct firmware *fw, void *context) -{ - if (!fw) { - pr_err("HDCP: failed to load keys\n"); - return; - } - - if(fw->size < HDCP_KEY_SIZE) { - pr_err("HDCP: firmware wrong size %d\n", fw->size); - return; - } - - hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL); - if(hdcp->keys == NULL) { - pr_err("HDCP: can't allocated space for keys\n"); - return; - } - - memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE); - - printk(KERN_INFO "HDCP: load hdcp key success\n"); - - if(fw->size > HDCP_KEY_SIZE) { - DBG("%s invalid key size %d", __FUNCTION__, fw->size - HDCP_KEY_SIZE); - if((fw->size - HDCP_KEY_SIZE) % 5) { - pr_err("HDCP: failed to load invalid keys\n"); - return; - } - hdcp->invalidkeys = kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL); - if(hdcp->invalidkeys == NULL) { - pr_err("HDCP: can't allocated space for invalid keys\n"); - return; - } - memcpy(hdcp->invalidkeys, fw->data + HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE); - hdcp->invalidkey = (fw->size - HDCP_KEY_SIZE)/5; - printk(KERN_INFO "HDCP: loaded hdcp invalid key success\n"); - } -} - -static ssize_t hdcp_enable_read(struct device *device, - struct device_attribute *attr, char *buf) -{ - int enable = 0; - - if(hdcp) - enable = hdcp->enable; - - return snprintf(buf, PAGE_SIZE, "%d\n", enable); -} - -static ssize_t hdcp_enable_write(struct device *device, - struct device_attribute *attr, const char *buf, size_t count) -{ - int enable; - - if(hdcp == NULL) - return -EINVAL; - - sscanf(buf, "%d", &enable); - if(hdcp->enable != enable) - { - /* Post event to workqueue */ - if(enable) { - if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0) - return -EFAULT; - } - else { - hdcp_cancel_work(&hdcp->pending_start); - hdcp_cancel_work(&hdcp->pending_wq_event); - - /* Post event to workqueue */ - if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0) - return -EFAULT; - } - hdcp->enable = enable; - } - return count; -} - -static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, hdcp_enable_read, hdcp_enable_write); - -static ssize_t hdcp_trytimes_read(struct device *device, - struct device_attribute *attr, char *buf) -{ - int trytimes = 0; - - if(hdcp) - trytimes = hdcp->retry_times; - - return snprintf(buf, PAGE_SIZE, "%d\n", trytimes); -} - -static ssize_t hdcp_trytimes_wrtie(struct device *device, - struct device_attribute *attr, const char *buf, size_t count) -{ - int trytimes; - - if(hdcp == NULL) - return -EINVAL; - - sscanf(buf, "%d", &trytimes); - if(hdcp->retry_times != trytimes) - hdcp->retry_times = trytimes; - - return count; -} - - -static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR, hdcp_trytimes_read, hdcp_trytimes_wrtie); - - -static struct miscdevice mdev; - -static int __init rk616_hdcp_init(void) -{ - int ret; - - DBG("[%s] %u", __FUNCTION__, jiffies_to_msecs(jiffies)); - - hdcp = kmalloc(sizeof(struct hdcp), GFP_KERNEL); - if(!hdcp) - { - printk(KERN_ERR ">>HDCP: kmalloc fail!"); - ret = -ENOMEM; - goto error0; - } - memset(hdcp, 0, sizeof(struct hdcp)); - mutex_init(&hdcp->lock); - - mdev.minor = MISC_DYNAMIC_MINOR; - mdev.name = "hdcp"; - mdev.mode = 0666; - if (misc_register(&mdev)) { - printk(KERN_ERR "HDCP: Could not add character driver\n"); - ret = HDMI_ERROR_FALSE; - goto error1; - } - ret = device_create_file(mdev.this_device, &dev_attr_enable); - if(ret) - { - printk(KERN_ERR "HDCP: Could not add sys file enable\n"); - ret = -EINVAL; - goto error2; - } - - ret = device_create_file(mdev.this_device, &dev_attr_trytimes); - if(ret) - { - printk(KERN_ERR "HDCP: Could not add sys file trytimes\n"); - ret = -EINVAL; - goto error3; - } - - hdcp->workqueue = create_singlethread_workqueue("hdcp"); - if (hdcp->workqueue == NULL) { - printk(KERN_ERR "HDCP,: create workqueue failed.\n"); - goto error4; - } - - - ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, - "hdcp.keys", mdev.this_device, GFP_KERNEL, - hdcp, hdcp_load_keys_cb); - if (ret < 0) { - printk(KERN_ERR "HDCP: request_firmware_nowait failed: %d\n", ret); - goto error5; - } - - rk616_hdmi_register_hdcp_callbacks(hdcp_start_frame_cb, - hdcp_irq_cb, - hdcp_power_on_cb, - hdcp_power_off_cb); - - DBG("%s success %u", __FUNCTION__, jiffies_to_msecs(jiffies)); - return 0; - -error5: - destroy_workqueue(hdcp->workqueue); -error4: - device_remove_file(mdev.this_device, &dev_attr_trytimes); -error3: - device_remove_file(mdev.this_device, &dev_attr_enable); -error2: - misc_deregister(&mdev); -error1: - if(hdcp->keys) - kfree(hdcp->keys); - if(hdcp->invalidkeys) - kfree(hdcp->invalidkeys); - kfree(hdcp); -error0: - return ret; -} - -static void __exit rk616_hdcp_exit(void) -{ - device_remove_file(mdev.this_device, &dev_attr_enable); - misc_deregister(&mdev); - if(hdcp->keys) - kfree(hdcp->keys); - if(hdcp->invalidkeys) - kfree(hdcp->invalidkeys); - kfree(hdcp); -} - -module_init(rk616_hdcp_init); -module_exit(rk616_hdcp_exit); diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdcp.h b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdcp.h deleted file mode 100755 index d97b0b6c04f7..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdcp.h +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef __rk616_HDCP_H__ -#define __rk616_HDCP_H__ - -/***************************/ -/* Definitions */ -/***************************/ - -/* Status / error codes */ -#define HDCP_OK 0 -#define HDCP_KEY_ERR 1 -#define HDCP_KSV_ERR 2 - -/* Delays */ -#define HDCP_ENABLE_DELAY 300 -#define HDCP_REAUTH_DELAY 100 - -/* Event source */ -#define HDCP_SRC_SHIFT 8 -#define HDCP_IOCTL_SRC (0x1 << HDCP_SRC_SHIFT) -#define HDCP_HDMI_SRC (0x2 << HDCP_SRC_SHIFT) -#define HDCP_IRQ_SRC (0x4 << HDCP_SRC_SHIFT) -#define HDCP_WORKQUEUE_SRC (0x8 << HDCP_SRC_SHIFT) - -/* Event */ -#define HDCP_ENABLE_CTL (HDCP_IOCTL_SRC | 0) -#define HDCP_DISABLE_CTL (HDCP_IOCTL_SRC | 1) -#define HDCP_START_FRAME_EVENT (HDCP_HDMI_SRC | 2) -#define HDCP_STOP_FRAME_EVENT (HDCP_HDMI_SRC | 3) -#define HDCP_KSV_LIST_RDY_EVENT (HDCP_IRQ_SRC | 4) -#define HDCP_FAIL_EVENT (HDCP_IRQ_SRC | 5) -#define HDCP_AUTH_PASS_EVENT (HDCP_IRQ_SRC | 6) -#define HDCP_AUTH_REATT_EVENT (HDCP_WORKQUEUE_SRC | 7) - -/* Key size */ -#define HDCP_KEY_SIZE 308 - -/* HDCP DDC Clock */ -#define HDCP_DDC_CLK 100000 - -/* Authentication retry times */ -#define HDCP_INFINITE_REAUTH 0x100 - -/* HDCP Regs */ -#define HDCP_CTRL1 0x52 - #define m_AUTH_START (1 << 7) - #define m_BKSV_VALID (1 << 6) - #define m_BKSV_INVALID (1 << 5) - #define m_ENCRYPT_ENABLE (1 << 4) - #define m_AUTH_STOP (1 << 3) - #define m_ADVANED_ENABLE (1 << 2) - #define m_HDMI_DVI (1 << 1) - #define m_HDCP_RESET (1 << 0) - - #define v_AUTH_START(n) (n << 7) - #define v_BKSV_VALID(n) (n << 6) - #define v_BKSV_INVALID(n) (n << 5) - #define v_ENCRYPT_ENABLE(n) (n << 4) - #define v_AUTH_STOP(n) (n << 3) - #define v_ADVANED_ENABLE(n) (n << 2) - #define v_HDMI_DVI(n) (n << 1) - #define v_HDCP_RESET(n) (n << 0) - -#define HDCP_CTRL2 0x53 - #define m_DISABLE_127_CHECK (1 << 7) - #define m_SKIP_BKSV_CHECK (1 << 6) - #define m_ENABLE_PJ_CHECK (1 << 5) - #define m_DISABLE_DEVICE_NUMBER_CHECK (1 << 4) - #define m_DELAY_RI_1_CLK (1 << 3) - #define m_USE_PRESET_AN (1 << 2) - #define m_KEY_COMBINATION (3 << 0) - - #define v_DISABLE_127_CHECK(n) (n << 7) - #define v_SKIP_BKSV_CHECK(n) (n << 6) - #define v_ENABLE_PJ_CHECK(n) (n << 5) - #define v_DISABLE_DEVICE_NUMBER_CHECK(n)(n << 4) - #define v_DELAY_RI_1_CLK(n) (n << 3) - #define v_USE_PRESET_AN(n) (n << 2) - #define v_KEY_COMBINATION(n) (n << 0) - -#define HDCP_KEY_STATUS 0x54 - #define m_KEY_READY (1 << 0) - -#define HDCP_CTRL_SOFT 0x57 - #define m_DISABLE_127_CHECK (1 << 7) - #define m_SKIP_BKSV_CHECK (1 << 6) - #define m_NOT_AUTHENTICATED (1 << 5) - #define m_ENCRYPTED (1 << 4) - #define m_ADVANCED_CIPHER (1 << 3) - -#define HDCP_BCAPS_RX 0x58 -#define HDCP_TIMER_100MS 0x63 -#define HDCP_TIMER_5S 0x64 -#define HDCP_ERROR 0x65 - #define m_DDC_NO_ACK (1 << 3) - #define m_PJ_MISMACH (1 << 2) - #define m_RI_MISMACH (1 << 1) - #define m_BKSV_WRONG (1 << 0) - -#define HDCP_KSV_BYTE0 0x66 -#define HDCP_KSV_BYTE1 0x67 -#define HDCP_KSV_BYTE2 0x68 -#define HDCP_KSV_BYTE3 0x69 -#define HDCP_KSV_BYTE4 0x6a - -#define HDCP_AN_SEED 0x6c - -#define HDCP_BCAPS_TX 0x80 -#define HDCP_BSTATE_0 0x81 -#define HDCP_BSTATE_1 0x82 - -#define HDCP_KEY_FIFO 0x98 - -#define HDCP_INT_MASK1 0xc2 -#define HDCP_INT_STATUS1 0xc3 - #define m_INT_HDCP_ERR (1 << 7) - #define m_INT_BKSV_READY (1 << 6) - #define m_INT_BKSV_UPDATE (1 << 5) - #define m_INT_AUTH_SUCCESS (1 << 4) - #define m_INT_AUTH_READY (1 << 3) - -#define HDCP_INT_MASK2 0xc4 -#define HDCP_INT_STATUS2 0xc5 - #define m_INT_SOFT_MODE_READY (1 << 7) - #define m_INT_AUTH_M0_REDAY (1 << 6) - #define m_INT_1st_FRAME_ARRIVE (1 << 5) - #define m_INT_AN_READY (1 << 4) - #define m_INT_ENCRYPTED (1 << 2) - #define m_INT_NOT_ENCRYPTED_AVMUTE (1 << 1) - #define m_INT_NOT_ENCRYPTED_AVUNMUTE (1 << 0) - -enum hdcp_states { - HDCP_DISABLED, - HDCP_ENABLE_PENDING, - HDCP_AUTHENTICATION_START, - HDCP_WAIT_KSV_LIST, - HDCP_LINK_INTEGRITY_CHECK, -}; - -enum hdmi_states { - HDMI_STOPPED, - HDMI_STARTED -}; - -#define HDCP_PRIVATE_KEY_SIZE 280 -#define HDCP_KEY_SHA_SIZE 20 - -struct hdcp_keys{ - u8 KSV[8]; - u8 DeviceKey[HDCP_PRIVATE_KEY_SIZE]; - u8 sha1[HDCP_KEY_SHA_SIZE]; -}; - -struct hdcp_delayed_work { - struct delayed_work work; - int event; -}; - -struct hdcp { - int enable; - int retry_times; - struct hdcp_keys *keys; - int invalidkey; - char *invalidkeys; - struct mutex lock; - struct completion complete; - struct workqueue_struct *workqueue; - - enum hdmi_states hdmi_state; - enum hdcp_states hdcp_state; - - struct delayed_work *pending_start; - struct delayed_work *pending_wq_event; - int retry_cnt; -}; - -extern struct hdcp *hdcp; - -#ifdef HDCP_DEBUG -#define DBG(format, ...) \ - printk(KERN_INFO "HDCP: " format "\n", ## __VA_ARGS__) -#else -#define DBG(format, ...) -#endif - -extern void rk616_hdcp_disable(void); -extern int rk616_hdcp_start_authentication(void); -extern int rk616_hdcp_check_bksv(void); -extern int rk616_hdcp_load_key2mem(struct hdcp_keys *key); -extern void rk616_hdcp_interrupt(char *status1, char *status2); -#endif /* __rk616_HDCP_H__ */ diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c deleted file mode 100755 index 1a5f5be79ecd..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c +++ /dev/null @@ -1,583 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#if defined(CONFIG_DEBUG_FS) -#include -#include -#include -#endif - -#include "rk616_hdmi.h" -#include "rk616_hdmi_hw.h" - -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_puts(s, "\n>>>rk616_ctl reg"); - for (i = 0; i < 16; i++) - seq_printf(s, " %2x", i); - - 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_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) -{ - 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_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_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, -}; -#endif - -#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) { - 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)) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - if (hdmi_drv == NULL) - return HDMI_ERROR_FALSE; - - 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; -} - -static void rk616_hdmi_early_suspend(void) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - - 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_drv->irq) - disable_irq(hdmi_drv->irq); - - 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); - -} - -static void rk616_hdmi_early_resume(void) -{ - struct hdmi *hdmi_drv = &hdmi_dev->driver; - struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; - - hdmi_dbg(hdmi_drv->dev, "hdmi exit early resume\n"); - - mutex_lock(&hdmi_drv->enable_mutex); - - 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_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); -} - -static int rk616_hdmi_fb_event_notify(struct notifier_block *self, - unsigned long action, void *data) -{ - 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; - } - } - - return NOTIFY_OK; -} - -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_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) -{ - 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 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/3036 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) || defined(SOC_CONFIG_RK3036) - grf_writel(HDMI_SEL_LCDC(lcdc_id), RK3036_GRF_SOC_CON6); -#endif - */ - lcdc_id = 0; - 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; -} - -#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 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_drv = &hdmi_dev->driver; - hdmi_drv->dev = &pdev->dev; - platform_set_drvdata(pdev, hdmi_dev); - spin_lock_init(&hdmi_dev->reg_lock); - -#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); - if (!(hdmi_dev->rk616_drv)) { - dev_err(hdmi_drv->dev, "null mfd device rk616!\n"); - goto err0; - } -#endif - -#ifdef CONFIG_SWITCH - 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); - - 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); - -#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)) { - dev_err(hdmi_drv->dev, "Unable to get hdmi hclk\n"); - ret = -ENXIO; - goto err1; - } - rk616_hdmi_clk_enable(hdmi_dev); /* enable clk may move to irq func */ - hdmi_dev->hclk_rate = clk_get_rate(hdmi_dev->hclk); - /* request and remap iomem */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(hdmi_drv->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; - } - if (rk616_hdmi_drv_init(hdmi_drv)) - goto err0; - - /* get the IRQ */ - hdmi_drv->irq = platform_get_irq(pdev, 0); - if (hdmi_drv->irq <= 0) { - dev_err(hdmi_drv->dev, "failed to get hdmi irq resource (%d).\n", - hdmi_drv->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 - 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; - } - if (rk616_hdmi_drv_init(hdmi_drv)) - goto err0; - - /* 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 - - //rk616_hdmi_work(hdmi_drv); - -#if defined(CONFIG_DEBUG_FS) - 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 { - 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 - - 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) || defined(SOC_CONFIG_RK3036) -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_drv->switch_hdmi)); -#endif - -err0: - 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) -{ - 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_drv->switch_hdmi)); -#endif - hdmi_unregister_display_sysfs(hdmi_drv); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&hdmi_drv->early_suspend); -#endif - 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); - } - - hdmi_dbg(hdmi_drv->dev, "rk616 hdmi removed.\n"); - kfree(hdmi_dev); - hdmi_dev = NULL; - } - - return 0; -} - -static void rk616_hdmi_shutdown(struct platform_device *pdev) -{ - struct rk_hdmi_device *hdmi_dev = platform_get_drvdata(pdev); - struct hdmi *hdmi_drv = NULL; - - if (hdmi_dev) { - hdmi_drv = &hdmi_dev->driver; -#ifdef CONFIG_HAS_EARLYSUSPEND - 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"); -} - - -static struct platform_driver rk616_hdmi_driver = { - .probe = rk616_hdmi_probe, - .remove = rk616_hdmi_remove, - .driver = { - .name = "rk616-hdmi", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(rk616_hdmi_of_match), - }, - .shutdown = rk616_hdmi_shutdown, -}; - -static int __init rk616_hdmi_init(void) -{ - return platform_driver_register(&rk616_hdmi_driver); -} - -static void __exit rk616_hdmi_exit(void) -{ - platform_driver_unregister(&rk616_hdmi_driver); -} - -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 deleted file mode 100755 index 5184a68149f3..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __RK616_HDMI_H__ -#define __RK616_HDMI_H__ - -#include "../../rk_hdmi.h" -#include - -enum { - INPUT_IIS, - INPUT_SPDIF -}; - -#if defined(CONFIG_SND_RK_SOC_HDMI_SPDIF) -#define HDMI_CODEC_SOURCE_SELECT INPUT_SPDIF -#else -#define HDMI_CODEC_SOURCE_SELECT INPUT_IIS -#endif - -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)); - -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 clk *pclk; /* HDMI APB clk */ - struct delayed_work rk616_delay_work; - struct work_struct rk616_irq_work_struct; - struct mfd_rk616 *rk616_drv; - struct dentry *debugfs_dir; - unsigned int hclk_rate; -}; - -#endif /* __RK616_HDMI_H__ */ diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hdcp.c b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hdcp.c deleted file mode 100755 index 67952427133f..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hdcp.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include "rk616_hdmi.h" -#include "rk616_hdmi_hw.h" -#include "rk616_hdcp.h" - -#define HDCPWrReg HDMIWrReg -#define HDCPRdReg HDMIRdReg -#define HDCPMskReg(temp,addr,Msk,val) do{ \ - HDMIRdReg(addr,&temp); \ - HDMIWrReg(addr, ((val)&(Msk))|(temp&(~Msk))); \ - }while(0) - -void rk616_hdcp_disable(void) -{ - char temp; - - // Diable HDCP Interrupt - HDCPWrReg(HDCP_INT_MASK1, 0x00); - // Stop and Reset HDCP - HDCPMskReg(temp, HDCP_CTRL1, m_ENCRYPT_ENABLE | m_AUTH_STOP | m_HDCP_RESET, - v_ENCRYPT_ENABLE(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1) ); -} - -int rk616_hdcp_load_key2mem(struct hdcp_keys *key) -{ - int i; - DBG("HDCP: rk616_hdcp_load_key2mem start"); - // Write 40 private key - for(i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) - HDCPWrReg(HDCP_KEY_FIFO, key->DeviceKey[i]); - - // Write 1st aksv - for(i = 0; i < 5; i++) - HDCPWrReg(HDCP_KEY_FIFO, key->KSV[i]); - - // Write 2nd aksv - for(i = 0; i < 5; i++) - HDCPWrReg(HDCP_KEY_FIFO, key->KSV[i]); - DBG("HDCP: rk616_hdcp_load_key2mem end"); - return HDCP_OK; -} - -int rk616_hdcp_start_authentication(void) -{ - char temp; - int retry = 0; - - if(hdcp->keys == NULL) { - printk(KERN_ERR "HDCP: key is not loaded\n"); - return HDCP_KEY_ERR; - } - - // Select TMDS CLK to configure regs - HDCPMskReg(temp, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS); - - HDCPRdReg(HDCP_KEY_STATUS,&temp); - while( ( temp & m_KEY_READY) == 0 ) { - if(retry > 10) { - printk(KERN_ERR "HDCP: loaded key error\n"); - return HDCP_KEY_ERR; - } - rk616_hdcp_load_key2mem(hdcp->keys); - msleep(1); - HDCPRdReg(HDCP_KEY_STATUS,&temp); - } - - // Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b) - DBG("TMDS frequency %d", hdmi->tmdsclk); - retry = hdmi->tmdsclk/(HDCP_DDC_CLK*4); - HDCPWrReg(DDC_CLK_L, retry & 0xFF); - HDCPWrReg(DDC_CLK_H, (retry >> 8) & 0xFF); - - HDCPWrReg(HDCP_CTRL2, 0x00); - - //Enable interrupt - HDCPWrReg(HDCP_INT_MASK1, m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE | m_INT_AUTH_SUCCESS | m_INT_AUTH_READY); -// HDCPWrReg(HDCP_INT_MASK2, 0xFF); - //Start authentication - HDCPMskReg(temp, HDCP_CTRL1, m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE, v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) | v_ADVANED_ENABLE(0)); - - return HDCP_OK; -} - -int rk616_hdcp_check_bksv(void) -{ - int i, j; - char temp = 0, bksv[5]; - char *invalidkey; - - for(i = 0; i < 5; i++) { - HDCPRdReg(HDCP_KSV_BYTE0 + (4 - i),&temp); - bksv[i] = temp & 0xFF; - } - DBG("bksv is 0x%02x%02x%02x%02x%02x", bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]); - - temp = 0; - for (i = 0; i < 5; i++) - { - for (j = 0; j < 8; j++) - { - if (bksv[i] & 0x01) - { - temp++; - } - bksv[i] >>= 1; - } - } - if (temp != 20) - return HDCP_KSV_ERR; - - for(i = 0; i < hdcp->invalidkey; i++) - { - invalidkey = hdcp->invalidkeys + i *5; - if(memcmp(bksv, invalidkey, 5) == 0) { - printk(KERN_ERR "HDCP: BKSV was revocated!!!\n"); - HDCPMskReg(temp, HDCP_CTRL1, m_BKSV_INVALID | m_ENCRYPT_ENABLE, v_BKSV_INVALID(1) | v_ENCRYPT_ENABLE(1)); - return HDCP_KSV_ERR; - } - } - HDCPMskReg(temp, HDCP_CTRL1, m_BKSV_VALID | m_ENCRYPT_ENABLE, v_BKSV_VALID(1) | v_ENCRYPT_ENABLE(1)); - return HDCP_OK; -} - -void rk616_hdcp_interrupt(char *status1, char *status2) -{ - char interrupt1 = 0; - char interrupt2 = 0; - char temp =0; - HDCPRdReg(HDCP_INT_STATUS1,&interrupt1); - HDCPRdReg(HDCP_INT_STATUS2,&interrupt2); - if(interrupt1) { - HDCPWrReg(HDCP_INT_STATUS1, interrupt1); - if(interrupt1 & m_INT_HDCP_ERR){ - HDCPRdReg(HDCP_ERROR,&temp); - printk(KERN_INFO "HDCP: Error 0x%02x\n", temp); - } - } - if(interrupt2) - HDCPWrReg(HDCP_INT_STATUS2, interrupt2); - - *status1 = interrupt1; - *status2 = interrupt2; -} diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c deleted file mode 100755 index 23febddfa9ae..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c +++ /dev/null @@ -1,710 +0,0 @@ -#include -#include -#include -#include -#include "rk616_hdmi.h" -#include "rk616_hdmi_hw.h" - -#if !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036) - -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_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_drv, struct rk_screen *screen, - bool connect) -{ - 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_drv, hdmi_drv->vic); - - rk616_set_vif(rk616_drv, screen, connect); - return 0; -} - -static int rk616_hdmi_init_pol_set(struct mfd_rk616 *rk616_drv, int pol) -{ - u32 val; - int ret; - int int_pol_mask = (1 << 5); - - if (pol) - val = 0x0; - else - val = 0x20; - ret = rk616_drv->write_dev_bits(rk616_drv, CRU_CFGMISC_CON, - int_pol_mask, &val); - - return 0; -} -#endif - -static int __maybe_unused rk616_hdmi_show_reg(struct hdmi *hdmi_drv) -{ - int i = 0; - u32 val = 0; - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); - - printk("\n>>>rk616_ctl reg"); - for (i = 0; i < 16; i++) - printk(" %2x", i); - - printk("\n-----------------------------------------------------------------"); - - for (i = 0; i <= PHY_PRE_DIV_RATIO; i++) { - hdmi_readl(hdmi_dev, i, &val); - if (i % 16 == 0) - printk("\n>>>rk616_ctl %2x:", i); - printk(" %02x", val); - } - printk("\n-----------------------------------------------------------------\n"); - - return 0; -} - -static inline void delay100us(void) -{ - msleep(1); -} - -static void rk616_hdmi_av_mute(struct hdmi *hdmi_drv, bool enable) -{ - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); - - hdmi_writel(hdmi_dev, AV_MUTE, - v_AUDIO_MUTE(enable) | v_VIDEO_MUTE(enable)); -} - -static void rk616_hdmi_sys_power(struct hdmi *hdmi_drv, bool enable) -{ - 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_drv, int mode) -{ - 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_drv->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); - } -#ifdef SOC_CONFIG_RK3036 - hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x15); - hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x14); - hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x10); -#else - 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); -#endif - 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_drv->dev, - "%s change pwr_mode LOWER_PWR pwr_mode = %d, mode = %d\n", - __func__, hdmi_drv->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); -#ifdef SOC_CONFIG_RK3036 - hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x17); -#else - hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x2f); -#endif - break; - default: - 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_drv) -{ - int value = 0; - 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) - return HDMI_HPD_ACTIVED; - else if (value) - return HDMI_HPD_INSERT; - else - return HDMI_HPD_REMOVED; -} -int rk616_hdmi_insert(struct hdmi *hdmi_drv) -{ - rk616_hdmi_set_pwr_mode(hdmi_drv, NORMAL); - return 0; -} - - -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; - 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; -#ifdef SOC_CONFIG_RK3036 - ddc_bus_freq = (hdmi_dev->hclk_rate>> 2) / HDMI_SCL_RATE; -#else - ddc_bus_freq = (HDMI_SYS_FREG_CLK >> 2) / HDMI_SCL_RATE; -#endif - 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 */ -#ifdef SOC_CONFIG_RK3036 - hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_EDID_READY); -#else - hdmi_writel(hdmi_dev, INTERRUPT_MASK1, - m_INT_HOTPLUG | m_INT_EDID_READY); -#endif - - for (trytime = 0; trytime < 10; trytime++) { - checksum = 0; - 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); - - printk("0x%02x ", c); -#endif - } - - /* 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; - } - } - } - //close edid irq -#ifdef SOC_CONFIG_RK3036 - hdmi_writel(hdmi_dev, INTERRUPT_MASK1, 0); -#else - hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG); -#endif - enable_irq(hdmi_drv->irq); - - return ret; -} - -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(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); - info[0] = 0x82; - info[1] = 0x02; - 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[6] = 0; - info[7] = vic; - info[8] = 0; - - /* Calculate AVI InfoFrame ChecKsum */ - for (i = 4; i < SIZE_AVI_INFOFRAME; i++) - info[3] += info[i]; - - info[3] = 0x100 - info[3]; - - 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_drv, - struct hdmi_video_para *vpara) -{ - int value; - struct fb_videomode *mode; - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); - - hdmi_dbg(hdmi_drv->dev, "[%s]\n", __func__); - - if (vpara == NULL) { - hdmi_err(hdmi_drv->dev, "[%s] input parameter error\n", - __func__); - return -1; - } - - /* 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)); - - /* 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(hdmi_dev, VIDEO_CONTRL3, value); - - /* Set ext video timing */ -#if 1 - hdmi_writel(hdmi_dev, VIDEO_TIMING_CTL, 0); - mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); - if (mode == NULL) { - hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __func__, - vpara->vic); - return -ENOENT; - } - hdmi_drv->tmdsclk = mode->pixclock; -#else - value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode); - if (mode->sync & FB_SYNC_HOR_HIGH_ACT) - value |= v_HSYNC_POLARITY(1); - if (mode->sync & FB_SYNC_VERT_HIGH_ACT) - value |= v_VSYNC_POLARITY(1); - 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(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(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(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(hdmi_dev, VIDEO_EXT_VBLANK, value & 0xFF); - - 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(hdmi_dev, VIDEO_EXT_VDELAY, value & 0xFF); - - value = mode->vsync_len; - hdmi_writel(hdmi_dev, VIDEO_EXT_VDURATION, value & 0xFF); -#endif - - if (vpara->output_mode == OUTPUT_HDMI) { - rk616_hdmi_config_avi(hdmi_drv, vpara->vic, - vpara->output_color); - hdmi_dbg(hdmi_drv->dev, "[%s] sucess output HDMI.\n", __func__); - } else { - hdmi_dbg(hdmi_drv->dev, "[%s] sucess output DVI.\n", __func__); - } - - 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); - } - return 0; -} - -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]; - for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++) - info[3] += info[i]; - - info[3] = 0x100 - info[3]; - - 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_drv, - struct hdmi_audio *audio) -{ - int rate, N, channel, mclk_fs; - 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) - channel = I2S_CHANNEL_3_4; - 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_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(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(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_drv, int enable) -{ - int mutestatus = 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(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(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_drv) -{ - - 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_drv) -{ - u32 interrupt = 0; - struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, - struct rk_hdmi_device, - driver); -#ifdef SOC_CONFIG_RK3036 - hdmi_readl(hdmi_dev, HDMI_STATUS,&interrupt); - if(interrupt){ - hdmi_writel(hdmi_dev, HDMI_STATUS, interrupt); - } - if (interrupt & m_INT_HOTPLUG) -#else - hdmi_readl(hdmi_dev, INTERRUPT_STATUS1,&interrupt); - if(interrupt){ - hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt); - } - if (interrupt & m_HOTPLUG) -#endif - { - 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)); - - }//plug out? - - if (hdmi_drv->hdcp_irq_cb) - hdmi_drv->hdcp_irq_cb(0); -} - -static void rk616_hdmi_reset(struct hdmi *hdmi_drv) -{ - u32 val = 0; - u32 msk = 0; - 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(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(hdmi_dev, SYS_CTRL, msk, val); -#ifdef SOC_CONFIG_RK3036 - hdmi_readl(hdmi_dev, HDMI_STATUS,&val);//enable hpg - val |= m_MASK_INT_HOTPLUG; - //hdmi_writel(hdmi_dev, HDMI_STATUS,val);//do this will lead to clear hpd irq -#else - hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG); -#endif - rk616_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR); // hjc delete for audis - //rk616_hdmi_set_pwr_mode(hdmi_drv, NORMAL); -} - -int rk616_hdmi_initial(struct hdmi *hdmi_drv) -{ - int rc = HDMI_ERROR_SUCESS; -#if !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036) - 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_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; - hdmi_drv->insert = rk616_hdmi_insert; - -#if defined(CONFIG_ARCH_RK3026) - rk3028_hdmi_reset_pclk(); - rk616_hdmi_reset(hdmi_drv); -#elif defined(SOC_CONFIG_RK3036) - rk3028_hdmi_reset_pclk(); - rk616_hdmi_reset(hdmi_drv); -#else - hdmi_drv->set_vif = rk616_hdmi_set_vif; - rk616_hdmi_reset(hdmi_drv); - rk616_hdmi_init_pol_set(rk616_drv, 0); -#endif - - 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 deleted file mode 100755 index 1bd7e5d02ff9..000000000000 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h +++ /dev/null @@ -1,372 +0,0 @@ -#ifndef _RK616_HDMI_HW_H -#define _RK616_HDMI_HW_H - -#define SOC_CONFIG_RK3036 -#include -#define RK616_HDMI_BASE 0x400 -enum PWR_MODE { - NORMAL, - LOWER_PWR, -}; -enum { - OUTPUT_DVI = 0, - OUTPUT_HDMI -}; - -#ifdef RK616_USE_MCLK_12M -#define HDMI_SYS_FREG_CLK 12000000 -#else -#define HDMI_SYS_FREG_CLK 11289600 -#endif - -#define HDMI_SCL_RATE (100*1000) -#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 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 AUDIO_I2S_SWAPS_SPDIF 0x3a -#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_96K 0x3000 -#define N_192K 0x6000 - -#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 DDC_CLK_L 0x4b -#define DDC_CLK_H 0x4c - -#define EDID_SEGMENT_POINTER 0x4d -#define EDID_WORD_ADDR 0x4e -#define EDID_FIFO_OFFSET 0x4f -#define EDID_FIFO_ADDR 0x50 - -/* CONTROL_PACKET_BUF_INDEX */ -#define CONTROL_PACKET_BUF_INDEX 0x9f -enum { - INFOFRAME_AVI = 0x06, - INFOFRAME_AAI = 0x08 -}; -#define CONTROL_PACKET_ADDR 0xa0 - -#define SIZE_AVI_INFOFRAME 0x11 /* 14 bytes */ -#define SIZE_AUDIO_INFOFRAME 0x0F /* 15 bytes */ -enum { - AVI_COLOR_MODE_RGB = 0, - AVI_COLOR_MODE_YCBCR422, - AVI_COLOR_MODE_YCBCR444 -}; -enum { - AVI_COLORIMETRY_NO_DATA = 0, - AVI_COLORIMETRY_SMPTE_170M, - AVI_COLORIMETRY_ITU709, - AVI_COLORIMETRY_EXTENDED -}; -enum { - AVI_CODED_FRAME_ASPECT_NO_DATA, - AVI_CODED_FRAME_ASPECT_4_3, - AVI_CODED_FRAME_ASPECT_16_9 -}; -enum { - ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME = 0x08, - ACTIVE_ASPECT_RATE_4_3, - ACTIVE_ASPECT_RATE_16_9, - ACTIVE_ASPECT_RATE_14_9 -}; - -#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 -#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 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) - #ifdef SOC_CONFIG_RK3036 - #define m_MASK_INT_HOTPLUG (1 << 5) - #define m_INT_HOTPLUG (1 << 1) - #else - #define m_DDC_SDA (1 << 5) - #define m_DDC_SDC (1 << 4) - #endif - - -#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 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 PHY_PRE_DIV_RATIO 0xed -#define v_PRE_DIV_RATIO(n) (n & 0x1f) - -#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; - struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; - - ret = rk616_drv->read_dev(rk616_drv, - (RK616_HDMI_BASE + ((offset) << 2)), val); - return ret; -} - -static inline int hdmi_writel(struct rk_hdmi_device *hdmi_dev, - u16 offset, u32 val) -{ - int ret; - struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; - - ret = rk616_drv->write_dev(rk616_drv, - (RK616_HDMI_BASE + ((offset) << 2)), &val); - return ret; -} - -static inline int hdmi_msk_reg(struct rk_hdmi_device *hdmi_dev, u16 offset, - u32 msk, u32 val) -{ - int ret; - struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv; - - ret = rk616_drv->write_dev_bits(rk616_drv, - (RK616_HDMI_BASE + ((offset) << 2)), - msk, &val); - return ret; -} -#else - -static inline int hdmi_readl(struct rk_hdmi_device *hdmi_dev, u16 offset, - u32 *val) -{ - int ret = 0; - - *val = readl_relaxed(hdmi_dev->regbase + (offset) * 0x04); - return ret; -} - -static inline int hdmi_writel(struct rk_hdmi_device *hdmi_dev, u16 offset, - u32 val) -{ - int ret = 0; - - writel_relaxed(val, hdmi_dev->regbase + (offset) * 0x04); - return ret; -} - -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_dev->regbase + (offset) * 0x04) & (0xFF - (msk)); - writel_relaxed(temp | ((val) & (msk)), hdmi_dev->regbase + (offset) * 0x04); - return ret; -} -#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036) -static inline void rk3028_hdmi_reset_pclk(void) -{ - writel_relaxed(0x00010001, RK_CRU_VIRT+ 0x128); - msleep(100); - writel_relaxed(0x00010000, RK_CRU_VIRT + 0x128); -} -#endif -#endif - -extern int rk616_hdmi_initial(struct hdmi *hdmi); -extern void rk616_hdmi_work(struct hdmi *hdmi); - -#endif diff --git a/drivers/video/rockchip/hdmi/rk_hdmi.h b/drivers/video/rockchip/hdmi/rk_hdmi.h deleted file mode 100755 index c853654871a5..000000000000 --- a/drivers/video/rockchip/hdmi/rk_hdmi.h +++ /dev/null @@ -1,434 +0,0 @@ -#ifndef __RK_HDMI_H__ -#define __RK_HDMI_H__ - -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_SWITCH -#include -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include -#include -#include - -/* default HDMI output video mode */ -#define HDMI_VIDEO_DEFAULT_MODE HDMI_1280x720p_60Hz - -#define HDMI_720X480P_60HZ_VIC 2 -#define HDMI_720X480I_60HZ_VIC 6 -#define HDMI_720X576P_50HZ_VIC 17 -#define HDMI_720X576I_50HZ_VIC 21 -#define HDMI_1280X720P_50HZ_VIC 19 -#define HDMI_1280X720P_60HZ_VIC 4 -#define HDMI_1920X1080P_50HZ_VIC 31 -#define HDMI_1920X1080I_50HZ_VIC 20 -#define HDMI_1920X1080P_60HZ_VIC 16 -#define HDMI_1920X1080I_60HZ_VIC 5 -#define HDMI_3840X2160P_24HZ_VIC 93 -#define HDMI_3840X2160P_25HZ_VIC 94 -#define HDMI_3840X2160P_30HZ_VIC 95 -#define HDMI_3840X2160P_50HZ_VIC 96 -#define HDMI_3840X2160P_60HZ_VIC 97 -#define HDMI_4096X2160P_24HZ_VIC 98 -#define HDMI_4096X2160P_25HZ_VIC 99 -#define HDMI_4096X2160P_30HZ_VIC 100 -#define HDMI_4096X2160P_50HZ_VIC 101 -#define HDMI_4096X2160P_60HZ_VIC 102 - -/* HDMI video source */ -enum { - HDMI_SOURCE_LCDC0 = 0, - HDMI_SOURCE_LCDC1 = 1 -}; - -enum { - HDMI_SOC_RK3036, - HDMI_SOC_RK312X, - HDMI_SOC_RK3288 -}; -/* - * If HDMI_ENABLE, system will auto configure output mode according to EDID - * If HDMI_DISABLE, system will output mode according to - * macro HDMI_VIDEO_DEFAULT_MODE - */ -#define HDMI_AUTO_CONFIGURE HDMI_DISABLE - -/* default HDMI output audio mode */ -#define HDMI_AUDIO_DEFAULT_CHANNEL 2 -#define HDMI_AUDIO_DEFAULT_RATE HDMI_AUDIO_FS_44100 -#define HDMI_AUDIO_DEFAULT_WORD_LENGTH HDMI_AUDIO_WORD_LENGTH_16bit - -enum { - VIDEO_INPUT_RGB_YCBCR_444 = 0, - VIDEO_INPUT_YCBCR422, - VIDEO_INPUT_YCBCR422_EMBEDDED_SYNC, - VIDEO_INPUT_2X_CLOCK, - VIDEO_INPUT_2X_CLOCK_EMBEDDED_SYNC, - VIDEO_INPUT_RGB444_DDR, - VIDEO_INPUT_YCBCR422_DDR -}; - -enum { - VIDEO_OUTPUT_RGB444 = 0, - VIDEO_OUTPUT_YCBCR444, - VIDEO_OUTPUT_YCBCR422, - VIDEO_OUTPUT_YCBCR420 -}; - -enum { - VIDEO_INPUT_COLOR_RGB = 0, - VIDEO_INPUT_COLOR_YCBCR444, - VIDEO_INPUT_COLOR_YCBCR422, - VIDEO_INPUT_COLOR_YCBCR420 -}; - -/* HDMI video mode code according CEA-861-E */ -enum hdmi_video_mode { - HDMI_640x480p_60Hz = 1, - HDMI_720x480p_60Hz_4_3, - HDMI_720x480p_60Hz_16_9, - HDMI_1280x720p_60Hz, - HDMI_1920x1080i_60Hz, /* 5 */ - HDMI_720x480i_60Hz_4_3, - HDMI_720x480i_60Hz_16_9, - HDMI_720x240p_60Hz_4_3, - HDMI_720x240p_60Hz_16_9, - HDMI_2880x480i_60Hz_4_3, /* 10 */ - HDMI_2880x480i_60Hz_16_9, - HDMI_2880x240p_60Hz_4_3, - HDMI_2880x240p_60Hz_16_9, - HDMI_1440x480p_60Hz_4_3, - HDMI_1440x480p_60Hz_16_9, /* 15 */ - HDMI_1920x1080p_60Hz, - HDMI_720x576p_50Hz_4_3, - HDMI_720x576p_50Hz_16_9, - HDMI_1280x720p_50Hz, - HDMI_1920x1080i_50Hz, /* 20 */ - HDMI_720x576i_50Hz_4_3, - HDMI_720x576i_50Hz_16_9, - HDMI_720x288p_50Hz_4_3, - HDMI_720x288p_50Hz_16_9, - HDMI_2880x576i_50Hz_4_3, /* 25 */ - HDMI_2880x576i_50Hz_16_9, - HDMI_2880x288p_50Hz_4_3, - HDMI_2880x288p_50Hz_16_9, - HDMI_1440x576p_50Hz_4_3, - HDMI_1440x576p_50Hz_16_9, /* 30 */ - HDMI_1920x1080p_50Hz, - HDMI_1920x1080p_24Hz, - HDMI_1920x1080p_25Hz, - HDMI_1920x1080p_30Hz, - HDMI_2880x480p_60Hz_4_3, /* 35 */ - HDMI_2880x480p_60Hz_16_9, - HDMI_2880x576p_50Hz_4_3, - HDMI_2880x576p_50Hz_16_9, - HDMI_1920x1080i_50Hz_2, /* V Line 1250 total */ - HDMI_1920x1080i_100Hz, /* 40 */ - HDMI_1280x720p_100Hz, - HDMI_720x576p_100Hz_4_3, - HDMI_720x576p_100Hz_16_9, - HDMI_720x576i_100Hz_4_3, - HDMI_720x576i_100Hz_16_9, /* 45 */ - HDMI_1920x1080i_120Hz, - HDMI_1280x720p_120Hz, - HDMI_720x480p_120Hz_4_3, - HDMI_720x480p_120Hz_16_9, - HDMI_720x480i_120Hz_4_3, /* 50 */ - HDMI_720x480i_120Hz_16_9, - HDMI_720x576p_200Hz_4_3, - HDMI_720x576p_200Hz_16_9, - HDMI_720x576i_200Hz_4_3, - HDMI_720x576i_200Hz_16_9, /* 55 */ - HDMI_720x480p_240Hz_4_3, - HDMI_720x480p_240Hz_16_9, - HDMI_720x480i_240Hz_4_3, - HDMI_720x480i_240Hz_16_9, - HDMI_1280x720p_24Hz, /* 60 */ - HDMI_1280x720p_25Hz, - HDMI_1280x720p_30Hz, - HDMI_1920x1080p_120Hz, - HDMI_1920x1080p_100Hz, -}; - -/* HDMI Video Data Color Mode */ -enum { - HDMI_COLOR_RGB = 0, - HDMI_COLOR_YCbCr422, - HDMI_COLOR_YCbCr444 -}; - -/* HDMI Video Color Depth */ -enum { - HDMI_COLOR_DEPTH_8BIT = 0x1, - HDMI_COLOR_DEPTH_10BIT = 0x2, - HDMI_COLOR_DEPTH_12BIT = 0x4, - HDMI_COLOR_DEPTH_16BIT = 0x8 -}; - -/* HDMI Audio type */ -enum hdmi_audio_type { - HDMI_AUDIO_LPCM = 1, - HDMI_AUDIO_AC3, - HDMI_AUDIO_MPEG1, - HDMI_AUDIO_MP3, - HDMI_AUDIO_MPEG2, - HDMI_AUDIO_AAC_LC, /* AAC */ - HDMI_AUDIO_DTS, - HDMI_AUDIO_ATARC, - HDMI_AUDIO_DSD, /* One bit Audio */ - HDMI_AUDIO_E_AC3, - HDMI_AUDIO_DTS_HD, - HDMI_AUDIO_MLP, - HDMI_AUDIO_DST, - HDMI_AUDIO_WMA_PRO -}; - -/* I2S Fs */ -enum hdmi_audio_fs { - HDMI_AUDIO_FS_32000 = 0x1, - HDMI_AUDIO_FS_44100 = 0x2, - HDMI_AUDIO_FS_48000 = 0x4, - HDMI_AUDIO_FS_88200 = 0x8, - HDMI_AUDIO_FS_96000 = 0x10, - HDMI_AUDIO_FS_176400 = 0x20, - HDMI_AUDIO_FS_192000 = 0x40 -}; - -/* Audio Word Length */ -enum hdmi_audio_word_length { - HDMI_AUDIO_WORD_LENGTH_16bit = 0x1, - HDMI_AUDIO_WORD_LENGTH_20bit = 0x2, - HDMI_AUDIO_WORD_LENGTH_24bit = 0x4 -}; - -/* EDID block size */ -#define HDMI_EDID_BLOCK_SIZE 128 - -/* HDMI state machine */ -enum hdmi_state { - HDMI_SLEEP = 0, - HDMI_INITIAL, - WAIT_HOTPLUG, - READ_PARSE_EDID, - WAIT_HDMI_ENABLE, - SYSTEM_CONFIG, - CONFIG_VIDEO, - CONFIG_AUDIO, - PLAY_BACK, -}; - -/* HDMI configuration command */ -enum hdmi_change { - HDMI_CONFIG_NONE = 0, - HDMI_CONFIG_VIDEO, - HDMI_CONFIG_AUDIO, - HDMI_CONFIG_COLOR, - HDMI_CONFIG_HDCP, - HDMI_CONFIG_ENABLE, - HDMI_CONFIG_DISABLE, - HDMI_CONFIG_DISPLAY -}; - -/* HDMI Hotplug status */ -enum { - HDMI_HPD_REMOVED = 0, - HDMI_HPD_INSERT, - HDMI_HPD_ACTIVED -}; - -/* HDMI STATUS */ -#define HDMI_DISABLE 0 -#define HDMI_ENABLE 1 -#define HDMI_UNKOWN 0xFF - -/* HDMI Error Code */ -enum hdmi_errorcode { - HDMI_ERROR_SUCESS = 0, - HDMI_ERROR_FALSE, - HDMI_ERROR_I2C, - HDMI_ERROR_EDID, -}; - -/* HDMI audio parameters */ -struct hdmi_audio { - u32 type; /* Audio type */ - u32 channel; /* Audio channel number */ - u32 rate; /* Audio sampling rate */ - u32 word_length; /* Audio data word length */ -}; - -struct hdmi_edid { - unsigned char sink_hdmi; /* HDMI display device flag */ - unsigned char ycbcr444; /* Display device support YCbCr444 */ - unsigned char ycbcr422; /* Display device support YCbCr422 */ - unsigned char deepcolor; /* bit3:DC_48bit; bit2:DC_36bit; - * bit1:DC_30bit; bit0:DC_Y444; - */ - unsigned char latency_fields_present; - unsigned char i_latency_fields_present; - unsigned char video_latency; - unsigned char audio_latency; - unsigned char interlaced_video_latency; - unsigned char interlaced_audio_latency; - unsigned char video_present; /* have additional video format - * abount 4k and/or 3d - */ - unsigned char support_3d; /* 3D format support */ - unsigned int maxtmdsclock; /* max tmds clock freq support */ - struct fb_monspecs *specs; /* Device spec */ - struct list_head modelist; /* Device supported display mode list */ - struct hdmi_audio *audio; /* Device supported audio info */ - int audio_num; /* Device supported audio type number */ - int base_audio_support; /* Device supported base audio */ - unsigned int cecaddress; /* CEC physical address */ -}; - -/* RK HDMI Video Configure Parameters */ -struct hdmi_video_para { - int vic; - int input_mode; /* input video data interface */ - int input_color; /* input video color mode */ - int output_mode; /* output hdmi or dvi */ - int output_color; /* output video color mode */ - unsigned char format_3d; /* output 3d format */ - unsigned char color_depth; /* color depth: 8bit; 10bit; - * 12bit; 16bit; - */ - unsigned char pixel_repet; /* pixel repettion */ - unsigned char pixel_pack_phase; /* pixel packing default phase */ - unsigned char color_limit_range; /* quantization range - * 0: full range(0~255) - * 1:limit range(16~235) - */ -}; - -struct rk_hdmi_drvdata { - u8 soc_type; - u32 reversed; -}; -struct hdmi; - -struct rk_hdmi_drv_ops { - int (*hdmi_debug) (struct hdmi *hdmi, int cmd); -}; - - -struct hdmi { - struct device *dev; - int id; - int irq; - struct rk_lcdc_driver *lcdc; - struct rk_hdmi_drvdata *data; - struct rk_display_device *ddev; -#ifdef CONFIG_SWITCH - struct switch_dev switch_hdmi; -#endif - - struct mutex lock; - struct workqueue_struct *workqueue; - struct delayed_work delay_work; - - spinlock_t irq_lock; - struct mutex enable_mutex; - - int wait; - struct completion complete; - - int suspend; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif - - struct hdmi_edid edid; - int enable; /* Enable HDMI output or not */ - int vic; /* HDMI output video mode code */ - struct hdmi_audio audio; /* HDMI output audio type */ - - int pwr_mode; /* power mode */ - int hotplug; /* hot plug status */ - int state; /* hdmi state machine status */ - int autoconfig; /* if true, auto config hdmi output mode - * according to EDID - */ - int command; /* HDMI configuration command */ - int display; /* HDMI display status */ - int xscale; /* x direction scale value */ - int yscale; /* y directoon scale value */ - int tmdsclk; /* TDMS Clock frequency */ - int pixclock; /* Pixel Clcok frequency */ - int uboot_logo; - - struct list_head pwrlist_head; - - int (*insert)(struct hdmi *hdmi); - int (*remove)(struct hdmi *hdmi); - void (*control_output)(struct hdmi *hdmi, int enable); - int (*config_video)(struct hdmi *hdmi, - struct hdmi_video_para *vpara); - int (*config_audio)(struct hdmi *hdmi, struct hdmi_audio *audio); - int (*detect_hotplug)(struct hdmi *hdmi); - /* call back for edid */ - int (*read_edid)(struct hdmi *hdmi, int block, unsigned char *buff); - int (*set_vif)(struct hdmi *hdmi, struct rk_screen *screen, - bool connect); - - /* call back for hdcp operation */ - void (*hdcp_cb)(void); - void (*hdcp_irq_cb)(int); - int (*hdcp_power_on_cb)(void); - void (*hdcp_power_off_cb)(void); - - /*call back for cec operation*/ - void (*cec_irq)(void); - void (*cec_set_device_pa)(int); - int (*cec_enumerate)(void); - struct rk_hdmi_drv_ops *ops; - unsigned int *support_vic; - int support_vic_num; -}; - -#define hdmi_err(dev, format, arg...) \ - dev_err(dev , format , ## arg) - -#ifdef HDMI_DEBUG -#define hdmi_dbg(dev, format, arg...) \ - dev_info(dev , format , ## arg) -#else -#define hdmi_dbg(dev, format, arg...) -#endif - -int hdmi_drv_register(struct hdmi *hdmi_drv); -int hdmi_get_hotplug(void); -int hdmi_set_info(struct rk_screen *screen, unsigned int vic); -void hdmi_init_lcdc(struct rk_screen *screen, - struct rk29lcd_info *lcd_info); -int hdmi_sys_init(struct hdmi *hdmi_drv); -int hdmi_sys_parse_edid(struct hdmi *hdmi_drv); -const char *hdmi_get_video_mode_name(unsigned char vic); -int hdmi_videomode_to_vic(struct fb_videomode *vmode); -const struct fb_videomode *hdmi_vic_to_videomode(int vic); -int hdmi_add_videomode(const struct fb_videomode *mode, - struct list_head *head); -struct hdmi_video_timing *hdmi_find_mode(int vic); -int hdmi_find_best_mode(struct hdmi *hdmi_drv, int vic); -int hdmi_ouputmode_select(struct hdmi *hdmi_drv, int edid_ok); -int hdmi_switch_fb(struct hdmi *hdmi_drv, int vic); -int hdmi_init_video_para(struct hdmi *hdmi_drv, - struct hdmi_video_para *video); -void hdmi_work(struct work_struct *work); -void hdmi_register_display_sysfs(struct hdmi *hdmi_drv, - struct device *parent); -void hdmi_unregister_display_sysfs(struct hdmi *hdmi_drv); - -int rk_hdmi_parse_dt(struct hdmi *hdmi_drv); -int rk_hdmi_pwr_enable(struct hdmi *dev_drv); -int rk_hdmi_pwr_disable(struct hdmi *dev_drv); - -#endif diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_edid.c b/drivers/video/rockchip/hdmi/rk_hdmi_edid.c deleted file mode 100755 index 7921c8f5e11a..000000000000 --- a/drivers/video/rockchip/hdmi/rk_hdmi_edid.c +++ /dev/null @@ -1,479 +0,0 @@ -#include "rk_hdmi.h" -#include "../../edid.h" - -#define hdmi_edid_error(fmt, ...) \ - printk(pr_fmt(fmt), ##__VA_ARGS__) - -#if 0 -#define hdmi_edid_debug(fmt, ...) \ - printk(pr_fmt(fmt), ##__VA_ARGS__) -#else -#define hdmi_edid_debug(fmt, ...) -#endif - -enum HDMI_EDID_ERRORCODE { - E_HDMI_EDID_SUCCESS = 0, - E_HDMI_EDID_PARAM, - E_HDMI_EDID_HEAD, - E_HDMI_EDID_CHECKSUM, - E_HDMI_EDID_VERSION, - E_HDMI_EDID_UNKOWNDATA, - E_HDMI_EDID_NOMEMORY -}; - -static const unsigned int double_aspect_vic[] = { - 3, 7, 9, 11, 13, 15, 18, 22, 24, 26, 28, 30, - 36, 38, 43, 45, 49, 51, 53, 55, 57, 59 -}; - -static int hdmi_edid_checksum(unsigned char *buf) -{ - int i; - int checksum = 0; - - for (i = 0; i < HDMI_EDID_BLOCK_SIZE; i++) - checksum += buf[i]; - - checksum &= 0xff; - - if (checksum == 0) - return E_HDMI_EDID_SUCCESS; - else - return E_HDMI_EDID_CHECKSUM; -} - -/* - * @Des Parse Detail Timing Descriptor. - * @Param buf : pointer to DTD data. - * @Param pvic: VIC of DTD descripted. - */ -static int hdmi_edid_parse_dtd(unsigned char *block, struct fb_videomode *mode) -{ - mode->xres = H_ACTIVE; - mode->yres = V_ACTIVE; - mode->pixclock = PIXEL_CLOCK; -/* - mode->pixclock /= 1000; - mode->pixclock = KHZ2PICOS(mode->pixclock); -*/ - mode->right_margin = H_SYNC_OFFSET; - mode->left_margin = (H_ACTIVE + H_BLANKING) - - (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); - mode->upper_margin = V_BLANKING - V_SYNC_OFFSET - - V_SYNC_WIDTH; - mode->lower_margin = V_SYNC_OFFSET; - mode->hsync_len = H_SYNC_WIDTH; - mode->vsync_len = V_SYNC_WIDTH; - if (HSYNC_POSITIVE) - mode->sync |= FB_SYNC_HOR_HIGH_ACT; - if (VSYNC_POSITIVE) - mode->sync |= FB_SYNC_VERT_HIGH_ACT; - mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) * - (V_ACTIVE + V_BLANKING)); - if (INTERLACED) { - mode->yres *= 2; - mode->upper_margin *= 2; - mode->lower_margin *= 2; - mode->vsync_len *= 2; - mode->vmode |= FB_VMODE_INTERLACED; - } - mode->flag = FB_MODE_IS_DETAILED; - - hdmi_edid_debug("<<<<<<<>>>>>>>>\n"); - hdmi_edid_debug("%d KHz Refresh %d Hz", PIXEL_CLOCK/1000, - mode->refresh); - hdmi_edid_debug("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET, - H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING); - hdmi_edid_debug("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET, - V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING); - hdmi_edid_debug("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-", - (VSYNC_POSITIVE) ? "+" : "-"); - return E_HDMI_EDID_SUCCESS; -} - -static int hdmi_edid_parse_base(unsigned char *buf, int *extend_num, - struct hdmi_edid *pedid) -{ - int rc; -#ifdef DEBUG - int i = 0; -#endif - - if (buf == NULL || extend_num == NULL) - return E_HDMI_EDID_PARAM; - -#ifdef DEBUG - for (i = 0; i < HDMI_EDID_BLOCK_SIZE; i++) { - hdmi_edid_debug("%02x ", buf[i]&0xff); - if ((i+1) % 16 == 0) - hdmi_edid_debug("\n"); - } -#endif - - /* Check first 8 byte to ensure it is an edid base block. */ - if (buf[0] != 0x00 || - buf[1] != 0xFF || - buf[2] != 0xFF || - buf[3] != 0xFF || - buf[4] != 0xFF || - buf[5] != 0xFF || - buf[6] != 0xFF || - buf[7] != 0x00) { - hdmi_edid_error("[EDID] check header error\n"); - return E_HDMI_EDID_HEAD; - } - - *extend_num = buf[0x7e]; -#ifdef DEBUG - hdmi_edid_debug("[EDID] extend block num is %d\n", buf[0x7e]); -#endif - - /* Checksum */ - rc = hdmi_edid_checksum(buf); - if (rc != E_HDMI_EDID_SUCCESS) { - hdmi_edid_error("[EDID] base block checksum error\n"); - return E_HDMI_EDID_CHECKSUM; - } - - pedid->specs = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); - if (pedid->specs == NULL) - return E_HDMI_EDID_NOMEMORY; - - fb_edid_to_monspecs(buf, pedid->specs); - - return E_HDMI_EDID_SUCCESS; -} - -/* Parse CEA Short Video Descriptor */ -static int hdmi_edid_get_cea_svd(unsigned char *buf, struct hdmi_edid *pedid) -{ - const struct fb_videomode *mode; - int count, i, j, vic; - - count = buf[0] & 0x1F; - for (i = 0; i < count; i++) { - hdmi_edid_debug("[EDID-CEA] %02x VID %d native %d\n", - buf[1 + i], - buf[1 + i] & 0x7f, - buf[1 + i] >> 7); - #ifndef HDMI_VERSION_2 - vic = buf[1 + i] & 0x7f; - #else - vic = buf[1 + i] & 0xff; - #endif - for (j = 0; j < ARRAY_SIZE(double_aspect_vic); j++) { - if (vic == double_aspect_vic[j]) { - vic--; - break; - } - } - if (vic) { - mode = hdmi_vic_to_videomode(vic); - if (mode) - hdmi_add_videomode(mode, &pedid->modelist); - } - } - return 0; -} - -/* Parse CEA Short Audio Descriptor */ -static int hdmi_edid_parse_cea_sad(unsigned char *buf, struct hdmi_edid *pedid) -{ - int i, count; - - count = buf[0] & 0x1F; - pedid->audio = kmalloc((count / 3) * sizeof(struct hdmi_audio), - GFP_KERNEL); - if (pedid->audio == NULL) - return E_HDMI_EDID_NOMEMORY; - - pedid->audio_num = count / 3; - for (i = 0; i < pedid->audio_num; i++) { - pedid->audio[i].type = (buf[1 + i * 3] >> 3) & 0x0F; - pedid->audio[i].channel = (buf[1 + i * 3] & 0x07) + 1; - pedid->audio[i].rate = buf[1 + i * 3 + 1]; - if (pedid->audio[i].type == HDMI_AUDIO_LPCM) /* LPCM */ - pedid->audio[i].word_length = buf[1 + i * 3 + 2]; -/* - printk("[EDID-CEA] type %d channel %d rate %d word length %d\n", - pedid->audio[i].type, pedid->audio[i].channel, - pedid->audio[i].rate, pedid->audio[i].word_length); -*/ - } - return E_HDMI_EDID_SUCCESS; -} - -/* Parse CEA Vendor Specific Data Block */ -static int hdmi_edid_parse_cea_sdb(unsigned char *buf, struct hdmi_edid *pedid) -{ - unsigned int count = 0, cur_offset = 0, i = 0; - unsigned int IEEEOUI = 0; - unsigned int supports_ai, dc_48bit, dc_36bit, dc_30bit, dc_y444; - unsigned int len_3d, len_4k; - unsigned char vic = 0; - const struct fb_videomode *mode; - - count = buf[0] & 0x1F; - IEEEOUI = buf[3]; - IEEEOUI <<= 8; - IEEEOUI += buf[2]; - IEEEOUI <<= 8; - IEEEOUI += buf[1]; - hdmi_edid_debug("[EDID-CEA] IEEEOUI is 0x%08x.\n", IEEEOUI); - if (IEEEOUI == 0x0c03) - pedid->sink_hdmi = 1; - - pedid->cecaddress = buf[cur_offset + 5]; - pedid->cecaddress |= buf[cur_offset + 4] << 8; - hdmi_edid_debug("[EDID-CEA] CEC Physical addres is 0x%08x.\n", pedid->cecaddress); - - if (count > 5) { - pedid->deepcolor = (buf[6] >> 3) & 0x0F; - supports_ai = buf[6] >> 7; - dc_48bit = (buf[6] >> 6) & 0x1; - dc_36bit = (buf[6] >> 5) & 0x1; - dc_30bit = (buf[6] >> 4) & 0x1; - dc_y444 = (buf[6] >> 3) & 0x1; - hdmi_edid_debug("[EDID-CEA] supports_ai %d\n" - "dc_48bit %d dc_36bit %d dc_30bit %d dc_y444 %d\n", - supports_ai, - dc_48bit, dc_36bit, dc_30bit, dc_y444); - } - if (count > 6) - pedid->maxtmdsclock = buf[7] * 5000000; - - if (count > 7) { - pedid->latency_fields_present = (buf[8] & 0x80) ? 1 : 0; - pedid->i_latency_fields_present = (buf[8] & 0x40) ? 1 : 0; - pedid->video_present = (buf[8] & 0x20) ? 1 : 0; - } - - cur_offset = 9; - if (count >= cur_offset) { - if (pedid->latency_fields_present == 1) { - pedid->video_latency = buf[cur_offset++]; - pedid->audio_latency = buf[cur_offset++]; - } - if (count >= cur_offset && pedid->i_latency_fields_present) { - pedid->interlaced_video_latency = buf[cur_offset++]; - pedid->interlaced_audio_latency = buf[cur_offset++]; - } - } - - if (pedid->video_present == 0) - return E_HDMI_EDID_SUCCESS; - - if (count >= cur_offset) { - pedid->support_3d = (buf[cur_offset++] & 0x80) ? 1 : 0; - - len_4k = (buf[cur_offset] >> 5) & 0x07; - len_3d = buf[cur_offset] & 0x1F; - cur_offset++; - } - if (count >= cur_offset && len_4k > 0) { - for (i = 0; i < len_4k; i++) { - #ifndef HDMI_VERSION_2 - vic = buf[cur_offset + i] & 0x7f; - if (vic > 0 && vic < 5) - vic = (vic == 4) ? 98 : (96 - vic); - hdmi_edid_debug("[EDID-CEA] %02x VID %d native %d\n", - buf[cur_offset + i], - vic, - buf[cur_offset + i] >> 7); - #else - vic = buf[cur_offset + i] & 0xff; - hdmi_edid_debug("[EDID-CEA] %02x VID %d native %d\n", - buf[cur_offset + i], vic); - #endif - if (vic) { - mode = hdmi_vic_to_videomode(vic); - if (mode) - hdmi_add_videomode(mode, - &pedid->modelist); - } - } - cur_offset += i; - } - -/* TODO Daisen wait to add - if (count >= cur_offset && pedid->support_3d && len_3d > 0) { - - } -*/ - return E_HDMI_EDID_SUCCESS; -} - -/* Parse CEA 861 Serial Extension. */ -static int hdmi_edid_parse_extensions_cea(unsigned char *buf, - struct hdmi_edid *pedid) -{ - unsigned int ddc_offset, native_dtd_num, cur_offset = 4; - unsigned int underscan_support, baseaudio_support; - unsigned int tag; - - if (buf == NULL) - return E_HDMI_EDID_PARAM; - - /* Check ces extension version */ - if (buf[1] != 3) { - hdmi_edid_error("[EDID-CEA] error version.\n"); - return E_HDMI_EDID_VERSION; - } - - ddc_offset = buf[2]; - underscan_support = (buf[3] >> 7) & 0x01; - baseaudio_support = (buf[3] >> 6) & 0x01; - pedid->ycbcr444 = (buf[3] >> 5) & 0x01; - pedid->ycbcr422 = (buf[3] >> 4) & 0x01; - native_dtd_num = buf[3] & 0x0F; - pedid->base_audio_support = baseaudio_support; - - /* Parse data block */ - while (cur_offset < ddc_offset) { - tag = buf[cur_offset] >> 5; - switch (tag) { - case 0x02: /* Video Data Block */ - hdmi_edid_debug("[EDID-CEA] It is a Video Data Block.\n"); - hdmi_edid_get_cea_svd(buf + cur_offset, pedid); - break; - case 0x01: /* Audio Data Block */ - hdmi_edid_debug("[EDID-CEA] It is a Audio Data Block.\n"); - hdmi_edid_parse_cea_sad(buf + cur_offset, pedid); - break; - case 0x04: /* Speaker Allocation Data Block */ - hdmi_edid_debug("[EDID-CEA] It is a Speaker Allocation Data Block.\n"); - break; - case 0x03: /* Vendor Specific Data Block */ - hdmi_edid_debug("[EDID-CEA] It is a Vendor Specific Data Block.\n"); - hdmi_edid_parse_cea_sdb(buf + cur_offset, pedid); - break; - case 0x05: /* VESA DTC Data Block */ - hdmi_edid_debug("[EDID-CEA] It is a VESA DTC Data Block.\n"); - break; - case 0x07: /* Use Extended Tag */ - hdmi_edid_debug("[EDID-CEA] It is a Use Extended Tag Data Block.\n"); - break; - default: - hdmi_edid_error("[EDID-CEA] unkowned data block tag.\n"); - break; - } - cur_offset += (buf[cur_offset] & 0x1F) + 1; - } -#if 1 -{ - /* Parse DTD */ - struct fb_videomode *vmode = kmalloc(sizeof(struct fb_videomode), - GFP_KERNEL); - if (vmode == NULL) - return E_HDMI_EDID_SUCCESS; - /* buf[126] = 0 and buf[127] = checksum */ - while (ddc_offset < HDMI_EDID_BLOCK_SIZE - 2) { - if (!buf[ddc_offset] && !buf[ddc_offset + 1]) - break; - memset(vmode, 0, sizeof(struct fb_videomode)); - hdmi_edid_parse_dtd(buf + ddc_offset, vmode); - hdmi_add_videomode(vmode, &pedid->modelist); - ddc_offset += 18; - } - kfree(vmode); -} -#endif - return E_HDMI_EDID_SUCCESS; -} - -static int hdmi_edid_parse_extensions(unsigned char *buf, - struct hdmi_edid *pedid) -{ - int rc; - - if (buf == NULL || pedid == NULL) - return E_HDMI_EDID_PARAM; - - /* Checksum */ - rc = hdmi_edid_checksum(buf); - if (rc != E_HDMI_EDID_SUCCESS) { - hdmi_edid_error("[EDID] extensions block checksum error\n"); - return E_HDMI_EDID_CHECKSUM; - } - - switch (buf[0]) { - case 0xF0: - hdmi_edid_debug("[EDID-EXTEND] It is a extensions block map.\n"); - break; - case 0x02: - hdmi_edid_debug("[EDID-EXTEND] It is a CEA 861 Series Extension.\n"); - hdmi_edid_parse_extensions_cea(buf, pedid); - break; - case 0x10: - hdmi_edid_debug("[EDID-EXTEND] It is a Video Timing Block Extension.\n"); - break; - case 0x40: - hdmi_edid_debug("[EDID-EXTEND] It is a Display Information Extension.\n"); - break; - case 0x50: - hdmi_edid_debug("[EDID-EXTEND] It is a Localized String Extension.\n"); - break; - case 0x60: - hdmi_edid_debug("[EDID-EXTEND] It is a Digital Packet Video Link Extension.\n"); - break; - default: - hdmi_edid_error("[EDID-EXTEND] Unkowned extension.\n"); - return E_HDMI_EDID_UNKOWNDATA; - } - - return E_HDMI_EDID_SUCCESS; -} - - -int hdmi_sys_parse_edid(struct hdmi *hdmi) -{ - struct hdmi_edid *pedid; - unsigned char *buff = NULL; - int rc = HDMI_ERROR_SUCESS, extendblock = 0, i; - - if (hdmi == NULL) - return HDMI_ERROR_FALSE; - - pedid = &(hdmi->edid); - memset(pedid, 0, sizeof(struct hdmi_edid)); - INIT_LIST_HEAD(&pedid->modelist); - - buff = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL); - if (buff == NULL) { - hdmi_dbg(hdmi->dev, - "[%s] can not allocate memory for edid buff.\n", - __func__); - return -1; - } - - /* Read base block edid. */ - memset(buff, 0 , HDMI_EDID_BLOCK_SIZE); - rc = hdmi->read_edid(hdmi, 0, buff); - if (rc) { - dev_err(hdmi->dev, "[HDMI] read edid base block error\n"); - goto out; - } - rc = hdmi_edid_parse_base(buff, &extendblock, pedid); - if (rc) { - dev_err(hdmi->dev, "[HDMI] parse edid base block error\n"); - goto out; - } - for (i = 1; i < extendblock + 1; i++) { - memset(buff, 0 , HDMI_EDID_BLOCK_SIZE); - rc = hdmi->read_edid(hdmi, i, buff); - if (rc) { - printk("[HDMI] read edid block %d error\n", i); - goto out; - } - rc = hdmi_edid_parse_extensions(buff, pedid); - if (rc) { - dev_err(hdmi->dev, "[HDMI] parse edid block %d error\n", - i); - continue; - } - } -out: - kfree(buff); - rc = hdmi_ouputmode_select(hdmi, rc); - return rc; -} diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c b/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c deleted file mode 100755 index 649a9909d7f0..000000000000 --- a/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c +++ /dev/null @@ -1,666 +0,0 @@ -#include -#include -#include "rk_hdmi.h" - -#define OUT_TYPE SCREEN_HDMI -#define OUT_FACE OUT_P888 -#define DCLK_POL 1 -#define SWAP_RB 0 -#define LCD_ACLK 800000000 - -struct hdmi *m_hdmi_drv; - -static const struct fb_videomode hdmi_mode[] = { - /* name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag(used for vic) */ -/* - {"640x480p@60Hz", 60, 640, 480, 25175000, 48, 16, 33, 10, 96, 2, 0, 0, 1 }, -*/ - {"720x480i@60Hz", 60, 720, 480, 27000000, 57, 19, 15, 4, 62, 3, 0, 1, 6 }, - {"720x576i@50Hz", 50, 720, 576, 27000000, 69, 12, 19, 2, 63, 3, 0, 1, 21}, - {"720x480p@60Hz", 60, 720, 480, 27000000, 60, 16, 30, 9, 62, 6, 0, 0, 2 }, - {"720x576p@50Hz", 50, 720, 576, 27000000, 68, 12, 39, 5, 64, 5, 0, 0, 17}, -/* - {"1280x720p@24Hz", 24, 1280, 720, 59400000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 60}, - {"1280x720p@25Hz", 25, 1280, 720, 74250000, 220, 2420, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 61}, - {"1280x720p@30Hz", 30, 1280, 720, 74250000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 62}, -*/ - {"1280x720p@50Hz", 50, 1280, 720, 74250000, 220, 440, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 19}, - {"1280x720p@60Hz", 60, 1280, 720, 74250000, 220, 110, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 4 }, -/* - {"1920x1080p@24Hz", 24, 1920, 1080, 74250000, 148, 638, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 32}, - {"1920x1080p@25Hz", 25, 1920, 1080, 74250000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 33}, - {"1920x1080p@30Hz", 30, 1920, 1080, 74250000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 34}, - {"1920x1080i@50Hz_2", 50, 1920, 1080, 72000000, 184, 32, 57, 23, 168, 5, FB_SYNC_HOR_HIGH_ACT, 1, 39}, -*/ - {"1920x1080i@50Hz", 50, 1920, 1080, 74250000, 148, 528, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 20}, - {"1920x1080i@60Hz", 60, 1920, 1080, 74250000, 148, 88, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 5 }, - {"1920x1080p@50Hz", 50, 1920, 1080, 148500000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 31}, - {"1920x1080p@60Hz", 60, 1920, 1080, 148500000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 16}, -/* - {"1440x288p@50Hz", 50, 720, 480, 27000000, 138, 24, 19, 2, 126, 3, 0, 0, 23}, - {"2880x576i@50Hz", 50, 1440, 240, 54000000, 276, 48, 19, 2, 252, 3, 0, 1, 25}, - {"2880x288p@50Hz", 50, 2880, 480, 54000000, 276, 48, 19, 3, 252, 3, 0, 0, 27}, - {"1440x576p@50Hz", 50, 2880, 480, 54000000, 136, 24, 39, 5, 128, 5, 0, 0, 29}, - {"2880x576p@50Hz", 50, 1920, 1080, 108000000, 272, 48, 39, 5, 256, 5, 0, 0, 37}, - {"1440x240p@60Hz", 60, 1440, 240, 27000000, 114, 38, 15, 4, 124, 3, 0, 0, 8 }, - {"2880x480i@60Hz", 60, 2880, 480, 54000000, 228, 76, 15, 4, 248, 3, 0, 1, 10}, - {"2880x480p@60Hz", 60, 2880, 480, 54000000, 228, 76, 15, 4, 248, 3, 0, 0, 12}, - {"1440x480p@60Hz", 60, 1440, 480, 54000000, 120, 32, 30, 9, 124, 6, 0, 0, 14}, - {"2880x480p@60Hz", 60, 2880, 480, 54000000, 240, 64, 30, 9, 248, 6, 0, 0, 35}, - - {"1920x1080i@100Hz", 100, 1920, 1080, 148500000, 148, 528, 15, 2, 44, 5, 1, 1, 40}, - {"1280x720p@100Hz", 100, 1280, 720, 148500000, 220, 440, 20, 5, 40, 5, 1, 0, 41}, - {"720x576p@100Hz", 100, 720, 576, 54000000, 68, 12, 39, 5, 64, 5, 0, 0, 42}, - {"1440x576i@100Hz", 100, 1440, 576, 54000000, 138, 24, 19, 2, 12, 3, 0, 1, 44}, - {"1920x1080p@100Hz", 100, 1920, 1080, 297000000, 148, 528, 36, 4, 44, 5, 1, 0, 64}, - - {"1920x1080i@120Hz", 120, 1920, 1080, 148500000, 148, 88, 15, 2, 44, 5, 1, 1, 46}, - {"1280x720p@120Hz", 120, 1280, 720, 148500000, 220, 110, 20, 5, 40, 5, 1, 0, 47}, - {"720x480p@120Hz", 120, 720, 480, 54000000, 60, 16, 30, 9, 62, 6, 0, 0, 48}, - {"1440x480i@120Hz", 120, 1440, 480, 54000000, 114, 38, 15, 4, 12, 3, 0, 1, 50}, - {"1920x1080p@120Hz", 120, 1920, 1080, 297000000, 148, 88, 36, 4, 44, 5, 1, 0, 63}, - - {"720x576p@200Hz", 200, 720, 576, 108000000, 68, 12, 39, 5, 64, 5, 0, 0, 52}, - {"1440x576i@200Hz", 200, 1920, 1080, 108000000, 138, 24, 19, 2, 12, 3, 0, 1, 54}, - - {"720x480p@240Hz", 240, 720, 480, 108000000, 60, 16, 30, 9, 62, 6, 0, 0, 56}, - {"1440x480i@240Hz", 240, 1440, 480, 108000000, 114, 38, 15, 4, 12, 3, 0, 1, 58}, -*/ - {"3840x2160p@24Hz", 24, 3840, 2160, 297000000, 296, 1276, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 93}, - {"3840x2160p@25Hz", 25, 3840, 2160, 297000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 94}, - {"3840x2160p@30Hz", 30, 3840, 2160, 297000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 95}, - {"3840x2160p@50Hz", 50, 3840, 2160, 594000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 96}, - {"3840x2160p@60Hz", 60, 3840, 2160, 594000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 97}, - {"4096x2160p@24Hz", 24, 4096, 2160, 297000000, 296, 1020, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 98}, - {"4096x2160p@25Hz", 25, 4096, 2160, 297000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 99}, - {"4096x2160p@30Hz", 30, 4096, 2160, 297000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 100}, - {"4096x2160p@50Hz", 50, 4096, 2160, 594000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 101}, - {"4096x2160p@60Hz", 60, 4096, 2160, 594000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 102}, - -}; - -void hdmi_init_lcdc(struct rk_screen *screen, struct rk29lcd_info *lcd_info) -{ - hdmi_set_info(screen, HDMI_VIDEO_DEFAULT_MODE); -} - -int hdmi_set_info(struct rk_screen *screen, unsigned int vic) -{ - int i; - - if (screen == NULL) - return -1; - - if (vic == 0) - vic = HDMI_VIDEO_DEFAULT_MODE; - - for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { - if (hdmi_mode[i].flag == vic) - break; - } - if (i == ARRAY_SIZE(hdmi_mode)) - return -1; - - memset(screen, 0, sizeof(struct rk_screen)); - - /* screen type & face */ - screen->type = OUT_TYPE; - screen->face = OUT_FACE; - screen->color_mode = COLOR_YCBCR; - - /* Screen size */ - screen->mode.xres = hdmi_mode[i].xres; - screen->mode.yres = hdmi_mode[i].yres; - - /* Timing */ - screen->mode.pixclock = hdmi_mode[i].pixclock; - screen->mode.refresh = hdmi_mode[i].refresh; - /* screen->lcdc_aclk = LCD_ACLK; */ - screen->mode.left_margin = hdmi_mode[i].left_margin; - screen->mode.right_margin = hdmi_mode[i].right_margin; - screen->mode.hsync_len = hdmi_mode[i].hsync_len; - screen->mode.upper_margin = hdmi_mode[i].upper_margin; - screen->mode.lower_margin = hdmi_mode[i].lower_margin; - screen->mode.vsync_len = hdmi_mode[i].vsync_len; - screen->mode.vmode = hdmi_mode[i].vmode; - screen->hdmi_resolution = hdmi_mode[i].flag; - if ((screen->hdmi_resolution == HDMI_720X480I_60HZ_VIC) || - (screen->hdmi_resolution == HDMI_720X576I_50HZ_VIC)) - screen->pixelrepeat = 1; - - /* Pin polarity */ -#if defined(CONFIG_HDMI_RK616) && !defined(CONFIG_ARCH_RK3026) - screen->pin_hsync = 0; - screen->pin_vsync = 0; -#else - screen->pin_hsync = 0; - if (FB_SYNC_HOR_HIGH_ACT & hdmi_mode[i].sync) - screen->pin_hsync = 1; - else - screen->pin_hsync = 0; - if (FB_SYNC_VERT_HIGH_ACT & hdmi_mode[i].sync) - screen->pin_vsync = 1; - else - screen->pin_vsync = 0; -#endif - screen->pin_den = 0; - screen->pin_dclk = DCLK_POL; - - /* Swap rule */ - screen->swap_rb = SWAP_RB; - screen->swap_rg = 0; - screen->swap_gb = 0; - screen->swap_delta = 0; - screen->swap_dumy = 0; - - /* Operation function */ - screen->init = NULL; - screen->standby = NULL; - - /* Init Default Overscan Value: - * TODO modify the value according to your need adjust value - */ - switch (vic) { - case 16: /* 1080p-60Hz */ - screen->overscan.left = 97; - screen->overscan.top = 97; - screen->overscan.right = 97; - screen->overscan.bottom = 97; - break; - default: - screen->overscan.left = 96; - screen->overscan.top = 96; - screen->overscan.right = 96; - screen->overscan.bottom = 96; - break; - } - - return 0; -} - -#ifdef HDMI_DEBUG -static void hdmi_show_sink_info(struct hdmi *hdmi) -{ - struct list_head *pos, *head = &hdmi->edid.modelist; - struct fb_modelist *modelist; - struct fb_videomode *m; - int i; - struct hdmi_audio *audio; - - hdmi_dbg(hdmi->dev, "******** Show Sink Info ********\n"); - hdmi_dbg(hdmi->dev, "Support video mode:\n"); - list_for_each(pos, head) { - modelist = list_entry(pos, struct fb_modelist, list); - m = &modelist->mode; - hdmi_dbg(hdmi->dev, " %s.\n", m->name); - } - - for (i = 0; i < hdmi->edid.audio_num; i++) { - audio = &(hdmi->edid.audio[i]); - switch (audio->type) { - case HDMI_AUDIO_LPCM: - hdmi_dbg(hdmi->dev, "Support audio type: LPCM\n"); - break; - case HDMI_AUDIO_AC3: - hdmi_dbg(hdmi->dev, "Support audio type: AC3\n"); - break; - case HDMI_AUDIO_MPEG1: - hdmi_dbg(hdmi->dev, "Support audio type: MPEG1\n"); - break; - case HDMI_AUDIO_MP3: - hdmi_dbg(hdmi->dev, "Support audio type: MP3\n"); - break; - case HDMI_AUDIO_MPEG2: - hdmi_dbg(hdmi->dev, "Support audio type: MPEG2\n"); - break; - case HDMI_AUDIO_AAC_LC: - hdmi_dbg(hdmi->dev, "Support audio type: AAC\n"); - break; - case HDMI_AUDIO_DTS: - hdmi_dbg(hdmi->dev, "Support audio type: DTS\n"); - break; - case HDMI_AUDIO_ATARC: - hdmi_dbg(hdmi->dev, "Support audio type: ATARC\n"); - break; - case HDMI_AUDIO_DSD: - hdmi_dbg(hdmi->dev, "Support audio type: DSD\n"); - break; - case HDMI_AUDIO_E_AC3: - hdmi_dbg(hdmi->dev, "Support audio type: E-AC3\n"); - break; - case HDMI_AUDIO_DTS_HD: - hdmi_dbg(hdmi->dev, "Support audio type: DTS-HD\n"); - break; - case HDMI_AUDIO_MLP: - hdmi_dbg(hdmi->dev, "Support audio type: MLP\n"); - break; - case HDMI_AUDIO_DST: - hdmi_dbg(hdmi->dev, "Support audio type: DST\n"); - break; - case HDMI_AUDIO_WMA_PRO: - hdmi_dbg(hdmi->dev, "Support audio type: WMP-PRO\n"); - break; - default: - hdmi_dbg(hdmi->dev, "Support audio type: Unkown\n"); - break; - } - - hdmi_dbg(hdmi->dev, "Support audio sample rate:\n"); - if (audio->rate & HDMI_AUDIO_FS_32000) - hdmi_dbg(hdmi->dev, " 32000\n"); - if (audio->rate & HDMI_AUDIO_FS_44100) - hdmi_dbg(hdmi->dev, " 44100\n"); - if (audio->rate & HDMI_AUDIO_FS_48000) - hdmi_dbg(hdmi->dev, " 48000\n"); - if (audio->rate & HDMI_AUDIO_FS_88200) - hdmi_dbg(hdmi->dev, " 88200\n"); - if (audio->rate & HDMI_AUDIO_FS_96000) - hdmi_dbg(hdmi->dev, " 96000\n"); - if (audio->rate & HDMI_AUDIO_FS_176400) - hdmi_dbg(hdmi->dev, " 176400\n"); - if (audio->rate & HDMI_AUDIO_FS_192000) - hdmi_dbg(hdmi->dev, " 192000\n"); - - hdmi_dbg(hdmi->dev, "Support audio word lenght:\n"); - if (audio->rate & HDMI_AUDIO_WORD_LENGTH_16bit) - hdmi_dbg(hdmi->dev, " 16bit\n"); - if (audio->rate & HDMI_AUDIO_WORD_LENGTH_20bit) - hdmi_dbg(hdmi->dev, " 20bit\n"); - if (audio->rate & HDMI_AUDIO_WORD_LENGTH_24bit) - hdmi_dbg(hdmi->dev, " 24bit\n"); - } - hdmi_dbg(hdmi->dev, "******** Show Sink Info ********\n"); -} -#endif - -/** - * hdmi_ouputmode_select - select hdmi transmitter output mode: hdmi or dvi? - * @hdmi: handle of hdmi - * @edid_ok: get EDID data success or not, HDMI_ERROR_SUCESS means success. - */ -int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok) -{ - struct list_head *head = &hdmi->edid.modelist; - struct fb_monspecs *specs = hdmi->edid.specs; - struct fb_videomode *modedb = NULL; - int i, pixclock; - - if (edid_ok != HDMI_ERROR_SUCESS) { - dev_err(hdmi->dev, - "warning: EDID error, assume sink as HDMI and asume minitor support audio output!!!!"); - hdmi->edid.sink_hdmi = 1; - /* if edid error,asume monitor support audio output */ - hdmi->edid.base_audio_support = 1; - } - - if (edid_ok != HDMI_ERROR_SUCESS) { - hdmi->edid.ycbcr444 = 0; - hdmi->edid.ycbcr422 = 0; - hdmi->autoconfig = HDMI_DISABLE; - } - if (head->next == head) { - dev_info(hdmi->dev, - "warning: no CEA video mode parsed from EDID !!!!"); - /* If EDID get error, list all system supported mode. - * If output mode is set to DVI and EDID is ok, check - * the output timing. - */ - - if (hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) { - /* Get max resolution timing */ - modedb = &specs->modedb[0]; - for (i = 0; i < specs->modedb_len; i++) { - if (specs->modedb[i].xres > modedb->xres) - modedb = &specs->modedb[i]; - else if (specs->modedb[i].yres > modedb->yres) - modedb = &specs->modedb[i]; - } - /* For some monitor, the max pixclock read from EDID - * is smaller than the clock of - * max resolution mode supported. - */ - pixclock = PICOS2KHZ(modedb->pixclock); - pixclock /= 250; - pixclock *= 250; - pixclock *= 1000; - if (pixclock == 148250000) - pixclock = 148500000; - if (pixclock > specs->dclkmax) - specs->dclkmax = pixclock; - } - - for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { - if (modedb) { - if ((hdmi_mode[i].pixclock < specs->dclkmin) || - (hdmi_mode[i].pixclock > specs->dclkmax) || - (hdmi_mode[i].refresh < specs->vfmin) || - (hdmi_mode[i].refresh > specs->vfmax) || - (hdmi_mode[i].xres > modedb->xres) || - (hdmi_mode[i].yres > modedb->yres)) - continue; - } - hdmi_add_videomode(&hdmi_mode[i], head); - } - } -#ifdef HDMI_DEBUG - hdmi_show_sink_info(hdmi); -#endif - return HDMI_ERROR_SUCESS; -} - -/** - * hdmi_videomode_compare - compare 2 videomodes - * @mode1: first videomode - * @mode2: second videomode - * - * RETURNS: - * 1 if mode1 > mode2, 0 if mode1 = mode2, -1 mode1 < mode2 - */ -static int hdmi_videomode_compare(const struct fb_videomode *mode1, - const struct fb_videomode *mode2) -{ - if (mode1->xres > mode2->xres) - return 1; - else if (mode1->xres == mode2->xres) { - if (mode1->yres > mode2->yres) - return 1; - else if (mode1->yres == mode2->yres) { - if (mode1->pixclock > mode2->pixclock) - return 1; - else if (mode1->pixclock == mode2->pixclock) { - if (mode1->refresh > mode2->refresh) - return 1; - else if (mode1->refresh == mode2->refresh) - return 0; - } - } - } - return -1; -} -int hdmi_check_support_videomode(int vic) -{ - int i, support = 0; - if (m_hdmi_drv->support_vic_num == 0) - return 1; - - for (i=0; isupport_vic_num; i++) { - if (m_hdmi_drv->support_vic[i] == vic) { - support = 1; - break; - } - } - if(i >= m_hdmi_drv->support_vic_num) - support = 0; - return support; -} - -/** - * hdmi_add_videomode: adds videomode entry to modelist - * @mode: videomode to add - * @head: struct list_head of modelist - * - * NOTES: - * Will only add unmatched mode entries - */ -int hdmi_add_videomode(const struct fb_videomode *mode, struct list_head *head) -{ - struct list_head *pos; - struct fb_modelist *modelist, *modelist_new; - struct fb_videomode *m; - int i, found = 0; - - for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { - m = (struct fb_videomode *)&hdmi_mode[i]; - if (fb_mode_is_equal(m, mode)) { - if(hdmi_check_support_videomode(m->flag)) - found = 1; - break; - } - } - - if (found) { - list_for_each(pos, head) { - modelist = list_entry(pos, struct fb_modelist, list); - m = &modelist->mode; - if (fb_mode_is_equal(m, mode)) { - /* m == mode */ - return 0; - } else { - if (hdmi_videomode_compare(m, mode) == -1) - break; - } - } - - modelist_new = kmalloc(sizeof(struct fb_modelist), GFP_KERNEL); - if (!modelist_new) - return -ENOMEM; - modelist_new->mode = hdmi_mode[i]; - list_add_tail(&modelist_new->list, pos); - } - - return 0; -} - -/** - * hdmi_videomode_to_vic: transverse video mode to vic - * @vmode: videomode to transverse - * - */ -int hdmi_videomode_to_vic(struct fb_videomode *vmode) -{ - unsigned char vic = 0; - int i = 0; - - for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { - if (vmode->vmode == hdmi_mode[i].vmode && - vmode->refresh == hdmi_mode[i].refresh && - vmode->xres == hdmi_mode[i].xres && - vmode->left_margin == hdmi_mode[i].left_margin && - vmode->right_margin == hdmi_mode[i].right_margin && - vmode->upper_margin == hdmi_mode[i].upper_margin && - vmode->lower_margin == hdmi_mode[i].lower_margin && - vmode->hsync_len == hdmi_mode[i].hsync_len && - vmode->vsync_len == hdmi_mode[i].vsync_len) { - /*if ((vmode->vmode == FB_VMODE_NONINTERLACED - && vmode->yres == hdmi_mode[i].yres) - || (vmode->vmode == FB_VMODE_INTERLACED - && vmode->yres == hdmi_mode[i].yres / 2))*/ - { - vic = hdmi_mode[i].flag; - break; - } - } - } - return vic; -} - -/** - * hdmi_vic_to_videomode: transverse vic mode to video mode - * @vmode: vic to transverse - * - */ -const struct fb_videomode *hdmi_vic_to_videomode(int vic) -{ - int i; - - if (vic == 0) - return NULL; - - for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { - if (hdmi_mode[i].flag == vic) - return &hdmi_mode[i]; - } - return NULL; -} - -/** - * hdmi_find_best_mode: find the video mode nearest to input vic - * @hdmi: - * @vic: input vic - * - * NOTES: - * If vic is zero, return the high resolution video mode vic. - */ -int hdmi_find_best_mode(struct hdmi *hdmi, int vic) -{ - struct list_head *pos, *head = &hdmi->edid.modelist; - struct fb_modelist *modelist; - struct fb_videomode *m = NULL; - int found = 0; - - if (vic) { - list_for_each(pos, head) { - modelist = list_entry(pos, struct fb_modelist, list); - m = &modelist->mode; - if (m->flag == vic) { - found = 1; - break; - } - } - } - if ((vic == 0 || found == 0) && head->next != head) { - modelist = list_entry(head->next, struct fb_modelist, list); - m = &modelist->mode; - } - if (m != NULL) - return m->flag; - else - return 0; -} - -const char *hdmi_get_video_mode_name(unsigned char vic) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { - if (vic == hdmi_mode[i].flag) - break; - } - if (i == ARRAY_SIZE(hdmi_mode)) - return NULL; - else - return hdmi_mode[i].name; -} - -/** - * hdmi_switch_fb: switch lcdc mode to required video mode - * @hdmi: - * @type: - * - * NOTES: - * - */ -int hdmi_switch_fb(struct hdmi *hdmi, int vic) -{ - int rc = 0; - struct rk_screen *screen; - - screen = kzalloc(sizeof(struct rk_screen), GFP_KERNEL); - if (screen == NULL) - return -1; - - if (hdmi->vic == 0) - hdmi->vic = HDMI_VIDEO_DEFAULT_MODE; - - rc = hdmi_set_info(screen, hdmi->vic); - - if (rc == 0) { - if (hdmi->set_vif) /* turn off vif for jettab */ - hdmi->set_vif(hdmi, screen, 0); - rk_fb_switch_screen(screen, 1, hdmi->lcdc->id); - rk_fb_disp_scale(hdmi->xscale, hdmi->yscale, hdmi->lcdc->id); - if (hdmi->set_vif) - hdmi->set_vif(hdmi, screen, 1); - - } - - kfree(screen); - - return rc; -} - -/** - * hdmi_init_video_para: init video_para variable - * - * NOTES: - *This parameters should be modified according to need by user - */ -int hdmi_init_video_para(struct hdmi *hdmi_drv, struct hdmi_video_para *video) -{ - struct rk_lcdc_driver *lcdc_drv = NULL; - - if (unlikely(hdmi_drv == NULL)) - return -1; - - lcdc_drv = hdmi_drv->lcdc; - if (unlikely(lcdc_drv == NULL)) - return -1; - - memset(video, 0, sizeof(struct hdmi_video_para)); - - video->vic = hdmi_drv->vic; - video->input_mode = VIDEO_INPUT_RGB_YCBCR_444; - if (lcdc_drv->output_color == COLOR_RGB) - video->input_color = VIDEO_INPUT_COLOR_RGB; - else - video->input_color = VIDEO_INPUT_COLOR_YCBCR444; - - video->output_mode = hdmi_drv->edid.sink_hdmi; - video->format_3d = 0; /* TODO modify according to EDID if need */ - video->pixel_repet = 0; - /* 0:IT Video Format 1:CE Video Format - * TODO modify according to EDID - */ - video->color_limit_range = 1; - -#ifdef SOURCE_ABOVE_10BIT - if (hdmi_drv->edid.deepcolor & HDMI_COLOR_DEPTH_16BIT) - video->color_depth = HDMI_COLOR_DEPTH_16BIT; - else if (hdmi_drv->edid.deepcolor & HDMI_COLOR_DEPTH_12BIT) - video->color_depth = HDMI_COLOR_DEPTH_12BIT; - else -#endif - if (hdmi_drv->edid.deepcolor & HDMI_COLOR_DEPTH_10BIT) - video->color_depth = HDMI_COLOR_DEPTH_10BIT; - else - video->color_depth = HDMI_COLOR_DEPTH_8BIT; -/* - if (hdmi_drv->edid.ycbcr444) - video->output_color = VIDEO_OUTPUT_YCBCR444; - else if (hdmi_drv->edid.ycbcr422) - video->output_color = VIDEO_OUTPUT_YCBCR422; - else -*/ video->output_color = VIDEO_OUTPUT_RGB444; - - /*For DVI, output RGB */ - if (hdmi_drv->edid.sink_hdmi == 0) - video->output_color = VIDEO_OUTPUT_RGB444; - - return 0; -} - -/** - * hdmi_drv_register: init hdmi_drv variable - * - * NOTES: - * - */ -int hdmi_drv_register(struct hdmi *hdmi_drv) -{ - m_hdmi_drv = hdmi_drv; - return 0; -} - -/** - * hdmi_get_status: get hdmi hotplug status - * - * NOTES: - * - */ -int hdmi_get_hotplug(void) -{ - if (m_hdmi_drv) - return m_hdmi_drv->hotplug; - else - return HDMI_HPD_REMOVED; -} diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_parse_dt.c b/drivers/video/rockchip/hdmi/rk_hdmi_parse_dt.c deleted file mode 100644 index 48e52ac603d1..000000000000 --- a/drivers/video/rockchip/hdmi/rk_hdmi_parse_dt.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "rk_hdmi.h" -#ifdef CONFIG_OF -#include -#include -#include - -/* rk hdmi power control parse from dts - * -*/ -int rk_hdmi_pwr_ctr_parse_dt(struct hdmi *dev_drv) -{ - struct device_node *root = of_find_node_by_name(dev_drv->dev->of_node, - "power_ctr_hdmi"); - struct device_node *child; - struct rk_disp_pwr_ctr_list *pwr_ctr; - struct list_head *pos; - enum of_gpio_flags flags; - u32 val = 0; - u32 debug = 0; - int ret; - - INIT_LIST_HEAD(&dev_drv->pwrlist_head); - if (!root) { - dev_err(dev_drv->dev, "can't find power_ctr node %d\n", - dev_drv->id); - return -ENODEV; - } - - for_each_child_of_node(root, child) { - pwr_ctr = kmalloc(sizeof(struct rk_disp_pwr_ctr_list), - GFP_KERNEL); - strcpy(pwr_ctr->pwr_ctr.name, child->name); - if (!of_property_read_u32(child, "rockchip,power_type", &val)) { - if (val == GPIO) { - pwr_ctr->pwr_ctr.type = GPIO; - pwr_ctr->pwr_ctr.gpio = - of_get_gpio_flags(child, 0, &flags); - if (!gpio_is_valid(pwr_ctr->pwr_ctr.gpio)) { - dev_err(dev_drv->dev, - "%s ivalid gpio\n", - child->name); - return -EINVAL; - } - pwr_ctr->pwr_ctr.atv_val = - flags & OF_GPIO_ACTIVE_LOW; - ret = gpio_request(pwr_ctr->pwr_ctr.gpio, - child->name); - if (ret) { - dev_err(dev_drv->dev, - "request %s gpio fail:%d\n", - child->name, ret); - return -1; - } - - } else { - pwr_ctr->pwr_ctr.type = REGULATOR; - - } - }; - of_property_read_u32(child, "rockchip,delay", &val); - pwr_ctr->pwr_ctr.delay = val; - of_property_read_u32(child, "rockchip,is_rst", &val); - pwr_ctr->pwr_ctr.is_rst = val; - list_add_tail(&pwr_ctr->list, &dev_drv->pwrlist_head); - } - - of_property_read_u32(root, "rockchip,debug", &debug); - - if (debug) { - list_for_each(pos, &dev_drv->pwrlist_head) { - pwr_ctr = list_entry(pos, struct rk_disp_pwr_ctr_list, - list); - dev_info(dev_drv->dev, "pwr_ctr_name:%s\n" - "pwr_type:%s\n" "gpio:%d\n" - "atv_val:%d\n" "delay:%d\n\n", - pwr_ctr->pwr_ctr.name, - (pwr_ctr->pwr_ctr.type == GPIO) ? - "gpio" : "regulator", - pwr_ctr->pwr_ctr.gpio, - pwr_ctr->pwr_ctr.atv_val, - pwr_ctr->pwr_ctr.delay); - } - } - - return 0; - -} - -int rk_hdmi_pwr_enable(struct hdmi *dev_drv) -{ - struct list_head *pos; - struct rk_disp_pwr_ctr_list *pwr_ctr_list; - struct pwr_ctr *pwr_ctr; - - if (list_empty(&dev_drv->pwrlist_head)) - return 0; - - list_for_each(pos, &dev_drv->pwrlist_head) { - pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, - list); - pwr_ctr = &pwr_ctr_list->pwr_ctr; - if (pwr_ctr->type == GPIO) { - gpio_direction_output(pwr_ctr->gpio, pwr_ctr->atv_val); - mdelay(pwr_ctr->delay); - if (pwr_ctr->is_rst == 1) { - if (pwr_ctr->atv_val == 1) - gpio_set_value(pwr_ctr->gpio, 0); - else - gpio_set_value(pwr_ctr->gpio, 1); - - mdelay(pwr_ctr->delay); - } - } - } - - return 0; -} - -int rk_hdmi_pwr_disable(struct hdmi *dev_drv) -{ - struct list_head *pos; - struct rk_disp_pwr_ctr_list *pwr_ctr_list; - struct pwr_ctr *pwr_ctr; - - if (list_empty(&dev_drv->pwrlist_head)) - return 0; - - list_for_each(pos, &dev_drv->pwrlist_head) { - pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, - list); - pwr_ctr = &pwr_ctr_list->pwr_ctr; - if (pwr_ctr->type == GPIO) { - gpio_set_value(pwr_ctr->gpio, pwr_ctr->atv_val); - if (pwr_ctr->is_rst == 1) { - if (pwr_ctr->atv_val == 1) - gpio_set_value(pwr_ctr->gpio, 0); - else - gpio_set_value(pwr_ctr->gpio, 1); - } - } - } - - return 0; -} - -int rk_hdmi_parse_dt(struct hdmi *hdmi_drv) -{ - struct device_node *np = hdmi_drv->dev->of_node; - int ret = 0, gpio = 0; - - if (!np) { - dev_err(hdmi_drv->dev, "could not find hdmi node\n"); - return -1; - } - - gpio = of_get_named_gpio(np, "rockchips,hdmi_irq_gpio", 0); - if (!gpio_is_valid(gpio)) - dev_info(hdmi_drv->dev, "invalid hdmi_irq_gpio: %d\n", gpio); - hdmi_drv->irq = gpio; - - ret = rk_hdmi_pwr_ctr_parse_dt(hdmi_drv); - - return ret; -} - -#else -int rk_hdmi_pwr_enable(struct hdmi *dev_drv) -{ - return 0; -} - -int rk_hdmi_pwr_disable(struct hdmi *dev_drv) -{ - return 0; -} - -int rk_hdmi_parse_dt(struct hdmi *hdmi_drv) -{ - return 0; -} -#endif diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_sysfs.c b/drivers/video/rockchip/hdmi/rk_hdmi_sysfs.c deleted file mode 100755 index 9ab7a1a96437..000000000000 --- a/drivers/video/rockchip/hdmi/rk_hdmi_sysfs.c +++ /dev/null @@ -1,272 +0,0 @@ -#include -#include -#include -#include -#include "rk_hdmi.h" - -static int hdmi_get_enable(struct rk_display_device *device) -{ - struct hdmi *hdmi = device->priv_data; - int enable; - - mutex_lock(&hdmi->enable_mutex); - enable = hdmi->enable; - mutex_unlock(&hdmi->enable_mutex); - - return enable; -} - -static int hdmi_set_enable(struct rk_display_device *device, int enable) -{ - struct hdmi *hdmi = device->priv_data; - - mutex_lock(&hdmi->enable_mutex); - if (hdmi->enable == enable) { - mutex_unlock(&hdmi->enable_mutex); - return 0; - } - hdmi->enable = enable; - - if (hdmi->suspend) { - mutex_unlock(&hdmi->enable_mutex); - return 0; - } - - if (enable == 0) { - if (hdmi->irq) - disable_irq(hdmi->irq); - mutex_unlock(&hdmi->enable_mutex); - hdmi->command = HDMI_CONFIG_ENABLE; - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0); - } else { - if (hdmi->irq) - enable_irq(hdmi->irq); - queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0); - mutex_unlock(&hdmi->enable_mutex); - } - return 0; -} - -static int hdmi_get_status(struct rk_display_device *device) -{ - struct hdmi *hdmi = device->priv_data; - - if (hdmi->hotplug == HDMI_HPD_ACTIVED) - return 1; - else - return 0; -} - -static int hdmi_get_modelist(struct rk_display_device *device, - struct list_head **modelist) -{ - struct hdmi *hdmi = device->priv_data; - - if (!hdmi->hotplug) - return -1; - *modelist = &hdmi->edid.modelist; - return 0; -} - -static int hdmi_set_mode(struct rk_display_device *device, - struct fb_videomode *mode) -{ - struct hdmi *hdmi = device->priv_data; - int vic = hdmi_videomode_to_vic(mode); - - hdmi->autoconfig = HDMI_DISABLE; - if (vic && hdmi->vic != vic) { - hdmi->vic = vic; - if (!hdmi->hotplug) - return 0; - hdmi->command = HDMI_CONFIG_VIDEO; - 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 - (10000)); - } - return 0; -} - -static int hdmi_get_mode(struct rk_display_device *device, - struct fb_videomode *mode) -{ - struct hdmi *hdmi = device->priv_data; - struct fb_videomode *vmode; - - if (!hdmi->hotplug) - return -1; - - vmode = (struct fb_videomode *)hdmi_vic_to_videomode(hdmi->vic); - if (unlikely(vmode == NULL)) - return -1; - *mode = *vmode; - return 0; -} - -static int hdmi_set_scale(struct rk_display_device *device, int direction, - int value) -{ - struct hdmi *hdmi = device->priv_data; - - if (!hdmi || value < 0 || value > 100) - return -1; - - if (!hdmi->hotplug) - return 0; - - if (direction == DISPLAY_SCALE_X) - hdmi->xscale = value; - else if (direction == DISPLAY_SCALE_Y) - hdmi->yscale = value; - else - return -1; - rk_fb_disp_scale(hdmi->xscale, hdmi->yscale, hdmi->lcdc->id); - return 0; -} - -static int hdmi_get_scale(struct rk_display_device *device, int direction) -{ - struct hdmi *hdmi = device->priv_data; - - if (!hdmi) - return -1; - - if (direction == DISPLAY_SCALE_X) - return hdmi->xscale; - else if (direction == DISPLAY_SCALE_Y) - return hdmi->yscale; - else - return -1; -} -static int hdmi_set_debug(struct rk_display_device *device, int cmd) -{ - struct hdmi *hdmi = device->priv_data; - - if (!hdmi) - return -1; - if (hdmi->ops && hdmi->ops->hdmi_debug) - hdmi->ops->hdmi_debug(hdmi,cmd); - - return 0; -} -//CEA 861-E: Audio Coding Type -//sync width enum hdmi_audio_type -static const char* const sAudioFormatStr[] = { - "", - "LPCM", //HDMI_AUDIO_LPCM = 1, - "AC3", //HDMI_AUDIO_AC3, - "MPEG1", //HDMI_AUDIO_MPEG1, - "MP3", //HDMI_AUDIO_MP3, - "MPEG2", //HDMI_AUDIO_MPEG2, - "AAC-LC", //HDMI_AUDIO_AAC_LC, //AAC - "DTS", //HDMI_AUDIO_DTS, - "ATARC", //HDMI_AUDIO_ATARC, - "DSD", //HDMI_AUDIO_DSD, //One bit Audio - "E-AC3", //HDMI_AUDIO_E_AC3, - "DTS-HD", //HDMI_AUDIO_DTS_HD, - "MLP", //HDMI_AUDIO_MLP, - "DST", //HDMI_AUDIO_DST, - "WMA-PRO", //HDMI_AUDIO_WMA_PRO -}; - -static int hdmi_get_edidaudioinfo(struct rk_display_device *device, char *audioinfo, int len) -{ - struct hdmi *hdmi = device->priv_data; - int i=0; - int size=0; - struct hdmi_audio *audio; - if(!hdmi) - return -1; - - memset(audioinfo, 0x00, len); - mutex_lock(&hdmi->lock); - //printk("hdmi:edid: audio_num: %d\n", hdmi->edid.audio_num); - for(i = 0; i < hdmi->edid.audio_num; i++) - { - audio = &(hdmi->edid.audio[i]); - if(audio->type<1 || audio->type>HDMI_AUDIO_WMA_PRO){ - printk("audio type: unsupported."); - continue; - } - size = strlen(sAudioFormatStr[audio->type]); - //printk("size: %d, type: %s\n", size, sAudioFormatStr[audio->type]); - memcpy(audioinfo, sAudioFormatStr[audio->type], size); - audioinfo[size]=','; - audioinfo += (size+1); - } - mutex_unlock(&hdmi->lock); - return 0; -} - - -static int hdmi_get_monspecs(struct rk_display_device *device, struct fb_monspecs *monspecs) -{ - struct hdmi *hdmi = device->priv_data; - - if (!hdmi) - return -1; - - mutex_lock(&hdmi->lock); - if(hdmi->edid.specs) - *monspecs = *(hdmi->edid.specs); - mutex_unlock(&hdmi->lock); - return 0; -} - -struct rk_display_ops hdmi_display_ops = { - .setenable = hdmi_set_enable, - .getenable = hdmi_get_enable, - .getstatus = hdmi_get_status, - .getmodelist = hdmi_get_modelist, - .setmode = hdmi_set_mode, - .getmode = hdmi_get_mode, - .setscale = hdmi_set_scale, - .getscale = hdmi_get_scale, - .setdebug = hdmi_set_debug, - .getedidaudioinfo = hdmi_get_edidaudioinfo, - .getmonspecs = hdmi_get_monspecs, -}; - -#if 1 -static int hdmi_display_probe(struct rk_display_device *device, void *devdata) -{ - device->owner = THIS_MODULE; - strcpy(device->type, "HDMI"); - device->priority = DISPLAY_PRIORITY_HDMI; -/* - device->name = kmalloc(strlen(name), GFP_KERNEL); - if(device->name) - strcpy(device->name, name); -*/ - device->priv_data = devdata; - device->ops = &hdmi_display_ops; - return 1; -} - -static struct rk_display_driver display_hdmi = { - .probe = hdmi_display_probe, -}; - -#ifdef CONFIG_DRM_ROCKCHIP -extern void rk_drm_display_register(struct rk_display_ops *extend_ops, - void *displaydata, int type); -#endif - -void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent) -{ - hdmi->ddev = - rk_display_device_register(&display_hdmi, parent, hdmi); -#ifdef CONFIG_DRM_ROCKCHIP - rk_drm_display_register(&hdmi_display_ops, hdmi, SCREEN_HDMI); -#endif -} - -void hdmi_unregister_display_sysfs(struct hdmi *hdmi) -{ - if (hdmi->ddev) - rk_display_device_unregister(hdmi->ddev); -} -#endif diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_task.c b/drivers/video/rockchip/hdmi/rk_hdmi_task.c deleted file mode 100755 index 6744144d36d6..000000000000 --- a/drivers/video/rockchip/hdmi/rk_hdmi_task.c +++ /dev/null @@ -1,345 +0,0 @@ -#include -#include -#include -#include -#include -#include "rk_hdmi.h" - -#define HDMI_MAX_TRY_TIMES 1 -#define HDMI_MAX_ID 1 - -static char *envp[] = { "INTERFACE=HDMI", NULL }; -static int uboot_vic=-1; -static void hdmi_sys_show_state(struct hdmi *hdmi) -{ - switch (hdmi->state) { - case HDMI_SLEEP: - hdmi_dbg(hdmi->dev, "HDMI_SLEEP\n"); - break; - case HDMI_INITIAL: - hdmi_dbg(hdmi->dev, "HDMI_INITIAL\n"); - break; - case WAIT_HOTPLUG: - hdmi_dbg(hdmi->dev, "WAIT_HOTPLUG\n"); - break; - case READ_PARSE_EDID: - hdmi_dbg(hdmi->dev, "READ_PARSE_EDID\n"); - break; - case WAIT_HDMI_ENABLE: - hdmi_dbg(hdmi->dev, "WAIT_HDMI_ENABLE\n"); - break; - case SYSTEM_CONFIG: - hdmi_dbg(hdmi->dev, "SYSTEM_CONFIG\n"); - break; - case CONFIG_VIDEO: - hdmi_dbg(hdmi->dev, "CONFIG_VIDEO\n"); - break; - case CONFIG_AUDIO: - hdmi_dbg(hdmi->dev, "CONFIG_AUDIO\n"); - break; - case PLAY_BACK: - hdmi_dbg(hdmi->dev, "PLAY_BACK\n"); - break; - default: - hdmi_dbg(hdmi->dev, "Unkown State %d\n", hdmi->state); - break; - } -} - -int hdmi_sys_init(struct hdmi *hdmi) -{ - if (uboot_vic > 0) { - hdmi->uboot_logo = support_uboot_display(); - hdmi->hotplug = HDMI_HPD_ACTIVED; - hdmi->state = PLAY_BACK; - hdmi->enable = HDMI_ENABLE; - hdmi->display = HDMI_DISABLE; - hdmi->vic = uboot_vic; - } else { - hdmi->hotplug = HDMI_HPD_REMOVED; - hdmi->state = HDMI_SLEEP; - hdmi->enable = HDMI_ENABLE; - hdmi->display = HDMI_DISABLE; - hdmi->vic = HDMI_VIDEO_DEFAULT_MODE; - hdmi->uboot_logo = 0; - } - hdmi_dbg(hdmi->dev, "uboot-logo=%d,uboot_vic=%d\n",hdmi->uboot_logo,uboot_vic); - hdmi->autoconfig = HDMI_AUTO_CONFIGURE; - hdmi->audio.channel = HDMI_AUDIO_DEFAULT_CHANNEL; - hdmi->audio.rate = HDMI_AUDIO_DEFAULT_RATE; - hdmi->audio.word_length = HDMI_AUDIO_DEFAULT_WORD_LENGTH; - - memset(&hdmi->edid, 0, sizeof(struct hdmi_edid)); - INIT_LIST_HEAD(&hdmi->edid.modelist); - mutex_init(&hdmi->lock); - return 0; -} - -void hdmi_sys_remove(struct hdmi *hdmi) -{ - int audio_need; - - audio_need = hdmi->edid.base_audio_support == 1 && - hdmi->edid.sink_hdmi == 1; - - fb_destroy_modelist(&hdmi->edid.modelist); - kfree(hdmi->edid.audio); - if (hdmi->edid.specs) { - kfree(hdmi->edid.specs->modedb); - kfree(hdmi->edid.specs); - } - memset(&hdmi->edid, 0, sizeof(struct hdmi_edid)); - INIT_LIST_HEAD(&hdmi->edid.modelist); - hdmi->display = HDMI_DISABLE; - if (hdmi->set_vif) - hdmi->set_vif(hdmi, hdmi->lcdc->cur_screen, 0); - rk_fb_switch_screen(hdmi->lcdc->cur_screen, 0, hdmi->lcdc->id); - kobject_uevent_env(&hdmi->ddev->dev->kobj, KOBJ_REMOVE, envp); - -#ifdef CONFIG_SWITCH - if (audio_need || - rk_fb_get_display_policy() == DISPLAY_POLICY_BOX) - switch_set_state(&(hdmi->switch_hdmi), 0); -#endif - rockchip_clear_system_status(SYS_STATUS_HDMI); -} - -static void hdmi_sys_sleep(struct hdmi *hdmi) -{ - mutex_lock(&hdmi->enable_mutex); - if (hdmi->enable && hdmi->irq) - disable_irq(hdmi->irq); - hdmi->state = HDMI_SLEEP; - hdmi->remove(hdmi); - if (hdmi->enable && hdmi->irq) - enable_irq(hdmi->irq); - mutex_unlock(&hdmi->enable_mutex); -} - -static int hdmi_process_command(struct hdmi *hdmi) -{ - int change, state = hdmi->state; - - change = hdmi->command; - if (change != HDMI_CONFIG_NONE) { - hdmi->command = HDMI_CONFIG_NONE; - switch (change) { - case HDMI_CONFIG_ENABLE: - /* disable HDMI */ - mutex_lock(&hdmi->enable_mutex); - if (!hdmi->enable || hdmi->suspend) { - if (hdmi->hotplug != HDMI_HPD_REMOVED) { - hdmi->hotplug = HDMI_HPD_REMOVED; - hdmi->control_output(hdmi, HDMI_DISABLE); - hdmi_sys_remove(hdmi); - } - hdmi->state = HDMI_SLEEP; - hdmi->remove(hdmi); - state = HDMI_SLEEP; - } - mutex_unlock(&hdmi->enable_mutex); - if (hdmi->wait == 1) { - complete(&hdmi->complete); - hdmi->wait = 0; - } - break; - case HDMI_CONFIG_COLOR: - if (state > CONFIG_VIDEO) - state = CONFIG_VIDEO; - break; - case HDMI_CONFIG_HDCP: - break; - case HDMI_CONFIG_DISPLAY: - break; - case HDMI_CONFIG_AUDIO: - if (state > CONFIG_AUDIO) - state = CONFIG_AUDIO; - break; - case HDMI_CONFIG_VIDEO: - default: - if (state > SYSTEM_CONFIG) { - state = SYSTEM_CONFIG; - hdmi->control_output(hdmi, HDMI_DISABLE); - msleep(2000); - } else { - if (hdmi->wait == 1) { - complete(&hdmi->complete); - hdmi->wait = 0; - } - } - break; - } - } else if (state == HDMI_SLEEP) { - state = WAIT_HOTPLUG; - } - return state; -} - -static DEFINE_MUTEX(work_mutex); - -void hdmi_work(struct work_struct *work) -{ - int hotplug, state_last; - int rc = HDMI_ERROR_SUCESS, trytimes = 0; - struct hdmi_video_para video; - struct delayed_work *delay_work = - container_of(work, struct delayed_work, work); - struct hdmi *hdmi = container_of(delay_work, struct hdmi, delay_work); - int command = hdmi->command; - - mutex_lock(&work_mutex); - /* Process hdmi command */ - hdmi->state = hdmi_process_command(hdmi); - - if (!hdmi->enable || hdmi->suspend) { - mutex_unlock(&work_mutex); - return; - } - hotplug = hdmi->detect_hotplug(hdmi); - hdmi_dbg(hdmi->dev, "[%s] hotplug %02x curvalue %d\n", __func__, - hotplug, hdmi->hotplug); - - if (hotplug != hdmi->hotplug) { - if (hotplug == HDMI_HPD_ACTIVED) { - if (hdmi->insert) - hdmi->insert(hdmi); - hdmi->state = READ_PARSE_EDID; - } else if (hdmi->hotplug == HDMI_HPD_ACTIVED) { - hdmi->hotplug = hotplug; - hdmi_sys_remove(hdmi); - if (hotplug == HDMI_HPD_REMOVED) { - hdmi_sys_sleep(hdmi); - } else { - hdmi->state = WAIT_HOTPLUG; - hdmi->remove(hdmi); - } - if (hdmi->wait == 1) { - complete(&hdmi->complete); - hdmi->wait = 0; - } - mutex_unlock(&work_mutex); - return; - } else if (hotplug == HDMI_HPD_REMOVED) { - hdmi->state = HDMI_SLEEP; - hdmi->remove(hdmi); - } - hdmi->hotplug = hotplug; - } else if (hotplug == HDMI_HPD_REMOVED) { - hdmi_sys_sleep(hdmi); - } else if (hotplug == HDMI_HPD_ACTIVED) { - if (hdmi->uboot_logo) { - if (hdmi->insert) - hdmi->insert(hdmi); - hdmi->state = READ_PARSE_EDID; - } - } - - do { - hdmi_sys_show_state(hdmi); - state_last = hdmi->state; - switch (hdmi->state) { - case READ_PARSE_EDID: - rc = hdmi_sys_parse_edid(hdmi); - if (rc == HDMI_ERROR_SUCESS) { - if (hdmi->cec_set_device_pa) - hdmi->cec_set_device_pa(hdmi->edid.cecaddress); - if (hdmi->cec_enumerate) - hdmi->cec_enumerate(); - hdmi->state = SYSTEM_CONFIG; - kobject_uevent_env(&hdmi->ddev->dev->kobj, - KOBJ_ADD, envp); - hdmi_dbg(hdmi->dev, - "[%s] base_audio_support =%d,sink_hdmi = %d\n", - __func__, - hdmi->edid.base_audio_support, - hdmi->edid.sink_hdmi); -#ifdef CONFIG_SWITCH - if ((hdmi->edid.base_audio_support == 1 && - hdmi->edid.sink_hdmi == 1) || - (rk_fb_get_display_policy() == - DISPLAY_POLICY_BOX)) - switch_set_state(&(hdmi->switch_hdmi), - 1); -#endif - rockchip_set_system_status(SYS_STATUS_HDMI); - } - - break; - case SYSTEM_CONFIG: - if ((hdmi->remove) && !hdmi->uboot_logo) - hdmi->remove(hdmi); - - if (hdmi->autoconfig) - hdmi->vic = hdmi_find_best_mode(hdmi, 0); - else - hdmi->vic = - hdmi_find_best_mode(hdmi, hdmi->vic); - rc = hdmi_switch_fb(hdmi, hdmi->vic); - if (rc == HDMI_ERROR_SUCESS) - hdmi->state = CONFIG_VIDEO; - if (hdmi->uboot_logo) { - hdmi->state = CONFIG_AUDIO; - } - - /* whether switch resolution */ - if (command == HDMI_CONFIG_VIDEO) - kobject_uevent_env(&hdmi->ddev->dev->kobj, - KOBJ_CHANGE, envp); - break; - case CONFIG_VIDEO: - hdmi->display = HDMI_DISABLE; - hdmi_init_video_para(hdmi, &video); - rc = hdmi->config_video(hdmi, &video); - if (rc == HDMI_ERROR_SUCESS) { - if (hdmi->edid.sink_hdmi) - hdmi->state = CONFIG_AUDIO; - else - hdmi->state = PLAY_BACK; - } - break; - case CONFIG_AUDIO: - rc = hdmi->config_audio(hdmi, &(hdmi->audio)); - - if (rc == HDMI_ERROR_SUCESS) - hdmi->state = PLAY_BACK; - break; - case PLAY_BACK: - if (hdmi->display != HDMI_ENABLE) { - hdmi->control_output(hdmi, HDMI_ENABLE); - hdmi->display = HDMI_ENABLE; - if (hdmi->hdcp_cb) - hdmi->hdcp_cb(); - } - - if (hdmi->wait == 1) { - complete(&hdmi->complete); - hdmi->wait = 0; - } - break; - default: - break; - } - if (rc != HDMI_ERROR_SUCESS) { - trytimes++; - msleep(20); - } - if (hdmi->state != state_last) - trytimes = 0; - - } while ((hdmi->state != state_last || - (rc != HDMI_ERROR_SUCESS)) && - trytimes < HDMI_MAX_TRY_TIMES); - hdmi_dbg(hdmi->dev, "[%s] done\n", __func__); - mutex_unlock(&work_mutex); -} - -static int __init bootloader_setup(char *str) -{ - if(str) { - printk("hdmi init vic is %s\n", str); - sscanf(str, "%d", &uboot_vic); - } - /*uboot_vic = 16;*/ - return 0; -} -early_param("hdmi.vic", bootloader_setup); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c new file mode 100644 index 000000000000..b73574bfc69b --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c @@ -0,0 +1,620 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rockchip-hdmi-cec.h" + +static struct cec_device *cec_dev; +struct input_dev *devinput; +static struct miscdevice mdev; + +int key_table[] = { + KEY_UP, + KEY_DOWN, + KEY_LEFT, + KEY_RIGHT, + KEY_REPLY, + KEY_BACK, + KEY_POWER, +}; + +static void cecmenucontrol(int uitemp); + +static int cecreadframe(struct cec_framedata *frame) +{ + if (frame == NULL || !cec_dev || cec_dev->readframe == NULL) + return -1; + else + return cec_dev->readframe(cec_dev->hdmi, frame); +} + +static int cecsendframe(struct cec_framedata *frame) +{ + if (frame == NULL || !cec_dev || cec_dev->readframe == NULL) + return -1; + else + return cec_dev->sendframe(cec_dev->hdmi, frame); +} + +static int cecsendping(char logicaddress) +{ + struct cec_framedata cecframe; + + memset(&cecframe, 0, sizeof(struct cec_framedata)); + cecframe.srcdestaddr = logicaddress << 4 | logicaddress; + return cec_dev->sendframe(cec_dev->hdmi, &cecframe); +} + +/*static int CecSendMessage (char opCode, char dest) +{ + struct cec_framedata cecframe; + + cecframe.opcode = opCode; + cecframe.srcdestaddr = MAKE_SRCDEST(cec_dev->address_logic, dest); + cecframe.argcount = 0; + + return cecsendframe(&cecframe); +}*/ + + +/*static void CecSendFeatureAbort (struct cec_framedata *pcpi, char reason) +{ + struct cec_framedata cecframe; + + if ((pcpi->srcdestaddr & 0x0F) != CEC_LOGADDR_UNREGORBC) { + cecframe.opcode = CECOP_FEATURE_ABORT; + cecframe.srcdestaddr = MAKE_SRCDEST( cec_dev->address_logic, + ( pcpi->srcdestaddr & 0xF0) >> 4 ); + cecframe.args[0] = pcpi->opcode; + cecframe.args[1] = reason; + cecframe.argcount = 2; + cecsendframe(&cecframe); + } +}*/ + +static void cecsendimageview(void) +{ + struct cec_framedata cecframe; + + cecframe.opcode = CECOP_IMAGE_VIEW_ON; + cecframe.srcdestaddr = MAKE_SRCDEST(cec_dev->address_logic, + CEC_LOGADDR_UNREGORBC); + cecframe.argcount = 0; + cecsendframe(&cecframe); +} + +static void cecsendactivesource(void) +{ + struct cec_framedata cecframe; + + cecframe.opcode = CECOP_ACTIVE_SOURCE; + cecframe.srcdestaddr = MAKE_SRCDEST(cec_dev->address_logic, + CEC_LOGADDR_UNREGORBC); + cecframe.args[0] = (cec_dev->address_phy & 0xFF00) >> 8; + cecframe.args[1] = (cec_dev->address_phy & 0x00FF); + cecframe.argcount = 2; + cecsendframe(&cecframe); +} + +static void cechandleinactivesource(struct cec_framedata *pcpi) +{ +} + +static void cechandlefeatureabort(struct cec_framedata *pcpi) +{ +} + +static bool validatececmessage(struct cec_framedata *pcpi) +{ + char parametercount = 0; + bool countok = true; + + /* Determine required parameter count */ + + switch (pcpi->opcode) { + case CECOP_IMAGE_VIEW_ON: + case CECOP_TEXT_VIEW_ON: + case CECOP_STANDBY: + case CECOP_GIVE_PHYSICAL_ADDRESS: + case CECOP_GIVE_DEVICE_POWER_STATUS: + case CECOP_GET_MENU_LANGUAGE: + case CECOP_GET_CEC_VERSION: + parametercount = 0; + break; + case CECOP_REPORT_POWER_STATUS: /* power status*/ + case CECOP_CEC_VERSION: /* cec version*/ + parametercount = 1; + break; + case CECOP_INACTIVE_SOURCE: /* physical address*/ + case CECOP_FEATURE_ABORT: + case CECOP_ACTIVE_SOURCE: /* physical address*/ + parametercount = 2; + break; + case CECOP_REPORT_PHYSICAL_ADDRESS: + case CECOP_DEVICE_VENDOR_ID: /* vendor id*/ + parametercount = 3; + break; + case CECOP_SET_OSD_NAME: /* osd name (1-14 bytes)*/ + case CECOP_SET_OSD_STRING: + parametercount = 1; /* must have a minimum of 1 operands*/ + break; + case CECOP_ABORT: + break; + case CECOP_ARC_INITIATE: + break; + case CECOP_ARC_REPORT_INITIATED: + break; + case CECOP_ARC_REPORT_TERMINATED: + break; + case CECOP_ARC_REQUEST_INITIATION: + break; + case CECOP_ARC_REQUEST_TERMINATION: + break; + case CECOP_ARC_TERMINATE: + break; + default: + break; + } + + /* Test for correct parameter count. */ + + if (pcpi->argcount < parametercount) + countok = false; + + return countok; +} + +static bool cecrxmsghandlerlast(struct cec_framedata *pcpi) +{ + bool isdirectaddressed; + struct cec_framedata cecframe; + + isdirectaddressed = !((pcpi->srcdestaddr & 0x0F) == + CEC_LOGADDR_UNREGORBC); + pr_info("isDirectAddressed %d\n", (int)isdirectaddressed); + if (validatececmessage(pcpi)) { + /* If invalid message, ignore it, but treat it as handled */ + if (isdirectaddressed) { + switch (pcpi->opcode) { + case CECOP_USER_CONTROL_PRESSED: + cecmenucontrol(pcpi->args[0]); + break; + + case CECOP_VENDOR_REMOTE_BUTTON_DOWN: + cecmenucontrol(pcpi->args[0]); + break; + case CECOP_FEATURE_ABORT: + cechandlefeatureabort(pcpi); + break; + + case CECOP_GIVE_OSD_NAME: + cecframe.opcode = CECOP_SET_OSD_NAME; + cecframe.srcdestaddr = + MAKE_SRCDEST(cec_dev->address_logic, + CEC_LOGADDR_TV); + cecframe.args[0] = 'r'; + cecframe.args[1] = 'k'; + cecframe.args[2] = '-'; + cecframe.args[3] = 'b'; + cecframe.args[4] = 'o'; + cecframe.args[5] = 'x'; + cecframe.argcount = 6; + cecsendframe(&cecframe); + break; + + case CECOP_VENDOR_COMMAND_WITH_ID: + + if (pcpi->args[2] == 00) { + cecframe.opcode = CECOP_SET_OSD_NAME; + cecframe.srcdestaddr = + MAKE_SRCDEST(cec_dev->address_logic, + CEC_LOGADDR_TV); + cecframe.args[0] = '1'; + cecframe.args[1] = '1'; + cecframe.args[2] = '1'; + cecframe.args[3] = '1'; + cecframe.args[4] = '1'; + cecframe.args[5] = '1'; + cecframe.argcount = 6; + cecsendframe(&cecframe); + } + break; + case CECOP_IMAGE_VIEW_ON: + case CECOP_TEXT_VIEW_ON: + /* In our case, respond the same to both these messages*/ + break; + + case CECOP_GIVE_DEVICE_VENDOR_ID: + cecframe.opcode = CECOP_DEVICE_VENDOR_ID; + cecframe.srcdestaddr = + MAKE_SRCDEST(cec_dev->address_logic, + CEC_LOGADDR_UNREGORBC); + cecframe.args[0] = 0x1; + cecframe.args[1] = 0x2; + cecframe.args[2] = 0x3; + cecframe.argcount = 3; + cecsendframe(&cecframe); + break; + + case CECOP_STANDBY: /* Direct and Broadcast*/ + /* Setting this here will let the main task know */ + /* (via SI_CecGetPowerState) and at the same time */ + /* prevent us from broadcasting a STANDBY message */ + /* of our own when the main task responds by */ + /* calling SI_CecSetPowerState( STANDBY ); */ + cec_dev->powerstatus = CEC_POWERSTATUS_STANDBY; + break; + + case CECOP_INACTIVE_SOURCE: + cechandleinactivesource(pcpi); + break; + + case CECOP_GIVE_PHYSICAL_ADDRESS: + + cecframe.opcode = CECOP_REPORT_PHYSICAL_ADDRESS; + cecframe.srcdestaddr = + MAKE_SRCDEST(cec_dev->address_logic, + CEC_LOGADDR_UNREGORBC); + cecframe.args[0] = (cec_dev->address_phy&0xFF00)>>8; + cecframe.args[1] = (cec_dev->address_phy&0x00FF); + cecframe.args[2] = cec_dev->address_logic; + cecframe.argcount = 3; + cecsendframe(&cecframe); + break; + + case CECOP_GIVE_DEVICE_POWER_STATUS: + /* TV responds with power status. */ + + cecframe.opcode = CECOP_REPORT_POWER_STATUS; + cecframe.srcdestaddr = + MAKE_SRCDEST(cec_dev->address_logic, + (pcpi->srcdestaddr & 0xF0) >> 4); + cec_dev->powerstatus = 0x00; + cecframe.args[0] = cec_dev->powerstatus; + cecframe.argcount = 1; + cecsendframe(&cecframe); + break; + + case CECOP_GET_MENU_LANGUAGE: + /* TV Responds with a Set Menu language command. */ + + cecframe.opcode = CECOP_SET_MENU_LANGUAGE; + cecframe.srcdestaddr = + MAKE_SRCDEST(cec_dev->address_logic, + CEC_LOGADDR_UNREGORBC); + cecframe.args[0] = 'e'; + cecframe.args[1] = 'n'; + cecframe.args[2] = 'g'; + cecframe.argcount = 3; + cecsendframe(&cecframe); + break; + + case CECOP_GET_CEC_VERSION: + /* TV responds to this request with it's CEC version support.*/ + + cecframe.srcdestaddr = + MAKE_SRCDEST(cec_dev->address_logic, + CEC_LOGADDR_TV); + cecframe.opcode = CECOP_CEC_VERSION; + cecframe.args[0] = 0x05; /* Report CEC1.4b*/ + cecframe.argcount = 1; + cecsendframe(&cecframe); + break; + + case CECOP_REPORT_POWER_STATUS: + /*Someone sent us their power state. + + l_sourcePowerStatus = pcpi->args[0]; + + let NEW SOURCE task know about it. + + if ( l_cecTaskState.task == SI_CECTASK_NEWSOURCE ) + { + l_cecTaskState.cpiState = CPI_RESPONSE; + }*/ + break; + + /* Do not reply to directly addressed 'Broadcast' msgs. */ + case CECOP_REQUEST_ACTIVE_SOURCE: + cecsendactivesource(); + break; + + case CECOP_ACTIVE_SOURCE: + case CECOP_REPORT_PHYSICAL_ADDRESS: + case CECOP_ROUTING_CHANGE: + case CECOP_ROUTING_INFORMATION: + case CECOP_SET_STREAM_PATH: + case CECOP_SET_MENU_LANGUAGE: + case CECOP_DEVICE_VENDOR_ID: + break; + + case CECOP_ABORT: + break; + default: + /*CecSendFeatureAbort(pcpi, CECAR_UNRECOG_OPCODE);*/ + break; + } + } else { + /* Respond to broadcast messages. */ + switch (pcpi->opcode) { + case CECOP_STANDBY: + /* Setting this here will let the main task know */ + /* (via SI_CecGetPowerState) and at the same time */ + /* prevent us from broadcasting a STANDBY message */ + /* of our own when the main task responds by */ + /* calling SI_CecSetPowerState( STANDBY ); */ + cec_dev->powerstatus = CEC_POWERSTATUS_STANDBY; + input_event(devinput, EV_KEY, KEY_POWER, 1); + input_sync(devinput); + input_event(devinput, EV_KEY, KEY_POWER, 0); + input_sync(devinput); + break; + + case CECOP_ACTIVE_SOURCE: + /*CecHandleActiveSource( pcpi );*/ + break; + + case CECOP_REPORT_PHYSICAL_ADDRESS: + /*CecHandleReportPhysicalAddress( pcpi );*/ + cecframe.srcdestaddr = + MAKE_SRCDEST(cec_dev->address_logic, + CEC_LOGADDR_UNREGORBC); + cecframe.opcode = CECOP_CEC_VERSION; + cecframe.args[0] = 0x05; /* CEC1.4b*/ + cecframe.argcount = 1; + cecsendframe(&cecframe); + break; + + /* Do not reply to 'Broadcast' msgs that we don't need.*/ + case CECOP_REQUEST_ACTIVE_SOURCE: + cecsendactivesource(); + break; + case CECOP_ROUTING_CHANGE: + case CECOP_ROUTING_INFORMATION: + case CECOP_SET_STREAM_PATH: + case CECOP_SET_MENU_LANGUAGE: + break; + } + } + } + + return 0; +} + +static void cecenumeration(void) +{ + char logicaddress[3] = {CEC_LOGADDR_PLAYBACK1, + CEC_LOGADDR_PLAYBACK2, + CEC_LOGADDR_PLAYBACK3}; + int i; + + if (!cec_dev) + return; + + for (i = 0; i < 3; i++) { + if (cecsendping(logicaddress[i])) { + cec_dev->address_logic = logicaddress[i]; + CECDBG("Logic Address is 0x%x\n", + cec_dev->address_logic); + break; + } + } + if (i == 3) + cec_dev->address_logic = CEC_LOGADDR_UNREGORBC; + cec_dev->setceclogicaddr(cec_dev->hdmi, cec_dev->address_logic); + cecsendimageview(); + cecsendactivesource(); +} + +static void cecworkfunc(struct work_struct *work) +{ + struct cec_delayed_work *cec_w = + container_of(work, struct cec_delayed_work, work.work); + struct cec_framedata cecframe; + + switch (cec_w->event) { + case EVENT_ENUMERATE: + cecenumeration(); + break; + case EVENT_RX_FRAME: + memset(&cecframe, 0, sizeof(struct cec_framedata)); + cecreadframe(&cecframe); + cecrxmsghandlerlast(&cecframe); + break; + default: + break; + } + + kfree(cec_w->data); + kfree(cec_w); +} + +void rockchip_hdmi_cec_submit_work(int event, int delay, void *data) +{ + struct cec_delayed_work *work; + + CECDBG("%s event %04x delay %d\n", __func__, event, delay); + + work = kmalloc(sizeof(*work), GFP_ATOMIC); + + if (work) { + INIT_DELAYED_WORK(&work->work, cecworkfunc); + work->event = event; + work->data = data; + queue_delayed_work(cec_dev->workqueue, + &work->work, + msecs_to_jiffies(delay)); + } else { + CECDBG(KERN_WARNING "CEC: Cannot allocate memory\n"); + } +} + +void rockchip_hdmi_cec_set_pa(int devpa) +{ + if (cec_dev) + cec_dev->address_phy = devpa; + cecenumeration(); +} + +static int cec_input_device_init(void) +{ + int err, i; + + devinput = input_allocate_device(); + if (!devinput) + return -ENOMEM; + devinput->name = "hdmi_cec_key"; + /*devinput->dev.parent = &client->dev;*/ + devinput->phys = "hdmi_cec_key/input0"; + devinput->id.bustype = BUS_HOST; + devinput->id.vendor = 0x0001; + devinput->id.product = 0x0001; + devinput->id.version = 0x0100; + err = input_register_device(devinput); + if (err < 0) { + input_free_device(devinput); + CECDBG("%s input device error", __func__); + return err; + } + for (i = 0; i < (sizeof(key_table)/sizeof(int)); i++) + input_set_capability(devinput, EV_KEY, key_table[i]); + return 0; +} + +static void cecmenucontrol(int uitemp) +{ + switch (uitemp) { + case S_CEC_MAKESURE: /*make sure*/ + CECDBG("CEC UIcommand makesure\n"); + input_event(devinput, EV_KEY, KEY_REPLY, 1); + input_sync(devinput); + input_event(devinput, EV_KEY, KEY_REPLY, 0); + input_sync(devinput); + break; + case S_CEC_UP: /*up*/ + CECDBG("CEC UIcommand up\n"); + input_event(devinput, EV_KEY, KEY_UP, 1); + input_sync(devinput); + input_event(devinput, EV_KEY, KEY_UP, 0); + input_sync(devinput); + break; + case S_CEC_DOWN: /*down*/ + CECDBG("CEC UIcommand down\n"); + input_event(devinput, EV_KEY, KEY_DOWN, 1); + input_sync(devinput); + input_event(devinput, EV_KEY, KEY_DOWN, 0); + input_sync(devinput); + break; + case S_CEC_LEFT: /*left*/ + CECDBG("CEC UIcommand left\n"); + input_event(devinput, EV_KEY, KEY_LEFT , 1); + input_sync(devinput); + input_event(devinput, EV_KEY, KEY_LEFT , 0); + input_sync(devinput); + break; + case S_CEC_RIGHT: /*right*/ + CECDBG("CEC UIcommand right\n"); + input_event(devinput, EV_KEY, KEY_RIGHT, 1); + input_sync(devinput); + input_event(devinput, EV_KEY, KEY_RIGHT, 0); + input_sync(devinput); + break; + case S_CEC_BACK: /*back*/ + CECDBG("CEC UIcommand back\n"); + input_event(devinput, EV_KEY, KEY_BACK, 1); + input_sync(devinput); + input_event(devinput, EV_KEY, KEY_BACK, 0); + input_sync(devinput); + break; + case S_CEC_VENDORBACK: + CECDBG("CEC UIcommand vendor back\n"); + input_event(devinput, EV_KEY, KEY_BACK, 1); + input_sync(devinput); + input_event(devinput, EV_KEY, KEY_BACK, 0); + input_sync(devinput); + break; + } +} + + +static ssize_t cec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", cec_dev->cecval); +} + +static ssize_t cec_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + + ret = sscanf(buf, "%s", cec_dev->cecval); + return strnlen(buf, PAGE_SIZE); +} + +static struct device_attribute cec_control_attr = { + .attr = {.name = "cec", .mode = 0666}, + .show = cec_show, + .store = cec_store, +}; + +int rockchip_hdmi_cec_init(struct hdmi *hdmi, + int (*sendframe)(struct hdmi *, + struct cec_framedata *), + int (*readframe)(struct hdmi *, + struct cec_framedata *), + void (*setceclogicaddr)(struct hdmi *, int)) +{ + int ret; + static int cecmicsdevflag = 1; + + mdev.minor = MISC_DYNAMIC_MINOR; + mdev.name = "cec"; + mdev.mode = 0666; + cec_dev = kmalloc(sizeof(*cec_dev), GFP_KERNEL); + if (!cec_dev) { + pr_err("HDMI CEC: kmalloc fail!"); + return -ENOMEM; + } + memset(cec_dev, 0, sizeof(struct cec_device)); + cec_dev->hdmi = hdmi; + cec_dev->cecval[0] = '1'; + cec_dev->cecval[1] = '\0'; + cec_dev->sendframe = sendframe; + cec_dev->readframe = readframe; + cec_dev->setceclogicaddr = setceclogicaddr; + cec_dev->workqueue = create_singlethread_workqueue("hdmi-cec"); + if (cec_dev->workqueue == NULL) { + pr_err("HDMI CEC: create workqueue failed.\n"); + return -1; + } + if (cecmicsdevflag) { + cec_input_device_init(); + if (misc_register(&mdev)) { + pr_err("CEC: Could not add cec misc driver\n"); + goto error; + } + + ret = device_create_file(mdev.this_device, &cec_control_attr); + if (ret) { + pr_err("CEC: Could not add sys file enable\n"); + goto error1; + } + cecmicsdevflag = 0; + } + return 0; + +error1: + misc_deregister(&mdev); +error: + ret = -EINVAL; + return ret; +} diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.h b/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.h new file mode 100644 index 000000000000..9847d06c7d46 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.h @@ -0,0 +1,186 @@ +#ifndef __ROCKCHIP_HDMI_CEC_H__ +#define __ROCKCHIP_HDMI_CEC_H__ +#include "rockchip-hdmi.h" + +#include + +enum { + CEC_LOGADDR_TV = 0x00, + CEC_LOGADDR_RECDEV1 = 0x01, + CEC_LOGADDR_RECDEV2 = 0x02, + CEC_LOGADDR_TUNER1 = 0x03, /* STB1 in Spev v1.3 */ + CEC_LOGADDR_PLAYBACK1 = 0x04, /* DVD1 in Spev v1.3 */ + CEC_LOGADDR_AUDSYS = 0x05, + CEC_LOGADDR_TUNER2 = 0x06, /* STB2 in Spec v1.3 */ + CEC_LOGADDR_TUNER3 = 0x07, /* STB3 in Spec v1.3 */ + CEC_LOGADDR_PLAYBACK2 = 0x08, /* DVD2 in Spec v1.3 */ + CEC_LOGADDR_RECDEV3 = 0x09, + CEC_LOGADDR_TUNER4 = 0x0A, /* RES1 in Spec v1.3 */ + CEC_LOGADDR_PLAYBACK3 = 0x0B, /* RES2 in Spec v1.3 */ + CEC_LOGADDR_RES3 = 0x0C, + CEC_LOGADDR_RES4 = 0x0D, + CEC_LOGADDR_FREEUSE = 0x0E, + CEC_LOGADDR_UNREGORBC = 0x0F + +}; + +enum { /* CEC Messages */ + CECOP_FEATURE_ABORT = 0x00, + CECOP_IMAGE_VIEW_ON = 0x04, + CECOP_TUNER_STEP_INCREMENT = 0x05, + CECOP_TUNER_STEP_DECREMENT = 0x06, + CECOP_TUNER_DEVICE_STATUS = 0x07, + CECOP_GIVE_TUNER_DEVICE_STATUS = 0x08, + CECOP_RECORD_ON = 0x09, + CECOP_RECORD_STATUS = 0x0A, + CECOP_RECORD_OFF = 0x0B, + CECOP_TEXT_VIEW_ON = 0x0D, + CECOP_RECORD_TV_SCREEN = 0x0F, + CECOP_GIVE_DECK_STATUS = 0x1A, + CECOP_DECK_STATUS = 0x1B, + CECOP_SET_MENU_LANGUAGE = 0x32, + CECOP_CLEAR_ANALOGUE_TIMER = 0x33, /* Spec 1.3A */ + CECOP_SET_ANALOGUE_TIMER = 0x34, /* Spec 1.3A */ + CECOP_TIMER_STATUS = 0x35, /* Spec 1.3A */ + CECOP_STANDBY = 0x36, + CECOP_PLAY = 0x41, + CECOP_DECK_CONTROL = 0x42, + CECOP_TIMER_CLEARED_STATUS = 0x43, /* Spec 1.3A */ + CECOP_USER_CONTROL_PRESSED = 0x44, + CECOP_USER_CONTROL_RELEASED = 0x45, + CECOP_GIVE_OSD_NAME = 0x46, + CECOP_SET_OSD_NAME = 0x47, + CECOP_SET_OSD_STRING = 0x64, + CECOP_SET_TIMER_PROGRAM_TITLE = 0x67, /* Spec 1.3A */ + CECOP_SYSTEM_AUDIO_MODE_REQUEST = 0x70, /* Spec 1.3A */ + CECOP_GIVE_AUDIO_STATUS = 0x71, /* Spec 1.3A */ + CECOP_SET_SYSTEM_AUDIO_MODE = 0x72, /* Spec 1.3A */ + CECOP_REPORT_AUDIO_STATUS = 0x7A, /* Spec 1.3A */ + CECOP_GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D, /* Spec 1.3A */ + CECOP_SYSTEM_AUDIO_MODE_STATUS = 0x7E, /* Spec 1.3A */ + CECOP_ROUTING_CHANGE = 0x80, + CECOP_ROUTING_INFORMATION = 0x81, + CECOP_ACTIVE_SOURCE = 0x82, + CECOP_GIVE_PHYSICAL_ADDRESS = 0x83, + CECOP_REPORT_PHYSICAL_ADDRESS = 0x84, + CECOP_REQUEST_ACTIVE_SOURCE = 0x85, + CECOP_SET_STREAM_PATH = 0x86, + CECOP_DEVICE_VENDOR_ID = 0x87, + CECOP_VENDOR_COMMAND = 0x89, + CECOP_VENDOR_REMOTE_BUTTON_DOWN = 0x8A, + CECOP_VENDOR_REMOTE_BUTTON_UP = 0x8B, + CECOP_GIVE_DEVICE_VENDOR_ID = 0x8C, + CECOP_MENU_REQUEST = 0x8D, + CECOP_MENU_STATUS = 0x8E, + CECOP_GIVE_DEVICE_POWER_STATUS = 0x8F, + CECOP_REPORT_POWER_STATUS = 0x90, + CECOP_GET_MENU_LANGUAGE = 0x91, + CECOP_SELECT_ANALOGUE_SERVICE = 0x92, /* Spec 1.3A */ + CECOP_SELECT_DIGITAL_SERVICE = 0x93, + CECOP_SET_DIGITAL_TIMER = 0x97, /* Spec 1.3A */ + CECOP_CLEAR_DIGITAL_TIMER = 0x99, /* Spec 1.3A */ + CECOP_SET_AUDIO_RATE = 0x9A, /* Spec 1.3A */ + CECOP_INACTIVE_SOURCE = 0x9D, /* Spec 1.3A */ + CECOP_CEC_VERSION = 0x9E, /* Spec 1.3A */ + CECOP_GET_CEC_VERSION = 0x9F, /* Spec 1.3A */ + CECOP_VENDOR_COMMAND_WITH_ID = 0xA0, /* Spec 1.3A */ + CECOP_CLEAR_EXTERNAL_TIMER = 0xA1, /* Spec 1.3A */ + CECOP_SET_EXTERNAL_TIMER = 0xA2, /* Spec 1.3A */ + CDCOP_HEADER = 0xF8, + CECOP_ABORT = 0xFF, + + CECOP_REPORT_SHORT_AUDIO = 0xA3, /* Spec 1.4 */ + CECOP_REQUEST_SHORT_AUDIO = 0xA4, /* Spec 1.4 */ + + CECOP_ARC_INITIATE = 0xC0, + CECOP_ARC_REPORT_INITIATED = 0xC1, + CECOP_ARC_REPORT_TERMINATED = 0xC2, + + CECOP_ARC_REQUEST_INITIATION = 0xC3, + CECOP_ARC_REQUEST_TERMINATION = 0xC4, + CECOP_ARC_TERMINATE = 0xC5, + +}; + +/* Operands for Opcode */ +enum { + CECAR_UNRECOG_OPCODE = 0x00, + CECAR_NOT_CORRECT_MODE, + CECAR_CANT_PROVIDE_SOURCE, + CECAR_INVALID_OPERAND, + CECAR_REFUSED +}; + +/* Operands for Opcode */ +enum { + CEC_POWERSTATUS_ON = 0x00, + CEC_POWERSTATUS_STANDBY = 0x01, + CEC_POWERSTATUS_STANDBY_TO_ON = 0x02, + CEC_POWERSTATUS_ON_TO_STANDBY = 0x03, +}; + +enum { + EVENT_RX_FRAME, + EVENT_ENUMERATE, +}; + +#define MAKE_SRCDEST(src, dest) ((src << 4) | dest) + +#define MAX_CMD_SIZE 16 + +struct cec_framedata { + char srcdestaddr; /* Source in upper nybble, dest in lower nybble */ + char opcode; + char args[MAX_CMD_SIZE]; + char argcount; + char nextframeargcount; +}; + +struct cec_delayed_work { + struct delayed_work work; + int event; + void *data; +}; + +struct cec_device { + struct workqueue_struct *workqueue; + struct hdmi *hdmi; + int address_phy; + int address_logic; + int powerstatus; + char cecval[32]; + + int (*sendframe)(struct hdmi *, struct cec_framedata *); + int (*readframe)(struct hdmi *, struct cec_framedata *); + void (*setceclogicaddr)(struct hdmi *, int); +}; + +#ifdef DEBUG +#define CECDBG(format, ...) \ + pr_info(format, ## __VA_ARGS__) +#else +#define CECDBG(format, ...) +#endif + +/*==================================== +//used for cec key control direction OK and back +====================================*/ +enum { + S_CEC_MAKESURE = 0x0, + S_CEC_UP = 0x1, + S_CEC_DOWN = 0x2, + S_CEC_LEFT = 0x3, + S_CEC_RIGHT = 0x4, + S_CEC_BACK = 0x0d, + S_CEC_VENDORBACK = 0x91, +}; + +int rockchip_hdmi_cec_init(struct hdmi *hdmi, + int (*sendframe)(struct hdmi *, + struct cec_framedata *), + int (*readframe)(struct hdmi *, + struct cec_framedata *), + void (*setceclogicaddr)(struct hdmi *, int)); +void rockchip_hdmi_cec_set_pa(int devpa); +void rockchip_hdmi_cec_submit_work(int event, int delay, void *data); +#endif /* __HDMI_CEC_H__ */ \ No newline at end of file diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c new file mode 100644 index 000000000000..b7b67178d083 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c @@ -0,0 +1,623 @@ +#include +#include "rockchip-hdmi.h" +#include "rockchip-hdmi-cec.h" + +struct hdmi_delayed_work { + struct delayed_work work; + struct hdmi *hdmi; + int event; + void *data; +}; + +struct hdmi_id_ref_info { + struct hdmi *hdmi; + int id; + int ref; +} ref_info[HDMI_MAX_ID]; + +static int uboot_vic; +static void hdmi_work_queue(struct work_struct *work); + +struct delayed_work *hdmi_submit_work(struct hdmi *hdmi, + int event, int delay, void *data) +{ + struct hdmi_delayed_work *work; + + DBG("%s event %04x delay %d", __func__, event, delay); + + work = kmalloc(sizeof(*work), GFP_ATOMIC); + + if (work) { + INIT_DELAYED_WORK(&work->work, hdmi_work_queue); + work->hdmi = hdmi; + work->event = event; + work->data = data; + queue_delayed_work(hdmi->workqueue, + &work->work, + msecs_to_jiffies(delay)); + } else { + pr_warn("HDMI: Cannot allocate memory to create work\n"); + return 0; + } + + return &work->work; +} + +static void hdmi_send_uevent(struct hdmi *hdmi, int uevent) +{ + char *envp[3]; + + envp[0] = "INTERFACE=HDMI"; + envp[1] = kmalloc(32, GFP_KERNEL); + if (envp[1] == NULL) + return; + sprintf(envp[1], "SCREEN=%d", hdmi->ddev->property); + envp[2] = NULL; + kobject_uevent_env(&hdmi->ddev->dev->kobj, uevent, envp); + kfree(envp[1]); +} + +static inline void hdmi_wq_set_output(struct hdmi *hdmi, int mute) +{ + DBG("%s mute %d", __func__, mute); + if (hdmi->ops->setmute) + hdmi->ops->setmute(hdmi, mute); +} + +static inline void hdmi_wq_set_audio(struct hdmi *hdmi) +{ + DBG("%s", __func__); + if (hdmi->ops->setaudio) + hdmi->ops->setaudio(hdmi, &hdmi->audio); +} + +static void hdmi_wq_set_video(struct hdmi *hdmi) +{ + struct hdmi_video video; + + DBG("%s", __func__); + + video.vic = hdmi->vic & HDMI_VIC_MASK; + if (hdmi->vic & HDMI_VIDEO_YUV420) + video.color_input = HDMI_COLOR_YCBCR420; + else + video.color_input = HDMI_COLOR_YCBCR444; + video.sink_hdmi = hdmi->edid.sink_hdmi; + video.format_3d = hdmi->mode_3d; + /* For DVI, output RGB */ + if (hdmi->edid.sink_hdmi == 0) { + video.color_output = HDMI_COLOR_RGB_0_255; + } else { + if (hdmi->colormode == HDMI_COLOR_AUTO) { + if (hdmi->edid.ycbcr444) + video.color_output = HDMI_COLOR_YCBCR444; + else if (hdmi->edid.ycbcr422) + video.color_output = HDMI_COLOR_YCBCR422; + else + video.color_output = HDMI_COLOR_RGB_16_235; + } else { + video.color_output = hdmi->colormode; + } + } + if ((hdmi->property->feature & SUPPORT_DEEP_10BIT) && + (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_30BITS)) { + if (hdmi->colordepth == HDMI_DEPP_COLOR_AUTO || + hdmi->colordepth == 10) + video.color_output_depth = 10; + } else { + video.color_output_depth = 8; + } + if (hdmi->vic & HDMI_VIDEO_YUV420) + video.color_output = HDMI_COLOR_YCBCR420; + pr_info("hdmi output corlor mode is %d\n", video.color_output); + if (hdmi->ops->setvideo) + hdmi->ops->setvideo(hdmi, &video); +} + +static void hdmi_wq_parse_edid(struct hdmi *hdmi) +{ + struct hdmi_edid *pedid; + unsigned char *buff = NULL; + int rc = HDMI_ERROR_SUCESS, extendblock = 0, i, trytimes; + + if (hdmi == NULL) + return; + + DBG("%s", __func__); + + pedid = &(hdmi->edid); + fb_destroy_modelist(&pedid->modelist); + memset(pedid, 0, sizeof(struct hdmi_edid)); + INIT_LIST_HEAD(&pedid->modelist); + + buff = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL); + if (buff == NULL) { + dev_err(hdmi->dev, + "[%s] can not allocate memory for edid buff.\n", + __func__); + rc = HDMI_ERROR_FALSE; + goto out; + } + + if (hdmi->ops->getedid == NULL) { + rc = HDMI_ERROR_FALSE; + goto out; + } + + /* Read base block edid.*/ + for (trytimes = 0; trytimes < 3; trytimes++) { + if (trytimes) + msleep(50); + memset(buff, 0 , HDMI_EDID_BLOCK_SIZE); + rc = hdmi->ops->getedid(hdmi, 0, buff); + if (rc) { + dev_err(hdmi->dev, + "[HDMI] read edid base block error\n"); + continue; + } + + rc = hdmi_edid_parse_base(buff, &extendblock, pedid); + if (rc) { + dev_err(hdmi->dev, + "[HDMI] parse edid base block error\n"); + continue; + } + if (!rc) + break; + } + if (rc) + goto out; + + for (i = 1; i < extendblock + 1; i++) { + for (trytimes = 0; trytimes < 3; trytimes++) { + if (trytimes) + msleep(20); + memset(buff, 0 , HDMI_EDID_BLOCK_SIZE); + rc = hdmi->ops->getedid(hdmi, i, buff); + if (rc) { + dev_err(hdmi->dev, + "[HDMI] read edid block %d error\n", + i); + continue; + } + + rc = hdmi_edid_parse_extensions(buff, pedid); + if (rc) { + dev_err(hdmi->dev, + "[HDMI] parse edid block %d error\n", + i); + continue; + } + + if (!rc) + break; + } + } +out: + kfree(buff); + rc = hdmi_ouputmode_select(hdmi, rc); +} + +static void hdmi_wq_insert(struct hdmi *hdmi) +{ + DBG("%s", __func__); + if (hdmi->ops->insert) + hdmi->ops->insert(hdmi); + hdmi_wq_parse_edid(hdmi); + if (hdmi->property->feature & SUPPORT_CEC) + rockchip_hdmi_cec_set_pa(hdmi->edid.cecaddress); + hdmi_send_uevent(hdmi, KOBJ_ADD); + if (hdmi->enable) { + hdmi->autoset = 0; + hdmi_set_lcdc(hdmi); + hdmi_wq_set_video(hdmi); + #ifdef CONFIG_SWITCH + if ((hdmi->edid.baseaudio_support && + hdmi->edid.sink_hdmi) || + rk_fb_get_display_policy() == DISPLAY_POLICY_BOX) + switch_set_state(&(hdmi->switchdev), 1); + #endif + hdmi_wq_set_audio(hdmi); + hdmi_wq_set_output(hdmi, hdmi->mute); + if (hdmi->ops->hdcp_cb) + hdmi->ops->hdcp_cb(hdmi); + if (hdmi->ops->setcec) + hdmi->ops->setcec(hdmi); + } + if (hdmi->uboot) + hdmi->uboot = 0; +} + +static void hdmi_wq_remove(struct hdmi *hdmi) +{ + struct list_head *pos, *n; + struct rk_screen screen; + + DBG("%s", __func__); + if (hdmi->ops->remove) + hdmi->ops->remove(hdmi); + + list_for_each_safe(pos, n, &hdmi->edid.modelist) { + list_del(pos); + kfree(pos); + } + + kfree(hdmi->edid.audio); + + if (hdmi->edid.specs) { + kfree(hdmi->edid.specs->modedb); + kfree(hdmi->edid.specs); + } + memset(&hdmi->edid, 0, sizeof(struct hdmi_edid)); + hdmi_init_modelist(hdmi); + hdmi->mute = HDMI_AV_UNMUTE; + hdmi->mode_3d = HDMI_3D_NONE; + hdmi->uboot = 0; + if (hdmi->hotplug == HDMI_HPD_ACTIVED) { + screen.type = SCREEN_HDMI; + rk_fb_switch_screen(&screen, 0, hdmi->lcdc->id); + } + hdmi->hotplug = HDMI_HPD_REMOVED; + hdmi_send_uevent(hdmi, KOBJ_REMOVE); + #ifdef CONFIG_SWITCH + if ((hdmi->edid.baseaudio_support && + hdmi->edid.sink_hdmi) || + rk_fb_get_display_policy() == DISPLAY_POLICY_BOX) + switch_set_state(&(hdmi->switchdev), 0); + #endif +} + +static void hdmi_work_queue(struct work_struct *work) +{ + struct hdmi_delayed_work *hdmi_w = + container_of(work, struct hdmi_delayed_work, work.work); + struct hdmi *hdmi = hdmi_w->hdmi; + int event = hdmi_w->event; + int hpd = HDMI_HPD_REMOVED; + + mutex_lock(&hdmi->lock); + + DBG("\nhdmi_work_queue() - evt= %x %d\n", + (event & 0xFF00) >> 8, + event & 0xFF); + + switch (event) { + case HDMI_ENABLE_CTL: + if (!hdmi->enable) { + hdmi->enable = 1; + if (!hdmi->sleep) { + if (hdmi->ops->enable) + hdmi->ops->enable(hdmi); + if (hdmi->hotplug == HDMI_HPD_ACTIVED) + hdmi_wq_insert(hdmi); + } + } + break; + case HDMI_RESUME_CTL: + if (hdmi->sleep) { + if (hdmi->ops->enable) + hdmi->ops->enable(hdmi); + hdmi->sleep = 0; + } + break; + case HDMI_DISABLE_CTL: + if (hdmi->enable) { + if (!hdmi->sleep) { + /* + if (hdmi->ops->disable) + hdmi->ops->disable(hdmi); + */ + hdmi_wq_remove(hdmi); + } + hdmi->enable = 0; + } + break; + case HDMI_SUSPEND_CTL: + if (!hdmi->sleep) { + hdmi_wq_set_output(hdmi, + HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE); + if (hdmi->ops->disable) + hdmi->ops->disable(hdmi); + if (hdmi->enable) + hdmi_wq_remove(hdmi); + hdmi->sleep = 1; + } + break; + case HDMI_HPD_CHANGE: + if (hdmi->ops->getstatus) + hpd = hdmi->ops->getstatus(hdmi); + DBG("hdmi_work_queue() - hpd is %d hotplug is %d", + hpd, hdmi->hotplug); + if (hpd != hdmi->hotplug) { + if (hpd == HDMI_HPD_ACTIVED) { + hdmi->hotplug = hpd; + hdmi_wq_insert(hdmi); + } else if (hdmi->hotplug == HDMI_HPD_ACTIVED) { + hdmi_wq_remove(hdmi); + } + hdmi->hotplug = hpd; + } + break; + case HDMI_SET_VIDEO: + if (hdmi->enable && !hdmi->sleep) { + hdmi_wq_set_output(hdmi, + HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE); + if (rk_fb_get_display_policy() == DISPLAY_POLICY_BOX) + msleep(2000); + else + msleep(1000); + hdmi_set_lcdc(hdmi); + hdmi_send_uevent(hdmi, KOBJ_CHANGE); + hdmi_wq_set_video(hdmi); + hdmi_wq_set_audio(hdmi); + hdmi_wq_set_output(hdmi, hdmi->mute); + if (hdmi->ops->hdcp_cb) + hdmi->ops->hdcp_cb(hdmi); + } + break; + case HDMI_SET_AUDIO: + if ((hdmi->mute & HDMI_AUDIO_MUTE) == 0 && + hdmi->enable && !hdmi->sleep) { + hdmi_wq_set_output(hdmi, HDMI_AUDIO_MUTE); + hdmi_wq_set_audio(hdmi); + hdmi_wq_set_output(hdmi, hdmi->mute); + } + break; + case HDMI_MUTE_AUDIO: + case HDMI_UNMUTE_AUDIO: + if (hdmi->mute & HDMI_AUDIO_MUTE || + !hdmi->enable || hdmi->sleep || + hdmi->hotplug != HDMI_HPD_ACTIVED) + break; + if (event == HDMI_MUTE_AUDIO) + hdmi_wq_set_output(hdmi, hdmi->mute | + HDMI_AUDIO_MUTE); + else + hdmi_wq_set_output(hdmi, + hdmi->mute & (~HDMI_AUDIO_MUTE)); + break; + case HDMI_SET_3D: + if (hdmi->ops->setvsi) { + if (hdmi->mode_3d != HDMI_3D_NONE) + hdmi->ops->setvsi(hdmi, hdmi->mode_3d, + HDMI_VIDEO_FORMAT_3D); + else if ((hdmi->vic & HDMI_TYPE_MASK) == 0) + hdmi->ops->setvsi(hdmi, hdmi->vic, + HDMI_VIDEO_FORMAT_NORMAL); + } + break; + case HDMI_SET_COLOR: + hdmi_wq_set_output(hdmi, + HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE); + msleep(100); + hdmi_wq_set_video(hdmi); + hdmi_wq_set_output(hdmi, hdmi->mute); + break; + case HDMI_ENABLE_HDCP: + if (hdmi->hotplug == HDMI_HPD_ACTIVED && hdmi->ops->hdcp_cb) + hdmi->ops->hdcp_cb(hdmi); + break; + default: + pr_err("HDMI: hdmi_work_queue() unkown event\n"); + break; + } + + kfree(hdmi_w->data); + kfree(hdmi_w); + + DBG("\nhdmi_work_queue() - exit evt= %x %d\n", + (event & 0xFF00) >> 8, + event & 0xFF); + mutex_unlock(&hdmi->lock); +} + +struct hdmi *rockchip_hdmi_register(struct hdmi_property *property, + struct hdmi_ops *ops) +{ + struct hdmi *hdmi; + char name[32]; + int i; + + if (property == NULL || ops == NULL) { + pr_err("HDMI: %s invalid parameter\n", __func__); + return NULL; + } + + for (i = 0; i < HDMI_MAX_ID; i++) { + if (ref_info[i].ref == 0) + break; + } + if (i == HDMI_MAX_ID) + return NULL; + + DBG("hdmi_register() - video source %d display %d", + property->videosrc, property->display); + + hdmi = kmalloc(sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) { + pr_err("HDMI: no memory to allocate hdmi device.\n"); + return NULL; + } + memset(hdmi, 0, sizeof(struct hdmi)); + mutex_init(&hdmi->lock); + + hdmi->property = property; + hdmi->ops = ops; + hdmi->enable = false; + hdmi->mute = HDMI_AV_UNMUTE; + hdmi->hotplug = HDMI_HPD_REMOVED; + hdmi->autoset = HDMI_AUTO_CONFIG; + if (uboot_vic > 0) { + hdmi->vic = uboot_vic; + hdmi->uboot = 1; + hdmi->autoset = 0; + } else if (hdmi->autoset) { + hdmi->vic = 0; + } else { + hdmi->vic = HDMI_VIDEO_DEFAULT_MODE; + } + hdmi->colormode = HDMI_VIDEO_DEFAULT_COLORMODE; + hdmi->colordepth = HDMI_DEPP_COLOR_AUTO; + hdmi->mode_3d = HDMI_3D_NONE; + hdmi->audio.type = HDMI_AUDIO_DEFAULT_TYPE; + hdmi->audio.channel = HDMI_AUDIO_DEFAULT_CHANNEL; + hdmi->audio.rate = HDMI_AUDIO_DEFAULT_RATE; + hdmi->audio.word_length = HDMI_AUDIO_DEFAULT_WORDLENGTH; + hdmi->xscale = 100; + hdmi->yscale = 100; + hdmi_init_modelist(hdmi); + +#ifndef CONFIG_ARCH_RK29 + if (hdmi->property->videosrc == DISPLAY_SOURCE_LCDC0) + hdmi->lcdc = rk_get_lcdc_drv("lcdc0"); + else + hdmi->lcdc = rk_get_lcdc_drv("lcdc1"); +#endif + memset(name, 0, 32); + sprintf(name, "hdmi-%s", hdmi->property->name); + hdmi->workqueue = create_singlethread_workqueue(name); + if (hdmi->workqueue == NULL) { + pr_err("HDMI,: create workqueue failed.\n"); + goto err_create_wq; + } + hdmi->ddev = hdmi_register_display_sysfs(hdmi, NULL); + if (hdmi->ddev == NULL) { + pr_err("HDMI : register display sysfs failed.\n"); + goto err_register_display; + } + hdmi->id = i; + #ifdef CONFIG_SWITCH + if (hdmi->id == 0) { + hdmi->switchdev.name = "hdmi"; + } else { + hdmi->switchdev.name = kzalloc(32, GFP_KERNEL); + memset((char *)hdmi->switchdev.name, 0, 32); + sprintf((char *)hdmi->switchdev.name, "hdmi%d", hdmi->id); + } + switch_dev_register(&(hdmi->switchdev)); + #endif + + ref_info[i].hdmi = hdmi; + ref_info[i].ref = 1; + return hdmi; + +err_register_display: + destroy_workqueue(hdmi->workqueue); +err_create_wq: + kfree(hdmi); + return NULL; +} + +void rockchip_hdmi_unregister(struct hdmi *hdmi) +{ + if (hdmi) { + flush_workqueue(hdmi->workqueue); + destroy_workqueue(hdmi->workqueue); + #ifdef CONFIG_SWITCH + switch_dev_unregister(&(hdmi->switchdev)); + #endif + hdmi_unregister_display_sysfs(hdmi); + fb_destroy_modelist(&hdmi->edid.modelist); + kfree(hdmi->edid.audio); + if (hdmi->edid.specs) { + kfree(hdmi->edid.specs->modedb); + kfree(hdmi->edid.specs); + } + kfree(hdmi); + + ref_info[hdmi->id].ref = 0; + ref_info[hdmi->id].hdmi = NULL; + + hdmi = NULL; + } +} + +int hdmi_get_hotplug(void) +{ + if (ref_info[0].hdmi) + return ref_info[0].hdmi->hotplug; + else + return HDMI_HPD_REMOVED; +} + +int hdmi_config_audio(struct hdmi_audio *audio) +{ + int i; + struct hdmi *hdmi; + + if (audio == NULL) + return HDMI_ERROR_FALSE; + + for (i = 0; i < HDMI_MAX_ID; i++) { + if (ref_info[i].ref == 0) + continue; + hdmi = ref_info[i].hdmi; + + /* + if (memcmp(audio, &hdmi->audio, sizeof(struct hdmi_audio)) == 0) + continue; + */ + /*for (j = 0; j < hdmi->edid.audio_num; j++) { + if (audio->type == hdmi->edid.audio_num) + break; + }*/ + + /*if ( (j == hdmi->edid.audio_num) || + (audio->channel > hdmi->edid.audio[j].channel) || + ((audio->rate & hdmi->edid.audio[j].rate) == 0)|| + ((audio->type == HDMI_AUDIO_LPCM) && + ((audio->word_length & + hdmi->edid.audio[j].word_length) == 0)) ) { + pr_warn("[%s] warning : input audio type + not supported in hdmi sink\n", __func__); + continue; + }*/ + memcpy(&hdmi->audio, audio, sizeof(struct hdmi_audio)); + hdmi_submit_work(hdmi, HDMI_SET_AUDIO, 0, NULL); + } + return 0; +} + +void hdmi_audio_mute(int mute) +{ + int i; + struct hdmi *hdmi; + + for (i = 0; i < HDMI_MAX_ID; i++) { + if (ref_info[i].ref == 0) + continue; + hdmi = ref_info[i].hdmi; + + if (mute) + hdmi_submit_work(hdmi, HDMI_MUTE_AUDIO, 0, NULL); + else + hdmi_submit_work(hdmi, HDMI_UNMUTE_AUDIO, 0, NULL); + } +} + +static int __init bootloader_setup(char *str) +{ + if (str) { + pr_info("hdmi init vic is %s\n", str); + if (kstrtoint(str, 0, &uboot_vic) < 0) + uboot_vic = 0; + } + return 0; +} + +early_param("hdmi.vic", bootloader_setup); + +static int __init hdmi_class_init(void) +{ + int i; + + for (i = 0; i < HDMI_MAX_ID; i++) { + ref_info[i].id = i; + ref_info[i].ref = 0; + ref_info[i].hdmi = NULL; + } + pr_info("Rockchip hdmi driver version 2.0\n."); + return 0; +} + +subsys_initcall(hdmi_class_init); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-edid.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-edid.c new file mode 100644 index 000000000000..f4541edffebd --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-edid.c @@ -0,0 +1,531 @@ +#include "rockchip-hdmi.h" +#include "../../edid.h" + +#ifdef EDIDDEBUG +#define EDBG DBG +#else +#define EDBG(format, ...) +#endif + +enum { + E_HDMI_EDID_SUCCESS = 0, + E_HDMI_EDID_PARAM, + E_HDMI_EDID_HEAD, + E_HDMI_EDID_CHECKSUM, + E_HDMI_EDID_VERSION, + E_HDMI_EDID_UNKOWNDATA, + E_HDMI_EDID_NOMEMORY +}; + +static int hdmi_edid_checksum(unsigned char *buf) +{ + int i; + int checksum = 0; + + for (i = 0; i < HDMI_EDID_BLOCK_SIZE; i++) + checksum += buf[i]; + + checksum &= 0xff; + + if (checksum == 0) + return E_HDMI_EDID_SUCCESS; + else + return E_HDMI_EDID_CHECKSUM; +} + +/* + @Des Parse Detail Timing Descriptor. + @Param buf : pointer to DTD data. + @Param pvic: VIC of DTD descripted. + */ +static int hdmi_edid_parse_dtd(unsigned char *block, struct fb_videomode *mode) +{ + mode->xres = H_ACTIVE; + mode->yres = V_ACTIVE; + mode->pixclock = PIXEL_CLOCK; +/* mode->pixclock /= 1000; + mode->pixclock = KHZ2PICOS(mode->pixclock); +*/ mode->right_margin = H_SYNC_OFFSET; + mode->left_margin = (H_ACTIVE + H_BLANKING) - + (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); + mode->upper_margin = V_BLANKING - V_SYNC_OFFSET - + V_SYNC_WIDTH; + mode->lower_margin = V_SYNC_OFFSET; + mode->hsync_len = H_SYNC_WIDTH; + mode->vsync_len = V_SYNC_WIDTH; + if (HSYNC_POSITIVE) + mode->sync |= FB_SYNC_HOR_HIGH_ACT; + if (VSYNC_POSITIVE) + mode->sync |= FB_SYNC_VERT_HIGH_ACT; + mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) * + (V_ACTIVE + V_BLANKING)); + if (INTERLACED) { + mode->yres *= 2; + mode->upper_margin *= 2; + mode->lower_margin *= 2; + mode->vsync_len *= 2; + mode->vmode |= FB_VMODE_INTERLACED; + } + mode->flag = FB_MODE_IS_DETAILED; + + EDBG("<<<<<<<>>>>>>>>\n"); + EDBG("%d KHz Refresh %d Hz", + PIXEL_CLOCK/1000, mode->refresh); + EDBG("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET, + H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING); + EDBG("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET, + V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING); + EDBG("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-", + (VSYNC_POSITIVE) ? "+" : "-"); + return E_HDMI_EDID_SUCCESS; +} + +int hdmi_edid_parse_base(unsigned char *buf, + int *extend_num, struct hdmi_edid *pedid) +{ + int rc; + + if (buf == NULL || extend_num == NULL) + return E_HDMI_EDID_PARAM; + + /* Check first 8 byte to ensure it is an edid base block. */ + if (buf[0] != 0x00 || + buf[1] != 0xFF || + buf[2] != 0xFF || + buf[3] != 0xFF || + buf[4] != 0xFF || + buf[5] != 0xFF || + buf[6] != 0xFF || + buf[7] != 0x00) { + pr_err("[EDID] check header error\n"); + return E_HDMI_EDID_HEAD; + } + + *extend_num = buf[0x7e]; + #ifdef DEBUG + EDBG("[EDID] extend block num is %d\n", buf[0x7e]); + #endif + + /* Checksum */ + rc = hdmi_edid_checksum(buf); + if (rc != E_HDMI_EDID_SUCCESS) { + pr_err("[EDID] base block checksum error\n"); + return E_HDMI_EDID_CHECKSUM; + } + + pedid->specs = kzalloc(sizeof(*pedid->specs), GFP_KERNEL); + if (pedid->specs == NULL) + return E_HDMI_EDID_NOMEMORY; + + fb_edid_to_monspecs(buf, pedid->specs); + + return E_HDMI_EDID_SUCCESS; +} + +/* Parse CEA Short Video Descriptor */ +static int hdmi_edid_get_cea_svd(unsigned char *buf, struct hdmi_edid *pedid) +{ + int count, i, vic; + + count = buf[0] & 0x1F; + for (i = 0; i < count; i++) { + EDBG("[CEA] %02x VID %d native %d\n", + buf[1 + i], buf[1 + i] & 0x7f, buf[1 + i] >> 7); + vic = buf[1 + i] & 0x7f; + hdmi_add_vic(vic, &pedid->modelist); + } +/* + struct list_head *pos; + struct display_modelist *modelist; + + list_for_each(pos, &pedid->modelist) { + modelist = list_entry(pos, struct display_modelist, list); + pr_info("%s vic %d\n", __FUNCTION__, modelist->vic); + } +*/ return 0; +} + +/* Parse CEA Short Audio Descriptor */ +static int hdmi_edid_parse_cea_sad(unsigned char *buf, struct hdmi_edid *pedid) +{ + int i, count; + + count = buf[0] & 0x1F; + pedid->audio = kmalloc((count/3)*sizeof(struct hdmi_audio), GFP_KERNEL); + if (pedid->audio == NULL) + return E_HDMI_EDID_NOMEMORY; + + pedid->audio_num = count/3; + for (i = 0; i < pedid->audio_num; i++) { + pedid->audio[i].type = (buf[1 + i*3] >> 3) & 0x0F; + pedid->audio[i].channel = (buf[1 + i*3] & 0x07) + 1; + pedid->audio[i].rate = buf[1 + i*3 + 1]; + if (pedid->audio[i].type == HDMI_AUDIO_LPCM) + pedid->audio[i].word_length = buf[1 + i*3 + 2]; + +/* pr_info("type %d channel %d rate %d word length %d\n", + pedid->audio[i].type, pedid->audio[i].channel, + pedid->audio[i].rate, pedid->audio[i].word_length); +*/ } + return E_HDMI_EDID_SUCCESS; +} + +static int hdmi_edid_parse_3dinfo(unsigned char *buf, struct list_head *head) +{ + int i, j, len = 0, format_3d, vic_mask; + unsigned char offset = 2, vic_2d, structure_3d; + struct list_head *pos; + struct display_modelist *modelist; + + if (buf[1] & 0xe0) { + len = (buf[1] & 0xe0) >> 5; + for (i = 0; i < len; i++) { + if (buf[offset]) + hdmi_add_vic((96 - buf[offset++]), head); + } + } + + if (buf[0] & 0x80) { + /* 3d supported */ + len += (buf[1] & 0x1F) + 2; + if (((buf[0] & 0x60) == 0x40) || ((buf[0] & 0x60) == 0x20)) { + format_3d = buf[offset++] << 8; + format_3d |= buf[offset++]; + if ((buf[0] & 0x60) == 0x20) { + vic_mask = 0xFFFF; + } else { + vic_mask = buf[offset++] << 8; + vic_mask |= buf[offset++]; + } + } else { + format_3d = 0; + vic_mask = 0; + } + + for (i = 0; i < 16; i++) { + if (vic_mask & (1 << i)) { + j = 0; + for (pos = (head)->next; pos != (head); + pos = pos->next) { + if (j++ == i) { + modelist = + list_entry(pos, struct display_modelist, list); + modelist->format_3d = format_3d; + break; + } + } + } + } + while (offset < len) { + vic_2d = (buf[offset] & 0xF0) >> 4; + structure_3d = (buf[offset++] & 0x0F); + j = 0; + for (pos = (head)->next; pos != (head); + pos = pos->next) { + j++; + if (j == vic_2d) { + modelist = + list_entry(pos, struct display_modelist, list); + modelist->format_3d |= + (1 << structure_3d); + if (structure_3d & 0x08) + modelist->detail_3d = + (buf[offset++] & 0xF0) >> 4; + break; + } + } + } + /* mandatory formats */ + for (pos = (head)->next; pos != (head); pos = pos->next) { + modelist = list_entry(pos, + struct display_modelist, + list); + if (modelist->vic == HDMI_1920X1080P_24HZ || + modelist->vic == HDMI_1280X720P_60HZ || + modelist->vic == HDMI_1280X720P_50HZ) { + modelist->format_3d |= + (1 << HDMI_3D_FRAME_PACKING) | + (1 << HDMI_3D_TOP_BOOTOM); + } else if (modelist->vic == HDMI_1920X1080I_60HZ || + modelist->vic == HDMI_1920X1080I_50HZ) { + modelist->format_3d |= + (1 << HDMI_3D_SIDE_BY_SIDE_HALF); + } + } + } + + return 0; +} +static int hdmi_edmi_parse_vsdb(unsigned char *buf, struct hdmi_edid *pedid, + int cur_offset, int IEEEOUI) +{ + int count, buf_offset; + + count = buf[cur_offset] & 0x1F; + switch (IEEEOUI) { + case 0x0c03: + pedid->sink_hdmi = 1; + pedid->cecaddress = buf[cur_offset + 5]; + pedid->cecaddress |= buf[cur_offset + 4] << 8; + EDBG("[CEA] CEC Physical addres is 0x%08x.\n", + pedid->cecaddress); + if (count > 6) + pedid->deepcolor = (buf[cur_offset + 6] >> 3) & 0x0F; + if (count > 7) { + pedid->maxtmdsclock = buf[cur_offset + 7] * 5000000; + EDBG("[CEA] maxtmdsclock is %d.\n", + pedid->maxtmdsclock); + } + if (count > 8) { + pedid->fields_present = buf[cur_offset + 8]; + EDBG("[CEA] fields_present is 0x%02x.\n", + pedid->fields_present); + } + buf_offset = cur_offset + 9; + if (pedid->fields_present & 0x80) { + pedid->video_latency = buf[buf_offset++]; + pedid->audio_latency = buf[buf_offset++]; + } + if (pedid->fields_present & 0x40) { + pedid->interlaced_video_latency = buf[buf_offset++]; + pedid->interlaced_audio_latency = buf[buf_offset++]; + } + if (pedid->fields_present & 0x20) { + hdmi_edid_parse_3dinfo(buf + buf_offset, + &pedid->modelist); + } + break; + case 0xc45dd8: + pedid->sink_hdmi = 1; + if (count > 4) + pedid->hf_vsdb_version = buf[cur_offset + 4]; + switch (pedid->hf_vsdb_version) { + case 1:/*compliant with HDMI Specification 2.0*/ + if (count > 5) { + pedid->maxtmdsclock = + buf[cur_offset + 5] * 5000000; + EDBG("[CEA] maxtmdsclock is %d.\n", + pedid->maxtmdsclock); + } + if (count > 6) { + pedid->scdc_present = buf[cur_offset+6] >> 7; + pedid->rr_capable = + (buf[cur_offset+6]&0x40) >> 6; + pedid->lte_340mcsc_scramble = + (buf[cur_offset+6]&0x08) >> 3; + pedid->independent_view = + (buf[cur_offset+6]&0x04) >> 2; + pedid->dual_view = + (buf[cur_offset+6]&0x02) >> 1; + pedid->osd_disparity_3d = + buf[cur_offset+6] & 0x01; + } + if (count > 7) { + pedid->deepcolor = buf[cur_offset+7]&0x7; + EDBG("[CEA] deepcolor is %d.\n", + pedid->deepcolor); + } + break; + default: + pr_info("hf_vsdb_version = %d\n", + pedid->hf_vsdb_version); + break; + } + break; + default: + pr_info("IEEOUT = 0x%x\n", IEEEOUI); + break; + } + return 0; +} + +static void hdmi_edid_parse_yuv420cmdb(unsigned char *buf, int count, + struct list_head *head) +{ + struct list_head *pos; + struct display_modelist *modelist; + int i, j, yuv420_mask, vic; + + for (i = 0; i < count - 1; i++) { + EDBG("vic which support yuv420 mode is %x\n", buf[i]); + yuv420_mask |= buf[i] << (8 * i); + } + for (i = 0; i < 32; i++) { + if (yuv420_mask & (1 << i)) { + j = 0; + for (pos = head->next; pos != (head); pos = pos->next) { + if (j++ == i) { + modelist = + list_entry(pos, struct display_modelist, list); + vic = modelist->vic | + HDMI_VIDEO_YUV420; + hdmi_add_vic(vic, head); + break; + } + } + } + } +} + +/* Parse CEA 861 Serial Extension. */ +static int hdmi_edid_parse_extensions_cea(unsigned char *buf, + struct hdmi_edid *pedid) +{ + unsigned int ddc_offset, native_dtd_num, cur_offset = 4; + unsigned int tag, IEEEOUI = 0, count, i; +/* unsigned int underscan_support, baseaudio_support; */ + + if (buf == NULL) + return E_HDMI_EDID_PARAM; + + /* Check ces extension version */ + if (buf[1] != 3) { + pr_err("[CEA] error version.\n"); + return E_HDMI_EDID_VERSION; + } + + ddc_offset = buf[2]; +/* underscan_support = (buf[3] >> 7) & 0x01; +*/ pedid->baseaudio_support = (buf[3] >> 6) & 0x01; + pedid->ycbcr444 = (buf[3] >> 5) & 0x01; + pedid->ycbcr422 = (buf[3] >> 4) & 0x01; + native_dtd_num = buf[3] & 0x0F; +/* EDBG("[CEA] ddc_offset %d underscan_support %d + baseaudio_support %d yuv_support %d + native_dtd_num %d\n", + ddc_offset, underscan_support, baseaudio_support, + yuv_support, native_dtd_num); +*/ /* Parse data block */ + while (cur_offset < ddc_offset) { + tag = buf[cur_offset] >> 5; + count = buf[cur_offset] & 0x1F; + switch (tag) { + case 0x02: /* Video Data Block */ + EDBG("[CEA] Video Data Block.\n"); + hdmi_edid_get_cea_svd(buf + cur_offset, pedid); + break; + case 0x01: /* Audio Data Block */ + EDBG("[CEA] Audio Data Block.\n"); + hdmi_edid_parse_cea_sad(buf + cur_offset, pedid); + break; + case 0x04: /* Speaker Allocation Data Block */ + EDBG("[CEA] Speaker Allocatio Data Block.\n"); + break; + case 0x03: /* Vendor Specific Data Block */ + EDBG("[CEA] Vendor Specific Data Block.\n"); + + IEEEOUI = buf[cur_offset + 3]; + IEEEOUI <<= 8; + IEEEOUI += buf[cur_offset + 2]; + IEEEOUI <<= 8; + IEEEOUI += buf[cur_offset + 1]; + EDBG("[CEA] IEEEOUI is 0x%08x.\n", IEEEOUI); + + hdmi_edmi_parse_vsdb(buf, pedid, + cur_offset, IEEEOUI); + break; + case 0x05: /* VESA DTC Data Block */ + EDBG("[CEA] VESA DTC Data Block.\n"); + break; + case 0x07: /* Use Extended Tag */ + EDBG("[CEA] Use Extended Tag Data Block %02x.\n", + buf[cur_offset + 1]); + switch (buf[cur_offset + 1]) { + case 0x00: + EDBG("[CEA] Video Capability Data Block\n"); + EDBG("value is %02x\n", buf[cur_offset + 2]); + break; + case 0x05: + EDBG("[CEA] Colorimetry Data Block\n"); + EDBG("value is %02x\n", buf[cur_offset + 2]); + break; + case 0x0e: + EDBG("[CEA] YCBCR 4:2:0 Video Data Block\n"); + for (i = 0; i < count - 1; i++) { + EDBG("mode is %d\n", + buf[cur_offset + 2 + i]); + pedid->ycbcr420 = 1; + IEEEOUI = buf[cur_offset + 2 + i] | + HDMI_VIDEO_YUV420; + hdmi_add_vic(IEEEOUI, + &pedid->modelist); + } + break; + case 0x0f: + EDBG("[CEA] YCBCR 4:2:0 Capability Map Data\n"); + hdmi_edid_parse_yuv420cmdb(&buf[cur_offset+2], + count, + &pedid->modelist); + pedid->ycbcr420 = 1; + break; + } + break; + default: + pr_err("[CEA] unkowned data block tag.\n"); + break; + } + cur_offset += (buf[cur_offset] & 0x1F) + 1; + } +#if 1 +{ + /* Parse DTD */ + struct fb_videomode *vmode = + kmalloc(sizeof(struct fb_videomode), GFP_KERNEL); + + if (vmode == NULL) + return E_HDMI_EDID_SUCCESS; + while (ddc_offset < HDMI_EDID_BLOCK_SIZE - 2) { + if (!buf[ddc_offset] && !buf[ddc_offset + 1]) + break; + memset(vmode, 0, sizeof(struct fb_videomode)); + hdmi_edid_parse_dtd(buf + ddc_offset, vmode); + hdmi_add_vic(hdmi_videomode_to_vic(vmode), &pedid->modelist); + ddc_offset += 18; + } + kfree(vmode); +} +#endif + return E_HDMI_EDID_SUCCESS; +} + +int hdmi_edid_parse_extensions(unsigned char *buf, struct hdmi_edid *pedid) +{ + int rc; + + if (buf == NULL || pedid == NULL) + return E_HDMI_EDID_PARAM; + + /* Checksum */ + rc = hdmi_edid_checksum(buf); + if (rc != E_HDMI_EDID_SUCCESS) { + pr_err("[EDID] extensions block checksum error\n"); + return E_HDMI_EDID_CHECKSUM; + } + + switch (buf[0]) { + case 0xF0: + EDBG("[EDID-EXTEND] Iextensions block map.\n"); + break; + case 0x02: + EDBG("[EDID-EXTEND] CEA 861 Series Extension.\n"); + hdmi_edid_parse_extensions_cea(buf, pedid); + break; + case 0x10: + EDBG("[EDID-EXTEND] Video Timing Block Extension.\n"); + break; + case 0x40: + EDBG("[EDID-EXTEND] Display Information Extension.\n"); + break; + case 0x50: + EDBG("[EDID-EXTEND] Localized String Extension.\n"); + break; + case 0x60: + EDBG("[EDID-EXTEND] Digital Packet Video Link Extension.\n"); + break; + default: + pr_err("[EDID-EXTEND] Unkowned Extension.\n"); + return E_HDMI_EDID_UNKOWNDATA; + } + + return E_HDMI_EDID_SUCCESS; +} diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c new file mode 100644 index 000000000000..26576eb44623 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c @@ -0,0 +1,691 @@ +#include "rockchip-hdmi.h" + +static const struct hdmi_video_timing hdmi_mode[] = { +/* name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag vic 2ndvic pixelrepeat interface */ + + { { "720x480i@60Hz", 60, 720, 480, 27000000, 57, 19, 15, 4, 62, 3, 0, 1, 0 }, 6, HDMI_720X480I_60HZ_16_9, 2, OUT_P888}, + { { "720x576i@50Hz", 50, 720, 576, 27000000, 69, 12, 19, 2, 63, 3, 0, 1, 0 }, 21, HDMI_720X576I_50HZ_16_9, 2, OUT_P888}, + { { "720x480p@60Hz", 60, 720, 480, 27000000, 60, 16, 30, 9, 62, 6, 0, 0, 0 }, 2, HDMI_720X480P_60HZ_16_9, 1, OUT_P888}, + { { "720x576p@50Hz", 50, 720, 576, 27000000, 68, 12, 39, 5, 64, 5, 0, 0, 0 }, 17, HDMI_720X576P_50HZ_16_9, 1, OUT_P888}, + { { "1280x720p@24Hz", 24, 1280, 720, 59400000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 60, HDMI_1280X720P_24HZ_4_3, 1, OUT_P888}, + { { "1280x720p@25Hz", 25, 1280, 720, 74250000, 220, 2420, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 61, HDMI_1280X720P_25HZ_4_3, 1, OUT_P888}, + { { "1280x720p@30Hz", 30, 1280, 720, 74250000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 62, HDMI_1280X720P_30HZ_4_3, 1, OUT_P888}, + { { "1280x720p@50Hz", 50, 1280, 720, 74250000, 220, 440, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 19, HDMI_1280X720P_50HZ_4_3, 1, OUT_P888}, + { { "1280x720p@60Hz", 60, 1280, 720, 74250000, 220, 110, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 4, HDMI_1280X720P_60HZ_4_3, 1, OUT_P888}, + { { "1920x1080i@50Hz", 50, 1920, 1080, 74250000, 148, 528, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 0 }, 20, 0, 1, OUT_P888}, + { { "1920x1080i@60Hz", 60, 1920, 1080, 74250000, 148, 88, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 0 }, 5, 0, 1, OUT_P888}, + { { "1920x1080p@24Hz", 24, 1920, 1080, 74250000, 148, 638, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 32, HDMI_1920X1080P_24HZ_4_3, 1, OUT_P888}, + { { "1920x1080p@25Hz", 25, 1920, 1080, 74250000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 33, HDMI_1920X1080P_25HZ_4_3, 1, OUT_P888}, + { { "1920x1080p@30Hz", 30, 1920, 1080, 74250000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 34, HDMI_1920X1080P_30HZ_4_3, 1, OUT_P888}, + { { "1920x1080p@50Hz", 50, 1920, 1080, 148500000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 31, HDMI_1920X1080P_50HZ_4_3, 1, OUT_P888}, + { { "1920x1080p@60Hz", 60, 1920, 1080, 148500000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 16, HDMI_1920X1080P_60HZ_4_3, 1, OUT_P888}, + { { "3840x2160p@24Hz", 24, 3840, 2160, 297000000, 296, 1276, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 93, HDMI_3840X2160P_24HZ_4_3, 1, OUT_P888}, + { { "3840x2160p@25Hz", 25, 3840, 2160, 297000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 94, HDMI_3840X2160P_25HZ_4_3, 1, OUT_P888}, + { { "3840x2160p@30Hz", 30, 3840, 2160, 297000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 95, HDMI_3840X2160P_30HZ_4_3, 1, OUT_P888}, + { { "4096x2160p@24Hz", 24, 4096, 2160, 297000000, 296, 1020, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 98, 0, 1, OUT_P888}, + { { "4096x2160p@25Hz", 25, 4096, 2160, 297000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 99, 0, 1, OUT_P888}, + { { "4096x2160p@30Hz", 30, 4096, 2160, 297000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 100, 0, 1, OUT_P888}, + { { "3840x2160p@50Hz", 50, 3840, 2160, 594000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 96, HDMI_3840X2160P_50HZ_4_3, 1, OUT_P888}, + { { "3840x2160p@60Hz", 60, 3840, 2160, 594000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 97, HDMI_3840X2160P_60HZ_4_3, 1, OUT_P888}, + { { "4096x2160p@50Hz", 50, 4096, 2160, 594000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 101, 0, 1, OUT_P888}, + { { "4096x2160p@60Hz", 60, 4096, 2160, 594000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 102, 0, 1, OUT_P888}, +}; + +static int hdmi_set_info(struct rk_screen *screen, struct hdmi *hdmi) +{ + int i; + struct fb_videomode *mode; + + if (screen == NULL || hdmi == NULL) + return HDMI_ERROR_FALSE; + + if (hdmi->vic == 0) + hdmi->vic = HDMI_VIDEO_DEFAULT_MODE; + + for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { + if (hdmi_mode[i].vic == (hdmi->vic & HDMI_VIC_MASK) || + hdmi_mode[i].vic_2nd == (hdmi->vic & HDMI_VIC_MASK)) + break; + } + if (i == ARRAY_SIZE(hdmi_mode)) + return HDMI_ERROR_FALSE; + + memset(screen, 0, sizeof(struct rk_screen)); + + /* screen type & face */ + screen->type = SCREEN_HDMI; + screen->color_mode = COLOR_YCBCR; + if (hdmi->vic & HDMI_VIDEO_YUV420) + screen->face = OUT_YUV_420; + else + screen->face = hdmi_mode[i].interface; + screen->pixelrepeat = hdmi_mode[i].pixelrepeat - 1; + mode = (struct fb_videomode *)&(hdmi_mode[i].mode); + + screen->mode = *mode; + + /* Pin polarity */ + #ifdef CONFIG_HDMI_RK616 + screen->pin_hsync = 0; + screen->pin_vsync = 0; + #else + if (FB_SYNC_HOR_HIGH_ACT & mode->sync) + screen->pin_hsync = 1; + else + screen->pin_hsync = 0; + if (FB_SYNC_VERT_HIGH_ACT & mode->sync) + screen->pin_vsync = 1; + else + screen->pin_vsync = 0; + #endif + screen->pin_den = 0; + screen->pin_dclk = 1; + + /* Swap rule */ + if (hdmi->soctype == HDMI_SOC_RK3368 && + screen->color_mode == COLOR_YCBCR && + screen->face == OUT_P888) + screen->swap_rb = 1; + else + screen->swap_rb = 0; + screen->swap_rg = 0; + screen->swap_gb = 0; + screen->swap_delta = 0; + screen->swap_dumy = 0; + + /* Operation function*/ + screen->init = NULL; + screen->standby = NULL; + + screen->overscan.left = hdmi->xscale; + screen->overscan.top = hdmi->yscale; + screen->overscan.right = hdmi->xscale; + screen->overscan.bottom = hdmi->yscale; + return 0; +} + +/** + * hdmi_find_best_mode: find the video mode nearest to input vic + * @hdmi: + * @vic: input vic + * + * NOTES: + * If vic is zero, return the high resolution video mode vic. + */ +int hdmi_find_best_mode(struct hdmi *hdmi, int vic) +{ + struct list_head *pos, *head = &hdmi->edid.modelist; + struct display_modelist *modelist; + int found = 0; +/* pr_info("%s vic %d\n", __FUNCTION__, vic); */ + if (vic) { + list_for_each(pos, head) { + modelist = + list_entry(pos, + struct display_modelist, list); + if (modelist->vic == vic) { + found = 1; + break; + } + } + } + if ((vic == 0 || found == 0) && head->next != head) { + /* If parse edid error, we select default mode; */ + if (hdmi->edid.specs == NULL || + hdmi->edid.specs->modedb_len == 0) + return HDMI_VIDEO_DEFAULT_MODE; + /*modelist = list_entry(head->prev, + struct display_modelist, list);*/ + else + modelist = list_entry(head->next, + struct display_modelist, list); + } + + if (modelist != NULL) + return modelist->vic; + else + return 0; +} +/** + * hdmi_set_lcdc: switch lcdc mode to required video mode + * @hdmi: + * + * NOTES: + * + */ +int hdmi_set_lcdc(struct hdmi *hdmi) +{ + int rc = 0; + struct rk_screen screen; + + if (hdmi->autoset) + hdmi->vic = hdmi_find_best_mode(hdmi, 0); + else + hdmi->vic = hdmi_find_best_mode(hdmi, hdmi->vic); + + if (hdmi->vic == 0) + hdmi->vic = HDMI_VIDEO_DEFAULT_MODE; + + rc = hdmi_set_info(&screen, hdmi); + + if (rc == 0) + rk_fb_switch_screen(&screen, 1, hdmi->lcdc->id); + + return rc; +} + +/** + * hdmi_videomode_compare - compare 2 videomodes + * @mode1: first videomode + * @mode2: second videomode + * + * RETURNS: + * 1 if mode1 > mode2, 0 if mode1 = mode2, -1 mode1 < mode2 + */ +static int hdmi_videomode_compare(const struct fb_videomode *mode1, + const struct fb_videomode *mode2) +{ + if (mode1->xres > mode2->xres) + return 1; + + if (mode1->xres == mode2->xres) { + if (mode1->yres > mode2->yres) + return 1; + if (mode1->yres == mode2->yres) { + if (mode1->vmode < mode2->vmode) + return 1; + if (mode1->pixclock > mode2->pixclock) + return 1; + if (mode1->pixclock == mode2->pixclock) { + if (mode1->refresh > mode2->refresh) + return 1; + if (mode1->refresh == mode2->refresh) { + if (mode2->flag > mode1->flag) + return 1; + if (mode2->flag < mode1->flag) + return -1; + if (mode2->vmode > mode1->vmode) + return 1; + if (mode2->vmode == mode1->vmode) + return 0; + } + } + } + } + return -1; +} + +/** + * hdmi_add_vic - add entry to modelist according vic + * @vic: vic to be added + * @head: struct list_head of modelist + * + * NOTES: + * Will only add unmatched mode entries + */ +int hdmi_add_vic(int vic, struct list_head *head) +{ + struct list_head *pos; + struct display_modelist *modelist; + int found = 0, v; + +/* DBG("%s vic %d", __FUNCTION__, vic); */ + if (vic == 0) + return -1; + + list_for_each(pos, head) { + modelist = list_entry(pos, struct display_modelist, list); + v = modelist->vic; + if (v == vic) { + found = 1; + break; + } + } + if (!found) { + modelist = kmalloc(sizeof(*modelist), + GFP_KERNEL); + + if (!modelist) + return -ENOMEM; + memset(modelist, 0, sizeof(struct display_modelist)); + modelist->vic = vic; + list_add_tail(&modelist->list, head); + } + return 0; +} + +/** + * hdmi_add_videomode: adds videomode entry to modelist + * @mode: videomode to be added + * @head: struct list_head of modelist + * + * NOTES: + * Will only add unmatched mode entries + */ +static int hdmi_add_videomode(const struct fb_videomode *mode, + struct list_head *head) +{ + struct list_head *pos; + struct display_modelist *modelist, *modelist_new; + struct fb_videomode *m; + int i, found = 0; + + for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { + m = (struct fb_videomode *)&(hdmi_mode[i].mode); + if (fb_mode_is_equal(m, mode)) { + found = 1; + break; + } + } + + if (found) { + list_for_each(pos, head) { + modelist = list_entry(pos, + struct display_modelist, list); + m = &modelist->mode; + if (fb_mode_is_equal(m, mode)) + return 0; + else if (hdmi_videomode_compare(m, mode) == -1) + break; + } + + modelist_new = kmalloc(sizeof(*modelist_new), GFP_KERNEL); + if (!modelist_new) + return -ENOMEM; + memset(modelist_new, 0, sizeof(struct display_modelist)); + modelist_new->mode = hdmi_mode[i].mode; + modelist_new->vic = hdmi_mode[i].vic; + list_add_tail(&modelist_new->list, pos); + } + + return 0; +} + +/** + * hdmi_show_sink_info: show hdmi sink device infomation + * @hdmi: handle of hdmi + */ +static void hdmi_show_sink_info(struct hdmi *hdmi) +{ + struct list_head *pos, *head = &hdmi->edid.modelist; + struct display_modelist *modelist; + struct fb_videomode *m; + int i; + struct hdmi_audio *audio; + + pr_info("******** Show Sink Info ********\n"); + pr_info("Max tmds clk is %u\n", hdmi->edid.maxtmdsclock); + if (hdmi->edid.hf_vsdb_version) + pr_info("Support HFVSDB\n"); + if (hdmi->edid.scdc_present) + pr_info("Support SCDC\n"); + pr_info("Support video mode:\n"); + list_for_each(pos, head) { + modelist = list_entry(pos, struct display_modelist, list); + m = &modelist->mode; + if (m->flag) + pr_info(" %s(YCbCr420)\n", m->name); + else + pr_info(" %s\n", m->name); + } + pr_info("Support video color mode:\n"); + pr_info(" RGB\n"); + if (hdmi->edid.ycbcr420) + pr_info(" YCbCr420\n"); + if (hdmi->edid.ycbcr422) + pr_info(" YCbCr422\n"); + if (hdmi->edid.ycbcr444) + pr_info(" YCbCr444\n"); + pr_info("Support video color depth:\n"); + pr_info(" 24bit\n"); + if (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_30BITS) + pr_info(" 30bit\n"); + if (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_36BITS) + pr_info(" 36bit\n"); + if (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_48BITS) + pr_info(" 48bit\n"); + + pr_info("Support audio type:\n"); + for (i = 0; i < hdmi->edid.audio_num; i++) { + audio = &(hdmi->edid.audio[i]); + switch (audio->type) { + case HDMI_AUDIO_LPCM: + pr_info(" LPCM\n"); + break; + case HDMI_AUDIO_AC3: + pr_info(" AC3\n"); + break; + case HDMI_AUDIO_MPEG1: + pr_info(" MPEG1\n"); + break; + case HDMI_AUDIO_MP3: + pr_info(" MP3\n"); + break; + case HDMI_AUDIO_MPEG2: + pr_info(" MPEG2\n"); + break; + case HDMI_AUDIO_AAC_LC: + pr_info("S AAC\n"); + break; + case HDMI_AUDIO_DTS: + pr_info(" DTS\n"); + break; + case HDMI_AUDIO_ATARC: + pr_info(" ATARC\n"); + break; + case HDMI_AUDIO_DSD: + pr_info(" DSD\n"); + break; + case HDMI_AUDIO_E_AC3: + pr_info(" E-AC3\n"); + break; + case HDMI_AUDIO_DTS_HD: + pr_info(" DTS-HD\n"); + break; + case HDMI_AUDIO_MLP: + pr_info(" MLP\n"); + break; + case HDMI_AUDIO_DST: + pr_info(" DST\n"); + break; + case HDMI_AUDIO_WMA_PRO: + pr_info(" WMP-PRO\n"); + break; + default: + pr_info(" Unkown\n"); + break; + } + pr_info("Support max audio channel is %d\n", audio->channel); + pr_info("Support audio sample rate:\n"); + if (audio->rate & HDMI_AUDIO_FS_32000) + pr_info(" 32000\n"); + if (audio->rate & HDMI_AUDIO_FS_44100) + pr_info(" 44100\n"); + if (audio->rate & HDMI_AUDIO_FS_48000) + pr_info(" 48000\n"); + if (audio->rate & HDMI_AUDIO_FS_88200) + pr_info(" 88200\n"); + if (audio->rate & HDMI_AUDIO_FS_96000) + pr_info(" 96000\n"); + if (audio->rate & HDMI_AUDIO_FS_176400) + pr_info(" 176400\n"); + if (audio->rate & HDMI_AUDIO_FS_192000) + pr_info(" 192000\n"); + pr_info("Support audio word lenght:\n"); + if (audio->rate & HDMI_AUDIO_WORD_LENGTH_16bit) + pr_info(" 16bit\n"); + if (audio->rate & HDMI_AUDIO_WORD_LENGTH_20bit) + pr_info(" 20bit\n"); + if (audio->rate & HDMI_AUDIO_WORD_LENGTH_24bit) + pr_info(" 24bit\n"); + pr_info("\n"); + } + pr_info("******** Show Sink Info ********\n"); +} + +/** + * hdmi_sort_modelist: sort modelist of edid + * @edid: edid to be sort + */ +static void hdmi_sort_modelist(struct hdmi_edid *edid, int feature) +{ + struct list_head *pos, *pos_new; + struct list_head head_new, *head = &edid->modelist; + struct display_modelist *modelist, *modelist_new, *modelist_n; + struct fb_videomode *m, *m_new; + int i, compare, vic; + + INIT_LIST_HEAD(&head_new); + list_for_each(pos, head) { + modelist = list_entry(pos, struct display_modelist, list); + /*pr_info("%s vic %d\n", __function__, modelist->vic);*/ + for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { + vic = modelist->vic & HDMI_VIC_MASK; + if (vic == hdmi_mode[i].vic || + vic == hdmi_mode[i].vic_2nd) { + if ((feature & SUPPORT_TMDS_600M) == 0 && + !(modelist->vic & HDMI_VIDEO_YUV420) && + hdmi_mode[i].mode.pixclock > 340000000 && + edid->maxtmdsclock < 340000000) + continue; + if ((feature & SUPPORT_4K) == 0 && + hdmi_mode[i].mode.xres >= 3840) + continue; + if ((feature & SUPPORT_4K_4096) == 0 && + hdmi_mode[i].mode.xres == 4096) + continue; + if ((modelist->vic & HDMI_VIDEO_YUV420) && + (feature & SUPPORT_YUV420) == 0) + continue; + if ((feature & SUPPORT_1080I) == 0 && + hdmi_mode[i].mode.xres == 1920 && + hdmi_mode[i].mode.vmode == + FB_VMODE_INTERLACED) + continue; + if ((feature & SUPPORT_480I_576I) == 0 && + hdmi_mode[i].mode.xres == 720 && + hdmi_mode[i].mode.vmode == + FB_VMODE_INTERLACED) + continue; + vic = modelist->vic; + modelist->vic = hdmi_mode[i].vic; + modelist->mode = hdmi_mode[i].mode; + if (vic & HDMI_VIDEO_YUV420) { + modelist->vic |= HDMI_VIDEO_YUV420; + modelist->mode.flag = 1; + } + compare = 1; + m = (struct fb_videomode *)&(modelist->mode); + list_for_each(pos_new, &head_new) { + modelist_new = + list_entry(pos_new, + struct display_modelist, + list); + m_new = &modelist_new->mode; + compare = + hdmi_videomode_compare(m, m_new); + if (compare != -1) + break; + } + if (compare != 0) { + modelist_n = + kmalloc(sizeof(*modelist_n), + GFP_KERNEL); + if (!modelist_n) + return; + *modelist_n = *modelist; + list_add_tail(&modelist_n->list, + pos_new); + } + break; + } + } + } + fb_destroy_modelist(head); + + edid->modelist = head_new; + edid->modelist.prev->next = &edid->modelist; +} + +/** + * hdmi_ouputmode_select - select hdmi transmitter output mode: hdmi or dvi? + * @hdmi: handle of hdmi + * @edid_ok: get EDID data success or not, HDMI_ERROR_SUCESS means success. + */ +int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok) +{ + struct list_head *head = &hdmi->edid.modelist; + struct fb_monspecs *specs = hdmi->edid.specs; + struct fb_videomode *modedb = NULL, *mode = NULL; + int i, pixclock; + + if (edid_ok != HDMI_ERROR_SUCESS) { + dev_err(hdmi->dev, "warning: EDID error, assume sink as HDMI !!!!"); + hdmi->edid.sink_hdmi = 1; + hdmi->edid.baseaudio_support = 1; + hdmi->edid.ycbcr444 = 0; + hdmi->edid.ycbcr422 = 0; + } + + if (head->next == head) { + dev_info(hdmi->dev, + "warning: no CEA video mode parsed from EDID !!!!\n"); + /* If EDID get error, list all system supported mode. + If output mode is set to DVI and EDID is ok, check + the output timing. + */ + if (hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) { + /* Get max resolution timing */ + modedb = &specs->modedb[0]; + for (i = 0; i < specs->modedb_len; i++) { + if (specs->modedb[i].xres > modedb->xres) + modedb = &specs->modedb[i]; + else if (specs->modedb[i].xres == + modedb->xres && + specs->modedb[i].yres > modedb->yres) + modedb = &specs->modedb[i]; + } + /* For some monitor, the max pixclock read from EDID + is smaller than the clock of max resolution mode + supported. We fix it. */ + pixclock = PICOS2KHZ(modedb->pixclock); + pixclock /= 250; + pixclock *= 250; + pixclock *= 1000; + if (pixclock == 148250000) + pixclock = 148500000; + if (pixclock > specs->dclkmax) + specs->dclkmax = pixclock; + } + + for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { + mode = (struct fb_videomode *)&(hdmi_mode[i].mode); + if (modedb) { + if ((mode->pixclock < specs->dclkmin) || + (mode->pixclock > specs->dclkmax) || + (mode->refresh < specs->vfmin) || + (mode->refresh > specs->vfmax) || + (mode->xres > modedb->xres) || + (mode->yres > modedb->yres)) + continue; + } else { + if (!(hdmi->property->feature & SUPPORT_4K) && + mode->xres >= 3840) + continue; + else if (mode->pixclock > 340000000) + continue; + } + hdmi_add_videomode(mode, head); + } + } else { + hdmi_sort_modelist(&hdmi->edid, hdmi->property->feature); + } + hdmi_show_sink_info(hdmi); + + return HDMI_ERROR_SUCESS; +} + +/** + * hdmi_videomode_to_vic: transverse video mode to vic + * @vmode: videomode to transverse + * + */ +int hdmi_videomode_to_vic(struct fb_videomode *vmode) +{ + struct fb_videomode *mode; + unsigned char vic = 0; + int i = 0; + + for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { + mode = (struct fb_videomode *)&(hdmi_mode[i].mode); + if (vmode->vmode == mode->vmode && + vmode->refresh == mode->refresh && + vmode->xres == mode->xres && + vmode->yres == mode->yres && + vmode->left_margin == mode->left_margin && + vmode->right_margin == mode->right_margin && + vmode->upper_margin == mode->upper_margin && + vmode->lower_margin == mode->lower_margin && + vmode->hsync_len == mode->hsync_len && + vmode->vsync_len == mode->vsync_len) { + vic = hdmi_mode[i].vic; + break; + } + } + return vic; +} + +/** + * hdmi_vic2timing: transverse vic mode to video timing + * @vmode: vic to transverse + * + */ +const struct hdmi_video_timing *hdmi_vic2timing(int vic) +{ + int i; + + if (vic == 0) + return NULL; + + for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { + if (hdmi_mode[i].vic == vic || hdmi_mode[i].vic_2nd == vic) + return &(hdmi_mode[i]); + } + return NULL; +} + +/** + * hdmi_vic_to_videomode: transverse vic mode to video mode + * @vmode: vic to transverse + * + */ +const struct fb_videomode *hdmi_vic_to_videomode(int vic) +{ + int i; + + if (vic == 0) + return NULL; + + for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { + if (hdmi_mode[i].vic == (vic & HDMI_VIC_MASK) || + hdmi_mode[i].vic_2nd == (vic & HDMI_VIC_MASK)) + return &hdmi_mode[i].mode; + } + return NULL; +} + +/** + * hdmi_init_modelist: initial hdmi mode list + * @hdmi: + * + * NOTES: + * + */ +void hdmi_init_modelist(struct hdmi *hdmi) +{ + int i, feature; + struct list_head *head = &hdmi->edid.modelist; + + feature = hdmi->property->feature; + INIT_LIST_HEAD(&hdmi->edid.modelist); + for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) { + if ((feature & SUPPORT_TMDS_600M) == 0 && + hdmi_mode[i].mode.pixclock > 340000000) + continue; + if ((feature & SUPPORT_4K) == 0 && + hdmi_mode[i].mode.xres >= 3840) + continue; + if ((feature & SUPPORT_4K_4096) == 0 && + hdmi_mode[i].mode.xres == 4096) + continue; + if ((feature & SUPPORT_1080I) == 0 && + hdmi_mode[i].mode.xres == 1920 && + hdmi_mode[i].mode.vmode == FB_VMODE_INTERLACED) + continue; + if ((feature & SUPPORT_480I_576I) == 0 && + hdmi_mode[i].mode.xres == 720 && + hdmi_mode[i].mode.vmode == FB_VMODE_INTERLACED) + continue; + hdmi_add_videomode(&(hdmi_mode[i].mode), head); + } +} diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c new file mode 100644 index 000000000000..134e8888acd9 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c @@ -0,0 +1,350 @@ +#include +#include +#include +#include +#include "rockchip-hdmi.h" + +static int hdmi_get_enable(struct rk_display_device *device) +{ + struct hdmi *hdmi = device->priv_data; + int enable; + + enable = hdmi->enable; + return enable; +} + +static int hdmi_set_enable(struct rk_display_device *device, int enable) +{ + struct hdmi *hdmi = device->priv_data; + + if (enable == 0) + hdmi_submit_work(hdmi, HDMI_DISABLE_CTL, 0, NULL); + else + hdmi_submit_work(hdmi, HDMI_ENABLE_CTL, 0, NULL); + return 0; +} + +static int hdmi_get_status(struct rk_display_device *device) +{ + struct hdmi *hdmi = device->priv_data; + + if (hdmi->hotplug == HDMI_HPD_ACTIVED) + return 1; + else + return 0; +} + +static int hdmi_get_modelist(struct rk_display_device *device, + struct list_head **modelist) +{ + struct hdmi *hdmi = device->priv_data; + + mutex_lock(&hdmi->lock); + *modelist = &hdmi->edid.modelist; + mutex_unlock(&hdmi->lock); + return 0; +} + +static int hdmi_set_mode(struct rk_display_device *device, + struct fb_videomode *mode) +{ + struct hdmi *hdmi = device->priv_data; + struct display_modelist *display_modelist = + container_of(mode, struct display_modelist, mode); + int vic = 0; + + if (mode == NULL) { + hdmi->autoset = 1; + vic = hdmi_find_best_mode(hdmi, 0); + } else { + hdmi->autoset = 0; + vic = display_modelist->vic; + } + + if (vic && hdmi->vic != vic) { + hdmi->vic = vic; + if (hdmi->hotplug == HDMI_HPD_ACTIVED) + hdmi_submit_work(hdmi, HDMI_SET_VIDEO, 0, NULL); + } + return 0; +} + +static int hdmi_get_mode(struct rk_display_device *device, + struct fb_videomode *mode) +{ + struct hdmi *hdmi = device->priv_data; + struct fb_videomode *vmode; + + if (mode == NULL) + return -1; + + if (hdmi->vic) { + vmode = (struct fb_videomode *) + hdmi_vic_to_videomode(hdmi->vic); + if (unlikely(vmode == NULL)) + return -1; + *mode = *vmode; + if (hdmi->vic & HDMI_VIDEO_YUV420) + mode->flag = 1; + } else { + memset(mode, 0, sizeof(struct fb_videomode)); + } + return 0; +} + +static int hdmi_set_3dmode(struct rk_display_device *device, int mode) +{ + struct hdmi *hdmi = device->priv_data; + struct list_head *modelist, *pos; + struct display_modelist *display_modelist = NULL; + + if (!hdmi) + return -1; + mutex_lock(&hdmi->lock); + modelist = &hdmi->edid.modelist; + list_for_each(pos, modelist) { + display_modelist = + list_entry(pos, struct display_modelist, list); + if (hdmi->vic == display_modelist->vic) + break; + else + display_modelist = NULL; + } + mutex_unlock(&hdmi->lock); + if (!display_modelist) + return -1; + + if ((mode != HDMI_3D_NONE) && + ((display_modelist->format_3d & (1 << mode)) == 0)) + return -1; + + if (hdmi->mode_3d != mode) { + hdmi->mode_3d = mode; + if (hdmi->hotplug == HDMI_HPD_ACTIVED) + hdmi_submit_work(hdmi, HDMI_SET_3D, 0, NULL); + } + return 0; +} + +static int hdmi_get_3dmode(struct rk_display_device *device) +{ + struct hdmi *hdmi = device->priv_data; + + if (!hdmi) + return -1; + else + return hdmi->mode_3d; +} + +/*CEA 861-E: Audio Coding Type + sync width enum hdmi_audio_type +*/ +static const char * const audioformatstr[] = { + "", + "LPCM", /*HDMI_AUDIO_LPCM = 1,*/ + "AC3", /*HDMI_AUDIO_AC3,*/ + "MPEG1", /*HDMI_AUDIO_MPEG1,*/ + "MP3", /*HDMI_AUDIO_MP3,*/ + "MPEG2", /*HDMI_AUDIO_MPEG2,*/ + "AAC-LC", /*HDMI_AUDIO_AAC_LC, AAC*/ + "DTS", /*HDMI_AUDIO_DTS,*/ + "ATARC", /*HDMI_AUDIO_ATARC,*/ + "DSD", /*HDMI_AUDIO_DSD, One bit Audio */ + "E-AC3", /*HDMI_AUDIO_E_AC3,*/ + "DTS-HD", /*HDMI_AUDIO_DTS_HD,*/ + "MLP", /*HDMI_AUDIO_MLP,*/ + "DST", /*HDMI_AUDIO_DST,*/ + "WMA-PRO", /*HDMI_AUDIO_WMA_PRO*/ +}; + +static int hdmi_get_edidaudioinfo(struct rk_display_device *device, + char *audioinfo, int len) +{ + struct hdmi *hdmi = device->priv_data; + int i = 0, size = 0; + struct hdmi_audio *audio; + + if (!hdmi) + return -1; + + memset(audioinfo, 0x00, len); + mutex_lock(&hdmi->lock); + /*printk("hdmi:edid: audio_num: %d\n", hdmi->edid.audio_num);*/ + for (i = 0; i < hdmi->edid.audio_num; i++) { + audio = &(hdmi->edid.audio[i]); + if (audio->type < 1 || audio->type > HDMI_AUDIO_WMA_PRO) { + pr_info("audio type: unsupported."); + continue; + } + size = strlen(audioformatstr[audio->type]); + memcpy(audioinfo, audioformatstr[audio->type], size); + audioinfo[size] = ','; + audioinfo += (size+1); + } + mutex_unlock(&hdmi->lock); + return 0; +} + +static int hdmi_get_color(struct rk_display_device *device, char *buf) +{ + struct hdmi *hdmi = device->priv_data; + int i, mode; + + mutex_lock(&hdmi->lock); + mode = (1 << HDMI_COLOR_RGB_0_255); + if (hdmi->edid.sink_hdmi) { + mode |= (1 << HDMI_COLOR_RGB_16_235); + if (hdmi->edid.ycbcr422) + mode |= (1 << HDMI_COLOR_YCBCR422); + if (hdmi->edid.ycbcr444) + mode |= (1 << HDMI_COLOR_YCBCR444); + } + i = snprintf(buf, PAGE_SIZE, + "Supported Color Mode: %d\n", mode); + i += snprintf(buf + i, PAGE_SIZE - i, + "Current Color Mode: %d\n", hdmi->colormode); + + mode = (1 << 1); /* 24 bit*/ + if (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_30BITS && + hdmi->property->feature & SUPPORT_DEEP_10BIT) + mode |= (1 << HDMI_DEEP_COLOR_30BITS); + if (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_36BITS && + hdmi->property->feature & SUPPORT_DEEP_12BIT) + mode |= (1 << HDMI_DEEP_COLOR_36BITS); + if (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_48BITS && + hdmi->property->feature & SUPPORT_DEEP_16BIT) + mode |= (1 << HDMI_DEEP_COLOR_48BITS); + i += snprintf(buf + i, PAGE_SIZE - i, + "Supported Color Depth: %d\n", mode); + i += snprintf(buf + i, PAGE_SIZE - i, + "Current Color Depth: %d\n", hdmi->colordepth); + mutex_unlock(&hdmi->lock); + return i; +} + +static int hdmi_set_color(struct rk_display_device *device, + const char *buf, int len) +{ + struct hdmi *hdmi = device->priv_data; + int value; + + if (!strncmp(buf, "mode", 4)) { + if (sscanf(buf, "mode=%d", &value) == -1) + return -1; + pr_debug("current mode is %d input mode is %d\n", + hdmi->colormode, value); + if (hdmi->colormode != value) + hdmi->colormode = value; + } else if (!strncmp(buf, "depth", 5)) { + if (sscanf(buf, "depth=%d", &value) == -1) + return -1; + pr_debug("current depth is %d input mode is %d\n", + hdmi->colordepth, value); + if (hdmi->colordepth != value) + hdmi->colordepth = value; + } else { + pr_err("%s unkown event\n", __func__); + return -1; + } + if (hdmi->hotplug == HDMI_HPD_ACTIVED) + hdmi_submit_work(hdmi, HDMI_SET_COLOR, 0, NULL); + return 0; +} + +static int hdmi_set_scale(struct rk_display_device *device, int direction, + int value) +{ + struct hdmi *hdmi = device->priv_data; + + if (!hdmi || value < 0 || value > 100) + return -1; + + if (!hdmi->hotplug) + return 0; + + if (direction == DISPLAY_SCALE_X) + hdmi->xscale = value; + else if (direction == DISPLAY_SCALE_Y) + hdmi->yscale = value; + else + return -1; + rk_fb_disp_scale(hdmi->xscale, hdmi->yscale, hdmi->lcdc->id); + return 0; +} + +static int hdmi_get_scale(struct rk_display_device *device, int direction) +{ + struct hdmi *hdmi = device->priv_data; + + if (!hdmi) + return -1; + + if (direction == DISPLAY_SCALE_X) + return hdmi->xscale; + else if (direction == DISPLAY_SCALE_Y) + return hdmi->yscale; + else + return -1; +} + +static int hdmi_get_monspecs(struct rk_display_device *device, + struct fb_monspecs *monspecs) +{ + struct hdmi *hdmi = device->priv_data; + + if (!hdmi) + return -1; + + mutex_lock(&hdmi->lock); + if (hdmi->edid.specs) + *monspecs = *(hdmi->edid.specs); + mutex_unlock(&hdmi->lock); + return 0; +} + +static struct rk_display_ops hdmi_display_ops = { + .setenable = hdmi_set_enable, + .getenable = hdmi_get_enable, + .getstatus = hdmi_get_status, + .getmodelist = hdmi_get_modelist, + .setmode = hdmi_set_mode, + .getmode = hdmi_get_mode, + .set3dmode = hdmi_set_3dmode, + .get3dmode = hdmi_get_3dmode, + .getedidaudioinfo = hdmi_get_edidaudioinfo, + .setcolor = hdmi_set_color, + .getcolor = hdmi_get_color, + .getmonspecs = hdmi_get_monspecs, + .setscale = hdmi_set_scale, + .getscale = hdmi_get_scale, +}; + +static int hdmi_display_probe(struct rk_display_device *device, void *devdata) +{ + struct hdmi *hdmi = devdata; + + device->owner = THIS_MODULE; + strcpy(device->type, "HDMI"); + device->priority = DISPLAY_PRIORITY_HDMI; + device->name = hdmi->property->name; + device->property = hdmi->property->display; + device->priv_data = devdata; + device->ops = &hdmi_display_ops; + return 1; +} + +static struct rk_display_driver display_hdmi = { + .probe = hdmi_display_probe, +}; + +struct rk_display_device *hdmi_register_display_sysfs(struct hdmi *hdmi, + struct device *parent) +{ + return rk_display_device_register(&display_hdmi, parent, hdmi); +} + +void hdmi_unregister_display_sysfs(struct hdmi *hdmi) +{ + if (hdmi->ddev) + rk_display_device_unregister(hdmi->ddev); +} diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi.h b/drivers/video/rockchip/hdmi/rockchip-hdmi.h new file mode 100644 index 000000000000..c9b2d2cd39e8 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi.h @@ -0,0 +1,491 @@ +#ifndef __ROCKCHIP_HDMI_H__ +#define __ROCKCHIP_HDMI_H__ + +#include +#include +#include +#ifdef CONFIG_SWITCH +#include +#endif + +#define HDMI_VIDEO_NORMAL (0 << 8) +#define HDMI_VIDEO_EXT (1 << 8) +#define HDMI_VIDEO_3D (2 << 8) +#define HDMI_VIDEO_DVI (3 << 8) +#define HDMI_VIDEO_YUV420 (4 << 8) +#define HDMI_VIC_MASK (0xFF) +#define HDMI_TYPE_MASK (0xFF << 8) +#define HDMI_MAX_ID 4 + +/* HDMI video information code according CEA-861-F */ +enum hdmi_video_infomation_code { + HDMI_640X480P_60HZ = 1, + HDMI_720X480P_60HZ_4_3, + HDMI_720X480P_60HZ_16_9, + HDMI_1280X720P_60HZ, + HDMI_1920X1080I_60HZ, /*5*/ + HDMI_720X480I_60HZ_4_3, + HDMI_720X480I_60HZ_16_9, + HDMI_720X240P_60HZ_4_3, + HDMI_720X240P_60HZ_16_9, + HDMI_2880X480I_60HZ_4_3, /*10*/ + HDMI_2880X480I_60HZ_16_9, + HDMI_2880X240P_60HZ_4_3, + HDMI_2880X240P_60HZ_16_9, + HDMI_1440X480P_60HZ_4_3, + HDMI_1440X480P_60HZ_16_9, /*15*/ + HDMI_1920X1080P_60HZ, + HDMI_720X576P_50HZ_4_3, + HDMI_720X576P_50HZ_16_9, + HDMI_1280X720P_50HZ, + HDMI_1920X1080I_50HZ, /*20*/ + HDMI_720X576I_50HZ_4_3, + HDMI_720X576I_50HZ_16_9, + HDMI_720X288P_50HZ_4_3, + HDMI_720X288P_50HZ_16_9, + HDMI_2880X576I_50HZ_4_3, /*25*/ + HDMI_2880X576I_50HZ_16_9, + HDMI_2880X288P_50HZ_4_3, + HDMI_2880X288P_50HZ_16_9, + HDMI_1440X576P_50HZ_4_3, + HDMI_1440X576P_50HZ_16_9, /*30*/ + HDMI_1920X1080P_50HZ, + HDMI_1920X1080P_24HZ, + HDMI_1920X1080P_25HZ, + HDMI_1920X1080P_30HZ, + HDMI_2880X480P_60HZ_4_3, /*35*/ + HDMI_2880X480P_60HZ_16_9, + HDMI_2880X576P_50HZ_4_3, + HDMI_2880X576P_50HZ_16_9, + HDMI_1920X1080I_50HZ_1250, /* V Line 1250 total*/ + HDMI_1920X1080I_100HZ, /*40*/ + HDMI_1280X720P_100HZ, + HDMI_720X576P_100HZ_4_3, + HDMI_720X576P_100HZ_16_9, + HDMI_720X576I_100HZ_4_3, + HDMI_720X576I_100HZ_16_9, /*45*/ + HDMI_1920X1080I_120HZ, + HDMI_1280X720P_120HZ, + HDMI_720X480P_120HZ_4_3, + HDMI_720X480P_120HZ_16_9, + HDMI_720X480I_120HZ_4_3, /*50*/ + HDMI_720X480I_120HZ_16_9, + HDMI_720X576P_200HZ_4_3, + HDMI_720X576P_200HZ_16_9, + HDMI_720X576I_200HZ_4_3, + HDMI_720X576I_200HZ_16_9, /*55*/ + HDMI_720X480P_240HZ_4_3, + HDMI_720X480P_240HZ_16_9, + HDMI_720X480I_240HZ_4_3, + HDMI_720X480I_240HZ_16_9, + HDMI_1280X720P_24HZ, /*60*/ + HDMI_1280X720P_25HZ, + HDMI_1280X720P_30HZ, + HDMI_1920X1080P_120HZ, + HDMI_1920X1080P_100HZ, + HDMI_1280X720P_24HZ_4_3, /*65*/ + HDMI_1280X720P_25HZ_4_3, + HDMI_1280X720P_30HZ_4_3, + HDMI_1280X720P_50HZ_4_3, + HDMI_1280X720P_60HZ_4_3, + HDMI_1280X720P_100HZ_4_3, /*70*/ + HDMI_1280X720P_120HZ_4_3, + HDMI_1920X1080P_24HZ_4_3, + HDMI_1920X1080P_25HZ_4_3, + HDMI_1920X1080P_30HZ_4_3, + HDMI_1920X1080P_50HZ_4_3, /*75*/ + HDMI_1920X1080P_60HZ_4_3, + HDMI_1920X1080P_100HZ_4_3, + HDMI_1920X1080P_120HZ_4_3, + HDMI_1680X720P_24HZ, + HDMI_1680X720P_25HZ, /*80*/ + HDMI_1680X720P_30HZ, + HDMI_1680X720P_50HZ, + HDMI_1680X720P_60HZ, + HDMI_1680X720P_100HZ, + HDMI_1680X720P_120HZ, /*85*/ + HDMI_2560X1080P_24HZ, + HDMI_2560X1080P_25HZ, + HDMI_2560X1080P_30HZ, + HDMI_2560X1080P_50HZ, + HDMI_2560X1080P_60HZ, /*90*/ + HDMI_2560X1080P_100HZ, + HDMI_2560X1080P_120HZ, + HDMI_3840X2160P_24HZ, + HDMI_3840X2160P_25HZ, + HDMI_3840X2160P_30HZ, /*95*/ + HDMI_3840X2160P_50HZ, + HDMI_3840X2160P_60HZ, + HDMI_4096X2160P_24HZ, + HDMI_4096X2160P_25HZ, + HDMI_4096X2160P_30HZ, /*100*/ + HDMI_4096X2160P_50HZ, + HDMI_4096X2160P_60HZ, + HDMI_3840X2160P_24HZ_4_3, + HDMI_3840X2160P_25HZ_4_3, + HDMI_3840X2160P_30HZ_4_3, /*105*/ + HDMI_3840X2160P_50HZ_4_3, + HDMI_3840X2160P_60HZ_4_3, +}; + +/* HDMI Extended Resolution */ +enum { + HDMI_VIC_4KX2K_30HZ = 1, + HDMI_VIC_4KX2K_25HZ, + HDMI_VIC_4KX2K_24HZ, + HDMI_VIC_4KX2K_24HZ_SMPTE +}; + +/* HDMI Video Format */ +enum { + HDMI_VIDEO_FORMAT_NORMAL = 0, + HDMI_VIDEO_FORMAT_4KX2K, + HDMI_VIDEO_FORMAT_3D, +}; + +/* HDMI 3D type */ +enum { + HDMI_3D_NONE = -1, + HDMI_3D_FRAME_PACKING = 0, + HDMI_3D_TOP_BOOTOM = 6, + HDMI_3D_SIDE_BY_SIDE_HALF = 8, +}; + +/* HDMI Video Data Color Mode */ +enum hdmi_video_color_mode { + HDMI_COLOR_AUTO = 0, + HDMI_COLOR_RGB_0_255, + HDMI_COLOR_RGB_16_235, + HDMI_COLOR_YCBCR444, + HDMI_COLOR_YCBCR422, + HDMI_COLOR_YCBCR420 +}; + +/* HDMI Video Data Color Depth */ +enum hdmi_deep_color { + HDMI_DEPP_COLOR_AUTO = 0, + HDMI_DEEP_COLOR_Y444 = 0x1, + HDMI_DEEP_COLOR_30BITS = 0x2, + HDMI_DEEP_COLOR_36BITS = 0x4, + HDMI_DEEP_COLOR_48BITS = 0x8, +}; + +/* HDMI Audio source */ +enum { + HDMI_AUDIO_SRC_IIS = 0, + HDMI_AUDIO_SRC_SPDIF +}; + +/* HDMI Audio Type */ +enum hdmi_audio_type { + HDMI_AUDIO_NLPCM = 0, + HDMI_AUDIO_LPCM = 1, + HDMI_AUDIO_AC3, + HDMI_AUDIO_MPEG1, + HDMI_AUDIO_MP3, + HDMI_AUDIO_MPEG2, + HDMI_AUDIO_AAC_LC, /*AAC */ + HDMI_AUDIO_DTS, + HDMI_AUDIO_ATARC, + HDMI_AUDIO_DSD, /* One bit Audio */ + HDMI_AUDIO_E_AC3, + HDMI_AUDIO_DTS_HD, + HDMI_AUDIO_MLP, + HDMI_AUDIO_DST, + HDMI_AUDIO_WMA_PRO +}; + +/* HDMI Audio Sample Rate */ +enum hdmi_audio_samplerate { + HDMI_AUDIO_FS_32000 = 0x1, + HDMI_AUDIO_FS_44100 = 0x2, + HDMI_AUDIO_FS_48000 = 0x4, + HDMI_AUDIO_FS_88200 = 0x8, + HDMI_AUDIO_FS_96000 = 0x10, + HDMI_AUDIO_FS_176400 = 0x20, + HDMI_AUDIO_FS_192000 = 0x40 +}; + +/* HDMI Audio Word Length */ +enum hdmi_audio_word_length { + HDMI_AUDIO_WORD_LENGTH_16bit = 0x1, + HDMI_AUDIO_WORD_LENGTH_20bit = 0x2, + HDMI_AUDIO_WORD_LENGTH_24bit = 0x4 +}; + +/* HDMI Hotplug Status */ +enum hdmi_hotpulg_status { + HDMI_HPD_REMOVED = 0, /* HDMI is disconnected */ + HDMI_HPD_INSERT, /* HDMI is connected, but HDP is low + or TMDS link is not pull up to 3.3V*/ + HDMI_HPD_ACTIVED /* HDMI is connected, all singnal + is normal */ +}; + +enum hdmi_mute_status { + HDMI_AV_UNMUTE = 0, + HDMI_VIDEO_MUTE = 0x1, + HDMI_AUDIO_MUTE = 0x2, +}; + +/* HDMI Error Code */ +enum hdmi_error_code { + HDMI_ERROR_SUCESS = 0, + HDMI_ERROR_FALSE, + HDMI_ERROR_I2C, + HDMI_ERROR_EDID, +}; + +/* HDMI Video Timing */ +struct hdmi_video_timing { + struct fb_videomode mode; /* Video timing*/ + unsigned int vic; /* Video information code*/ + unsigned int vic_2nd; + unsigned int pixelrepeat; /* Video pixel repeat rate*/ + unsigned int interface; /* Video input interface*/ +}; + +/* HDMI Video Parameters */ +struct hdmi_video { + unsigned int vic; /* Video information code*/ + unsigned int color_input; /* Input video color mode*/ + unsigned int color_output; /* Output video color mode*/ + unsigned int color_output_depth;/* Output video Color Depth*/ + unsigned int sink_hdmi; /* Output signal is DVI or HDMI*/ + unsigned int format_3d; /* Output 3D mode*/ +}; + +/* HDMI Audio Parameters */ +struct hdmi_audio { + u32 type; /*Audio type*/ + u32 channel; /*Audio channel number*/ + u32 rate; /*Audio sampling rate*/ + u32 word_length; /*Audio data word length*/ +}; + +/* HDMI EDID Information */ +struct hdmi_edid { + unsigned char sink_hdmi; /*HDMI display device flag*/ + unsigned char ycbcr444; /*Display device support YCbCr444*/ + unsigned char ycbcr422; /*Display device support YCbCr422*/ + unsigned char ycbcr420; /*Display device support YCbCr420*/ + unsigned char deepcolor; /*bit3:DC_48bit; bit2:DC_36bit; + bit1:DC_30bit; bit0:DC_Y444;*/ + unsigned int cecaddress; /*CEC physical address*/ + unsigned int maxtmdsclock; /*Max supported tmds clock*/ + unsigned char fields_present; /*bit7: latency + bit6: i_lantency + bit5: hdmi_video*/ + unsigned char video_latency; + unsigned char audio_latency; + unsigned char interlaced_video_latency; + unsigned char interlaced_audio_latency; + /* for hdmi 2.0 */ + unsigned char hf_vsdb_version; + unsigned char scdc_present; + unsigned char rr_capable; + unsigned char lte_340mcsc_scramble; + unsigned char independent_view; + unsigned char dual_view; + unsigned char osd_disparity_3d; + + struct fb_monspecs *specs; /*Device spec*/ + struct list_head modelist; /*Device supported display mode list*/ + unsigned char baseaudio_support; + struct hdmi_audio *audio; /*Device supported audio info*/ + unsigned int audio_num; /*Device supported audio type number*/ +}; + +struct hdmi; + +struct hdmi_ops { + int (*enable)(struct hdmi *); + int (*disable)(struct hdmi *); + int (*getstatus)(struct hdmi *); + int (*insert)(struct hdmi *); + int (*remove)(struct hdmi *); + int (*getedid)(struct hdmi *, int, unsigned char *); + int (*setvideo)(struct hdmi *, struct hdmi_video *); + int (*setaudio)(struct hdmi *, struct hdmi_audio *); + int (*setmute)(struct hdmi *, int); + int (*setvsi)(struct hdmi *, unsigned char, unsigned char); + int (*setcec)(struct hdmi *); + /* call back for hdcp operatoion */ + void (*hdcp_cb)(struct hdmi *); + void (*hdcp_irq_cb)(int); + int (*hdcp_power_on_cb)(void); + void (*hdcp_power_off_cb)(void); +}; + +enum rk_hdmi_feature { + SUPPORT_480I_576I = (1 << 0), + SUPPORT_1080I = (1 << 1), + SUPPORT_DEEP_10BIT = (1 << 2), + SUPPORT_DEEP_12BIT = (1 << 3), + SUPPORT_DEEP_16BIT = (1 << 4), + SUPPORT_4K = (1 << 5), + SUPPORT_4K_4096 = (1 << 6), + SUPPORT_TMDS_600M = (1 << 7), + SUPPORT_YUV420 = (1 << 8), + SUPPORT_CEC = (1 << 9), + SUPPORT_HDCP = (1 << 10), + SUPPORT_HDCP2 = (1 << 11), +}; + +struct hdmi_property { + char *name; + int videosrc; + int display; + int feature; + void *priv; +}; + +enum { + HDMI_SOC_RK3036 = 0, + HDMI_SOC_RK312X, + HDMI_SOC_RK3288, + HDMI_SOC_RK3368 +}; + +/* HDMI Information */ +struct hdmi { + int id; /*HDMI id*/ + int soctype; + struct device *dev; /*HDMI device*/ + struct rk_lcdc_driver *lcdc; /*HDMI linked lcdc*/ + struct rk_display_device *ddev; /*Registered display device*/ + #ifdef CONFIG_SWITCH + struct switch_dev switchdev; /*Registered switch device*/ + #endif + + struct hdmi_property *property; + struct hdmi_ops *ops; + + struct mutex lock; /* mutex for hdmi operation*/ + struct workqueue_struct *workqueue; + + bool uboot; /* if true, HDMI is initialized in uboot*/ + + int hotplug; /* hot plug status*/ + int autoset; /* if true, auto set hdmi output mode according EDID.*/ + int mute; /* HDMI display status: + 2 means mute audio, + 1 means mute display; + 0 is unmute*/ + int colordepth; + int colormode; + + struct hdmi_edid edid; /* EDID information*/ + int enable; /* Enable flag*/ + int sleep; /* Sleep flag*/ + int vic; /* HDMI output video information code*/ + int mode_3d; /* HDMI output video 3d mode*/ + struct hdmi_audio audio; /* HDMI output audio information.*/ + + int xscale; + int yscale; +}; + +/* HDMI EDID Block Size */ +#define HDMI_EDID_BLOCK_SIZE 128 + +/* SCDC Registers */ +#define SCDC_SINK_VER 0x01 /* sink version */ +#define SCDC_SOURCE_VER 0x02 /* source version */ +#define SCDC_UPDATE_0 0x10 /* Update_0 */ +#define SCDC_UPDATE_1 0x11 /* Update_1 */ +#define SCDC_UPDATE_RESERVED 0x12 /* 0x12-0x1f - Reserved */ +#define SCDC_TMDS_CONFIG 0x20 /* TMDS_Config */ +#define SCDC_SCRAMBLER_STAT 0x21 /* Scrambler_Status */ +#define SCDC_CONFIG_0 0x30 /* Config_0 */ +#define SCDC_CONFIG_RESERVED 0x31 /* 0x31-0x3f - Reserved */ +#define SCDC_STATUS_FLAG_0 0x40 /* Status_Flag_0 */ +#define SCDC_STATUS_FLAG_1 0x41 /* Status_Flag_1 */ +#define SCDC_STATUS_RESERVED 0x42 /* 0x42-0x4f - Reserved */ +#define SCDC_ERR_DET_0_L 0x50 /* Err_Det_0_L */ +#define SCDC_ERR_DET_0_H 0x51 /* Err_Det_0_H */ +#define SCDC_ERR_DET_1_L 0x52 /* Err_Det_1_L */ +#define SCDC_ERR_DET_1_H 0x53 /* Err_Det_1_H */ +#define SCDC_ERR_DET_2_L 0x54 /* Err_Det_2_L */ +#define SCDC_ERR_DET_2_H 0x55 /* Err_Det_2_H */ +#define SCDC_ERR_DET_CHKSUM 0x56 /* Err_Det_Checksum */ +#define SCDC_TEST_CFG_0 0xc0 /* Test_config_0 */ +#define SCDC_TEST_RESERVED 0xc1 /* 0xc1-0xcf */ +#define SCDC_MAN_OUI_3RD 0xd0 /* Manufacturer IEEE OUI, + Third Octet */ +#define SCDC_MAN_OUI_2ND 0xd1 /* Manufacturer IEEE OUI, + Second Octet */ +#define SCDC_MAN_OUI_1ST 0xd2 /* Manufacturer IEEE OUI, + First Octet */ +#define SCDC_DEVICE_ID 0xd3 /* 0xd3-0xdd - Device ID */ +#define SCDC_MAN_SPECIFIC 0xde /* 0xde-0xff - ManufacturerSpecific */ + +/* Event source */ +#define HDMI_SRC_SHIFT 8 +#define HDMI_SYSFS_SRC (0x1 << HDMI_SRC_SHIFT) +#define HDMI_SUSPEND_SRC (0x2 << HDMI_SRC_SHIFT) +#define HDMI_IRQ_SRC (0x4 << HDMI_SRC_SHIFT) +#define HDMI_WORKQUEUE_SRC (0x8 << HDMI_SRC_SHIFT) + +/* Event */ +#define HDMI_ENABLE_CTL (HDMI_SYSFS_SRC | 0) +#define HDMI_DISABLE_CTL (HDMI_SYSFS_SRC | 1) +#define HDMI_SUSPEND_CTL (HDMI_SUSPEND_SRC | 2) +#define HDMI_RESUME_CTL (HDMI_SUSPEND_SRC | 3) +#define HDMI_HPD_CHANGE (HDMI_IRQ_SRC | 4) +#define HDMI_SET_VIDEO (HDMI_SYSFS_SRC | 5) +#define HDMI_SET_AUDIO (HDMI_SYSFS_SRC | 6) +#define HDMI_SET_3D (HDMI_SYSFS_SRC | 7) +#define HDMI_MUTE_AUDIO (HDMI_SYSFS_SRC | 8) +#define HDMI_UNMUTE_AUDIO (HDMI_SYSFS_SRC | 9) +#define HDMI_SET_COLOR (HDMI_SYSFS_SRC | 10) +#define HDMI_ENABLE_HDCP (HDMI_SYSFS_SRC | 11) + +#define HDMI_DEFAULT_SCALE 95 +#define HDMI_AUTO_CONFIG false + +/* HDMI default vide mode */ +#define HDMI_VIDEO_DEFAULT_MODE HDMI_1280X720P_60HZ + /*HDMI_1920X1080P_60HZ*/ +#define HDMI_VIDEO_DEFAULT_COLORMODE HDMI_COLOR_AUTO +#define HDMI_VIDEO_DEFAULT_COLORDEPTH HDMI_DEPP_COLOR_AUTO + +/* HDMI default audio parameter */ +#define HDMI_AUDIO_DEFAULT_TYPE HDMI_AUDIO_LPCM +#define HDMI_AUDIO_DEFAULT_CHANNEL 2 +#define HDMI_AUDIO_DEFAULT_RATE HDMI_AUDIO_FS_44100 +#define HDMI_AUDIO_DEFAULT_WORDLENGTH HDMI_AUDIO_WORD_LENGTH_16bit + +#ifdef DEBUG +#define DBG(format, ...) \ + pr_info(format, ## __VA_ARGS__) +#else +#define DBG(format, ...) +#endif + +struct hdmi *rockchip_hdmi_register(struct hdmi_property *property, + struct hdmi_ops *ops); +void rockchip_hdmi_unregister(struct hdmi *hdmi); +struct delayed_work *hdmi_submit_work(struct hdmi *hdmi, + int event, int delay, void *data); + +struct rk_display_device *hdmi_register_display_sysfs(struct hdmi *hdmi, + struct device *parent); +void hdmi_unregister_display_sysfs(struct hdmi *hdmi); + +int hdmi_edid_parse_base(unsigned char *buf, + int *extend_num, struct hdmi_edid *pedid); +int hdmi_edid_parse_extensions(unsigned char *buf, + struct hdmi_edid *pedid); + +void hdmi_init_modelist(struct hdmi *hdmi); +int hdmi_set_lcdc(struct hdmi *hdmi); +int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok); +int hdmi_add_vic(int vic, struct list_head *head); +int hdmi_find_best_mode(struct hdmi *hdmi, int vic); +int hdmi_videomode_to_vic(struct fb_videomode *vmode); +const struct fb_videomode *hdmi_vic_to_videomode(int vic); +const struct hdmi_video_timing *hdmi_vic2timing(int vic); +int hdmi_config_audio(struct hdmi_audio *audio); +int hdmi_get_hotplug(void); +#endif diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/Kconfig b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/Kconfig new file mode 100644 index 000000000000..52ca668c34c7 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/Kconfig @@ -0,0 +1,7 @@ +config RK_HDMI_V1 + bool "RockChip HDMI V1 support" + depends on RK_HDMI + default y + help + Support rockchip hdmi version 1 if you say y here. + diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/Makefile b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/Makefile new file mode 100644 index 000000000000..9a67d1dcd6ca --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for HDMI linux kernel module. +# + +ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG + +obj-$(CONFIG_RK_HDMI_V1) += rockchip_hdmiv1_hw.o rockchip_hdmiv1.o rockchip_hdmiv1_cec.o rockchip_hdmiv1_hdcp.o diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.c new file mode 100644 index 000000000000..9c780587c50f --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.c @@ -0,0 +1,443 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if defined(CONFIG_DEBUG_FS) +#include +#include +#include +#endif + +#include "rockchip_hdmiv1.h" +#include "rockchip_hdmiv1_hw.h" + +static struct hdmi_dev *hdmi_dev; + +#if defined(CONFIG_DEBUG_FS) +static int rockchip_hdmiv1_reg_show(struct seq_file *s, void *v) +{ + int i = 0; + u32 val = 0; + + seq_puts(s, "\n\n>>>rk3036_ctl reg"); + for (i = 0; i < 16; i++) + seq_printf(s, " %2x", i); + + 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>>>rk3036_ctl %2x:", i); + seq_printf(s, " %02x", val); + } + seq_puts(s, + "\n-----------------------------------------------------------------\n"); + + return 0; +} + +static ssize_t rockchip_hdmiv1_reg_write(struct file *file, + const char __user *buf, + size_t count, + loff_t *ppos) +{ + u32 reg; + u32 val; + char kbuf[25]; + static int ret; + struct hdmi *hdmi_drv = hdmi_dev->hdmi; + + if (copy_from_user(kbuf, buf, count)) + return -EFAULT; + ret = sscanf(kbuf, "%x%x", ®, &val); + if ((reg < 0) || (reg > 0xed)) { + dev_info(hdmi_drv->dev, "it is no hdmi reg\n"); + return count; + } + dev_info(hdmi_drv->dev, "/**********rk3036 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 rockchip_hdmiv1_reg_open(struct inode *inode, struct file *file) +{ + return single_open(file, rockchip_hdmiv1_reg_show, NULL); +} + +static const struct file_operations rockchip_hdmiv1_reg_fops = { + .owner = THIS_MODULE, + .open = rockchip_hdmiv1_reg_open, + .read = seq_read, + .write = rockchip_hdmiv1_reg_write, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + +static int rockchip_hdmiv1_clk_enable(struct hdmi_dev *hdmi_dev) +{ + struct hdmi *hdmi_drv; + + hdmi_drv = hdmi_dev->hdmi; + if (!hdmi_dev->clk_on) { + if (hdmi_dev->soctype == HDMI_SOC_RK312X) + clk_prepare_enable(hdmi_dev->pd); + + 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 rockchip_hdmiv1_clk_disable(struct hdmi_dev *hdmi_dev) +{ + struct hdmi *hdmi_drv; + + hdmi_drv = hdmi_dev->hdmi; + if (hdmi_dev->clk_on) { + spin_lock(&hdmi_dev->reg_lock); + hdmi_dev->clk_on = 0; + spin_unlock(&hdmi_dev->reg_lock); + if (hdmi_dev->soctype == HDMI_SOC_RK312X) + clk_disable_unprepare(hdmi_dev->pd); + clk_disable_unprepare(hdmi_dev->hclk); + } + + return 0; +} + +static void rockchip_hdmiv1_early_suspend(void) +{ + struct hdmi *hdmi_drv = hdmi_dev->hdmi; + struct delayed_work *delay_work; + + dev_info(hdmi_drv->dev, "hdmi suspend\n"); + delay_work = hdmi_submit_work(hdmi_drv, + HDMI_SUSPEND_CTL, 0, NULL); + if (delay_work) + flush_delayed_work(delay_work); + mutex_lock(&hdmi_drv->lock); + if (hdmi_dev->irq) + disable_irq(hdmi_dev->irq); + mutex_unlock(&hdmi_drv->lock); + rockchip_hdmiv1_clk_disable(hdmi_dev); +} + +static void rockchip_hdmiv1_early_resume(void) +{ + struct hdmi *hdmi_drv = hdmi_dev->hdmi; + + dev_info(hdmi_drv->dev, "hdmi resume\n"); + mutex_lock(&hdmi_drv->lock); + rockchip_hdmiv1_clk_enable(hdmi_dev); + rockchip_hdmiv1_initial(hdmi_drv); + if (hdmi_drv->enable && hdmi_dev->irq) { + rockchip_hdmiv1_irq(hdmi_drv); + enable_irq(hdmi_dev->irq); + } + mutex_unlock(&hdmi_drv->lock); + hdmi_submit_work(hdmi_drv, HDMI_RESUME_CTL, 0, NULL); +} + +static int rockchip_hdmiv1_fb_event_notify(struct notifier_block *self, + unsigned long action, + void *data) +{ + 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: + if (!hdmi_dev->hdmi->sleep) + rockchip_hdmiv1_early_suspend(); + break; + } + } else if (action == FB_EVENT_BLANK) { + switch (blank_mode) { + case FB_BLANK_UNBLANK: + if (hdmi_dev->hdmi->sleep) + rockchip_hdmiv1_early_resume(); + break; + default: + break; + } + } + + return NOTIFY_OK; +} + +static struct notifier_block rockchip_hdmiv1_fb_notifier = { + .notifier_call = rockchip_hdmiv1_fb_event_notify, +}; + +static irqreturn_t rockchip_hdmiv1_irq_func(int irq, void *dev_id) +{ + struct hdmi *hdmi_drv = hdmi_dev->hdmi; + + if ((hdmi_drv->sleep == 0) && (hdmi_drv->enable == 1)) + rockchip_hdmiv1_irq(hdmi_drv); + + return IRQ_HANDLED; +} + +static struct hdmi_property rockchip_hdmiv1_property = { + .videosrc = DISPLAY_SOURCE_LCDC0, + .display = DISPLAY_MAIN, +}; +static struct hdmi_ops rockchip_hdmiv1_ops; + +#if defined(CONFIG_OF) +static const struct of_device_id rockchip_hdmiv1_dt_ids[] = { + {.compatible = "rockchip,rk3036-hdmi"}, + {.compatible = "rockchip,rk312x-hdmi"}, + {} +}; + +static int rockchip_hdmiv1_parse_dt(struct hdmi_dev *hdmi_dev) +{ + int val = 0; + struct device_node *np = hdmi_dev->dev->of_node; + const struct of_device_id *match; + + match = of_match_node(rockchip_hdmiv1_dt_ids, np); + if (!match) + return PTR_ERR(match); + + if (!strcmp(match->compatible, "rockchip,rk3036-hdmi")) { + hdmi_dev->soctype = HDMI_SOC_RK3036; + } else if (!strcmp(match->compatible, "rockchip,rk312x-hdmi")) { + hdmi_dev->soctype = HDMI_SOC_RK312X; + } else { + pr_err("It is not a valid rockchip soc!"); + return -ENOMEM; + } + + if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val)) + rockchip_hdmiv1_property.videosrc = val; + + if (!of_property_read_u32(np, "rockchip,hdmi_audio_source", &val)) + hdmi_dev->audiosrc = val; + + if (!of_property_read_u32(np, "rockchip,cec_enable", &val) && + (val == 1)) { + pr_info("hdmi support cec\n"); + rockchip_hdmiv1_property.feature |= SUPPORT_CEC; + } + if (!of_property_read_u32(np, "rockchip,hdcp_enable", &val) && + (val == 1)) { + pr_info("hdmi support hdcp\n"); + rockchip_hdmiv1_property.feature |= SUPPORT_HDCP; + } + /*hdmi_dev->grf_base = + syscon_regmap_lookup_by_phandle(np, "rockchip,grf");*/ + return 0; +} +MODULE_DEVICE_TABLE(of, rockchip_hdmiv1_dt_ids); +#endif + + +static int rockchip_hdmiv1_probe(struct platform_device *pdev) +{ + int ret; + struct resource *res; + struct delayed_work *delay_work; + + hdmi_dev = devm_kzalloc(&pdev->dev, + sizeof(struct hdmi_dev), + GFP_KERNEL); + if (!hdmi_dev) { + dev_err(hdmi_dev->dev, ">>rk_hdmi kmalloc fail!"); + return -ENOMEM; + } + hdmi_dev->dev = &pdev->dev; + platform_set_drvdata(pdev, hdmi_dev); + spin_lock_init(&hdmi_dev->reg_lock); + rockchip_hdmiv1_parse_dt(hdmi_dev); + /* 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 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); + dev_err(hdmi_dev->dev, "cannot ioremap registers,err=%d\n", + ret); + goto failed; + } + if (hdmi_dev->soctype == HDMI_SOC_RK312X) { + hdmi_dev->pd = devm_clk_get(hdmi_dev->dev, "pd_hdmi"); + if (IS_ERR(hdmi_dev->pd)) { + dev_err(hdmi_dev->hdmi->dev, "Unable to get hdmi pd\n"); + ret = -ENXIO; + goto failed; + } + } + hdmi_dev->hclk = devm_clk_get(hdmi_dev->dev, "pclk_hdmi"); + if (IS_ERR(hdmi_dev->hclk)) { + dev_err(hdmi_dev->hdmi->dev, "Unable to get hdmi hclk\n"); + ret = -ENXIO; + goto failed; + } + /* enable clk */ + rockchip_hdmiv1_clk_enable(hdmi_dev); + hdmi_dev->hclk_rate = clk_get_rate(hdmi_dev->hclk); + + rockchip_hdmiv1_dev_init_ops(&rockchip_hdmiv1_ops); + rockchip_hdmiv1_property.name = (char *)pdev->name; + rockchip_hdmiv1_property.priv = hdmi_dev; + rockchip_hdmiv1_property.feature |= SUPPORT_1080I | + SUPPORT_480I_576I; + hdmi_dev->hdmi = rockchip_hdmi_register(&rockchip_hdmiv1_property, + &rockchip_hdmiv1_ops); + if (hdmi_dev->hdmi == NULL) { + dev_err(&pdev->dev, "register hdmi device failed\n"); + ret = -ENOMEM; + goto failed; + } + hdmi_dev->hdmi->dev = &pdev->dev; + + fb_register_client(&rockchip_hdmiv1_fb_notifier); + rockchip_hdmiv1_initial(hdmi_dev->hdmi); + rk_display_device_enable(hdmi_dev->hdmi->ddev); + if (rk_fb_get_display_policy() == DISPLAY_POLICY_BOX) { + delay_work = hdmi_submit_work(hdmi_dev->hdmi, + HDMI_HPD_CHANGE, 0, NULL); + if (delay_work) + flush_delayed_work(delay_work); + } +#if defined(CONFIG_DEBUG_FS) + hdmi_dev->debugfs_dir = debugfs_create_dir("rockchip_hdmiv1", NULL); + if (IS_ERR(hdmi_dev->debugfs_dir)) { + dev_err(hdmi_dev->hdmi->dev, + "failed to create debugfs dir for hdmi!\n"); + } else { + debugfs_create_file("hdmi", S_IRUSR, + hdmi_dev->debugfs_dir, hdmi_dev->hdmi, + &rockchip_hdmiv1_reg_fops); + } +#endif + + /* get the IRQ */ + hdmi_dev->irq = platform_get_irq(pdev, 0); + if (hdmi_dev->irq <= 0) { + dev_err(hdmi_dev->hdmi->dev, "failed to get hdmi irq resource (%d).\n", + hdmi_dev->irq); + hdmi_dev->irq = 0; + } else { + /* request the IRQ */ + ret = devm_request_irq(hdmi_dev->hdmi->dev, + hdmi_dev->irq, + rockchip_hdmiv1_irq_func, + IRQF_TRIGGER_HIGH | IRQF_DISABLED, + dev_name(hdmi_dev->hdmi->dev), + hdmi_dev->hdmi); + if (ret) { + dev_err(hdmi_dev->hdmi->dev, "hdmi request_irq failed (%d)\n", + ret); + goto failed1; + } + } + dev_info(hdmi_dev->hdmi->dev, "hdmi probe success.\n"); + return 0; + +failed1: + rockchip_hdmi_unregister(hdmi_dev->hdmi); +failed: + kfree(hdmi_dev); + hdmi_dev = NULL; + dev_err(&pdev->dev, "rk3288 hdmi probe error.\n"); + return ret; +} + +static int rockchip_hdmiv1_remove(struct platform_device *pdev) +{ + struct hdmi *hdmi_drv = NULL; + + hdmi_drv = hdmi_dev->hdmi; + rockchip_hdmi_unregister(hdmi_drv); + return 0; +} + +static void rockchip_hdmiv1_shutdown(struct platform_device *pdev) +{ + struct hdmi_dev *hdmi_dev = platform_get_drvdata(pdev); + struct hdmi *hdmi_drv = NULL; + + if (hdmi_dev) { + hdmi_drv = hdmi_dev->hdmi; +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&hdmi_drv->early_suspend); +#endif + mutex_lock(&hdmi_drv->lock); + hdmi_drv->sleep = 1; + if (!hdmi_drv->enable) { + mutex_unlock(&hdmi_drv->lock); + return; + } + if (hdmi_dev->irq) + disable_irq(hdmi_dev->irq); + mutex_unlock(&hdmi_drv->lock); + if (hdmi_drv->hotplug == HDMI_HPD_ACTIVED) + hdmi_drv->ops->setmute(hdmi_drv, + HDMI_VIDEO_MUTE | + HDMI_AUDIO_MUTE); + rockchip_hdmiv1_clk_disable(hdmi_dev); + } + dev_info(hdmi_drv->dev, "rk hdmi shut down.\n"); +} + + +static struct platform_driver rockchip_hdmiv1_driver = { + .probe = rockchip_hdmiv1_probe, + .remove = rockchip_hdmiv1_remove, + .driver = { + .name = "rk-hdmi", + .owner = THIS_MODULE, + #if defined(CONFIG_OF) + .of_match_table = of_match_ptr(rockchip_hdmiv1_dt_ids), + #endif + }, + .shutdown = rockchip_hdmiv1_shutdown, +}; + +static int __init rockchip_hdmiv1_init(void) +{ + return platform_driver_register(&rockchip_hdmiv1_driver); +} + +static void __exit rockchip_hdmiv1_exit(void) +{ + platform_driver_unregister(&rockchip_hdmiv1_driver); +} + +module_init(rockchip_hdmiv1_init); +module_exit(rockchip_hdmiv1_exit); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.h b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.h new file mode 100644 index 000000000000..7926ff8684a9 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.h @@ -0,0 +1,38 @@ +#ifndef __ROCKCHIP_HDMI_V1_H__ +#define __ROCKCHIP_HDMI_V1_H__ + +#include "../rockchip-hdmi.h" + +struct hdmi_dev { + void __iomem *regbase; + int regbase_phy; + int regsize_phy; + + struct clk *pd; + struct clk *hclk; + unsigned int hclk_rate; + + struct hdmi *hdmi; + struct device *dev; + struct dentry *debugfs_dir; + int irq; + + struct work_struct irq_work; + struct delayed_work delay_work; + struct workqueue_struct *workqueue; + +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif + int soctype; + int audiosrc; + int enable; + unsigned char clk_disable; + unsigned char clk_on; + spinlock_t reg_lock; + + unsigned int tmdsclk; + unsigned int pixelrepeat; + int pwr_mode; +}; +#endif /* __RK3036_HDMI_H__ */ diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_cec.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_cec.c new file mode 100644 index 000000000000..1cc59ac65c09 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_cec.c @@ -0,0 +1,163 @@ +#include "rockchip_hdmiv1.h" +#include "rockchip_hdmiv1_hw.h" +#include "../rockchip-hdmi-cec.h" + +struct cec_t { + wait_queue_head_t wait; + int busfree; + int tx_done; +}; + +static int init = 1; +static struct cec_t cec; + +static int rockchip_hdmiv1_cec_read_frame(struct hdmi *hdmi, + struct cec_framedata *frame) +{ + int i, length, val; + char *data = (char *)frame; + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + if (frame == NULL) + return -1; + + hdmi_readl(hdmi_dev, CEC_RX_LENGTH, &length); + hdmi_writel(hdmi_dev, CEC_RX_OFFSET, 0); + + CECDBG("CEC: %s length is %d\n", __func__, length); + for (i = 0; i < length; i++) { + hdmi_readl(hdmi_dev, CEC_DATA, &val); + data[i] = val; + pr_info("%02x\n", data[i]); + } + return 0; +} + +static int rockchip_hdmiv1_cec_send_frame(struct hdmi *hdmi, + struct cec_framedata *frame) +{ + int i; + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + CECDBG("CEC: TX srcdestaddr %x opcode %x ", + frame->srcdestaddr, frame->opcode); + if (frame->argcount) { + DBG("args:"); + for (i = 0; i < frame->argcount; i++) + DBG("%02x ", frame->args[i]); + } + CECDBG("\n"); + + hdmi_writel(hdmi_dev, CEC_TX_OFFSET, 0); + hdmi_writel(hdmi_dev, CEC_DATA, frame->srcdestaddr); + hdmi_writel(hdmi_dev, CEC_DATA, frame->opcode); + + for (i = 0; i < frame->argcount; i++) + hdmi_writel(hdmi_dev, CEC_DATA, frame->args[i]); + + hdmi_writel(hdmi_dev, CEC_TX_LENGTH, frame->argcount + 2); + + /*Wait for bus free*/ + cec.busfree = 1; + hdmi_writel(hdmi_dev, CEC_CTRL, m_BUSFREETIME_ENABLE); + CECDBG("start wait bus free\n"); + if (wait_event_interruptible_timeout(cec.wait, + cec.busfree == 0, + msecs_to_jiffies(17))) + return -1; + + CECDBG("end wait bus free,start tx,busfree=%d\n", cec.busfree); + /*Start TX*/ + cec.tx_done = 0; + hdmi_writel(hdmi_dev, CEC_CTRL, m_BUSFREETIME_ENABLE|m_START_TX); + if (wait_event_interruptible_timeout(cec.wait, + cec.tx_done != 0, + msecs_to_jiffies(100))) + hdmi_writel(hdmi_dev, CEC_CTRL, 0); + CECDBG("end tx,tx_done=%d\n", cec.tx_done); + + if (cec.tx_done == 1) { + cec.tx_done = 0; + return 0; + } else { + return -1; + } +} + +void rockchip_hdmiv1_cec_setcecla(struct hdmi *hdmi, int ceclgaddr) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + /*for(i = 0; i < 3; i++) { + if(Cec_Ping(la_player[i]) == 1) { + cec.address_logic = la_player[i]; + break; + } + } + if(i == 3) + return -1; + //Broadcast our physical address. + GPIO_CecSendMessage(CECOP_GET_MENU_LANGUAGE,CEC_LOGADDR_TV); + msleep(100);*/ + CECDBG("CEC: %s\n", __func__); + hdmi_writel(hdmi_dev, CEC_LOGICADDR, ceclgaddr); +} + +void rockchip_hdmiv1_cec_isr(struct hdmi_dev *hdmi_dev) +{ + int tx_isr = 0, rx_isr = 0; + + hdmi_readl(hdmi_dev, CEC_TX_INT, &tx_isr); + hdmi_readl(hdmi_dev, CEC_RX_INT, &rx_isr); + + CECDBG("CEC: rockchip_hdmiv1_cec_isr:tx_isr %02x rx_isr %02x\n\n", + tx_isr, rx_isr); + + hdmi_writel(hdmi_dev, CEC_TX_INT, tx_isr); + hdmi_writel(hdmi_dev, CEC_RX_INT, rx_isr); + + if (tx_isr & m_TX_BUSNOTFREE) { + cec.busfree = 0; + CECDBG("CEC: m_TX_BUSNOTFREE,busfree=%d\n", cec.busfree); + } else if (tx_isr & m_TX_DONE) { + cec.tx_done = 1; + CECDBG("CEC: m_TX_DONE,busfree=%d\n", cec.tx_done); + } else { + cec.tx_done = -1; + CECDBG("CEC: else:busfree=%d\n", cec.tx_done); + } + + wake_up_interruptible_all(&cec.wait); + if (rx_isr & m_RX_DONE) + rockchip_hdmi_cec_submit_work(EVENT_RX_FRAME, 0, NULL); +} + +void rockchip_hdmiv1_cec_init(struct hdmi *hdmi) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + if (init) { + /*Fref = Fsys / ((register 0xd4 + 1)*(register 0xd5 + 1))*/ + /*Fref = 0.5M, Fsys = 74.25M*/ + hdmi_writel(hdmi_dev, CEC_CLK_H, 11); + hdmi_writel(hdmi_dev, CEC_CLK_L, 11); + + /*Set bus free time to 16.8ms*/ + hdmi_writel(hdmi_dev, CEC_BUSFREETIME_L, 0xd0); + hdmi_writel(hdmi_dev, CEC_BUSFREETIME_H, 0x20); + + /*Enable TX/RX INT*/ + hdmi_writel(hdmi_dev, CEC_TX_INT, 0xFF); + hdmi_writel(hdmi_dev, CEC_RX_INT, 0xFF); + + CECDBG(KERN_ERR "CEC: rockchip_hdmiv1_cec_init sucess\n"); + rockchip_hdmi_cec_init(hdmi, + rockchip_hdmiv1_cec_send_frame, + rockchip_hdmiv1_cec_read_frame, + rockchip_hdmiv1_cec_setcecla); + init = 0; + init_waitqueue_head(&cec.wait); + } + CECDBG("%s", __func__); +} + diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.c new file mode 100644 index 000000000000..0617e4f2c91f --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.c @@ -0,0 +1,837 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rockchip_hdmiv1.h" +#include "rockchip_hdmiv1_hdcp.h" +#include "rockchip_hdmiv1_hw.h" + +static struct hdcp *hdcp; + +static void hdcp_work_queue(struct work_struct *work); + +#define AUTH_TIMEOUT (2*HZ) +static struct timer_list auth_timer; +static int timer_state; + +static int is_1b_03_test(struct hdmi_dev *hdmi_dev) +{ + int reg_value; + int reg_val_1; + + hdmi_readl(hdmi_dev, 0x58, ®_value); + hdmi_readl(hdmi_dev, 0xc3, ®_val_1); + + if (reg_value != 0) { + if ((reg_val_1 & 0x40) == 0) + return 1; + } + return 0; +} + +static void rockchip_hdmiv1_set_colorbar(struct hdmi_dev *hdmi_dev, + int enable) +{ + static int display_mask; + int reg_value; + int tmds_clk; + + tmds_clk = hdmi_dev->tmdsclk; + if (enable) { + if (!display_mask) { + if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) { + hdmi_readl(hdmi_dev, SYS_CTRL, ®_value); + hdmi_msk_reg(hdmi_dev, SYS_CTRL, + m_REG_CLK_SOURCE, + v_REG_CLK_SOURCE_SYS); + hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00); + hdmi_writel(hdmi_dev, SYS_CTRL, reg_value); + } else { + hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00); + } + display_mask = 1; + } + } else { + if (display_mask) { + if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) { + hdmi_readl(hdmi_dev, SYS_CTRL, ®_value); + hdmi_msk_reg(hdmi_dev, SYS_CTRL, + m_REG_CLK_SOURCE, + v_REG_CLK_SOURCE_SYS); + hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10); + hdmi_writel(hdmi_dev, SYS_CTRL, reg_value); + } else { + hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10); + } + display_mask = 0; + } + } +} + +static void rockchip_hdmiv1_hdcp_disable(struct hdmi_dev *hdmi_dev) +{ + int reg_value; + int tmds_clk; + + tmds_clk = hdmi_dev->tmdsclk; + if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) { + hdmi_readl(hdmi_dev, SYS_CTRL, ®_value); + hdmi_msk_reg(hdmi_dev, SYS_CTRL, + m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS); + } + + /* Diable HDCP Interrupt*/ + hdmi_writel(hdmi_dev, HDCP_INT_MASK1, 0x00); + /* Stop and Reset HDCP*/ + hdmi_msk_reg(hdmi_dev, HDCP_CTRL1, + m_AUTH_START | m_AUTH_STOP | m_HDCP_RESET, + v_AUTH_START(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1)); + + if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) + hdmi_writel(hdmi_dev, SYS_CTRL, reg_value); +} + +static int rockchip_hdmiv1_hdcp_key_check(struct hdcp_keys *key) +{ + int i = 0; + + DBG("HDCP: check hdcp key\n"); + /*check 40 private key */ + for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) { + if (key->devicekey[i] != 0x00) + return HDCP_KEY_VALID; + } + /*check aksv*/ + for (i = 0; i < 5; i++) { + if (key->ksv[i] != 0x00) + return HDCP_KEY_VALID; + } + + return HDCP_KEY_INVALID; +} + +static int rockchip_hdmiv1_hdcp_load_key2mem(void) +{ + int i; + struct hdmi_dev *hdmi_dev; + struct hdcp_keys *key; + + if (!hdcp) + return -1; + hdmi_dev = hdcp->hdmi_dev; + key = hdcp->keys; + DBG("HDCP: rockchip_hdmiv1_hdcp_load_key2mem start\n"); + /* Write 40 private key*/ + for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) + hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->devicekey[i]); + /* Write 1st aksv*/ + for (i = 0; i < 5; i++) + hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->ksv[i]); + /* Write 2nd aksv*/ + for (i = 0; i < 5; i++) + hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->ksv[i]); + DBG("HDCP: rockchip_hdmiv1_hdcp_load_key2mem end\n"); + return HDCP_OK; +} + +static int rockchip_hdmiv1_hdcp_start_authentication(struct hdmi_dev *hdmi_dev) +{ + int temp; + int retry = 0; + int tmds_clk; + + tmds_clk = hdmi_dev->tmdsclk; + if (hdcp->keys == NULL) { + HDCP_WARN("HDCP: key is not loaded\n"); + return HDCP_KEY_ERR; + } + if (rockchip_hdmiv1_hdcp_key_check(hdcp->keys) == HDCP_KEY_INVALID) { + HDCP_WARN("loaded HDCP key is incorrect\n"); + return HDCP_KEY_ERR; + } + if (tmds_clk > (HDMI_SYS_FREG_CLK << 2)) { + /*Select TMDS CLK to configure regs*/ + hdmi_msk_reg(hdmi_dev, SYS_CTRL, + m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS); + } else { + hdmi_msk_reg(hdmi_dev, SYS_CTRL, + m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS); + } + hdmi_writel(hdmi_dev, HDCP_TIMER_100MS, 0x28); + hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp); + while ((temp & m_KEY_READY) == 0) { + if (retry > 1000) { + HDCP_WARN("HDCP: loaded key error\n"); + return HDCP_KEY_ERR; + } + rockchip_hdmiv1_hdcp_load_key2mem(); + usleep_range(900, 1000); + hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp); + retry++; + } + /*Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b)*/ + retry = hdmi_dev->hclk_rate/(HDCP_DDC_CLK << 2); + hdmi_writel(hdmi_dev, DDC_CLK_L, retry & 0xFF); + hdmi_writel(hdmi_dev, DDC_CLK_H, (retry >> 8) & 0xFF); + hdmi_writel(hdmi_dev, HDCP_CTRL2, 0x67); + /*Enable interrupt*/ + hdmi_writel(hdmi_dev, HDCP_INT_MASK1, + m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE | + m_INT_AUTH_SUCCESS | m_INT_AUTH_READY); + hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x00); + /*Start authentication*/ + hdmi_msk_reg(hdmi_dev, HDCP_CTRL1, + m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE | + m_AUTH_STOP | m_HDCP_RESET, + v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) | + v_ADVANED_ENABLE(0) | v_AUTH_STOP(0) | v_HDCP_RESET(0)); + + if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) { + hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, + v_REG_CLK_SOURCE_TMDS); + } + return HDCP_OK; +} + +static int rockchip_hdmiv1_hdcp_stop_authentication(struct hdmi_dev *hdmi_dev) +{ + hdmi_msk_reg(hdmi_dev, SYS_CTRL, + m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS); + hdmi_writel(hdmi_dev, DDC_CLK_L, 0x1c); + hdmi_writel(hdmi_dev, DDC_CLK_H, 0x00); + hdmi_writel(hdmi_dev, HDCP_CTRL2, 0x08); + hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x06); + hdmi_writel(hdmi_dev, HDCP_CTRL1, 0x02); + return 0; + /*hdmi_writel(HDCP_CTRL1, 0x0a);*/ +} + +static int rockchip_hdmiv1_hdcp_error(int value) +{ + if (value & 0x80) + HDCP_WARN("Timed out waiting for downstream repeater\n"); + else if (value & 0x40) + HDCP_WARN("Too many devices connected to repeater tree\n"); + else if (value & 0x20) + HDCP_WARN("SHA-1 hash check of BKSV list failed\n"); + else if (value & 0x10) + HDCP_WARN("SHA-1 hash check of BKSV list failed\n"); + else if (value & 0x08) + HDCP_WARN("DDC channels no acknowledge\n"); + else if (value & 0x04) + HDCP_WARN("Pj mismatch\n"); + else if (value & 0x02) + HDCP_WARN("Ri mismatch\n"); + else if (value & 0x01) + HDCP_WARN("Bksv is wrong\n"); + else + return 0; + return 1; +} + +static void rockchip_hdmiv1_hdcp_interrupt(struct hdmi_dev *hdmi_dev, + char *status1, char *status2) +{ + int interrupt1 = 0; + int interrupt2 = 0; + int temp = 0; + int tmds_clk; + + tmds_clk = hdmi_dev->tmdsclk; + hdmi_readl(hdmi_dev, HDCP_INT_STATUS1, &interrupt1); + hdmi_readl(hdmi_dev, HDCP_INT_STATUS2, &interrupt2); + + if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) + hdmi_msk_reg(hdmi_dev, SYS_CTRL, + m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS); + + if (interrupt1) { + hdmi_writel(hdmi_dev, HDCP_INT_STATUS1, interrupt1); + if (interrupt1 & m_INT_HDCP_ERR) { + hdmi_readl(hdmi_dev, HDCP_ERROR, &temp); + HDCP_WARN("HDCP: Error reg 0x65 = 0x%02x\n", temp); + rockchip_hdmiv1_hdcp_error(temp); + hdmi_writel(hdmi_dev, HDCP_ERROR, temp); + } + } + if (interrupt2) + hdmi_writel(hdmi_dev, HDCP_INT_STATUS2, interrupt2); + + *status1 = interrupt1; + *status2 = interrupt2; + + if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) + hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, + v_REG_CLK_SOURCE_TMDS); +/* + hdmi_readl(HDCP_ERROR, &temp); + DBG("HDCP: Error reg 0x65 = 0x%02x\n", temp); +*/ +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_submit_work + *----------------------------------------------------------------------------- + */ +static struct delayed_work *hdcp_submit_work(int event, int delay) +{ + struct hdcp_delayed_work *work; + + DBG("%s event %04x delay %d\n", __func__, event, delay); + work = kmalloc(sizeof(*work), GFP_ATOMIC); + + if (work) { + INIT_DELAYED_WORK(&work->work, hdcp_work_queue); + work->event = event; + queue_delayed_work(hdcp->workqueue, + &work->work, + msecs_to_jiffies(delay)); + } else { + HDCP_WARN("HDCP:Cannot allocate memory to create work\n"); + return 0; + } + + return &work->work; +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_cancel_work + *----------------------------------------------------------------------------- + */ +static void hdcp_cancel_work(struct delayed_work **work) +{ + int ret = 0; + + if (*work) { + ret = cancel_delayed_work(*work); + if (ret != 1) { + ret = cancel_work_sync(&((*work)->work)); + HDCP_WARN("Canceling sync work failed %d\n", ret); + } + kfree(*work); + *work = 0; + } +} + +/*----------------------------------------------------------------------------- + * Function: auth_timer_func + *----------------------------------------------------------------------------- + */ +static void auth_timer_func(unsigned long data) +{ + HDCP_WARN("hdcp auth 2 second timeout\n"); + if (hdcp->auth_state == 0) { + mod_timer(&auth_timer, jiffies + AUTH_TIMEOUT); + if ((hdcp->hdcp_state != HDCP_DISABLED) && + (hdcp->hdcp_state != HDCP_ENABLE_PENDING)) { + if (is_1b_03_test(hdcp->hdmi_dev)) + return; + hdcp_submit_work(HDCP_FAIL_EVENT, 0); + } + } +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_wq_authentication_failure + *----------------------------------------------------------------------------- + */ +static void hdcp_wq_authentication_failure(void) +{ + if (hdcp->hdmi_state == HDMI_STOPPED) + return; + + rockchip_hdmiv1_hdcp_disable(hdcp->hdmi_dev); +/* + rockchip_hdmiv1_hdmi_control_output(false); + */ + rockchip_hdmiv1_set_colorbar(hdcp->hdmi_dev, 1); + hdcp_cancel_work(&hdcp->pending_wq_event); + if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) { + if (hdcp->retry_cnt <= HDCP_INFINITE_REAUTH) { + hdcp->retry_cnt--; + HDCP_WARN("authentication failed attempts=%d\n", + hdcp->retry_cnt); + } else { + HDCP_WARN("authentication failed retrying\n"); + } + hdcp->hdcp_state = HDCP_AUTHENTICATION_START; + + if (hdcp->auth_state == 1 && timer_state == 0) { + DBG("add auth timer\n"); + hdcp->auth_state = 0; + hdcp->retry_cnt = HDCP_INFINITE_REAUTH; + auth_timer.expires = jiffies + AUTH_TIMEOUT; + add_timer(&auth_timer); + timer_state = 1; + } + + hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT, + HDCP_REAUTH_DELAY); + } else { + HDCP_WARN("authentication failed HDCP disabled\n"); + hdcp->hdcp_state = HDCP_ENABLE_PENDING; + + if (timer_state == 1) { + DBG("delete auth timer\n"); + del_timer_sync(&auth_timer); + timer_state = 0; + } + } +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_wq_start_authentication + *----------------------------------------------------------------------------- + */ +static void hdcp_wq_start_authentication(void) +{ + int status = HDCP_OK; + + hdcp->hdcp_state = HDCP_AUTHENTICATION_START; + DBG("HDCP: authentication start\n"); + status = rockchip_hdmiv1_hdcp_start_authentication(hdcp->hdmi_dev); + if (status != HDCP_OK) { + DBG("HDCP: authentication failed\n"); + hdcp_wq_authentication_failure(); + } else { + /*hdcp->hdcp_state = HDCP_WAIT_KSV_LIST;*/ + hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; + } +} +#if 0 +/*----------------------------------------------------------------------------- + * Function: hdcp_wq_check_bksv + *----------------------------------------------------------------------------- + */ +static void hdcp_wq_check_bksv(void) +{ + int status = HDCP_OK; + + DBG("Check BKSV start"); + status = rockchip_hdmiv1_hdcp_check_bksv(); + if (status != HDCP_OK) { + HDCP_WARN("HDCP: Check BKSV failed"); + hdcp->retry_cnt = 0; + hdcp_wq_authentication_failure(); + } else { + DBG("HDCP: Check BKSV successful"); + hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK; + /* Restore retry counter */ + if (hdcp->retry_times == 0) + hdcp->retry_cnt = HDCP_INFINITE_REAUTH; + else + hdcp->retry_cnt = hdcp->retry_times; + } +} +#endif +/*----------------------------------------------------------------------------- + * Function: hdcp_wq_authentication_sucess + *----------------------------------------------------------------------------- + */ +static void hdcp_wq_authentication_sucess(void) +{ + hdcp->auth_state = 1; + if (timer_state == 1) { + DBG("delete auth timer\n"); + timer_state = 0; + del_timer_sync(&auth_timer); + } + + rockchip_hdmiv1_set_colorbar(hdcp->hdmi_dev, 0); + HDCP_WARN("HDCP: authentication pass\n"); +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_wq_disable + *----------------------------------------------------------------------------- + */ +static void hdcp_wq_disable(int event) +{ + HDCP_WARN("HDCP: disabled\n"); + + hdcp_cancel_work(&hdcp->pending_wq_event); + rockchip_hdmiv1_hdcp_disable(hdcp->hdmi_dev); + if (event == HDCP_DISABLE_CTL) { + hdcp->hdcp_state = HDCP_DISABLED; + if (hdcp->hdmi_state == HDMI_STARTED) + rockchip_hdmiv1_set_colorbar(hdcp->hdmi_dev, 0); + } else if (event == HDCP_STOP_FRAME_EVENT) { + hdcp->hdcp_state = HDCP_ENABLE_PENDING; + } +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_work_queue + *----------------------------------------------------------------------------- + */ +static void hdcp_work_queue(struct work_struct *work) +{ + struct hdcp_delayed_work *hdcp_w = + container_of(work, struct hdcp_delayed_work, work.work); + int event = hdcp_w->event; + + mutex_lock(&hdcp->lock); + DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d\n", + jiffies_to_msecs(jiffies), + hdcp->hdmi_state, + hdcp->hdcp_state, + (event & 0xFF00) >> 8, + event & 0xFF); + + if (event == HDCP_STOP_FRAME_EVENT) + hdcp->hdmi_state = HDMI_STOPPED; + if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) + hdcp_wq_disable(event); + if (event & HDCP_WORKQUEUE_SRC) + hdcp->pending_wq_event = 0; + /* First handle HDMI state */ + if (event == HDCP_START_FRAME_EVENT) { + hdcp->pending_start = 0; + hdcp->hdmi_state = HDMI_STARTED; + } + + /**********************/ + /* HDCP state machine */ + /**********************/ + switch (hdcp->hdcp_state) { + case HDCP_DISABLED: + /* HDCP enable control or re-authentication event */ + if (event == HDCP_ENABLE_CTL) { + /*if (hdcp->retry_times == 0) + hdcp->retry_cnt = HDCP_INFINITE_REAUTH; + else + hdcp->retry_cnt = hdcp->retry_times;*/ + hdcp->retry_cnt = HDCP_INFINITE_REAUTH; + if (hdcp->hdmi_state == HDMI_STARTED) + hdcp_wq_start_authentication(); + else + hdcp->hdcp_state = HDCP_ENABLE_PENDING; + } + break; + case HDCP_ENABLE_PENDING: + /* HDMI start frame event */ + if (event == HDCP_START_FRAME_EVENT) + hdcp_wq_start_authentication(); + break; + case HDCP_AUTHENTICATION_START: + /* Re-authentication */ + if (event == HDCP_AUTH_REATT_EVENT) + hdcp_wq_start_authentication(); + break; +#if 0 + case HDCP_WAIT_KSV_LIST: + /* KSV failure */ + if (event == HDCP_FAIL_EVENT) { + HDCP_WARN("HDCP: KSV switch failure\n"); + hdcp_wq_authentication_failure(); + } + /* KSV list ready event */ + else if (event == HDCP_KSV_LIST_RDY_EVENT) + hdcp_wq_check_bksv(); + break; +#endif + case HDCP_LINK_INTEGRITY_CHECK: + /* authentication failure */ + if (event == HDCP_FAIL_EVENT) { + HDCP_WARN("HDCP: Ri check failure\n"); + hdcp_wq_authentication_failure(); + } else if (event == HDCP_AUTH_PASS_EVENT) { + hdcp_wq_authentication_sucess(); + } + break; + default: + HDCP_WARN("HDCP: error - unknow HDCP state\n"); + break; + } + kfree(hdcp_w); + if (event == HDCP_STOP_FRAME_EVENT) + complete(&hdcp->complete); + mutex_unlock(&hdcp->lock); +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_start_frame_cb + *----------------------------------------------------------------------------- + */ +static void hdcp_start_frame_cb(struct hdmi *hdmi) +{ + DBG("hdcp_start_frame_cb()\n"); + + /* Cancel any pending work */ + if (hdcp->pending_start) + hdcp_cancel_work(&hdcp->pending_start); + if (hdcp->pending_wq_event) + hdcp_cancel_work(&hdcp->pending_wq_event); + + if (timer_state == 0) { + DBG("add auth timer\n"); + auth_timer.expires = jiffies + AUTH_TIMEOUT; + add_timer(&auth_timer); + timer_state = 1; + } + + hdcp->retry_cnt = HDCP_INFINITE_REAUTH; + hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT, + HDCP_ENABLE_DELAY); +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_irq_cb + *----------------------------------------------------------------------------- + */ +static void hdcp_irq_cb(int status) +{ + char interrupt1; + char interrupt2; + + rockchip_hdmiv1_hdcp_interrupt(hdcp->hdmi_dev, + &interrupt1, + &interrupt2); + DBG("%s 0x%02x 0x%02x\n", __func__, interrupt1, interrupt2); + if (interrupt1 & m_INT_HDCP_ERR) { + if ((hdcp->hdcp_state != HDCP_DISABLED) && + (hdcp->hdcp_state != HDCP_ENABLE_PENDING)) + hdcp_submit_work(HDCP_FAIL_EVENT, 0); + } +/* + else if (interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE)) + hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0); + */ + else if (interrupt1 & m_INT_AUTH_SUCCESS) + hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0); +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_power_on_cb + *----------------------------------------------------------------------------- + */ +static int hdcp_power_on_cb(void) +{ + DBG("%s", __func__); + return rockchip_hdmiv1_hdcp_load_key2mem(); +} + +/*----------------------------------------------------------------------------- + * Function: hdcp_power_off_cb + *----------------------------------------------------------------------------- + */ +static void hdcp_power_off_cb(void) +{ + unsigned int time; + + DBG("%s\n", __func__); + if (timer_state == 1) { + DBG("delete auth timer\n"); + timer_state = 0; + del_timer_sync(&auth_timer); + } + hdcp->auth_state = 0; + + if (!hdcp->enable) + return; + rockchip_hdmiv1_hdcp_stop_authentication(hdcp->hdmi_dev); + hdcp_cancel_work(&hdcp->pending_start); + hdcp_cancel_work(&hdcp->pending_wq_event); + init_completion(&hdcp->complete); + /* Post event to workqueue */ + time = msecs_to_jiffies(5000); + if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0)) + wait_for_completion_interruptible_timeout(&hdcp->complete, + time); +} + +/* + * Load HDCP key to external HDCP memory + */ +static void hdcp_load_keys_cb(const struct firmware *fw, void *context) +{ + if (!fw) { + pr_err("HDCP: failed to load keys\n"); + return; + } + if (fw->size < HDCP_KEY_SIZE) { + pr_err("HDCP: firmware wrong size %d\n", (int)fw->size); + return; + } + hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL); + if (hdcp->keys == NULL) { + pr_err("HDCP: can't allocated space for keys\n"); + return; + } + memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE); + HDCP_WARN("HDCP: load hdcp key success\n"); + + if (fw->size > HDCP_KEY_SIZE) { + DBG("%s invalid key size %d\n", __func__, + (int)fw->size - HDCP_KEY_SIZE); + if ((fw->size - HDCP_KEY_SIZE) % 5) { + pr_err("HDCP: failed to load invalid keys\n"); + return; + } + hdcp->invalidkeys = + kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL); + if (hdcp->invalidkeys == NULL) { + pr_err("HDCP: can't allocated space for invalid keys\n"); + return; + } + memcpy(hdcp->invalidkeys, fw->data + + HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE); + hdcp->invalidkey = (fw->size - HDCP_KEY_SIZE)/5; + HDCP_WARN("HDCP: loaded hdcp invalid key success\n"); + } +} + +static ssize_t hdcp_enable_read(struct device *device, + struct device_attribute *attr, + char *buf) +{ + int enable = 0; + + if (hdcp) + enable = hdcp->enable; + return snprintf(buf, PAGE_SIZE, "%d\n", enable); +} + +static ssize_t hdcp_enable_write(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int enable; + + if (hdcp == NULL) + return -EINVAL; + if (kstrtoint(buf, 0, &enable)) + return -EINVAL; + if (hdcp->enable != enable) { + /* Post event to workqueue */ + if (enable) { + if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0) + return -EFAULT; + } else { + hdcp_cancel_work(&hdcp->pending_start); + hdcp_cancel_work(&hdcp->pending_wq_event); + + /* Post event to workqueue */ + if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0) + return -EFAULT; + } + hdcp->enable = enable; + } + return count; +} + +static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, + hdcp_enable_read, hdcp_enable_write); + +static ssize_t hdcp_trytimes_read(struct device *device, + struct device_attribute *attr, + char *buf) +{ + int trytimes = 0; + + if (hdcp) + trytimes = hdcp->retry_times; + return snprintf(buf, PAGE_SIZE, "%d\n", trytimes); +} + +static ssize_t hdcp_trytimes_wrtie(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int trytimes; + + if (hdcp == NULL) + return -EINVAL; + if (kstrtoint(buf, 0, &trytimes)) + return -EINVAL; + if (hdcp->retry_times != trytimes) + hdcp->retry_times = trytimes; + return count; +} + + +static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR, + hdcp_trytimes_read, hdcp_trytimes_wrtie); +static struct miscdevice mdev; + +int rockchip_hdmiv1_hdcp_init(struct hdmi *hdmi) +{ + int ret; + + DBG("[%s]\n", __func__); + if (hdcp) + return 0; + + hdcp = kmalloc(sizeof(*hdcp), GFP_KERNEL); + if (!hdcp) { + HDCP_WARN(">>HDCP: kmalloc fail!\n"); + ret = -ENOMEM; + goto error0; + } + memset(hdcp, 0, sizeof(struct hdcp)); + mutex_init(&hdcp->lock); + mdev.minor = MISC_DYNAMIC_MINOR; + mdev.name = "hdcp"; + mdev.mode = 0666; + if (misc_register(&mdev)) { + HDCP_WARN("HDCP: Could not add character driver\n"); + ret = HDMI_ERROR_FALSE; + goto error1; + } + ret = device_create_file(mdev.this_device, &dev_attr_enable); + if (ret) { + HDCP_WARN("HDCP: Could not add sys file enable\n"); + ret = -EINVAL; + goto error2; + } + ret = device_create_file(mdev.this_device, &dev_attr_trytimes); + if (ret) { + HDCP_WARN("HDCP: Could not add sys file trytimes\n"); + ret = -EINVAL; + goto error3; + } + hdcp->workqueue = create_singlethread_workqueue("hdcp"); + if (hdcp->workqueue == NULL) { + HDCP_WARN("HDCP,: create workqueue failed.\n"); + goto error4; + } + ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, + "hdcp", mdev.this_device, + GFP_KERNEL, hdcp, + hdcp_load_keys_cb); + if (ret < 0) { + HDCP_WARN("HDCP: request_firmware_nowait failed: %d\n", ret); + goto error5; + } + hdcp->hdmi_dev = hdmi->property->priv; + hdmi->ops->hdcp_cb = hdcp_start_frame_cb; + hdmi->ops->hdcp_irq_cb = hdcp_irq_cb; + hdmi->ops->hdcp_power_on_cb = hdcp_power_on_cb; + hdmi->ops->hdcp_power_off_cb = hdcp_power_off_cb; + + init_timer(&auth_timer); + auth_timer.data = 0; + auth_timer.function = auth_timer_func; + DBG("%s success\n", __func__); + return 0; +error5: + destroy_workqueue(hdcp->workqueue); +error4: + device_remove_file(mdev.this_device, &dev_attr_trytimes); +error3: + device_remove_file(mdev.this_device, &dev_attr_enable); +error2: + misc_deregister(&mdev); +error1: + kfree(hdcp->keys); + kfree(hdcp->invalidkeys); + kfree(hdcp); +error0: + return ret; +} + diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.h b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.h new file mode 100644 index 000000000000..3fea4c627529 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.h @@ -0,0 +1,186 @@ +#ifndef __ROCKCHIP_HDMIV1_HDCP_H__ +#define __ROCKCHIP_HDMIV1_HDCP_H__ + +/***************************/ +/* Definitions */ +/***************************/ + +/* Status / error codes */ +#define HDCP_OK 0 +#define HDCP_KEY_ERR 1 +#define HDCP_KSV_ERR 2 +#define HDCP_KEY_VALID 3 +#define HDCP_KEY_INVALID 4 + +/* Delays */ +#define HDCP_ENABLE_DELAY 300 +#define HDCP_REAUTH_DELAY 100 + +/* Event source */ +#define HDCP_SRC_SHIFT 8 +#define HDCP_IOCTL_SRC (0x1 << HDCP_SRC_SHIFT) +#define HDCP_HDMI_SRC (0x2 << HDCP_SRC_SHIFT) +#define HDCP_IRQ_SRC (0x4 << HDCP_SRC_SHIFT) +#define HDCP_WORKQUEUE_SRC (0x8 << HDCP_SRC_SHIFT) + +/* Event */ +#define HDCP_ENABLE_CTL (HDCP_IOCTL_SRC | 0) +#define HDCP_DISABLE_CTL (HDCP_IOCTL_SRC | 1) +#define HDCP_START_FRAME_EVENT (HDCP_HDMI_SRC | 2) +#define HDCP_STOP_FRAME_EVENT (HDCP_HDMI_SRC | 3) +#define HDCP_KSV_LIST_RDY_EVENT (HDCP_IRQ_SRC | 4) +#define HDCP_FAIL_EVENT (HDCP_IRQ_SRC | 5) +#define HDCP_AUTH_PASS_EVENT (HDCP_IRQ_SRC | 6) +#define HDCP_AUTH_REATT_EVENT (HDCP_WORKQUEUE_SRC | 7) + +/* Key size */ +#define HDCP_KEY_SIZE 308 + +/* HDCP DDC Clock */ +#define HDCP_DDC_CLK 100000 + +/* Authentication retry times */ +#define HDCP_INFINITE_REAUTH 0x100 + +/* HDCP Regs */ +#define HDCP_CTRL1 0x52 + #define m_AUTH_START (1 << 7) + #define m_BKSV_VALID (1 << 6) + #define m_BKSV_INVALID (1 << 5) + #define m_ENCRYPT_ENABLE (1 << 4) + #define m_AUTH_STOP (1 << 3) + #define m_ADVANED_ENABLE (1 << 2) + #define m_HDMI_DVI (1 << 1) + #define m_HDCP_RESET (1 << 0) + + #define v_AUTH_START(n) (n << 7) + #define v_BKSV_VALID(n) (n << 6) + #define v_BKSV_INVALID(n) (n << 5) + #define v_ENCRYPT_ENABLE(n) (n << 4) + #define v_AUTH_STOP(n) (n << 3) + #define v_ADVANED_ENABLE(n) (n << 2) + #define v_HDMI_DVI(n) (n << 1) + #define v_HDCP_RESET(n) (n << 0) + +#define HDCP_CTRL2 0x53 + #define m_DISABLE_127_CHECK (1 << 7) + #define m_SKIP_BKSV_CHECK (1 << 6) + #define m_ENABLE_PJ_CHECK (1 << 5) + #define m_DISABLE_DEVICE_NUMBER_CHECK (1 << 4) + #define m_DELAY_RI_1_CLK (1 << 3) + #define m_USE_PRESET_AN (1 << 2) + #define m_KEY_COMBINATION (3 << 0) + + #define v_DISABLE_127_CHECK(n) (n << 7) + #define v_SKIP_BKSV_CHECK(n) (n << 6) + #define v_ENABLE_PJ_CHECK(n) (n << 5) + #define v_DISABLE_DEVICE_NUMBER_CHECK(n)(n << 4) + #define v_DELAY_RI_1_CLK(n) (n << 3) + #define v_USE_PRESET_AN(n) (n << 2) + #define v_KEY_COMBINATION(n) (n << 0) + +#define HDCP_KEY_STATUS 0x54 + #define m_KEY_READY (1 << 0) + +#define HDCP_CTRL_SOFT 0x57 + #define m_DISABLE_127_CHECK (1 << 7) + #define m_SKIP_BKSV_CHECK (1 << 6) + #define m_NOT_AUTHENTICATED (1 << 5) + #define m_ENCRYPTED (1 << 4) + #define m_ADVANCED_CIPHER (1 << 3) + +#define HDCP_BCAPS_RX 0x58 +#define HDCP_TIMER_100MS 0x63 +#define HDCP_TIMER_5S 0x64 +#define HDCP_ERROR 0x65 + #define m_DDC_NO_ACK (1 << 3) + #define m_PJ_MISMACH (1 << 2) + #define m_RI_MISMACH (1 << 1) + #define m_BKSV_WRONG (1 << 0) + +#define HDCP_KSV_BYTE0 0x66 +#define HDCP_KSV_BYTE1 0x67 +#define HDCP_KSV_BYTE2 0x68 +#define HDCP_KSV_BYTE3 0x69 +#define HDCP_KSV_BYTE4 0x6a + +#define HDCP_AN_SEED 0x6c + +#define HDCP_BCAPS_TX 0x80 +#define HDCP_BSTATE_0 0x81 +#define HDCP_BSTATE_1 0x82 + +#define HDCP_KEY_FIFO 0x98 + +#define HDCP_INT_MASK1 0xc2 +#define HDCP_INT_STATUS1 0xc3 + #define m_INT_HDCP_ERR (1 << 7) + #define m_INT_BKSV_READY (1 << 6) + #define m_INT_BKSV_UPDATE (1 << 5) + #define m_INT_AUTH_SUCCESS (1 << 4) + #define m_INT_AUTH_READY (1 << 3) + +#define HDCP_INT_MASK2 0xc4 +#define HDCP_INT_STATUS2 0xc5 + #define m_INT_SOFT_MODE_READY (1 << 7) + #define m_INT_AUTH_M0_REDAY (1 << 6) + #define m_INT_1st_FRAME_ARRIVE (1 << 5) + #define m_INT_AN_READY (1 << 4) + #define m_INT_ENCRYPTED (1 << 2) + #define m_INT_NOT_ENCRYPTED_AVMUTE (1 << 1) + #define m_INT_NOT_ENCRYPTED_AVUNMUTE (1 << 0) + +enum hdcp_states { + HDCP_DISABLED, + HDCP_ENABLE_PENDING, + HDCP_AUTHENTICATION_START, + HDCP_WAIT_KSV_LIST, + HDCP_LINK_INTEGRITY_CHECK, +}; + +enum hdmi_states { + HDMI_STOPPED, + HDMI_STARTED +}; + +#define HDCP_PRIVATE_KEY_SIZE 280 +#define HDCP_KEY_SHA_SIZE 20 + +struct hdcp_keys { + u8 ksv[8]; + u8 devicekey[HDCP_PRIVATE_KEY_SIZE]; + u8 sha1[HDCP_KEY_SHA_SIZE]; +}; + +struct hdcp_delayed_work { + struct delayed_work work; + int event; +}; + +struct hdcp { + int enable; + int retry_times; + struct hdcp_keys *keys; + int invalidkey; + char *invalidkeys; + struct mutex lock; + struct completion complete; + struct workqueue_struct *workqueue; + + enum hdmi_states hdmi_state; + enum hdcp_states hdcp_state; + + struct delayed_work *pending_start; + struct delayed_work *pending_wq_event; + int retry_cnt; + int auth_state; + struct hdmi_dev *hdmi_dev; +}; + +#if 1 +#define HDCP_WARN(x...) pr_warn(x) +#else +#define I2S_DBG(x...) do { } while (0) +#endif +int rockchip_hdmiv1_hdcp_init(struct hdmi *hdmi); +#endif /* __ROCKCHIP_HDMIV1_HDCP_H__ */ diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.c new file mode 100644 index 000000000000..9e0c721ac538 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.c @@ -0,0 +1,952 @@ +#include +#include +#include +#include +#include "rockchip_hdmiv1.h" +#include "rockchip_hdmiv1_hw.h" +#include "rockchip_hdmiv1_hdcp.h" + +static inline void delay100us(void) +{ + usleep_range(99, 100); +} + +static void rockchip_hdmiv1_av_mute(struct hdmi *hdmi_drv, bool enable) +{ + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + if (enable) { + hdmi_msk_reg(hdmi_dev, AV_MUTE, + m_AVMUTE_CLEAR | m_AVMUTE_ENABLE, + v_AVMUTE_CLEAR(0) | v_AVMUTE_ENABLE(1)); + } else { + hdmi_msk_reg(hdmi_dev, AV_MUTE, + m_AVMUTE_CLEAR | m_AVMUTE_ENABLE, + v_AVMUTE_CLEAR(1) | v_AVMUTE_ENABLE(0)); + } + hdmi_msk_reg(hdmi_dev, PACKET_SEND_AUTO, + m_PACKET_GCP_EN, v_PACKET_GCP_EN(1)); +} + +static void rockchip_hdmiv1_sys_power(struct hdmi *hdmi_drv, bool enable) +{ + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + 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 rockchip_hdmiv1_set_pwr_mode(struct hdmi *hdmi_drv, int mode) +{ + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + if (hdmi_dev->pwr_mode == mode) + return; + + dev_info(hdmi_drv->dev, "%s change pwr_mode %d --> %d\n", __func__, + hdmi_dev->pwr_mode, mode); + + switch (mode) { + case NORMAL: + dev_info(hdmi_drv->dev, + "%s change pwr_mode NORMAL\n", + __func__); + rockchip_hdmiv1_sys_power(hdmi_drv, false); + if (hdmi_dev->soctype == HDMI_SOC_RK3036) { + hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x6f); + hdmi_writel(hdmi_dev, PHY_DRIVER, 0xbb); + } else if (hdmi_dev->soctype == HDMI_SOC_RK312X) { + hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x5f); + hdmi_writel(hdmi_dev, PHY_DRIVER, 0xaa); + } + + hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x15); + hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x14); + hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x10); + hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x0f); + hdmi_writel(hdmi_dev, 0xce, 0x00); + hdmi_writel(hdmi_dev, 0xce, 0x01); + rockchip_hdmiv1_sys_power(hdmi_drv, true); + break; + case LOWER_PWR: + dev_info(hdmi_drv->dev, + "%s change pwr_mode LOWER_PWR\n", + __func__); + rockchip_hdmiv1_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, 0x17); + break; + default: + dev_info(hdmi_drv->dev, "unkown rk3036 hdmi pwr mode %d\n", + mode); + } + + hdmi_dev->pwr_mode = mode; +} + +int rockchip_hdmiv1_detect_hotplug(struct hdmi *hdmi_drv) +{ + int value = 0; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + hdmi_readl(hdmi_dev, HDMI_STATUS, &value); + value &= m_HOTPLUG; + if (value == m_HOTPLUG) + return HDMI_HPD_ACTIVED; + else if (value) + return HDMI_HPD_INSERT; + else + return HDMI_HPD_REMOVED; +} + +int rockchip_hdmiv1_insert(struct hdmi *hdmi_drv) +{ + rockchip_hdmiv1_set_pwr_mode(hdmi_drv, NORMAL); + return 0; +} + + +int rockchip_hdmiv1_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; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + if (block % 2) + offset = HDMI_EDID_BLOCK_SIZE; + + if (block / 2) + segment = 1; + ddc_bus_freq = (hdmi_dev->hclk_rate >> 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); + + dev_info(hdmi_drv->dev, + "EDID DATA (Segment = %d Block = %d Offset = %d):\n", + (int)segment, (int)block, (int)offset); + disable_irq(hdmi_dev->irq); + + /* Enable edid interrupt */ + hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_EDID_READY); + + for (trytime = 0; trytime < 10; trytime++) { + checksum = 0; + 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 < 200; i++) { + /* Wait edid interrupt */ + usleep_range(900, 1000); + 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); + printk("0x%02x ", c); +#endif + } + + if ((checksum & 0xff) == 0) { + ret = 0; + dev_info(hdmi_drv->dev, + "[%s] edid read sucess\n", __func__); + break; + } + } + } + /*close edid irq*/ + hdmi_writel(hdmi_dev, INTERRUPT_MASK1, 0); + /* clear EDID interrupt reg */ + hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, + m_INT_EDID_READY); + + enable_irq(hdmi_dev->irq); + + return ret; +} + +static const char coeff_csc[][24] = { + /*YUV2RGB:601 SD mode(Y[16:235],UV[16:240],RGB[0:255]): + R = 1.164*Y +1.596*V - 204 + G = 1.164*Y - 0.391*U - 0.813*V + 154 + B = 1.164*Y + 2.018*U - 258*/ + { + 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc, + 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a, + 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02}, + + /*YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]): + R = Y + 1.402*V - 248 + G = Y - 0.344*U - 0.714*V + 135 + B = Y + 1.772*U - 227*/ + { + 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8, + 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87, + 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3}, + /*YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]): + R = 1.164*Y +1.793*V - 248 + G = 1.164*Y - 0.213*U - 0.534*V + 77 + B = 1.164*Y + 2.115*U - 289*/ + { + 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8, + 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d, + 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21}, + /*RGB2YUV:601 SD mode: + Cb = -0.291G - 0.148R + 0.439B + 128 + Y = 0.504G + 0.257R + 0.098B + 16 + Cr = -0.368G + 0.439R - 0.071B + 128*/ + { + /*0x11, 0x78, 0x01, 0xc1, 0x10, 0x48, 0x00, 0x80, + 0x02, 0x04, 0x01, 0x07, 0x00, 0x64, 0x00, 0x10, + 0x11, 0x29, 0x10, 0x97, 0x01, 0xc1, 0x00, 0x80*/ + + /*0x11,0x4b,0x01,0x8a,0x10,0x3f,0x00,0x80, + 0x01,0xbb,0x00,0xe2,0x00,0x56,0x00,0x1d, + 0x11,0x05,0x10,0x85,0x01,0x8a,0x00,0x80*/ + + 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80, + 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e, + 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80 + }, + + /*RGB2YUV:709 HD mode: + Cb = - 0.338G - 0.101R + 0.439B + 128 + Y = 0.614G + 0.183R + 0.062B + 16 + Cr = - 0.399G + 0.439R - 0.040B + 128*/ + { + 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80, + 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10, + 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80 + }, + /*RGB[0:255]2RGB[16:235]: + R' = R x (235-16)/255 + 16; + G' = G x (235-16)/255 + 16; + B' = B x (235-16)/255 + 16;*/ + { + 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10, + 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10}, +}; + +static int rockchip_hdmiv1_video_csc(struct hdmi *hdmi_drv, + struct hdmi_video *vpara) +{ + int value, i, csc_mode, c0_c2_change, auto_csc, csc_enable; + const char *coeff = NULL; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + /* Enable or disalbe color space convert */ + dev_info(hdmi_drv->dev, "[%s] input_color=%d,output_color=%d\n", + __func__, vpara->color_input, vpara->color_output); + if (vpara->color_input == vpara->color_output) { + if ((vpara->color_input >= HDMI_COLOR_YCBCR444) || + (vpara->color_input == HDMI_COLOR_RGB_0_255)) { + value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1); + hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); + hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, + m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP, + v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) | + v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE)); + return 0; + } else if (vpara->color_input == HDMI_COLOR_RGB_16_235) { + csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT; + auto_csc = AUTO_CSC_DISABLE; + c0_c2_change = C0_C2_CHANGE_DISABLE; + csc_enable = v_CSC_ENABLE; + } + } + + switch (vpara->vic) { + case HDMI_720X480I_60HZ_4_3: + case HDMI_720X576I_50HZ_4_3: + case HDMI_720X480P_60HZ_4_3: + case HDMI_720X576P_50HZ_4_3: + case HDMI_720X480I_60HZ_16_9: + case HDMI_720X576I_50HZ_16_9: + case HDMI_720X480P_60HZ_16_9: + case HDMI_720X576P_50HZ_16_9: + if (((vpara->color_input == HDMI_COLOR_RGB_0_255) || + (vpara->color_input == HDMI_COLOR_RGB_16_235)) && + vpara->color_output >= HDMI_COLOR_YCBCR444) { + csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT; + auto_csc = AUTO_CSC_DISABLE; + c0_c2_change = C0_C2_CHANGE_DISABLE; + csc_enable = v_CSC_ENABLE; + } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 && + ((vpara->color_output == HDMI_COLOR_RGB_0_255) || + (vpara->color_output == HDMI_COLOR_RGB_16_235))) { +#ifdef AUTO_DEFINE_CSC + csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT; + auto_csc = AUTO_CSC_ENABLE; + c0_c2_change = C0_C2_CHANGE_DISABLE; + csc_enable = v_CSC_DISABLE; +#else + csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT; + auto_csc = AUTO_CSC_DISABLE; + c0_c2_change = C0_C2_CHANGE_ENABLE; + csc_enable = v_CSC_ENABLE; +#endif + } + break; + default: + if (((vpara->color_input == HDMI_COLOR_RGB_0_255) || + (vpara->color_input == HDMI_COLOR_RGB_16_235)) && + vpara->color_output >= HDMI_COLOR_YCBCR444) { + csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT; + auto_csc = AUTO_CSC_DISABLE; + c0_c2_change = C0_C2_CHANGE_DISABLE; + csc_enable = v_CSC_ENABLE; + } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 && + ((vpara->color_output == HDMI_COLOR_RGB_0_255) || + (vpara->color_output == HDMI_COLOR_RGB_16_235))) { +#ifdef AUTO_DEFINE_CSC + csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT; + auto_csc = AUTO_CSC_ENABLE; + c0_c2_change = C0_C2_CHANGE_DISABLE; + csc_enable = v_CSC_DISABLE; +#else + /*CSC_ITU709_16_235_TO_RGB_0_255_8BIT;*/ + csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT; + auto_csc = AUTO_CSC_DISABLE; + c0_c2_change = C0_C2_CHANGE_ENABLE; + csc_enable = v_CSC_ENABLE; +#endif + } + break; + } + + coeff = coeff_csc[csc_mode]; + for (i = 0; i < 24; i++) + hdmi_writel(hdmi_dev, VIDEO_CSC_COEF+i, coeff[i]); + + value = v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1); + hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); + hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, + m_VIDEO_AUTO_CSC | + m_VIDEO_C0_C2_SWAP, + v_VIDEO_AUTO_CSC(auto_csc) | + v_VIDEO_C0_C2_SWAP(c0_c2_change)); + +#if 0 + if (vpara->input_color != vpara->output_color) { + if (vpara->input_color == VIDEO_INPUT_COLOR_RGB) {/*rgb2yuv*/ + coeff = coeff_csc[3]; + for (i = 0; i < 24; i++) + hdmi_writel(hdmi_dev, + VIDEO_CSC_COEF+i, coeff[i]); + + value = v_SOF_DISABLE | v_CSC_ENABLE; + hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); + hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, + m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, + v_VIDEO_AUTO_CSC(0) | + v_VIDEO_C0_C2_EXCHANGE(1)); + } else {/*yuv2rgb*/ +#ifdef AUTO_DEFINE_CSC + value = v_SOF_DISABLE | v_CSC_DISABLE; + hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); + hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, + m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, + v_VIDEO_AUTO_CSC(1) | + v_VIDEO_C0_C2_EXCHANGE(1)); +#else + if (hdmi_drv->lcdc->cur_screen->mode.xres <= 576) { + /*x <= 576,REC-601*/ + coeff = coeff_csc[0]; + pr_info("xres<=576,xres=%d\n", + hdmi_drv->lcdc->cur_screen->mode.xres); + } else/*x > 576,REC-709*/{ + coeff = coeff_csc[2]; + pr_info("xres>576,xres=%d\n", + hdmi_drv->lcdc->cur_screen->mode.xres); + } + for (i = 0; i < 24; i++) + hdmi_writel(hdmi_dev, + VIDEO_CSC_COEF+i, coeff[i]); + + value = v_SOF_DISABLE | v_CSC_ENABLE; + hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); + hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, + m_VIDEO_AUTO_CSC | + m_VIDEO_C0_C2_EXCHANGE, + v_VIDEO_AUTO_CSC(0) | + v_VIDEO_C0_C2_EXCHANGE(0)); +#endif + } + } else { + if (vpara->input_color == VIDEO_INPUT_COLOR_RGB) { + /*rgb[0:255]->rbg[16:235]*/ + coeff = coeff_csc[5]; + for (i = 0; i < 24; i++) + hdmi_writel(hdmi_dev, + VIDEO_CSC_COEF+i, coeff[i]); + + value = v_SOF_DISABLE | v_CSC_ENABLE; + hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); + hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, + m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE, + v_VIDEO_AUTO_CSC(0) | + v_VIDEO_C0_C2_EXCHANGE(1)); + } else { + value = v_SOF_DISABLE; + hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value); + hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL, + m_VIDEO_AUTO_CSC | + m_VIDEO_C0_C2_EXCHANGE, + v_VIDEO_AUTO_CSC(0) | + v_VIDEO_C0_C2_EXCHANGE(1)); + } + } +#endif + return 0; +} + +static int rockchip_hdmiv1_config_vsi(struct hdmi *hdmi, + unsigned char vic_3d, + unsigned char format) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + char info[SIZE_VSI_INFOFRAME]; + int i; + + DBG("[%s] vic_3d %d format %d.\n", __func__, vic_3d, format); + memset(info, 0, SIZE_VSI_INFOFRAME); + hdmi_msk_reg(hdmi_dev, PACKET_SEND_AUTO, + m_PACKET_VSI_EN, v_PACKET_VSI_EN(0)); + hdmi_writel(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_VSI); + /* Header Bytes */ + info[0] = 0x81; + info[1] = 0x01; + /* PB1 - PB3 contain the 24bit IEEE Registration Identifier */ + info[4] = 0x03; + info[5] = 0x0c; + info[6] = 0x00; + /* PB4 - HDMI_Video_Format into bits 7:5 */ + info[7] = format << 5; + /* PB5 - Depending on the video format, this byte will contain either + the HDMI_VIC code in buts 7:0, OR the 3D_Structure in bits 7:4. */ + switch (format) { + case HDMI_VIDEO_FORMAT_4KX2K: + /* This is a 2x4K mode, set the HDMI_VIC in buts 7:0. Values + are from HDMI 1.4 Spec, 8.2.3.1 (Table 8-13). */ + info[2] = 0x06 - 1; + info[8] = vic_3d; + info[9] = 0; + break; + case HDMI_VIDEO_FORMAT_3D: + /* This is a 3D mode, set the 3D_Structure in buts 7:4 + Bits 3:0 are reseved so set to 0. Values are from HDMI 1.4 + Spec, Appendix H (Table H-2). */ + info[8] = vic_3d << 4; + /* Add the Extended data field when the 3D format is + Side-by-Side(Half). See Spec Table H-3 for details. */ + if ((info[8] >> 4) == HDMI_3D_SIDE_BY_SIDE_HALF) { + info[2] = 0x06; + info[9] = 0x00; + } else { + info[2] = 0x06 - 1; + } + break; + default: + info[2] = 0x06 - 2; + info[8] = 0; + info[9] = 0; + break; + } + info[3] = info[0] + info[1] + info[2]; + /* Calculate InfoFrame ChecKsum */ + for (i = 4; i < SIZE_VSI_INFOFRAME; i++) + info[3] += info[i]; + info[3] = 0x100 - info[3]; + + for (i = 0; i < SIZE_VSI_INFOFRAME; i++) + hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]); + hdmi_msk_reg(hdmi_dev, PACKET_SEND_AUTO, + m_PACKET_VSI_EN, v_PACKET_VSI_EN(1)); + return 0; +} + +static void rockchip_hdmiv1_config_avi(struct hdmi *hdmi_drv, + unsigned char vic, + unsigned char output_color) +{ + int i; + int avi_color_mode; + char info[SIZE_AVI_INFOFRAME]; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + memset(info, 0, SIZE_AVI_INFOFRAME); + hdmi_writel(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); + info[0] = 0x82; + info[1] = 0x02; + info[2] = 0x0D; + info[3] = info[0] + info[1] + info[2]; + + if ((output_color == HDMI_COLOR_RGB_0_255) || + (output_color == HDMI_COLOR_RGB_16_235)) + avi_color_mode = AVI_COLOR_MODE_RGB; + else if (output_color == HDMI_COLOR_YCBCR444) + avi_color_mode = AVI_COLOR_MODE_YCBCR444; + else if (output_color == HDMI_COLOR_YCBCR422) + avi_color_mode = AVI_COLOR_MODE_YCBCR422; + + info[4] = (avi_color_mode << 5); + 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; + if ((vic == HDMI_720X480I_60HZ_4_3) || + (vic == HDMI_720X576I_50HZ_4_3) || + (vic == HDMI_720X480I_60HZ_16_9) || + (vic == HDMI_720X480I_60HZ_16_9)) + info[8] = 1; + else + info[8] = 0; + + /* Calculate AVI InfoFrame ChecKsum */ + for (i = 4; i < SIZE_AVI_INFOFRAME; i++) + info[3] += info[i]; + + info[3] = 0x100 - info[3]; + + for (i = 0; i < SIZE_AVI_INFOFRAME; i++) + hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]); +} + +static int rockchip_hdmiv1_config_video(struct hdmi *hdmi_drv, + struct hdmi_video *vpara) +{ + struct fb_videomode *mode; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + int value; + + dev_dbg(hdmi_drv->dev, "[%s]\n", __func__); + + if (vpara == NULL) { + dev_err(hdmi_drv->dev, "[%s] input parameter error\n", + __func__); + return -1; + } + + if (hdmi_dev->soctype == HDMI_SOC_RK3036) { + /*rk3036 vop only can output rgb fmt*/ + vpara->color_input = HDMI_COLOR_RGB_0_255; + } else if (hdmi_dev->soctype == HDMI_SOC_RK312X) { + /* rk3128 vop can output yuv444 fmt */ + /*if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444) + vpara->output_color = VIDEO_OUTPUT_YCBCR444; + else + vpara->output_color = VIDEO_OUTPUT_RGB444;*/ + } + + mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); + if (mode == NULL) { + dev_err(hdmi_drv->dev, "[%s] not found vic %d\n", __func__, + vpara->vic); + return -ENOENT; + } + hdmi_dev->tmdsclk = mode->pixclock; + if (hdmi_drv->uboot) + return 0; + /* Disable video and audio output */ + hdmi_msk_reg(hdmi_dev, AV_MUTE, + m_AUDIO_MUTE | m_VIDEO_BLACK, + v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); + + /* 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); + + value = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS); + if (vpara->color_output <= HDMI_COLOR_RGB_16_235) + value |= v_VIDEO_OUTPUT_COLOR(0); + else + value |= v_VIDEO_OUTPUT_COLOR((vpara->color_output - 2) & 0x3); + if (vpara->color_input <= HDMI_COLOR_RGB_16_235) + value |= v_VIDEO_INPUT_CSP(0); + else + value |= v_VIDEO_INPUT_CSP((vpara->color_input - 2) & 0x1); + + hdmi_writel(hdmi_dev, VIDEO_CONTRL2, value); + /* Set HDMI Mode */ + hdmi_writel(hdmi_dev, HDCP_CTRL, v_HDMI_DVI(vpara->sink_hdmi)); + + /* Enable or disalbe color space convert */ + rockchip_hdmiv1_video_csc(hdmi_drv, vpara); + + /* Set ext video timing */ + if (mode->vmode || mode->pixclock <= 27000000) { + hdmi_writel(hdmi_dev, VIDEO_TIMING_CTL, 0); + } else { + value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode); + if (mode->sync & FB_SYNC_HOR_HIGH_ACT) + value |= v_HSYNC_POLARITY(1); + if (mode->sync & FB_SYNC_VERT_HIGH_ACT) + value |= v_VSYNC_POLARITY(1); + 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(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(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(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(hdmi_dev, VIDEO_EXT_VBLANK, value & 0xFF); + + 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(hdmi_dev, VIDEO_EXT_VDELAY, value & 0xFF); + + value = mode->vsync_len; + hdmi_writel(hdmi_dev, VIDEO_EXT_VDURATION, value & 0xFF); + } + if (vpara->sink_hdmi == OUTPUT_HDMI) { + rockchip_hdmiv1_config_avi(hdmi_drv, vpara->vic, + vpara->color_output); + if (vpara->format_3d != HDMI_3D_NONE) { + rockchip_hdmiv1_config_vsi(hdmi_drv, + vpara->format_3d, + HDMI_VIDEO_FORMAT_3D); + } else if ((vpara->vic > 92 && vpara->vic < 96) || + (vpara->vic == 98)) { + vpara->vic = (vpara->vic == 98) ? + 4 : (96 - vpara->vic); + rockchip_hdmiv1_config_vsi(hdmi_drv, + vpara->vic, + HDMI_VIDEO_FORMAT_4KX2K); + } else { + rockchip_hdmiv1_config_vsi(hdmi_drv, + vpara->vic, + HDMI_VIDEO_FORMAT_NORMAL); + } + dev_info(hdmi_drv->dev, + "[%s] sucess output HDMI.\n", __func__); + } else { + dev_info(hdmi_drv->dev, + "[%s] sucess output DVI.\n", __func__); + } + + /* 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); + + return 0; +} + +static void rockchip_hdmiv1_config_aai(struct hdmi *hdmi_drv) +{ + int i; + char info[SIZE_AUDIO_INFOFRAME]; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + memset(info, 0, SIZE_AUDIO_INFOFRAME); + + info[0] = 0x84; + info[1] = 0x01; + info[2] = 0x0A; + + info[3] = info[0] + info[1] + info[2]; + for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++) + info[3] += info[i]; + + info[3] = 0x100 - info[3]; + + 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 rockchip_hdmiv1_config_audio(struct hdmi *hdmi_drv, + struct hdmi_audio *audio) +{ + int rate, N, channel, mclk_fs; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + if (audio->channel < 3) + channel = I2S_CHANNEL_1_2; + else if (audio->channel < 5) + channel = I2S_CHANNEL_3_4; + 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_drv->dev, + "[%s] not support such sample rate %d\n", + __func__, audio->rate); + return -ENOENT; + } + + /* set_audio source I2S */ + if (hdmi_dev->audiosrc == HDMI_AUDIO_SRC_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(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); + rockchip_hdmiv1_config_aai(hdmi_drv); + + return 0; +} + +int rockchip_hdmiv1_control_output(struct hdmi *hdmi_drv, int enable) +{ + int mutestatus = 0; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + if (hdmi_drv->uboot) { + hdmi_drv->uboot = 0; + return 0; + } + + if (enable == HDMI_AV_UNMUTE) { + if (hdmi_dev->pwr_mode == LOWER_PWR) + rockchip_hdmiv1_set_pwr_mode(hdmi_drv, NORMAL); + + rockchip_hdmiv1_sys_power(hdmi_drv, true); + rockchip_hdmiv1_sys_power(hdmi_drv, false); + delay100us(); + rockchip_hdmiv1_sys_power(hdmi_drv, true); + hdmi_writel(hdmi_dev, 0xce, 0x00); + delay100us(); + hdmi_writel(hdmi_dev, 0xce, 0x01); + + hdmi_readl(hdmi_dev, AV_MUTE, &mutestatus); + if (mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) { + hdmi_msk_reg(hdmi_dev, AV_MUTE, + m_AUDIO_MUTE | m_VIDEO_BLACK, + v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); + } + rockchip_hdmiv1_av_mute(hdmi_drv, 0); + } else { + hdmi_msk_reg(hdmi_dev, AV_MUTE, + m_AUDIO_MUTE | m_VIDEO_BLACK, + v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); + rockchip_hdmiv1_av_mute(hdmi_drv, 1); + msleep(100); + rockchip_hdmiv1_set_pwr_mode(hdmi_drv, LOWER_PWR); + } + return 0; +} + +int rockchip_hdmiv1_removed(struct hdmi *hdmi_drv) +{ + dev_info(hdmi_drv->dev, "Removed.\n"); + if (hdmi_drv->ops->hdcp_power_off_cb) + hdmi_drv->ops->hdcp_power_off_cb(); + + rockchip_hdmiv1_control_output(hdmi_drv, -1); + rockchip_hdmiv1_set_pwr_mode(hdmi_drv, LOWER_PWR); + + return HDMI_ERROR_SUCESS; +} + +static int rockchip_hdmiv1_enable(struct hdmi *hdmi_drv) +{ + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + if (!hdmi_dev->enable) + hdmi_dev->enable = 1; + hdmi_submit_work(hdmi_drv, HDMI_HPD_CHANGE, 10, NULL); + return 0; +} + +static int rockchip_hdmiv1_disable(struct hdmi *hdmi_drv) +{ + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + if (hdmi_dev->enable) + hdmi_dev->enable = 0; + + return 0; +} + +void rockchip_hdmiv1_irq(struct hdmi *hdmi_drv) +{ + u32 interrupt = 0; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &interrupt); + if (interrupt) { + hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt); + dev_info(hdmi_drv->dev, "Clear edid irq.\n"); + } + + hdmi_readl(hdmi_dev, HDMI_STATUS, &interrupt); + if (interrupt) + hdmi_writel(hdmi_dev, HDMI_STATUS, interrupt); + if (interrupt & m_INT_HOTPLUG) + hdmi_submit_work(hdmi_drv, HDMI_HPD_CHANGE, 20, NULL); + + if (hdmi_drv->ops->hdcp_irq_cb) + hdmi_drv->ops->hdcp_irq_cb(0); + if (hdmi_drv->property->feature & SUPPORT_CEC) + rockchip_hdmiv1_cec_isr(hdmi_dev); +} + +static void rockchip_hdmiv1_reset(struct hdmi *hdmi_drv) +{ + u32 val = 0; + u32 msk = 0; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL); + delay100us(); + 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(hdmi_dev, SYS_CTRL, msk, val); + + rockchip_hdmiv1_set_pwr_mode(hdmi_drv, LOWER_PWR); +} + +void rockchip_hdmiv1_dev_init_ops(struct hdmi_ops *ops) +{ + if (ops) { + ops->disable = rockchip_hdmiv1_disable; + ops->enable = rockchip_hdmiv1_enable; + ops->remove = rockchip_hdmiv1_removed; + ops->setmute = rockchip_hdmiv1_control_output; + ops->setvideo = rockchip_hdmiv1_config_video; + ops->setaudio = rockchip_hdmiv1_config_audio; + ops->getstatus = rockchip_hdmiv1_detect_hotplug; + ops->getedid = rockchip_hdmiv1_read_edid; + ops->insert = rockchip_hdmiv1_insert; + ops->setvsi = rockchip_hdmiv1_config_vsi; + } +} + +int rockchip_hdmiv1_initial(struct hdmi *hdmi_drv) +{ + int rc = HDMI_ERROR_SUCESS; + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + + hdmi_dev->pwr_mode = NORMAL; + + if (!hdmi_drv->uboot) { + rockchip_hdmiv1_reset_pclk(); + rockchip_hdmiv1_reset(hdmi_drv); + } else if (hdmi_drv->ops->getstatus(hdmi_drv) == HDMI_HPD_REMOVED) { + rockchip_hdmiv1_removed(hdmi_drv); + hdmi_drv->lcdc->uboot_logo = 0; + hdmi_drv->uboot = 0; + } + if (hdmi_drv->property->feature & SUPPORT_CEC) + rockchip_hdmiv1_cec_init(hdmi_drv); + if (hdmi_drv->property->feature & SUPPORT_HDCP) + rockchip_hdmiv1_hdcp_init(hdmi_drv); + return rc; +} diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.h b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.h new file mode 100644 index 000000000000..0b442d303048 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.h @@ -0,0 +1,448 @@ +#ifndef __ROCKCHIP_HDMI_V1_HW_H__ +#define __ROCKCHIP_HDMI_V1_HW_H__ + +#include +#include + +enum PWR_MODE { + NORMAL, + LOWER_PWR, +}; +enum { + OUTPUT_DVI = 0, + OUTPUT_HDMI +}; + +/* C0 C2 Change */ +enum { + C0_C2_CHANGE_ENABLE, /* enable c0 c2 change*/ + C0_C2_CHANGE_DISABLE /* disable c0 c2 change*/ +}; + +/* Auto CSC mode enable */ +enum { + AUTO_CSC_DISABLE, /* disable auto csc*/ + AUTO_CSC_ENABLE /* enable auto csc*/ +}; + + +/* Color Limit Range */ +enum { + COLOR_LIMIT_RANGE_0_255, /* Color Limit Range 0 To 255*/ + COLOR_LIMIT_RANGE_16_235, /* Color Limit Range 16 To 235*/ +}; +/* Color Space Convertion Mode */ +enum { + CSC_ITU601_16_235_TO_RGB_0_255_8BIT,/* YCbCr 16-235 input to RGB + 0-255 output according BT601 + that is 8bit clolor depth */ + CSC_ITU601_0_255_TO_RGB_0_255_8BIT, /* YCbCr 0-255 input to RGB + 0-255 output according BT601 + that is 8bit clolor depth */ + CSC_ITU709_16_235_TO_RGB_0_255_8BIT,/* YCbCr 16-235 input to RGB + 0-255 output according BT709 + that is 8bit clolor depth */ + CSC_RGB_0_255_TO_ITU601_16_235_8BIT,/* RGB 0-255 input to YCbCr + 16-235 output according BT601 + that is 8bit clolor depth */ + CSC_RGB_0_255_TO_ITU709_16_235_8BIT,/* RGB 0-255 input to YCbCr 16-235 + output accroding BT709 that is + 8bit clolor depth */ + CSC_RGB_0_255_TO_RGB_16_235_8BIT, /* RGB 0-255 input to RGB 16-235 + output that is 8bit clolor depth + */ +}; + + +#define AUTO_DEFINE_CSC +#ifdef RK616_USE_MCLK_12M +#define HDMI_SYS_FREG_CLK 12000000 +#else +#define HDMI_SYS_FREG_CLK 11289600 +#endif + +#define HDMI_SCL_RATE (100*1000) +#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_COLOR (3 << 6) +#define m_VIDEO_INPUT_BITS (3 << 4) +#define m_VIDEO_INPUT_CSP (1 << 0) +#define v_VIDEO_OUTPUT_COLOR(n) (((n)&0x3) << 6) +#define v_VIDEO_INPUT_BITS(n) (n << 4) +#define v_VIDEO_INPUT_CSP(n) (n << 0) + +enum { + VIDEO_INPUT_12BITS = 0, + VIDEO_INPUT_10BITS, + VIDEO_INPUT_REVERT, + VIDEO_INPUT_8BITS +}; +#define VIDEO_CONTRL 0x03 +#define m_VIDEO_AUTO_CSC (1 << 7) +#define v_VIDEO_AUTO_CSC(n) (n << 7) +#define m_VIDEO_C0_C2_SWAP (1 << 0) +#define v_VIDEO_C0_C2_SWAP(n) (n << 0) + + +#define VIDEO_CONTRL3 0x04 +#define m_COLOR_DEPTH_NOT_INDICATED (1 << 4) +#define m_SOF (1 << 3) +#define m_COLOR_RANGE (1 << 2) +#define m_CSC (1 << 0) +#define v_COLOR_DEPTH_NOT_INDICATED(n) ((n) << 4) /*1: Force GCP CD[3:0] zero + 0: GCP CD[3:0] according + color depth*/ +#define v_SOF_ENABLE (0 << 3) +#define v_SOF_DISABLE (1 << 3) +#define v_COLOR_RANGE_FULL (1 << 2) +#define v_COLOR_RANGE_LIMITED (0 << 2) +#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_AVMUTE_CLEAR(n) (n << 7) +#define v_AVMUTE_ENABLE(n) (n << 6) +#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 VIDEO_CSC_COEF 0x18 + + +#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 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 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 DDC_CLK_L 0x4b +#define DDC_CLK_H 0x4c + +#define EDID_SEGMENT_POINTER 0x4d +#define EDID_WORD_ADDR 0x4e +#define EDID_FIFO_OFFSET 0x4f +#define EDID_FIFO_ADDR 0x50 + + +#define PACKET_SEND_MANUAL 0x9c +#define PACKET_SEND_AUTO 0x9d + #define m_PACKET_GCP_EN (1 << 7) + #define m_PACKET_MSI_EN (1 << 6) /*MPEG Source InfoFrame*/ + #define m_PACKET_SDI_EN (1 << 5) /*Source product descriptor*/ + #define m_PACKET_VSI_EN (1 << 4) /*HDMI Vendor Specific + InfoFrame*/ + #define v_PACKET_GCP_EN(n) ((n & 1) << 7) + #define v_PACKET_MSI_EN(n) ((n & 1) << 6) + #define v_PACKET_SDI_EN(n) ((n & 1) << 5) + #define v_PACKET_VSI_EN(n) ((n & 1) << 4) + +/* CONTROL_PACKET_BUF_INDEX */ +#define CONTROL_PACKET_BUF_INDEX 0x9f +enum { + INFOFRAME_VSI = 0x05, + INFOFRAME_AVI = 0x06, + INFOFRAME_AAI = 0x08, +}; +#define CONTROL_PACKET_ADDR 0xa0 +#define SIZE_VSI_INFOFRAME 0x0A /* 10 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, + AVI_COLOR_MODE_YCBCR444 +}; +enum { + AVI_COLORIMETRY_NO_DATA = 0, + AVI_COLORIMETRY_SMPTE_170M, + AVI_COLORIMETRY_ITU709, + AVI_COLORIMETRY_EXTENDED +}; +enum { + AVI_CODED_FRAME_ASPECT_NO_DATA, + AVI_CODED_FRAME_ASPECT_4_3, + AVI_CODED_FRAME_ASPECT_16_9 +}; +enum { + ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME = 0x08, + ACTIVE_ASPECT_RATE_4_3, + ACTIVE_ASPECT_RATE_16_9, + ACTIVE_ASPECT_RATE_14_9 +}; + +#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_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_MASK_INT_HOTPLUG (1 << 5) + #define m_INT_HOTPLUG (1 << 1) + #define v_MASK_INT_HOTPLUG(n) ((n & 0x1) << 5) + +#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 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 PHY_PRE_DIV_RATIO 0xed +#define v_PRE_DIV_RATIO(n) (n & 0x1f) + + +/*-----START----- HDMI CEC CTRL------START------*/ +#define CEC_CTRL 0xd0 + #define m_ADJUST_FOR_HISENSE (1 << 6) + #define m_REJECT_RX_BROADCAST (1 << 5) + #define m_BUSFREETIME_ENABLE (1 << 2) + #define m_REJECT_RX (1 << 1) + #define m_START_TX (1 << 0) + +#define CEC_DATA 0xd1 +#define CEC_TX_OFFSET 0xd2 +#define CEC_RX_OFFSET 0xd3 +#define CEC_CLK_H 0xd4 +#define CEC_CLK_L 0xd5 +#define CEC_TX_LENGTH 0xd6 +#define CEC_RX_LENGTH 0xd7 +#define CEC_TX_INT_MASK 0xd8 + #define m_TX_DONE (1 << 3) + #define m_TX_NOACK (1 << 2) + #define m_TX_BROADCAST_REJ (1 << 1) + #define m_TX_BUSNOTFREE (1 << 0) + +#define CEC_RX_INT_MASK 0xd9 + #define m_RX_LA_ERR (1 << 4) + #define m_RX_GLITCH (1 << 3) + #define m_RX_DONE (1 << 0) + +#define CEC_TX_INT 0xda +#define CEC_RX_INT 0xdb +#define CEC_BUSFREETIME_L 0xdc +#define CEC_BUSFREETIME_H 0xdd +#define CEC_LOGICADDR 0xde +/*------END------ HDMI CEC CTRL------END-------*/ + + +static inline int hdmi_readl(struct hdmi_dev *hdmi_dev, + u16 offset, + u32 *val) +{ + int ret = 0; + + *val = readl_relaxed(hdmi_dev->regbase + (offset) * 0x04); + return ret; +} + +static inline int hdmi_writel(struct hdmi_dev *hdmi_dev, + u16 offset, + u32 val) +{ + int ret = 0; + + writel_relaxed(val, hdmi_dev->regbase + (offset) * 0x04); + return ret; +} + +static inline int hdmi_msk_reg(struct hdmi_dev *hdmi_dev, + u16 offset, u32 msk, u32 val) +{ + int ret = 0; + u32 temp; + + temp = readl_relaxed(hdmi_dev->regbase + + (offset) * 0x04) & (0xFF - (msk)); + writel_relaxed(temp | ((val) & (msk)), + hdmi_dev->regbase + (offset) * 0x04); + return ret; +} +static inline void rockchip_hdmiv1_reset_pclk(void) +{ + writel_relaxed(0x00010001, RK_CRU_VIRT + 0x128); + msleep(100); + writel_relaxed(0x00010000, RK_CRU_VIRT + 0x128); +} + + + +void rockchip_hdmiv1_dev_init_ops(struct hdmi_ops *ops); +int rockchip_hdmiv1_initial(struct hdmi *hdmi); +void rockchip_hdmiv1_irq(struct hdmi *hdmi); +void rockchip_hdmiv1_cec_init(struct hdmi *hdmi); +void rockchip_hdmiv1_cec_isr(struct hdmi_dev *hdmi_dev); + +#endif diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/Kconfig b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/Kconfig new file mode 100644 index 000000000000..5d62e73ceac8 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/Kconfig @@ -0,0 +1,7 @@ +config RK_HDMI_V2 + bool "RockChip HDMI V2 support" + depends on RK_HDMI + default y + help + Rockchip hdmi version 2 which support hdmi 2.0. + diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/Makefile b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/Makefile new file mode 100644 index 000000000000..ddff17707dac --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for HDMI linux kernel module. +# + +ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG + +obj-$(CONFIG_RK_HDMI_V2) += rockchip_hdmiv2.o rockchip_hdmiv2_hw.o rockchip_hdmiv2_cec.o rockchip_hdmiv2_hdcp.o diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c new file mode 100644 index 000000000000..fdfeead8d431 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c @@ -0,0 +1,532 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_DEBUG_FS) +#include +#include +#include +#include +#endif + +#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 = { + .videosrc = DISPLAY_SOURCE_LCDC0, + .display = DISPLAY_MAIN, +}; + +#if defined(CONFIG_DEBUG_FS) +static const struct rockchip_hdmiv2_reg_table hdmi_reg_table[] = { + {IDENTIFICATION_BASE, CONFIG3_ID}, + {INTERRUPT_BASE, IH_MUTE}, + {VIDEO_SAMPLER_BASE, TX_BCBDATA1}, + {VIDEO_PACKETIZER_BASE, VP_MASK}, + {FRAME_COMPOSER_BASE, FC_DBGTMDS2}, + {HDMI_SOURCE_PHY_BASE, PHY_PLLCFGFREQ2}, + {I2C_MASTER_PHY_BASE, PHY_I2CM_SDA_HOLD}, + {AUDIO_SAMPLER_BASE, AHB_DMA_STPADDR_SET1_0}, + {MAIN_CONTROLLER_BASE, MC_SWRSTZREQ_2}, + {COLOR_SPACE_CONVERTER_BASE, CSC_SPARE_2}, + {HDCP_ENCRYPTION_ENGINE_BASE, HDCP_REVOC_LIST}, + {HDCP_BKSV_BASE, HDCPREG_BKSV4}, + {HDCP_AN_BASE, HDCPREG_AN7}, + {HDCP2REG_BASE, HDCP2REG_MUTE}, + {ENCRYPTED_DPK_EMBEDDED_BASE, HDCPREG_DPK6}, + {CEC_ENGINE_BASE, CEC_WKUPCTRL}, + {I2C_MASTER_BASE, I2CM_SCDC_UPDATE1}, +}; + +static int rockchip_hdmiv2_reg_show(struct seq_file *s, void *v) +{ + int i = 0, j = 0; + u32 val = 0; + + seq_puts(s, "\n>>>hdmi_ctl reg "); + for (i = 0; i < 16; i++) + seq_printf(s, " %2x", i); + seq_puts(s, "\n-----------------------------------------------------------------"); + + for (i = 0; i < ARRAY_SIZE(hdmi_reg_table); 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) + 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) +{ + u32 reg; + u32 val; + char kbuf[25]; + + if (copy_from_user(kbuf, buf, count)) + return -EFAULT; + if (sscanf(kbuf, "%x%x", ®, &val) == -1) + return -EFAULT; + if ((reg < 0) || (reg > I2CM_SCDC_UPDATE1)) { + dev_info(hdmi_dev->hdmi->dev, "it is no hdmi reg\n"); + return count; + } + dev_info(hdmi_dev->hdmi->dev, + "/**********hdmi reg config******/"); + dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val); + hdmi_writel(hdmi_dev, reg, val); + + return count; +} + +static int rockchip_hdmiv2_reg_open(struct inode *inode, struct file *file) +{ + struct hdmi_dev *hdmi_dev = inode->i_private; + + return single_open(file, rockchip_hdmiv2_reg_show, hdmi_dev); +} + +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, +}; +#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); + /* 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); + rockchip_hdmiv2_clk_disable(hdmi_dev); +} + +static void rockchip_hdmiv2_early_resume(struct early_suspend *h) +{ + struct hdmi *hdmi = hdmi_dev->hdmi; + + HDMIDBG("hdmi exit early resume\n"); + /* iomux to default state for hdmi use when resume */ + pinctrl_select_state(hdmi_dev->dev->pins->p, + hdmi_dev->dev->pins->default_state); + rockchip_hdmiv2_clk_enable(hdmi_dev); + 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); +} +#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) + +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 && + hdmi_dev->soctype == HDMI_SOC_RK3288) { + 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); + hdmi_dev->clk_on |= HDMI_PD_ON; + } + + if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) { + if (hdmi_dev->pclk == NULL) { + hdmi_dev->pclk = + devm_clk_get(hdmi_dev->dev, "pclk_hdmi"); + if (IS_ERR(hdmi_dev->pclk)) { + dev_err(hdmi_dev->dev, + "Unable to get hdmi pclk\n"); + return -1; + } + } + clk_prepare_enable(hdmi_dev->pclk); + hdmi_dev->clk_on |= HDMI_PCLK_ON; + } + + if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) { + if (hdmi_dev->hdcp_clk == NULL) { + hdmi_dev->hdcp_clk = + devm_clk_get(hdmi_dev->dev, "hdcp_clk_hdmi"); + if (IS_ERR(hdmi_dev->hdcp_clk)) { + dev_err(hdmi_dev->dev, + "Unable to get hdmi hdcp_clk\n"); + return -1; + } + } + clk_prepare_enable(hdmi_dev->hdcp_clk); + hdmi_dev->clk_on |= HDMI_HDCPCLK_ON; + } + + if ((rk_hdmi_property.feature & SUPPORT_CEC) && + (hdmi_dev->clk_on & HDMI_CECCLK_ON) == 0) { + if (hdmi_dev->cec_clk == NULL) { + hdmi_dev->cec_clk = + devm_clk_get(hdmi_dev->dev, "cec_clk_hdmi"); + if (IS_ERR(hdmi_dev->cec_clk)) { + dev_err(hdmi_dev->dev, + "Unable to get hdmi cec_clk\n"); + return -1; + } + } + clk_prepare_enable(hdmi_dev->cec_clk); + hdmi_dev->clk_on |= HDMI_CECCLK_ON; + } + return 0; +} + +static int rockchip_hdmiv2_clk_disable(struct hdmi_dev *hdmi_dev) +{ + 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); + hdmi_dev->clk_on &= ~HDMI_PD_ON; + } + + if ((hdmi_dev->clk_on & HDMI_PCLK_ON) && + (hdmi_dev->pclk != NULL)) { + 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)) { + clk_disable_unprepare(hdmi_dev->hdcp_clk); + hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON; + } + + return 0; +} + +static int rockchip_hdmiv2_fb_event_notify(struct notifier_block *self, + 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; + + if (action == FB_EARLY_EVENT_BLANK) { + switch (blank_mode) { + 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); + rockchip_hdmiv2_clk_disable(hdmi_dev); + } + break; + } + } else if (action == FB_EVENT_BLANK) { + switch (blank_mode) { + case FB_BLANK_UNBLANK: + HDMIDBG("resume hdmi\n"); + if (hdmi->sleep) { + rockchip_hdmiv2_clk_enable(hdmi_dev); + rockchip_hdmiv2_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); + } + break; + default: + break; + } + } + return NOTIFY_OK; +} + +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), + msecs_to_jiffies(50)); + } +} +#endif + +static struct hdmi_ops rk_hdmi_ops; + + +#if defined(CONFIG_OF) +static const struct of_device_id rk_hdmi_dt_ids[] = { + {.compatible = "rockchip,rk3288-hdmi",}, + {.compatible = "rockchip,rk3368-hdmi",}, + {} +}; + +static int rockchip_hdmiv2_parse_dt(struct hdmi_dev *hdmi_dev) +{ + int val = 0; + struct device_node *np = hdmi_dev->dev->of_node; + const struct of_device_id *match; + + match = of_match_node(rk_hdmi_dt_ids, np); + if (!match) + return PTR_ERR(match); + + if (!strcmp(match->compatible, "rockchip,rk3288-hdmi")) { + hdmi_dev->soctype = HDMI_SOC_RK3288; + } else if (!strcmp(match->compatible, "rockchip,rk3368-hdmi")) { + hdmi_dev->soctype = HDMI_SOC_RK3368; + } else { + pr_err("It is not a valid rockchip soc!"); + return -ENOMEM; + } + + if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val)) + rk_hdmi_property.videosrc = val; + + if (!of_property_read_u32(np, "rockchip,hdmi_audio_source", &val)) + hdmi_dev->audiosrc = val; + + if (!of_property_read_u32(np, "rockchip,cec_enable", &val) && + (val == 1)) { + pr_info("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"); + rk_hdmi_property.feature |= SUPPORT_HDCP; + } + #ifdef CONFIG_MFD_SYSCON + hdmi_dev->grf_base = + syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); + #endif + return 0; +} +#endif + +static int rockchip_hdmiv2_probe(struct platform_device *pdev) +{ + int ret = -1; + struct resource *res; + + HDMIDBG("%s\n", __func__); + hdmi_dev = kmalloc(sizeof(*hdmi_dev), GFP_KERNEL); + if (!hdmi_dev) { + dev_err(&pdev->dev, ">>rockchip hdmiv2 kmalloc fail!"); + return -ENOMEM; + } + memset(hdmi_dev, 0, sizeof(struct hdmi_dev)); + platform_set_drvdata(pdev, hdmi_dev); + hdmi_dev->dev = &pdev->dev; + + rockchip_hdmiv2_parse_dt(hdmi_dev); + + /*request and remap iomem*/ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get register resource\n"); + 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); + dev_err(&pdev->dev, + "cannot ioremap registers,err=%d\n", ret); + goto failed; + } + + /*enable pd and pclk and hdcp_clk*/ + if (rockchip_hdmiv2_clk_enable(hdmi_dev) < 0) { + 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;*/ + if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0) + rk_hdmi_property.feature |= + SUPPORT_4K | + SUPPORT_TMDS_600M; + } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) { + rk_hdmi_property.feature |= + SUPPORT_4K | + SUPPORT_4K_4096 | + SUPPORT_YUV420; + } + hdmi_dev->hdmi = + rockchip_hdmi_register(&rk_hdmi_property, &rk_hdmi_ops); + if (hdmi_dev->hdmi == NULL) { + dev_err(&pdev->dev, "register hdmi device failed\n"); + ret = -ENOMEM; + goto failed1; + } + mutex_init(&hdmi_dev->ddc_lock); + hdmi_dev->hdmi->dev = &pdev->dev; + hdmi_dev->hdmi->soctype = hdmi_dev->soctype; + fb_register_client(&rockchip_hdmiv2_fb_notifier); + rockchip_hdmiv2_dev_initial(hdmi_dev); + pinctrl_select_state(hdmi_dev->dev->pins->p, + hdmi_dev->dev->pins->default_state); +#if defined(CONFIG_DEBUG_FS) + hdmi_dev->debugfs_dir = debugfs_create_dir("rockchip_hdmiv2", NULL); + 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, + hdmi_dev->debugfs_dir, + hdmi_dev, &rockchip_hdmiv2_reg_fops); +#endif + rk_display_device_enable(hdmi_dev->hdmi->ddev); + +#ifndef HDMI_INT_USE_POLL + /* get and request the IRQ */ + hdmi_dev->irq = platform_get_irq(pdev, 0); + if (hdmi_dev->irq <= 0) { + dev_err(hdmi_dev->dev, + "failed to get hdmi irq resource (%d).\n", + hdmi_dev->irq); + ret = -ENXIO; + 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); + if (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), + rockchip_hdmiv2_irq_work_func); + rockchip_hdmiv2_irq_work_func(NULL); + +#endif + dev_info(&pdev->dev, "rockchip hdmiv2 probe sucess.\n"); + return 0; + +failed1: + rockchip_hdmi_unregister(hdmi_dev->hdmi); +failed: + kfree(hdmi_dev); + hdmi_dev = NULL; + dev_err(&pdev->dev, "rk3288 hdmi probe error.\n"); + return ret; +} + +static int rockchip_hdmiv2_remove(struct platform_device *pdev) +{ + dev_info(&pdev->dev, "rk3288 hdmi driver removed.\n"); + return 0; +} + +static void rockchip_hdmiv2_shutdown(struct platform_device *pdev) +{ + struct hdmi *hdmi; + + if (hdmi_dev) { + #ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&hdmi_dev->early_suspend); + #endif + hdmi = hdmi_dev->hdmi; + if (hdmi->hotplug == HDMI_HPD_ACTIVED && + hdmi->ops->setmute) + hdmi->ops->setmute(hdmi, HDMI_VIDEO_MUTE); + } +} + +static struct platform_driver rockchip_hdmiv2_driver = { + .probe = rockchip_hdmiv2_probe, + .remove = rockchip_hdmiv2_remove, + .driver = { + .name = "rockchip-hdmiv2", + .owner = THIS_MODULE, + #if defined(CONFIG_OF) + .of_match_table = of_match_ptr(rk_hdmi_dt_ids), + #endif + }, + .shutdown = rockchip_hdmiv2_shutdown, +}; + +static int __init rockchip_hdmiv2_init(void) +{ + return platform_driver_register(&rockchip_hdmiv2_driver); +} + +static void __exit rockchip_hdmiv2_exit(void) +{ + platform_driver_unregister(&rockchip_hdmiv2_driver); +} + +module_init(rockchip_hdmiv2_init); +module_exit(rockchip_hdmiv2_exit); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h new file mode 100644 index 000000000000..7e4b4535c0f4 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h @@ -0,0 +1,52 @@ +#ifndef __RK32_HDMI_H__ +#define __RK32_HDMI_H__ +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include "../rockchip-hdmi.h" + +#ifdef DEBUG +#define HDMIDBG(format, ...) \ + pr_info(format, ## __VA_ARGS__) +#else +#define HDMIDBG(format, ...) +#endif + +struct hdmi_dev { + void __iomem *regbase; + int regbase_phy; + int regsize_phy; + struct regmap *grf_base; + + struct clk *pd; + struct clk *pclk; + struct clk *hdcp_clk; + struct clk *cec_clk; + struct hdmi *hdmi; + struct device *dev; + struct dentry *debugfs_dir; + int irq; + + struct work_struct irq_work; + struct delayed_work delay_work; + struct workqueue_struct *workqueue; + +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif + int soctype; + int audiosrc; + int enable; + unsigned char clk_disable; + unsigned char clk_on; + + unsigned long pixelclk; + unsigned int tmdsclk; + unsigned int pixelrepeat; + unsigned char colordepth; + + bool tmdsclk_ratio_change; + struct mutex ddc_lock; /*mutex for ddc operation */ +}; +#endif /*__RK32_HDMI_H__*/ diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c new file mode 100644 index 000000000000..e7c1a8337101 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c @@ -0,0 +1,113 @@ +#include +#include "../rockchip-hdmi-cec.h" +#include "rockchip_hdmiv2.h" +#include "rockchip_hdmiv2_hw.h" + +/* static wait_queue_head_t wait;*/ +static int init = 1; +void rockchip_hdmiv2_cec_isr(struct hdmi_dev *hdmi_dev, char cec_int) +{ + CECDBG("%s cec 0x%x\n", __func__, cec_int); + if (cec_int & m_EOM) + rockchip_hdmi_cec_submit_work(EVENT_RX_FRAME, 0, NULL); + if (cec_int & m_DONE) + CECDBG("send frame success\n"); +} + +static int rockchip_hdmiv2_cec_readframe(struct hdmi *hdmi, + struct cec_framedata *frame) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + int i, count; + char *data = (char *)frame; + + if (frame == NULL) + return -1; + count = hdmi_readl(hdmi_dev, CEC_RX_CNT); + CECDBG("%s count %d\n", __func__, count); + for (i = 0; i < count; i++) { + data[i] = hdmi_readl(hdmi_dev, CEC_RX_DATA0 + i); + CECDBG("%02x\n", data[i]); + } + hdmi_writel(hdmi_dev, CEC_LOCK, 0x0); + return 0; +} + + +void rockchip_hdmiv2_cec_setcecla(struct hdmi *hdmi, int ceclgaddr) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + short val; + + if (ceclgaddr < 0 || ceclgaddr > 16) + return; + val = 1 << ceclgaddr; + hdmi_writel(hdmi_dev, CEC_ADDR_L, val & 0xff); + hdmi_writel(hdmi_dev, CEC_ADDR_H, val>>8); +} + +static int rockchip_hdmiv2_cec_sendframe(struct hdmi *hdmi, + struct cec_framedata *frame) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + int i, interrupt; + + CECDBG("TX srcdestaddr %02x opcode %02x ", + frame->srcdestaddr, frame->opcode); + if (frame->argcount) { + CECDBG("args:"); + for (i = 0; i < frame->argcount; i++) + CECDBG("%02x ", frame->args[i]); + } + CECDBG("\n"); + if ((frame->srcdestaddr & 0x0f) == ((frame->srcdestaddr >> 4) & 0x0f)) { + /*it is a ping command*/ + hdmi_writel(hdmi_dev, CEC_TX_DATA0, frame->srcdestaddr); + hdmi_writel(hdmi_dev, CEC_TX_CNT, 1); + } else { + hdmi_writel(hdmi_dev, CEC_TX_DATA0, frame->srcdestaddr); + hdmi_writel(hdmi_dev, CEC_TX_DATA0 + 1, frame->opcode); + for (i = 0; i < frame->argcount; i++) + hdmi_writel(hdmi_dev, + CEC_TX_DATA0 + 2 + i, frame->args[i]); + hdmi_writel(hdmi_dev, CEC_TX_CNT, frame->argcount + 2); + } + /*Start TX*/ + hdmi_msk_reg(hdmi_dev, CEC_CTRL, m_CEC_SEND, v_CEC_SEND(1)); + i = 20; + while (i--) { + usleep_range(900, 1000); + interrupt = hdmi_readl(hdmi_dev, IH_CEC_STAT0); + if (interrupt & (m_ERR_INITIATOR | m_ARB_LOST | + m_NACK | m_DONE)) { + hdmi_writel(hdmi_dev, IH_CEC_STAT0, + interrupt & (m_ERR_INITIATOR | + m_ARB_LOST | m_NACK | m_DONE)); + break; + } + } + CECDBG("%s interrupt 0x%02x\n", __func__, interrupt); + if (interrupt & m_DONE) + return 0; + else if (interrupt & m_NACK) + return 1; + else + return -1; +} + +void rockchip_hdmiv2_cec_init(struct hdmi *hdmi) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + if (init) { + rockchip_hdmi_cec_init(hdmi, + rockchip_hdmiv2_cec_sendframe, + rockchip_hdmiv2_cec_readframe, + rockchip_hdmiv2_cec_setcecla); + init = 0; + /* init_waitqueue_head(&wait); */ + } + hdmi_writel(hdmi_dev, IH_MUTE_CEC_STAT0, m_ERR_INITIATOR | + m_ARB_LOST | m_NACK | m_DONE); + CECDBG("%s", __func__); +} diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hdcp.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hdcp.c new file mode 100644 index 000000000000..d321811dd81f --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hdcp.c @@ -0,0 +1,299 @@ +#include +#include +#include +#include +#include +#include +#include +#include "rockchip_hdmiv2.h" +#include "rockchip_hdmiv2_hw.h" + +#define HDCP_KEY_SIZE 308 +#define HDCP_PRIVATE_KEY_SIZE 280 +#define HDCP_KEY_SHA_SIZE 20 +#define HDCP_KEY_SEED_SIZE 2 + +struct hdcp_keys { + u8 KSV[8]; + u8 devicekey[HDCP_PRIVATE_KEY_SIZE]; + u8 sha1[HDCP_KEY_SHA_SIZE]; +}; + +struct hdcp { + struct hdmi *hdmi; + int enable; + int retry_times; + struct hdcp_keys *keys; + char *seeds; + int invalidkey; + char *invalidkeys; +}; + +static struct miscdevice mdev; +static struct hdcp *hdcp = NULL; + +static void hdcp_load_key(struct hdmi *hdmi, struct hdcp_keys *key) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + int i, value; + + /* Disable decryption logic */ + hdmi_writel(hdmi_dev, HDCPREG_RMCTL, 0); + /* Poll untile DPK write is allowed */ + do { + value = hdmi_readl(hdmi_dev, HDCPREG_RMSTS); + } while ((value & m_DPK_WR_OK_STS) == 0); + + /* write unencryped AKSV */ + hdmi_writel(hdmi_dev, HDCPREG_DPK6, 0); + hdmi_writel(hdmi_dev, HDCPREG_DPK5, 0); + hdmi_writel(hdmi_dev, HDCPREG_DPK4, key->KSV[4]); + hdmi_writel(hdmi_dev, HDCPREG_DPK3, key->KSV[3]); + hdmi_writel(hdmi_dev, HDCPREG_DPK2, key->KSV[2]); + hdmi_writel(hdmi_dev, HDCPREG_DPK1, key->KSV[1]); + hdmi_writel(hdmi_dev, HDCPREG_DPK0, key->KSV[0]); + /* Poll untile DPK write is allowed */ + do { + value = hdmi_readl(hdmi_dev, HDCPREG_RMSTS); + } while ((value & m_DPK_WR_OK_STS) == 0); + + if (hdcp->seeds != NULL) { + hdmi_writel(hdmi_dev, HDCPREG_RMCTL, 1); + hdmi_writel(hdmi_dev, HDCPREG_SEED1, hdcp->seeds[0]); + hdmi_writel(hdmi_dev, HDCPREG_SEED0, hdcp->seeds[1]); + } else { + hdmi_writel(hdmi_dev, HDCPREG_RMCTL, 0); + } + + /* write private key */ + for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i += 7) { + hdmi_writel(hdmi_dev, HDCPREG_DPK6, key->devicekey[i + 6]); + hdmi_writel(hdmi_dev, HDCPREG_DPK5, key->devicekey[i + 5]); + hdmi_writel(hdmi_dev, HDCPREG_DPK4, key->devicekey[i + 4]); + hdmi_writel(hdmi_dev, HDCPREG_DPK3, key->devicekey[i + 3]); + hdmi_writel(hdmi_dev, HDCPREG_DPK2, key->devicekey[i + 2]); + hdmi_writel(hdmi_dev, HDCPREG_DPK1, key->devicekey[i + 1]); + hdmi_writel(hdmi_dev, HDCPREG_DPK0, key->devicekey[i]); + + do { + value = hdmi_readl(hdmi_dev, HDCPREG_RMSTS); + } while ((value & m_DPK_WR_OK_STS) == 0); + } + + pr_info("%s success\n", __func__); +} + +static void hdcp_load_keys_cb(const struct firmware *fw, + void *context) +{ + struct hdmi *hdmi = (struct hdmi *)context; + + if (fw->size < HDCP_KEY_SIZE) { + pr_err("HDCP: firmware wrong size %d\n", (int)fw->size); + return; + } + hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL); + memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE); + + if (fw->size > HDCP_KEY_SIZE) { + if ((fw->size - HDCP_KEY_SIZE) < HDCP_KEY_SEED_SIZE) { + pr_err("HDCP: invalid seed key size\n"); + return; + } + hdcp->seeds = kmalloc(HDCP_KEY_SEED_SIZE, GFP_KERNEL); + if (hdcp->seeds == NULL) { + pr_err("HDCP: can't allocated space for seed keys\n"); + return; + } + memcpy(hdcp->seeds, fw->data + HDCP_KEY_SIZE, + HDCP_KEY_SEED_SIZE); + } + hdcp_load_key(hdmi, hdcp->keys); +} + +static void rockchip_hdmiv2_hdcp_start(struct hdmi *hdmi) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + if (!hdcp->enable) + return; + if (hdmi_dev->soctype == HDMI_SOC_RK3368) { + hdmi_msk_reg(hdmi_dev, HDCP2REG_CTRL, + m_HDCP2_OVR_EN | m_HDCP2_FORCE, + v_HDCP2_OVR_EN(1) | v_HDCP2_FORCE(0)); + hdmi_writel(hdmi_dev, HDCP2REG_MASK, 0x00); + hdmi_writel(hdmi_dev, HDCP2REG_MUTE, 0x00); + } + + hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, + m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1)); + hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, + m_HDMI_DVI, v_HDMI_DVI(hdmi->edid.sink_hdmi)); + hdmi_writel(hdmi_dev, A_OESSWCFG, 0x40); + hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, + m_ENCRYPT_BYPASS | m_FEATURE11_EN | m_SYNC_RI_CHECK, + v_ENCRYPT_BYPASS(0) | v_FEATURE11_EN(0) | + v_SYNC_RI_CHECK(1)); + hdmi_msk_reg(hdmi_dev, A_HDCPCFG1, + m_ENCRYPT_DISBALE | m_PH2UPSHFTENC, + v_ENCRYPT_DISBALE(0) | v_PH2UPSHFTENC(1)); + /* Reset HDCP Engine */ + hdmi_msk_reg(hdmi_dev, A_HDCPCFG1, + m_HDCP_SW_RST, v_HDCP_SW_RST(0)); + + hdmi_writel(hdmi_dev, A_APIINTMSK, 0x00); + hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_RX_DETECT, v_RX_DETECT(1)); + + hdmi_msk_reg(hdmi_dev, MC_CLKDIS, + m_HDCPCLK_DISABLE, v_HDCPCLK_DISABLE(0)); + pr_info("%s success\n", __func__); +} + +static void rockchip_hdmiv2_hdcp_stop(struct hdmi *hdmi) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + if (!hdcp->enable) + return; + + hdmi_msk_reg(hdmi_dev, MC_CLKDIS, + m_HDCPCLK_DISABLE, v_HDCPCLK_DISABLE(1)); + hdmi_writel(hdmi_dev, A_APIINTMSK, 0xff); + hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_RX_DETECT, v_RX_DETECT(0)); +} + +static ssize_t hdcp_enable_read(struct device *device, + struct device_attribute *attr, char *buf) +{ + int enable = 0; + + if (hdcp) + enable = hdcp->enable; + + return snprintf(buf, PAGE_SIZE, "%d\n", enable); +} + +static ssize_t hdcp_enable_write(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int enable; + + if (hdcp == NULL) + return -EINVAL; + + if (kstrtoint(buf, 0, &enable)) + return -EINVAL; + + if (hdcp->enable != enable) { + if (!hdcp->enable) + hdmi_submit_work(hdcp->hdmi, HDMI_ENABLE_HDCP, 0, NULL); + else + rockchip_hdmiv2_hdcp_stop(hdcp->hdmi); + hdcp->enable = enable; + } + + return count; +} +static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, + hdcp_enable_read, hdcp_enable_write); + +static ssize_t hdcp_trytimes_read(struct device *device, + struct device_attribute *attr, char *buf) +{ + int trytimes = 0; + + if (hdcp) + trytimes = hdcp->retry_times; + + return snprintf(buf, PAGE_SIZE, "%d\n", trytimes); +} + +static ssize_t hdcp_trytimes_wrtie(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int trytimes; + + if (hdcp == NULL) + return -EINVAL; + + if (kstrtoint(buf, 0, &trytimes)) + return -EINVAL; + + if (hdcp->retry_times != trytimes) + hdcp->retry_times = trytimes; + + return count; +} +static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR, + hdcp_trytimes_read, hdcp_trytimes_wrtie); + +static int hdcp_init(struct hdmi *hdmi) +{ + int ret; + + mdev.minor = MISC_DYNAMIC_MINOR; + mdev.name = "hdcp"; + mdev.mode = 0666; + hdcp = kmalloc(sizeof(*hdcp), GFP_KERNEL); + if (!hdcp) { + pr_err("HDCP: kmalloc fail!\n"); + ret = -ENOMEM; + goto error0; + } + memset(hdcp, 0, sizeof(struct hdcp)); + hdcp->hdmi = hdmi; + if (misc_register(&mdev)) { + pr_err("HDCP: Could not add character driver\n"); + ret = HDMI_ERROR_FALSE; + goto error1; + } + ret = device_create_file(mdev.this_device, &dev_attr_enable); + if (ret) { + pr_err("HDCP: Could not add sys file enable\n"); + ret = -EINVAL; + goto error2; + } + ret = device_create_file(mdev.this_device, &dev_attr_trytimes); + if (ret) { + pr_err("HDCP: Could not add sys file enable\n"); + ret = -EINVAL; + goto error3; + } + + ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, + "hdcp", mdev.this_device, GFP_KERNEL, + hdmi, hdcp_load_keys_cb); + + if (ret < 0) { + pr_err("HDCP: request_firmware_nowait failed: %d\n", ret); + goto error4; + } + + hdmi->ops->hdcp_cb = rockchip_hdmiv2_hdcp_start; + return 0; + +error4: + device_remove_file(mdev.this_device, &dev_attr_trytimes); +error3: + device_remove_file(mdev.this_device, &dev_attr_enable); +error2: + misc_deregister(&mdev); +error1: + kfree(hdcp->keys); + kfree(hdcp->invalidkeys); + kfree(hdcp); +error0: + return ret; +} + +void rockchip_hdmiv2_hdcp_init(struct hdmi *hdmi) +{ + pr_info("%s", __func__); + if (hdcp == NULL) + hdcp_init(hdmi); + else + hdcp_load_key(hdmi, hdcp->keys); +} + diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.c new file mode 100644 index 000000000000..4636b2891746 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.c @@ -0,0 +1,1743 @@ +#include +#include +#include +#include +#include "rockchip_hdmiv2.h" +#include "rockchip_hdmiv2_hw.h" + +static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = { + /*tmdsclk = (pixclk / ref_cntrl ) * (fbdiv2 * fbdiv1) / nctrl / tmdsmhl + opmode: 0:HDMI1.4 1:HDMI2.0 + */ +/* |pixclock| tmdsclock|pixrepet|colordepth|prepdiv|tmdsmhl|opmode| + fbdiv2|fbdiv1|ref_cntrl|nctrl|propctrl|intctrl|gmpctrl| */ + {27000000, 27000000, 0, 8, 0, 0, 0, + 2, 3, 0, 3, 3, 0, 0}, + {27000000, 33750000, 0, 10, 1, 0, 0, + 5, 1, 0, 3, 3, 0, 0}, + {27000000, 40500000, 0, 12, 2, 0, 0, + 3, 3, 0, 3, 3, 0, 0}, + {27000000, 54000000, 0, 16, 3, 0, 0, + 2, 3, 0, 2, 5, 0, 1}, +/* {74250000, 74250000, 0, 8, 0, 0, 0, + 1, 3, 0, 2, 5, 0, 1}, */ + {74250000, 74250000, 0, 8, 0, 0, 0, + 4, 3, 3, 2, 7, 0, 3}, + {74250000, 92812500, 0, 10, 1, 0, 0, + 5, 0, 1, 1, 7, 0, 2}, + {74250000, 111375000, 0, 12, 2, 0, 0, + 1, 2, 0, 1, 7, 0, 2}, + {74250000, 148500000, 0, 16, 3, 0, 0, + 1, 3, 0, 1, 7, 0, 2}, + {148500000, 74250000, 0, 8, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 3}, + {148500000, 148500000, 0, 8, 0, 0, 0, + 1, 1, 0, 1, 0, 0, 3}, + {148500000, 185625000, 0, 10, 1, 0, 0, + 5, 0, 3, 0, 7, 0, 3}, + {148500000, 222750000, 0, 12, 2, 0, 0, + 1, 2, 1, 0, 7, 0, 3}, + {148500000, 297000000, 0, 16, 3, 0, 0, + 1, 1, 0, 0, 7, 0, 3}, + {297000000, 148500000, 0, 8, 0, 0, 0, + 1, 0, 1, 0, 0, 0, 3}, + {297000000, 297000000, 0, 8, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 3}, + {297000000, 371250000, 0, 10, 1, 3, 1, + 5, 0, 3, 0, 7, 0, 3}, + {297000000, 445500000, 0, 12, 2, 3, 1, + 1, 2, 2, 0, 7, 0, 3}, + {297000000, 594000000, 0, 16, 1, 3, 1, + 1, 3, 1, 0, 0, 0, 3}, +/* {594000000, 297000000, 0, 8, 0, 0, 0, + 1, 3, 3, 1, 0, 0, 3},*/ + {594000000, 297000000, 0, 8, 0, 0, 0, + 1, 0, 1, 0, 0, 0, 3}, + {594000000, 594000000, 0, 8, 0, 3, 1, + 1, 3, 3, 0, 0, 0, 3}, +}; +/* ddc i2c master reset */ +static void rockchip_hdmiv2_i2cm_reset(struct hdmi_dev *hdmi_dev) +{ + hdmi_msk_reg(hdmi_dev, I2CM_SOFTRSTZ, + m_I2CM_SOFTRST, v_I2CM_SOFTRST(0)); + usleep_range(90, 100); +} + +/*set read/write offset,set read/write mode*/ +static void rockchip_hdmiv2_i2cm_write_request(struct hdmi_dev *hdmi_dev, + u8 offset, u8 data) +{ + hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset); + hdmi_writel(hdmi_dev, I2CM_DATAO, data); + hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_WR, v_I2CM_WR(1)); +} + +static void rockchip_hdmiv2_i2cm_read_request(struct hdmi_dev *hdmi_dev, + u8 offset) +{ + hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset); + hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD, v_I2CM_RD(1)); +} + +static void rockchip_hdmiv2_i2cm_write_data(struct hdmi_dev *hdmi_dev, + u8 data, u8 offset) +{ + u8 interrupt; + int trytime = 2; + int i = 20; + + while (trytime-- > 0) { + rockchip_hdmiv2_i2cm_write_request(hdmi_dev, offset, data); + while (i--) { + usleep_range(900, 1000); + interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0); + if (interrupt) + hdmi_writel(hdmi_dev, + IH_I2CM_STAT0, interrupt); + + if (interrupt & (m_SCDC_READREQ | + m_I2CM_DONE | m_I2CM_ERROR)) + break; + } + + if (interrupt & m_I2CM_DONE) { + dev_dbg(hdmi_dev->hdmi->dev, + "[%s] write offset %02x data %02x success\n", + __func__, offset, data); + trytime = 0; + } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) { + dev_err(hdmi_dev->hdmi->dev, + "[%s] write data error\n", __func__); + rockchip_hdmiv2_i2cm_reset(hdmi_dev); + } + } +} + +static int rockchip_hdmiv2_i2cm_read_data(struct hdmi_dev *hdmi_dev, u8 offset) +{ + u8 interrupt, val; + int trytime = 2; + int i = 20; + + while (trytime-- > 0) { + rockchip_hdmiv2_i2cm_read_request(hdmi_dev, offset); + while (i--) { + usleep_range(900, 1000); + interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0); + if (interrupt) + hdmi_writel(hdmi_dev, IH_I2CM_STAT0, interrupt); + + if (interrupt & (m_SCDC_READREQ | + m_I2CM_DONE | m_I2CM_ERROR)) + break; + } + + if (interrupt & m_I2CM_DONE) { + val = hdmi_readl(hdmi_dev, I2CM_DATAI); + trytime = 0; + } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) { + pr_err("[%s] read data error\n", __func__); + rockchip_hdmiv2_i2cm_reset(hdmi_dev); + } + } + return val; +} + +static void rockchip_hdmiv2_i2cm_mask_int(struct hdmi_dev *hdmi_dev, int mask) +{ + if (0 == mask) { + hdmi_msk_reg(hdmi_dev, I2CM_INT, + m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0)); + hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, + m_I2CM_NACK_MASK | m_I2CM_ARB_MASK, + v_I2CM_NACK_MASK(0) | v_I2CM_ARB_MASK(0)); + } else { + hdmi_msk_reg(hdmi_dev, I2CM_INT, + m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(1)); + hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, + m_I2CM_NACK_MASK | m_I2CM_ARB_MASK, + v_I2CM_NACK_MASK(1) | v_I2CM_ARB_MASK(1)); + } +} + +#define I2C_DIV_FACTOR 100000 +static u16 i2c_count(u16 sfrclock, u16 sclmintime) +{ + unsigned long tmp_scl_period = 0; + + if (((sfrclock * sclmintime) % I2C_DIV_FACTOR) != 0) + tmp_scl_period = (unsigned long)((sfrclock * sclmintime) + + (I2C_DIV_FACTOR - ((sfrclock * sclmintime) % + I2C_DIV_FACTOR))) / I2C_DIV_FACTOR; + else + tmp_scl_period = (unsigned long)(sfrclock * sclmintime) / + I2C_DIV_FACTOR; + + return (u16)(tmp_scl_period); +} + +#define EDID_I2C_MIN_SS_SCL_HIGH_TIME 50000 +#define EDID_I2C_MIN_SS_SCL_LOW_TIME 50000 + +static void rockchip_hdmiv2_i2cm_clk_init(struct hdmi_dev *hdmi_dev) +{ + /* Set DDC I2C CLK which devided from DDC_CLK. */ + hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_0_ADDR, + i2c_count(24000, EDID_I2C_MIN_SS_SCL_HIGH_TIME)); + hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_0_ADDR, + i2c_count(24000, EDID_I2C_MIN_SS_SCL_LOW_TIME)); + hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE, + v_I2CM_FAST_STD_MODE(STANDARD_MODE)); +} + +static int rockchip_hdmiv2_scdc_get_sink_version(struct hdmi_dev *hdmi_dev) +{ + return rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SINK_VER); +} + +static void rockchip_hdmiv2_scdc_set_source_version(struct hdmi_dev *hdmi_dev, + u8 version) +{ + rockchip_hdmiv2_i2cm_write_data(hdmi_dev, version, SCDC_SOURCE_VER); +} + + +static void rockchip_hdmiv2_scdc_read_request(struct hdmi_dev *hdmi_dev, + int enable) +{ + hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE, + m_I2CM_READ_REQ_EN, v_I2CM_READ_REQ_EN(enable)); + rockchip_hdmiv2_i2cm_write_data(hdmi_dev, enable, SCDC_CONFIG_0); +} + +#ifdef HDMI_20_SCDC +static void rockchip_hdmiv2_scdc_update_read(struct hdmi_dev *hdmi_dev) +{ + hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE, + m_I2CM_READ_UPDATE, v_I2CM_READ_UPDATE(1)); +} + + +static int rockchip_hdmiv2_scdc_get_scambling_status(struct hdmi_dev *hdmi_dev) +{ + int val; + + val = rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SCRAMBLER_STAT); + return val; +} + +static void rockchip_hdmiv2_scdc_enable_polling(struct hdmi_dev *hdmi_dev, + int enable) +{ + rockchip_hdmiv2_scdc_read_request(hdmi_dev, enable); + hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE, + m_I2CM_UPRD_VSYNC_EN, v_I2CM_UPRD_VSYNC_EN(enable)); +} + +static int rockchip_hdmiv2_scdc_get_status_reg0(struct hdmi_dev *hdmi_dev) +{ + rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1); + rockchip_hdmiv2_scdc_update_read(hdmi_dev); + return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE0); +} + +static int rockchip_hdmiv2_scdc_get_status_reg1(struct hdmi_dev *hdmi_dev) +{ + rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1); + rockchip_hdmiv2_scdc_update_read(hdmi_dev); + return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE1); +} +#endif + +static void rockchip_hdmiv2_scdc_init(struct hdmi_dev *hdmi_dev) +{ + rockchip_hdmiv2_i2cm_reset(hdmi_dev); + rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1); + rockchip_hdmiv2_i2cm_clk_init(hdmi_dev); + /* set scdc i2c addr */ + hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_SCDC_ADDR); + rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0);/*enable interrupt*/ +} + + +static int rockchip_hdmiv2_scrambling_enable(struct hdmi_dev *hdmi_dev, + int enable) +{ + HDMIDBG("%s enable %d\n", __func__, enable); + if (1 == enable) { + /* Write on Rx the bit Scrambling_Enable, register 0x20 */ + rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 1, SCDC_TMDS_CONFIG); + /* TMDS software reset request */ + hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ, + m_TMDS_SWRST, v_TMDS_SWRST(0)); + /* Enable/Disable Scrambling */ + hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL, + m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(1)); + } else { + /* Enable/Disable Scrambling */ + hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL, + m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(0)); + /* TMDS software reset request */ + hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ, + m_TMDS_SWRST, v_TMDS_SWRST(0)); + /* Write on Rx the bit Scrambling_Enable, register 0x20 */ + rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 0, SCDC_TMDS_CONFIG); + } + return 0; +} + + + +static const struct phy_mpll_config_tab *get_phy_mpll_tab( + unsigned int pixclock, unsigned int tmdsclk, + char pixrepet, char colordepth) +{ + int i; + + if (pixclock == 0) + return NULL; + HDMIDBG("%s pixClock %u pixRepet %d colorDepth %d\n", + __func__, pixclock, pixrepet, colordepth); + for (i = 0; i < ARRAY_SIZE(PHY_MPLL_TABLE); i++) { + if ((PHY_MPLL_TABLE[i].pix_clock == pixclock) && + (PHY_MPLL_TABLE[i].tmdsclock == tmdsclk) && + (PHY_MPLL_TABLE[i].pix_repet == pixrepet) && + (PHY_MPLL_TABLE[i].color_depth == colordepth)) + return &PHY_MPLL_TABLE[i]; + } + return NULL; +} + +static void rockchip_hdmiv2_powerdown(struct hdmi_dev *hdmi_dev) +{ + hdmi_msk_reg(hdmi_dev, PHY_CONF0, + m_PDDQ_SIG | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG, + v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) | + v_ENHPD_RXSENSE_SIG(1)); + hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f); +} + +static int rockchip_hdmiv2_write_phy(struct hdmi_dev *hdmi_dev, + int reg_addr, int val) +{ + int trytime = 2, i = 0, op_status = 0; + + while (trytime--) { + hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr); + hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_1, (val >> 8) & 0xff); + hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_0, val & 0xff); + hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_WRITE); + + i = 20; + while (i--) { + usleep_range(900, 1000); + op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0); + if (op_status) + hdmi_writel(hdmi_dev, + IH_I2CMPHY_STAT0, + op_status); + + if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) + break; + } + + if (op_status & m_I2CMPHY_DONE) + return 0; + else + dev_err(hdmi_dev->hdmi->dev, + "[%s] operation error,trytime=%d\n", + __func__, trytime); + msleep(100); + } + + return -1; +} + +static int __maybe_unused rockchip_hdmiv2_read_phy(struct hdmi_dev *hdmi_dev, + int reg_addr) +{ + int trytime = 2, i = 0, op_status = 0; + int val = 0; + + while (trytime--) { + hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr); + hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_1, 0x00); + hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_0, 0x00); + hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_READ); + + i = 20; + while (i--) { + usleep_range(900, 1000); + op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0); + if (op_status) + hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0, + op_status); + + if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) + break; + } + + if (op_status & m_I2CMPHY_DONE) { + val = hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_1); + val = (val & 0xff) << 8; + val += (hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_0) & 0xff); + pr_debug("phy_reg0x%02x: 0x%04x", + reg_addr, val); + return val; + } else { + pr_err("[%s] operation error,trytime=%d\n", + __func__, trytime); + } + msleep(100); + } + + return -1; +} + +void rockchip_hdmiv2_dump_phy_regs(struct hdmi_dev *hdmi_dev) +{ + int i; + + for (i = 0; i < 0x28; i++) + pr_info("phy reg %02x val %04x\n", + i, rockchip_hdmiv2_read_phy(hdmi_dev, i)); +} + +static int rockchip_hdmiv2_config_phy(struct hdmi_dev *hdmi_dev) +{ + int stat = 0, i = 0; + const struct phy_mpll_config_tab *phy_mpll = NULL; + + hdmi_msk_reg(hdmi_dev, PHY_I2CM_DIV, + m_PHY_I2CM_FAST_STD, v_PHY_I2CM_FAST_STD(0)); + /* power off PHY */ + /* hdmi_writel(hdmi_dev, PHY_CONF0, 0x1e); */ + hdmi_msk_reg(hdmi_dev, PHY_CONF0, + m_PDDQ_SIG | m_TXPWRON_SIG | m_SVSRET_SIG, + v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) | v_SVSRET_SIG(1)); + + if (hdmi_dev->tmdsclk_ratio_change && + hdmi_dev->hdmi->edid.scdc_present == 1) { + mutex_lock(&hdmi_dev->ddc_lock); + rockchip_hdmiv2_scdc_init(hdmi_dev); + stat = rockchip_hdmiv2_i2cm_read_data(hdmi_dev, + SCDC_TMDS_CONFIG); + if (hdmi_dev->tmdsclk > 340000000) + stat |= 2; + else + stat &= 0x1; + rockchip_hdmiv2_i2cm_write_data(hdmi_dev, + stat, SCDC_TMDS_CONFIG); + mutex_unlock(&hdmi_dev->ddc_lock); + } + /* reset PHY */ + hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1)); + usleep_range(1000, 2000); + hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0)); + + /* Set slave address as PHY GEN2 address */ + hdmi_writel(hdmi_dev, PHY_I2CM_SLAVE, PHY_GEN2_ADDR); + + /* config the required PHY I2C register */ + phy_mpll = get_phy_mpll_tab(hdmi_dev->pixelclk, + hdmi_dev->tmdsclk, + hdmi_dev->pixelrepeat - 1, + hdmi_dev->colordepth); + if (phy_mpll) { + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_OPMODE_PLLCFG, + v_PREP_DIV(phy_mpll->prep_div) | + v_TMDS_CNTRL( + phy_mpll->tmdsmhl_cntrl) | + v_OPMODE(phy_mpll->opmode) | + v_FBDIV2_CNTRL( + phy_mpll->fbdiv2_cntrl) | + v_FBDIV1_CNTRL( + phy_mpll->fbdiv1_cntrl) | + v_REF_CNTRL(phy_mpll->ref_cntrl) | + v_MPLL_N_CNTRL(phy_mpll->n_cntrl)); + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLCURRCTRL, + v_MPLL_PROP_CNTRL( + phy_mpll->prop_cntrl) | + v_MPLL_INT_CNTRL( + phy_mpll->int_cntrl)); + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLGMPCTRL, + v_MPLL_GMP_CNTRL( + phy_mpll->gmp_cntrl)); + } + if (hdmi_dev->tmdsclk <= 74250000) { + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL, + v_OVERRIDE(1) | v_SLOPEBOOST(0) | + v_TX_SYMON(1) | v_TX_TRAON(0) | + v_TX_TRBON(0) | v_CLK_SYMON(1)); + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS, + v_TX_TERM(R100_OHMS)); + } else if (hdmi_dev->tmdsclk <= 148500000) { + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL, + v_OVERRIDE(1) | v_SLOPEBOOST(1) | + v_TX_SYMON(1) | v_TX_TRAON(0) | + v_TX_TRBON(0) | v_CLK_SYMON(1)); + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS, + v_TX_TERM(R100_OHMS)); + } else if (hdmi_dev->tmdsclk <= 340000000) { + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL, + v_OVERRIDE(1) | v_SLOPEBOOST(1) | + v_TX_SYMON(1) | v_TX_TRAON(0) | + v_TX_TRBON(0) | v_CLK_SYMON(1)); + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS, + v_TX_TERM(R100_OHMS)); + } else if (hdmi_dev->tmdsclk > 340000000) { + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL, + v_OVERRIDE(1) | v_SLOPEBOOST(0) | + v_TX_SYMON(1) | v_TX_TRAON(0) | + v_TX_TRBON(0) | v_CLK_SYMON(1)); + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS, + v_TX_TERM(R100_OHMS)); + } + + if (hdmi_dev->tmdsclk < 297000000) + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL, + v_SUP_TXLVL(18) | v_SUP_CLKLVL(17)); + else + rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL, + v_SUP_TXLVL(14) | v_SUP_CLKLVL(13)); + + rockchip_hdmiv2_write_phy(hdmi_dev, 0x05, 0x8000); + if (hdmi_dev->tmdsclk_ratio_change) + msleep(100); + /* power on PHY */ + hdmi_writel(hdmi_dev, PHY_CONF0, 0x2e); + /* + hdmi_msk_reg(hdmi_dev, PHY_CONF0, + m_PDDQ_SIG | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG, + v_PDDQ_SIG(0) | v_TXPWRON_SIG(1) | + v_ENHPD_RXSENSE_SIG(1)); + */ + /* check if the PHY PLL is locked */ + #define PHY_TIMEOUT 10000 + while (i++ < PHY_TIMEOUT) { + if ((i % 10) == 0) { + stat = hdmi_readl(hdmi_dev, PHY_STAT0); + if (stat & m_PHY_LOCK) + break; + usleep_range(1000, 2000); + } + } + if ((stat & m_PHY_LOCK) == 0) { + stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK); + dev_err(hdmi_dev->hdmi->dev, + "PHY PLL not locked: PCLK_ON=%d,TMDSCLK_ON=%d\n", + (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5); + return -1; + } + + return 0; +} + +static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv, + struct hdmi_video *vpara) +{ + struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv; + int value, vsync_pol, hsync_pol, de_pol; + struct hdmi_video_timing *timing = NULL; + struct fb_videomode *mode = NULL; + u32 sink_version, tmdsclk; + + vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync; + hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync; + de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0; + + hdmi_msk_reg(hdmi_dev, A_VIDPOLCFG, + m_DATAEN_POL | m_VSYNC_POL | m_HSYNC_POL, + v_DATAEN_POL(de_pol) | + v_VSYNC_POL(vsync_pol) | + v_HSYNC_POL(hsync_pol)); + + timing = (struct hdmi_video_timing *)hdmi_vic2timing(vpara->vic); + if (timing == NULL) { + dev_err(hdmi_drv->dev, + "[%s] not found vic %d\n", __func__, vpara->vic); + return -ENOENT; + } + mode = &(timing->mode); + if (vpara->color_input == HDMI_COLOR_YCBCR420) + tmdsclk = mode->pixclock / 2; + else + tmdsclk = mode->pixclock; + switch (vpara->color_output_depth) { + case 10: + tmdsclk += tmdsclk / 4; + break; + case 12: + tmdsclk += tmdsclk / 2; + break; + case 16: + tmdsclk += tmdsclk; + break; + case 8: + default: + break; + } + + if (tmdsclk > 594000000) { + vpara->color_output_depth = 8; + tmdsclk = mode->pixclock; + } + pr_info("pixel clk is %u tmds clk is %u\n", mode->pixclock, tmdsclk); + if ((tmdsclk > 340000000 && hdmi_dev->tmdsclk < 340000000) || + (tmdsclk < 340000000 && hdmi_dev->tmdsclk > 340000000)) + hdmi_dev->tmdsclk_ratio_change = true; + else + hdmi_dev->tmdsclk_ratio_change = false; + + hdmi_dev->tmdsclk = tmdsclk; + hdmi_dev->pixelclk = mode->pixclock; + hdmi_dev->pixelrepeat = timing->pixelrepeat; + hdmi_dev->colordepth = vpara->color_output_depth; + + /* Video Register has already been set in uboot, + so we no need to set again */ + + if (hdmi_drv->uboot) + return -1; + + /* Start/stop HDCP keepout window generation */ + hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, + m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1)); + if (hdmi_drv->edid.scdc_present == 1) { + if (tmdsclk > 340000000) {/* used for HDMI 2.0 TX */ + mutex_lock(&hdmi_dev->ddc_lock); + rockchip_hdmiv2_scdc_init(hdmi_dev); + sink_version = + rockchip_hdmiv2_scdc_get_sink_version(hdmi_dev); + pr_info("sink scdc version is %d\n", sink_version); + sink_version = hdmi_drv->edid.hf_vsdb_version; + rockchip_hdmiv2_scdc_set_source_version(hdmi_dev, + sink_version); + if (hdmi_drv->edid.rr_capable == 1) + rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1); + rockchip_hdmiv2_scrambling_enable(hdmi_dev, 1); + mutex_unlock(&hdmi_dev->ddc_lock); + } else { + mutex_lock(&hdmi_dev->ddc_lock); + rockchip_hdmiv2_scdc_init(hdmi_dev); + rockchip_hdmiv2_scrambling_enable(hdmi_dev, 0); + mutex_unlock(&hdmi_dev->ddc_lock); + } + } + + hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, + m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL | + m_FC_HDMI_DVI | m_FC_INTERLACE_MODE, + v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) | + v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->sink_hdmi) | + v_FC_INTERLACE_MODE(mode->vmode)); + if (mode->vmode == FB_VMODE_INTERLACED) + hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, + m_FC_VBLANK, v_FC_VBLANK(1)); + else + hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, + m_FC_VBLANK, v_FC_VBLANK(0)); + + value = mode->xres; + if (vpara->color_input == HDMI_COLOR_YCBCR420) + value = value / 2; + hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(value >> 8)); + hdmi_writel(hdmi_dev, FC_INHACTIV0, (value & 0xff)); + + value = mode->yres; + hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(value >> 8)); + hdmi_writel(hdmi_dev, FC_INVACTIV0, (value & 0xff)); + + value = mode->hsync_len + mode->left_margin + mode->right_margin; + if (vpara->color_input == HDMI_COLOR_YCBCR420) + value = value / 2; + hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(value >> 8)); + hdmi_writel(hdmi_dev, FC_INHBLANK0, (value & 0xff)); + + value = mode->vsync_len + mode->upper_margin + mode->lower_margin; + hdmi_writel(hdmi_dev, FC_INVBLANK, (value & 0xff)); + + value = mode->right_margin; + if (vpara->color_input == HDMI_COLOR_YCBCR420) + value = value / 2; + hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1, v_FC_HSYNCINDEAY1(value >> 8)); + hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (value & 0xff)); + + value = mode->lower_margin; + hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (value & 0xff)); + + value = mode->hsync_len; + if (vpara->color_input == HDMI_COLOR_YCBCR420) + value = value / 2; + hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(value >> 8)); + hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (value & 0xff)); + + value = mode->vsync_len; + hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (value & 0xff)); + + /*Set the control period minimum duration + (min. of 12 pixel clock cycles, refer to HDMI 1.4b specification)*/ + hdmi_writel(hdmi_dev, FC_CTRLDUR, 12); + hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32); + + hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, + (hdmi_dev->tmdsclk/1000) * 50 / (256 * 512)); + +#if 0 + /* spacing < 256^2 * config / tmdsClock, spacing <= 50ms + * worst case: tmdsClock == 25MHz => config <= 19 + */ + hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, 1); + + /*Set PreambleFilter*/ + for (i = 0; i < 3; i++) { + value = (i + 1) * 11; + if (i == 0) /*channel 0*/ + hdmi_writel(hdmi_dev, FC_CH0PREAM, value); + else if (i == 1) /*channel 1*/ + hdmi_writel(hdmi_dev, FC_CH1PREAM, value & 0x3f); + else if (i == 2) /*channel 2*/ + hdmi_writel(hdmi_dev, FC_CH2PREAM, value & 0x3f); + } +#endif + + hdmi_writel(hdmi_dev, FC_PRCONF, v_FC_PR_FACTOR(timing->pixelrepeat)); + + return 0; +} + +static int rockchip_hdmiv2_video_packetizer(struct hdmi_dev *hdmi_dev, + struct hdmi_video *vpara) +{ + unsigned char color_depth = 0; + unsigned char output_select = 0; + unsigned char remap_size = 0; + + if (vpara->color_output == HDMI_COLOR_YCBCR422) { + switch (vpara->color_output_depth) { + case 8: + remap_size = YCC422_16BIT; + break; + case 10: + remap_size = YCC422_20BIT; + break; + case 12: + remap_size = YCC422_24BIT; + break; + default: + remap_size = YCC422_16BIT; + break; + } + + output_select = OUT_FROM_YCC422_REMAP; + /*Config remap size for the different color Depth*/ + hdmi_msk_reg(hdmi_dev, VP_REMAP, + m_YCC422_SIZE, v_YCC422_SIZE(remap_size)); + } else { + switch (vpara->color_output_depth) { + case 10: + color_depth = COLOR_DEPTH_30BIT; + output_select = OUT_FROM_PIXEL_PACKING; + break; + case 12: + color_depth = COLOR_DEPTH_36BIT; + output_select = OUT_FROM_PIXEL_PACKING; + break; + case 16: + color_depth = COLOR_DEPTH_48BIT; + output_select = OUT_FROM_PIXEL_PACKING; + break; + case 8: + default: + color_depth = COLOR_DEPTH_24BIT_DEFAULT; + output_select = OUT_FROM_8BIT_BYPASS; + break; + } + + /*Config Color Depth*/ + hdmi_msk_reg(hdmi_dev, VP_PR_CD, + m_COLOR_DEPTH, v_COLOR_DEPTH(color_depth)); + } + + /*Config pixel repettion*/ + hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR, + v_DESIRED_PR_FACTOR(hdmi_dev->pixelrepeat - 1)); + if (hdmi_dev->pixelrepeat > 1) + hdmi_msk_reg(hdmi_dev, VP_CONF, + m_PIXEL_REPET_EN | m_BYPASS_SEL, + v_PIXEL_REPET_EN(1) | v_BYPASS_SEL(0)); + else + hdmi_msk_reg(hdmi_dev, VP_CONF, + m_PIXEL_REPET_EN | m_BYPASS_SEL, + v_PIXEL_REPET_EN(0) | v_BYPASS_SEL(1)); + + /*config output select*/ + if (output_select == OUT_FROM_PIXEL_PACKING) { /* pixel packing */ + hdmi_msk_reg(hdmi_dev, VP_CONF, + m_BYPASS_EN | m_PIXEL_PACK_EN | + m_YCC422_EN | m_OUTPUT_SEL, + v_BYPASS_EN(0) | v_PIXEL_PACK_EN(1) | + v_YCC422_EN(0) | v_OUTPUT_SEL(output_select)); + } else if (output_select == OUT_FROM_YCC422_REMAP) { /* YCC422 */ + hdmi_msk_reg(hdmi_dev, VP_CONF, + m_BYPASS_EN | m_PIXEL_PACK_EN | + m_YCC422_EN | m_OUTPUT_SEL, + v_BYPASS_EN(0) | v_PIXEL_PACK_EN(0) | + v_YCC422_EN(1) | v_OUTPUT_SEL(output_select)); + } else if (output_select == OUT_FROM_8BIT_BYPASS || + output_select == 3) { /* bypass */ + hdmi_msk_reg(hdmi_dev, VP_CONF, + m_BYPASS_EN | m_PIXEL_PACK_EN | + m_YCC422_EN | m_OUTPUT_SEL, + v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) | + v_YCC422_EN(0) | v_OUTPUT_SEL(output_select)); + } + +#if defined(HDMI_VIDEO_STUFFING) + /* YCC422 and pixel packing stuffing*/ + hdmi_msk_reg(hdmi_dev, VP_STUFF, m_PR_STUFFING, v_PR_STUFFING(1)); + hdmi_msk_reg(hdmi_dev, VP_STUFF, + m_YCC422_STUFFING | m_PP_STUFFING, + v_YCC422_STUFFING(1) | v_PP_STUFFING(1)); +#endif + return 0; +} + +static int rockchip_hdmiv2_video_sampler(struct hdmi_dev *hdmi_dev, + struct hdmi_video *vpara) +{ + int map_code = 0; + + if (vpara->color_input == HDMI_COLOR_YCBCR422) { + /* YCC422 mapping is discontinued - only map 1 is supported */ + switch (vpara->color_output_depth) { + case 8: + map_code = VIDEO_YCBCR422_8BIT; + break; + case 10: + map_code = VIDEO_YCBCR422_10BIT; + break; + case 12: + map_code = VIDEO_YCBCR422_12BIT; + break; + default: + map_code = VIDEO_YCBCR422_8BIT; + break; + } + } else if (vpara->color_input == HDMI_COLOR_YCBCR420 || + vpara->color_input == HDMI_COLOR_YCBCR444) { + switch (vpara->color_output_depth) { + case 10: + map_code = VIDEO_YCBCR444_10BIT; + break; + case 12: + map_code = VIDEO_YCBCR444_12BIT; + break; + case 16: + map_code = VIDEO_YCBCR444_16BIT; + break; + case 8: + default: + map_code = VIDEO_YCBCR444_8BIT; + break; + } + } else { + switch (vpara->color_output_depth) { + case 10: + map_code = VIDEO_RGB444_10BIT; + break; + case 12: + map_code = VIDEO_RGB444_12BIT; + break; + case 16: + map_code = VIDEO_RGB444_16BIT; + break; + case 8: + default: + map_code = VIDEO_RGB444_8BIT; + break; + } + map_code += (vpara->color_input == HDMI_COLOR_YCBCR444) ? + 8 : 0; + } + + /* Set Data enable signal from external + and set video sample input mapping */ + hdmi_msk_reg(hdmi_dev, TX_INVID0, + m_INTERNAL_DE_GEN | m_VIDEO_MAPPING, + v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code)); + +#if defined(HDMI_VIDEO_STUFFING) + hdmi_writel(hdmi_dev, TX_GYDATA0, 0x00); + hdmi_writel(hdmi_dev, TX_GYDATA1, 0x00); + hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, + m_GYDATA_STUFF, v_GYDATA_STUFF(1)); + hdmi_writel(hdmi_dev, TX_RCRDATA0, 0x00); + hdmi_writel(hdmi_dev, TX_RCRDATA1, 0x00); + hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, + m_RCRDATA_STUFF, v_RCRDATA_STUFF(1)); + hdmi_writel(hdmi_dev, TX_BCBDATA0, 0x00); + hdmi_writel(hdmi_dev, TX_BCBDATA1, 0x00); + hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, + m_BCBDATA_STUFF, v_BCBDATA_STUFF(1)); +#endif + return 0; +} + +static const char coeff_csc[][24] = { + /* G R B Bias + A1 | A2 | A3 | A4 | + B1 | B2 | B3 | B4 | + C1 | C2 | C3 | C4 | */ + { /* CSC_RGB_0_255_TO_RGB_16_235_8BIT */ + 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /*G*/ + 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x00, 0x40, /*R*/ + 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x00, 0x40, /*B*/ + }, + { /* CSC_RGB_0_255_TO_RGB_16_235_10BIT */ + 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /*G*/ + 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x01, 0x00, /*R*/ + 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x01, 0x00, /*B*/ + }, + { /* CSC_RGB_0_255_TO_ITU601_16_235_8BIT */ + 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x00, 0x40, /*Y*/ + 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x02, 0x00, /*Cr*/ + 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x02, 0x00, /*Cb*/ + }, + { /* CSC_RGB_0_255_TO_ITU601_16_235_10BIT */ + 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x01, 0x00, /*Y*/ + 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x08, 0x00, /*Cr*/ + 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x08, 0x00, /*Cb*/ + }, + { /* CSC_RGB_0_255_TO_ITU709_16_235_8BIT */ + 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x00, 0x40, /*Y*/ + 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x02, 0x00, /*Cr*/ + 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x02, 0x00, /*Cb*/ + }, + { /* CSC_RGB_0_255_TO_ITU709_16_235_10BIT */ + 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x01, 0x00, /*Y*/ + 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x08, 0x00, /*Cr*/ + 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x08, 0x00, /*Cb*/ + }, + /* Y Cr Cb Bias */ + { /* CSC_ITU601_16_235_TO_RGB_0_255_8BIT */ + 0x20, 0x00, 0x69, 0x26, 0x74, 0xfd, 0x01, 0x0e, /*G*/ + 0x20, 0x00, 0x2c, 0xdd, 0x00, 0x00, 0x7e, 0x9a, /*R*/ + 0x20, 0x00, 0x00, 0x00, 0x38, 0xb4, 0x7e, 0x3b, /*B*/ + }, + { /* CSC_ITU709_16_235_TO_RGB_0_255_8BIT */ + 0x20, 0x00, 0x71, 0x06, 0x7a, 0x02, 0x00, 0xa7, /*G*/ + 0x20, 0x00, 0x32, 0x64, 0x00, 0x00, 0x7e, 0x6d, /*R*/ + 0x20, 0x00, 0x00, 0x00, 0x3b, 0x61, 0x7e, 0x25, /*B*/ + }, +}; + +static int rockchip_hdmiv2_video_csc(struct hdmi_dev *hdmi_dev, + struct hdmi_video *vpara) +{ + int i, mode, interpolation, decimation, csc_scale; + const char *coeff = NULL; + unsigned char color_depth = 0; + + if (vpara->color_input == vpara->color_output) { + hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL, + m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(0)); + return 0; + } + + if (vpara->color_input == HDMI_COLOR_YCBCR422 && + vpara->color_output != HDMI_COLOR_YCBCR422 && + vpara->color_output != HDMI_COLOR_YCBCR420) { + interpolation = 1; + hdmi_msk_reg(hdmi_dev, CSC_CFG, + m_CSC_INTPMODE, v_CSC_INTPMODE(interpolation)); + } + + if ((vpara->color_input == HDMI_COLOR_RGB_0_255 || + vpara->color_input == HDMI_COLOR_YCBCR444) && + vpara->color_output == HDMI_COLOR_YCBCR422) { + decimation = 1; + hdmi_msk_reg(hdmi_dev, CSC_CFG, + m_CSC_DECIMODE, v_CSC_DECIMODE(decimation)); + } + + switch (vpara->vic) { + case HDMI_720X480I_60HZ_4_3: + case HDMI_720X576I_50HZ_4_3: + case HDMI_720X480P_60HZ_4_3: + case HDMI_720X576P_50HZ_4_3: + case HDMI_720X480I_60HZ_16_9: + case HDMI_720X576I_50HZ_16_9: + case HDMI_720X480P_60HZ_16_9: + case HDMI_720X576P_50HZ_16_9: + if (vpara->color_input == HDMI_COLOR_RGB_0_255 && + vpara->color_output >= HDMI_COLOR_YCBCR444) { + mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT; + csc_scale = 0; + } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 && + vpara->color_output == HDMI_COLOR_RGB_0_255) { + mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT; + csc_scale = 1; + } + break; + default: + if (vpara->color_input == HDMI_COLOR_RGB_0_255 && + vpara->color_output >= HDMI_COLOR_YCBCR444) { + mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT; + csc_scale = 0; + } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 && + vpara->color_output == HDMI_COLOR_RGB_0_255) { + mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT; + csc_scale = 1; + } + break; + } + + if ((vpara->color_input == HDMI_COLOR_RGB_0_255) && + (vpara->color_output == HDMI_COLOR_RGB_16_235)) { + mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT; + csc_scale = 0; + } + + switch (vpara->color_output_depth) { + case 10: + color_depth = COLOR_DEPTH_30BIT; + mode += 1; + break; + case 12: + color_depth = COLOR_DEPTH_36BIT; + mode += 2; + break; + case 16: + color_depth = COLOR_DEPTH_48BIT; + mode += 3; + break; + case 8: + default: + color_depth = COLOR_DEPTH_24BIT; + break; + } + + coeff = coeff_csc[mode]; + for (i = 0; i < 24; i++) + hdmi_writel(hdmi_dev, CSC_COEF_A1_MSB + i, coeff[i]); + + hdmi_msk_reg(hdmi_dev, CSC_SCALE, + m_CSC_SCALE, v_CSC_SCALE(csc_scale)); + /*config CSC_COLOR_DEPTH*/ + hdmi_msk_reg(hdmi_dev, CSC_SCALE, + m_CSC_COLOR_DEPTH, v_CSC_COLOR_DEPTH(color_depth)); + + /* enable CSC */ + hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL, + m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(1)); + + return 0; +} + + +static int hdmi_dev_detect_hotplug(struct hdmi *hdmi) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + u32 value = hdmi_readl(hdmi_dev, PHY_STAT0); + + HDMIDBG("[%s] reg%x value %02x\n", __func__, PHY_STAT0, value); + + if (value & m_PHY_HPD) + return HDMI_HPD_ACTIVED; + else + return HDMI_HPD_REMOVED; +} + +static int hdmi_dev_read_edid(struct hdmi *hdmi, int block, unsigned char *buff) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + int i = 0, n = 0, index = 0, ret = -1, trytime = 5; + int offset = (block % 2) * 0x80; + int interrupt = 0; + + HDMIDBG("[%s] block %d\n", __func__, block); + + rockchip_hdmiv2_i2cm_reset(hdmi_dev); + + /* Set DDC I2C CLK which devided from DDC_CLK to 100KHz. */ + rockchip_hdmiv2_i2cm_clk_init(hdmi_dev); + + /* Enable I2C interrupt for reading edid */ + rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0); + + hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR); + hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR); + hdmi_writel(hdmi_dev, I2CM_SEGPTR, block / 2); + for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) { + for (trytime = 0; trytime < 5; trytime++) { + hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8 * n); + /* enable extend sequential read operation */ + if (block == 0) + hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, + m_I2CM_RD8, v_I2CM_RD8(1)); + else + hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, + m_I2CM_RD8_EXT, + v_I2CM_RD8_EXT(1)); + + i = 20; + while (i--) { + usleep_range(900, 1000); + interrupt = hdmi_readl(hdmi_dev, + IH_I2CM_STAT0); + if (interrupt) + hdmi_writel(hdmi_dev, + IH_I2CM_STAT0, interrupt); + + if (interrupt & + (m_SCDC_READREQ | m_I2CM_DONE | + m_I2CM_ERROR)) + break; + } + + if (interrupt & m_I2CM_DONE) { + for (index = 0; index < 8; index++) + buff[8 * n + index] = + hdmi_readl(hdmi_dev, + I2CM_READ_BUFF0 + + index); + + if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) { + ret = 0; + goto exit; + } + break; + } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) { + dev_err(hdmi->dev, + "[%s] edid read %d error\n", + __func__, offset + 8 * n); + } + } + if (trytime == 5) { + dev_err(hdmi->dev, + "[%s] edid read error\n", __func__); + break; + } + } + +exit: + /* Disable I2C interrupt */ + rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1); + + #ifdef DEBUG + if (!ret) { + for (index = 0; index < 128; index++) { + printk("0x%02x ,", buff[index]); + if ((index + 1) % 16 == 0) + printk("\n"); + } + } + #endif + return ret; +} + +static void hdmi_dev_config_avi(struct hdmi_dev *hdmi_dev, + struct hdmi_video *vpara) +{ + unsigned char colorimetry, ext_colorimetry, aspect_ratio, y1y0; + unsigned char rgb_quan_range = AVI_QUANTIZATION_RANGE_DEFAULT; + + /* Set AVI infoFrame Data byte1 */ + if (vpara->color_output == HDMI_COLOR_YCBCR444) + y1y0 = AVI_COLOR_MODE_YCBCR444; + else if (vpara->color_output == HDMI_COLOR_YCBCR422) + y1y0 = AVI_COLOR_MODE_YCBCR422; + else if (vpara->color_output == HDMI_COLOR_YCBCR420) + y1y0 = AVI_COLOR_MODE_YCBCR420; + else + y1y0 = AVI_COLOR_MODE_RGB; + + hdmi_msk_reg(hdmi_dev, FC_AVICONF0, + m_FC_ACTIV_FORMAT | m_FC_RGC_YCC, + v_FC_RGC_YCC(y1y0) | v_FC_ACTIV_FORMAT(1)); + + /* Set AVI infoFrame Data byte2 */ + switch (vpara->vic) { + case HDMI_720X480I_60HZ_4_3: + case HDMI_720X576I_50HZ_4_3: + case HDMI_720X480P_60HZ_4_3: + case HDMI_720X576P_50HZ_4_3: + aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3; + colorimetry = AVI_COLORIMETRY_SMPTE_170M; + break; + case HDMI_720X480I_60HZ_16_9: + case HDMI_720X576I_50HZ_16_9: + case HDMI_720X480P_60HZ_16_9: + case HDMI_720X576P_50HZ_16_9: + aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9; + colorimetry = AVI_COLORIMETRY_SMPTE_170M; + break; + default: + aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9; + colorimetry = AVI_COLORIMETRY_ITU709; + } + + if (vpara->color_output_depth > 8) { + colorimetry = AVI_COLORIMETRY_EXTENDED; + ext_colorimetry = 6; + } else if (vpara->color_output == HDMI_COLOR_RGB_16_235 || + vpara->color_output == HDMI_COLOR_RGB_0_255) { + colorimetry = AVI_COLORIMETRY_NO_DATA; + ext_colorimetry = 0; + } + + hdmi_writel(hdmi_dev, FC_AVICONF1, + v_FC_COLORIMETRY(colorimetry) | + v_FC_PIC_ASPEC_RATIO(aspect_ratio) | + v_FC_ACT_ASPEC_RATIO(ACTIVE_ASPECT_RATE_DEFAULT)); + + /* Set AVI infoFrame Data byte3 */ + hdmi_msk_reg(hdmi_dev, FC_AVICONF2, + m_FC_EXT_COLORIMETRY | m_FC_QUAN_RANGE, + v_FC_EXT_COLORIMETRY(ext_colorimetry) | + v_FC_QUAN_RANGE(rgb_quan_range)); + + /* Set AVI infoFrame Data byte4 */ + if ((vpara->vic > 92 && vpara->vic < 96) || (vpara->vic == 98)) + hdmi_writel(hdmi_dev, FC_AVIVID, 0); + else + hdmi_writel(hdmi_dev, FC_AVIVID, vpara->vic & 0xff); + /* Set AVI infoFrame Data byte5 */ + hdmi_msk_reg(hdmi_dev, FC_AVICONF3, m_FC_YQ | m_FC_CN, + v_FC_YQ(YQ_LIMITED_RANGE) | v_FC_CN(CN_GRAPHICS)); +} + +static int hdmi_dev_config_vsi(struct hdmi *hdmi, + unsigned char vic_3d, unsigned char format) +{ + int i = 0, id = 0x000c03; + unsigned char data[3] = {0}; + + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + HDMIDBG("[%s] vic %d format %d.\n", __func__, vic_3d, format); + + hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(0)); + hdmi_writel(hdmi_dev, FC_VSDIEEEID2, id & 0xff); + hdmi_writel(hdmi_dev, FC_VSDIEEEID1, (id >> 8) & 0xff); + hdmi_writel(hdmi_dev, FC_VSDIEEEID0, (id >> 16) & 0xff); + + data[0] = format << 5; /* PB4 --HDMI_Video_Format */ + switch (format) { + case HDMI_VIDEO_FORMAT_4KX2K: + data[1] = vic_3d; /* PB5--HDMI_VIC */ + data[2] = 0; + break; + case HDMI_VIDEO_FORMAT_3D: + data[1] = vic_3d << 4; /* PB5--3D_Structure field */ + data[2] = 0; /* PB6--3D_Ext_Data field */ + break; + default: + data[1] = 0; + data[2] = 0; + break; + } + + for (i = 0; i < 3; i++) + hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]); + hdmi_writel(hdmi_dev, FC_VSDSIZE, 0x6); +/* if (auto_send) { */ + hdmi_writel(hdmi_dev, FC_DATAUTO1, 0); + hdmi_writel(hdmi_dev, FC_DATAUTO2, 0x11); + hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(1)); +/* } + else { + hdmi_msk_reg(hdmi_dev, FC_DATMAN, m_VSD_MAN, v_VSD_MAN(1)); + } +*/ + return 0; +} + +static int hdmi_dev_config_video(struct hdmi *hdmi, struct hdmi_video *vpara) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + HDMIDBG("%s vic %d 3dformat %d color mode %d color depth %d\n", + __func__, vpara->vic, vpara->format_3d, + vpara->color_output, vpara->color_output_depth); + + if (hdmi_dev->soctype == HDMI_SOC_RK3288) + vpara->color_input = HDMI_COLOR_RGB_0_255; + + if (!hdmi->uboot) { + /* befor configure video, we power off phy */ + hdmi_msk_reg(hdmi_dev, PHY_CONF0, + m_PDDQ_SIG | m_TXPWRON_SIG, + v_PDDQ_SIG(1) | v_TXPWRON_SIG(0)); + + /* force output blue */ + if (vpara->color_output == HDMI_COLOR_RGB_0_255) { + hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00); /*R*/ + hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00); /*G*/ + hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x00); /*B*/ + } else if (vpara->color_output == HDMI_COLOR_RGB_16_235) { + hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x10); /*R*/ + hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*G*/ + hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x10); /*B*/ + } else { + hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x80); /*R*/ + hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*G*/ + hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x80); /*B*/ + } + hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, + m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1)); + } + + hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE); + if (rockchip_hdmiv2_video_framecomposer(hdmi, vpara) < 0) + return -1; + + if (rockchip_hdmiv2_video_packetizer(hdmi_dev, vpara) < 0) + return -1; + /* Color space convert */ + if (rockchip_hdmiv2_video_csc(hdmi_dev, vpara) < 0) + return -1; + if (rockchip_hdmiv2_video_sampler(hdmi_dev, vpara) < 0) + return -1; + + if (vpara->sink_hdmi == OUTPUT_HDMI) { + hdmi_dev_config_avi(hdmi_dev, vpara); + if (vpara->format_3d != HDMI_3D_NONE) { + hdmi_dev_config_vsi(hdmi, + vpara->format_3d, + HDMI_VIDEO_FORMAT_3D); + } else if ((vpara->vic > 92 && vpara->vic < 96) || + (vpara->vic == 98)) { + vpara->vic = (vpara->vic == 98) ? + 4 : (96 - vpara->vic); + hdmi_dev_config_vsi(hdmi, + vpara->vic, + HDMI_VIDEO_FORMAT_4KX2K); + } else { + hdmi_dev_config_vsi(hdmi, + vpara->vic, + HDMI_VIDEO_FORMAT_NORMAL); + } + dev_info(hdmi->dev, "[%s] sucess output HDMI.\n", __func__); + } else { + dev_info(hdmi->dev, "[%s] sucess output DVI.\n", __func__); + } + + rockchip_hdmiv2_config_phy(hdmi_dev); + return 0; +} + +static void hdmi_dev_config_aai(struct hdmi_dev *hdmi_dev, + struct hdmi_audio *audio) +{ + /*Refer to CEA861-E Audio infoFrame*/ + /*Set both Audio Channel Count and Audio Coding + Type Refer to Stream Head for HDMI*/ + hdmi_msk_reg(hdmi_dev, FC_AUDICONF0, + m_FC_CHN_CNT | m_FC_CODING_TYEP, + v_FC_CHN_CNT(audio->channel-1) | v_FC_CODING_TYEP(0)); + + /*Set both Audio Sample Size and Sample Frequency + Refer to Stream Head for HDMI*/ + hdmi_msk_reg(hdmi_dev, FC_AUDICONF1, + m_FC_SAMPLE_SIZE | m_FC_SAMPLE_FREQ, + v_FC_SAMPLE_SIZE(0) | v_FC_SAMPLE_FREQ(0)); + + /*Set Channel Allocation*/ + hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00); + + /*Set LFEPBL¡¢DOWN-MIX INH and LSV*/ + hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00); +} + +static int hdmi_dev_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + int word_length = 0, channel = 0, mclk_fs; + unsigned int N = 0, CTS = 0; + int rate = 0; + + HDMIDBG("%s\n", __func__); + + if (audio->channel < 3) + channel = I2S_CHANNEL_1_2; + else if (audio->channel < 5) + channel = I2S_CHANNEL_3_4; + else if (audio->channel < 7) + channel = I2S_CHANNEL_5_6; + else + channel = I2S_CHANNEL_7_8; + + switch (audio->rate) { + case HDMI_AUDIO_FS_32000: + mclk_fs = FS_64; + rate = AUDIO_32K; + if (hdmi_dev->tmdsclk >= 594000000) + N = N_32K_HIGHCLK; + else if (hdmi_dev->tmdsclk >= 297000000) + N = N_32K_MIDCLK; + else + N = N_32K_LOWCLK; + /*div a num to avoid the value is exceed 2^32(int)*/ + CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 32); + break; + case HDMI_AUDIO_FS_44100: + mclk_fs = FS_64; + rate = AUDIO_441K; + if (hdmi_dev->tmdsclk >= 594000000) + N = N_441K_HIGHCLK; + else if (hdmi_dev->tmdsclk >= 297000000) + N = N_441K_MIDCLK; + else + N = N_441K_LOWCLK; + + CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 441); + break; + case HDMI_AUDIO_FS_48000: + mclk_fs = FS_64; + rate = AUDIO_48K; + if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/ + N = N_48K_HIGHCLK; + else if (hdmi_dev->tmdsclk >= 297000000) + N = N_48K_MIDCLK; + else + N = N_48K_LOWCLK; + + CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 48); + break; + case HDMI_AUDIO_FS_88200: + mclk_fs = FS_64; + rate = AUDIO_882K; + if (hdmi_dev->tmdsclk >= 594000000) + N = N_882K_HIGHCLK; + else if (hdmi_dev->tmdsclk >= 297000000) + N = N_882K_MIDCLK; + else + N = N_882K_LOWCLK; + + CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 882); + break; + case HDMI_AUDIO_FS_96000: + mclk_fs = FS_64; + rate = AUDIO_96K; + if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/ + N = N_96K_HIGHCLK; + else if (hdmi_dev->tmdsclk >= 297000000) + N = N_96K_MIDCLK; + else + N = N_96K_LOWCLK; + + CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 96); + break; + case HDMI_AUDIO_FS_176400: + mclk_fs = FS_64; + rate = AUDIO_1764K; + if (hdmi_dev->tmdsclk >= 594000000) + N = N_1764K_HIGHCLK; + else if (hdmi_dev->tmdsclk >= 297000000) + N = N_1764K_MIDCLK; + else + N = N_1764K_LOWCLK; + + CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 1764); + break; + case HDMI_AUDIO_FS_192000: + mclk_fs = FS_64; + rate = AUDIO_192K; + if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/ + N = N_192K_HIGHCLK; + else if (hdmi_dev->tmdsclk >= 297000000) + N = N_192K_MIDCLK; + else + N = N_192K_LOWCLK; + + CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 192); + break; + default: + dev_err(hdmi_dev->hdmi->dev, + "[%s] not support such sample rate %d\n", + __func__, audio->rate); + return -ENOENT; + } + + switch (audio->word_length) { + case HDMI_AUDIO_WORD_LENGTH_16bit: + word_length = I2S_16BIT_SAMPLE; + break; + case HDMI_AUDIO_WORD_LENGTH_20bit: + word_length = I2S_20BIT_SAMPLE; + break; + case HDMI_AUDIO_WORD_LENGTH_24bit: + word_length = I2S_24BIT_SAMPLE; + break; + default: + word_length = I2S_16BIT_SAMPLE; + } + + HDMIDBG("rate = %d, tmdsclk = %u, N = %d, CTS = %d\n", + audio->rate, hdmi_dev->tmdsclk, N, CTS); + /* more than 2 channels => layout 1 else layout 0 */ + hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, + m_AUD_PACK_LAYOUT, + v_AUD_PACK_LAYOUT((audio->channel > 2) ? 1 : 0)); + + if (hdmi_dev->audiosrc == HDMI_AUDIO_SRC_IIS) { + hdmi_msk_reg(hdmi_dev, AUD_CONF0, + m_I2S_SEL, v_I2S_SEL(AUDIO_SPDIF_GPA)); + hdmi_msk_reg(hdmi_dev, AUD_SPDIF1, + m_SET_NLPCM | m_SPDIF_WIDTH, + v_SET_NLPCM(PCM_LINEAR) | + v_SPDIF_WIDTH(word_length)); + /*Mask fifo empty and full int and reset fifo*/ + hdmi_msk_reg(hdmi_dev, AUD_SPDIFINT, + m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK, + v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1)); + hdmi_msk_reg(hdmi_dev, AUD_SPDIF0, + m_SW_SAUD_FIFO_RST, v_SW_SAUD_FIFO_RST(1)); + } else { + /*Mask fifo empty and full int and reset fifo*/ + hdmi_msk_reg(hdmi_dev, AUD_INT, + m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK, + v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1)); + hdmi_msk_reg(hdmi_dev, AUD_CONF0, + m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1)); + hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7); + usleep_range(90, 100); + hdmi_msk_reg(hdmi_dev, AUD_CONF0, + m_I2S_SEL | m_I2S_IN_EN, + v_I2S_SEL(AUDIO_I2S) | v_I2S_IN_EN(channel)); + hdmi_writel(hdmi_dev, AUD_CONF1, + v_I2S_MODE(I2S_STANDARD_MODE) | + v_I2S_WIDTH(word_length)); + } + + hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS, + m_LFS_FACTOR, v_LFS_FACTOR(mclk_fs)); + + /*Set N value*/ + hdmi_msk_reg(hdmi_dev, AUD_N3, m_NCTS_ATOMIC_WR, v_NCTS_ATOMIC_WR(1)); + /*Set CTS by manual*/ + hdmi_msk_reg(hdmi_dev, AUD_CTS3, + m_N_SHIFT | m_CTS_MANUAL | m_AUD_CTS3, + v_N_SHIFT(N_SHIFT_1) | + v_CTS_MANUAL(1) | + v_AUD_CTS3(CTS >> 16)); + hdmi_writel(hdmi_dev, AUD_CTS2, (CTS >> 8) & 0xff); + hdmi_writel(hdmi_dev, AUD_CTS1, CTS & 0xff); + + hdmi_msk_reg(hdmi_dev, AUD_N3, m_AUD_N3, v_AUD_N3(N >> 16)); + hdmi_writel(hdmi_dev, AUD_N2, (N >> 8) & 0xff); + hdmi_writel(hdmi_dev, AUD_N1, N & 0xff); + + /* set channel status register */ + hdmi_msk_reg(hdmi_dev, FC_AUDSCHNLS7, + m_AUDIO_SAMPLE_RATE, v_AUDIO_SAMPLE_RATE(rate)); + /* hdmi_writel(hdmi_dev, FC_AUDSCHNLS2, 0x1); */ + /* hdmi_writel(hdmi_dev, FC_AUDSCHNLS8, ((~rate) << 4) | 0x2); */ + + hdmi_dev_config_aai(hdmi_dev, audio); + + return 0; +} + +static int hdmi_dev_control_output(struct hdmi *hdmi, int enable) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + HDMIDBG("[%s] %d\n", __func__, enable); + + if (enable == HDMI_AV_UNMUTE) { + hdmi_writel(hdmi_dev, FC_DBGFORCE, 0x00); + hdmi_msk_reg(hdmi_dev, FC_GCP, + m_FC_SET_AVMUTE | m_FC_CLR_AVMUTE, + v_FC_SET_AVMUTE(0) | v_FC_CLR_AVMUTE(1)); + } else { + if (enable & HDMI_VIDEO_MUTE) { + hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, + m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1)); + hdmi_msk_reg(hdmi_dev, FC_GCP, + m_FC_SET_AVMUTE | m_FC_CLR_AVMUTE, + v_FC_SET_AVMUTE(1) | v_FC_CLR_AVMUTE(0)); + } +/* if (enable & HDMI_AUDIO_MUTE) { + hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, + m_AUD_PACK_SAMPFIT, + v_AUD_PACK_SAMPFIT(0x0F)); + } +*/ if (enable == (HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE)) { + msleep(100); + rockchip_hdmiv2_powerdown(hdmi_dev); + hdmi_dev->tmdsclk = 0; +/* + hdmi_msk_reg(hdmi_dev, PHY_CONF0, + m_PDDQ_SIG | m_TXPWRON_SIG, + v_PDDQ_SIG(1) | v_TXPWRON_SIG(0)); + hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f); +*/ } + } + return 0; +} + +static int hdmi_dev_insert(struct hdmi *hdmi) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + HDMIDBG("%s\n", __func__); + hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE); + return HDMI_ERROR_SUCESS; +} + +static int hdmi_dev_remove(struct hdmi *hdmi) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + HDMIDBG("%s\n", __func__); + rockchip_hdmiv2_powerdown(hdmi_dev); + hdmi_dev->tmdsclk = 0; + return HDMI_ERROR_SUCESS; +} + +static int hdmi_dev_enable(struct hdmi *hdmi) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + HDMIDBG("%s\n", __func__); + if (!hdmi_dev->enable) { + hdmi_writel(hdmi_dev, IH_MUTE, 0x00); + hdmi_dev->enable = 1; + } + hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 10, NULL); + return 0; +} + +static int hdmi_dev_disable(struct hdmi *hdmi) +{ + struct hdmi_dev *hdmi_dev = hdmi->property->priv; + + HDMIDBG("%s\n", __func__); + if (hdmi_dev->enable) { + hdmi_dev->enable = 0; + hdmi_writel(hdmi_dev, IH_MUTE, 0x1); + } + return 0; +} + +void rockchip_hdmiv2_dev_init_ops(struct hdmi_ops *ops) +{ + if (ops) { + ops->enable = hdmi_dev_enable; + ops->disable = hdmi_dev_disable; + ops->getstatus = hdmi_dev_detect_hotplug; + ops->insert = hdmi_dev_insert; + ops->remove = hdmi_dev_remove; + ops->getedid = hdmi_dev_read_edid; + ops->setvideo = hdmi_dev_config_video; + ops->setaudio = hdmi_dev_config_audio; + ops->setmute = hdmi_dev_control_output; + ops->setvsi = hdmi_dev_config_vsi; + } +} + +void rockchip_hdmiv2_dev_initial(struct hdmi_dev *hdmi_dev) +{ + struct hdmi *hdmi = hdmi_dev->hdmi; + + if (!hdmi->uboot) { + /* reset hdmi */ + if (hdmi_dev->soctype == HDMI_SOC_RK3288) { + writel_relaxed((1 << 9) | (1 << 25), + RK_CRU_VIRT + 0x01d4); + udelay(1); + writel_relaxed((0 << 9) | (1 << 25), + RK_CRU_VIRT + 0x01d4); + } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) { + pr_info("reset hdmi\n"); + regmap_write(hdmi_dev->grf_base, 0x031c, + (1 << 9) | (1 << 25)); + udelay(5); + regmap_write(hdmi_dev->grf_base, 0x031c, + (0 << 9) | (1 << 25)); + } + rockchip_hdmiv2_powerdown(hdmi_dev); + } + /*mute unnecessary interrrupt, only enable hpd*/ + hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT0, 0xff); + hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT1, 0xff); + hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT2, 0xff); + hdmi_writel(hdmi_dev, IH_MUTE_AS_STAT0, 0xff); + hdmi_writel(hdmi_dev, IH_MUTE_PHY_STAT0, 0xfe); + hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, 0xff); + hdmi_writel(hdmi_dev, IH_MUTE_CEC_STAT0, 0xff); + hdmi_writel(hdmi_dev, IH_MUTE_VP_STAT0, 0xff); + hdmi_writel(hdmi_dev, IH_MUTE_I2CMPHY_STAT0, 0xff); + hdmi_writel(hdmi_dev, IH_MUTE_AHBDMAAUD_STAT0, 0xff); + + /* disable hdcp interrup */ + hdmi_writel(hdmi_dev, A_APIINTMSK, 0xff); + hdmi_writel(hdmi_dev, PHY_MASK, 0xf1); + + if (hdmi->property->feature & SUPPORT_CEC) + rockchip_hdmiv2_cec_init(hdmi); + if (hdmi->property->feature & SUPPORT_HDCP) + rockchip_hdmiv2_hdcp_init(hdmi); +} + +irqreturn_t rockchip_hdmiv2_dev_irq(int irq, void *priv) +{ + struct hdmi_dev *hdmi_dev = priv; + struct hdmi *hdmi = hdmi_dev->hdmi; + char phy_pol = hdmi_readl(hdmi_dev, PHY_POL0); + char phy_status = hdmi_readl(hdmi_dev, PHY_STAT0); + char phy_int0 = hdmi_readl(hdmi_dev, PHY_INI0); + /*read interrupt*/ + char fc_stat0 = hdmi_readl(hdmi_dev, IH_FC_STAT0); + char fc_stat1 = hdmi_readl(hdmi_dev, IH_FC_STAT1); + char fc_stat2 = hdmi_readl(hdmi_dev, IH_FC_STAT2); + char aud_int = hdmi_readl(hdmi_dev, IH_AS_SATA0); + char phy_int = hdmi_readl(hdmi_dev, IH_PHY_STAT0); + char vp_stat0 = hdmi_readl(hdmi_dev, IH_VP_STAT0); + char cec_int = hdmi_readl(hdmi_dev, IH_CEC_STAT0); + char hdcp_int = hdmi_readl(hdmi_dev, A_APIINTSTAT); + char hdcp2_int = hdmi_readl(hdmi_dev, HDCP2REG_STAT); + + /*clear interrupt*/ + hdmi_writel(hdmi_dev, IH_FC_STAT0, fc_stat0); + hdmi_writel(hdmi_dev, IH_FC_STAT1, fc_stat1); + hdmi_writel(hdmi_dev, IH_FC_STAT2, fc_stat2); + hdmi_writel(hdmi_dev, IH_VP_STAT0, vp_stat0); + + if (phy_int0 || phy_int) { + phy_pol = (phy_int0 & (~phy_status)) | ((~phy_int0) & phy_pol); + hdmi_writel(hdmi_dev, PHY_POL0, phy_pol); + hdmi_writel(hdmi_dev, IH_PHY_STAT0, phy_int); + if ((phy_int & m_HPD) || ((phy_int & 0x3c) == 0x3c)) + hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 20, NULL); + } + + /* Audio error */ + if (aud_int) { + hdmi_writel(hdmi_dev, IH_AS_SATA0, aud_int); + hdmi_msk_reg(hdmi_dev, AUD_CONF0, + m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1)); + hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7); + } + /* CEC */ + if (cec_int) { + hdmi_writel(hdmi_dev, IH_CEC_STAT0, cec_int); + rockchip_hdmiv2_cec_isr(hdmi_dev, cec_int); + } + /* HDCP */ + if (hdcp_int) { + hdmi_writel(hdmi_dev, A_APIINTCLR, hdcp_int); + pr_info("hdcp_int is 0x%02x\n", hdcp_int); + } + + /* HDCP2 */ + if (hdcp2_int) { + hdmi_writel(hdmi_dev, HDCP2REG_STAT, hdcp2_int); + pr_info("hdcp2_int is 0x%02x\n", hdcp2_int); + } + return IRQ_HANDLED; +} diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.h b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.h new file mode 100644 index 000000000000..bcc2864ae449 --- /dev/null +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.h @@ -0,0 +1,1568 @@ +#ifndef _RK3288_HDMI_HW_H +#define _RK3288_HDMI_HW_H +#include +#include "../rockchip-hdmi.h" + +/*#define HDMI_INT_USE_POLL 1*/ + +enum PWR_MODE { + NORMAL, + LOWER_PWR, +}; + +enum { + OUTPUT_DVI = 0, + OUTPUT_HDMI, +}; + +/* Color Space Convertion Mode */ +enum { + CSC_RGB_0_255_TO_RGB_16_235_8BIT, /* RGB 0-255 input to RGB + 16-235 output that is 8bit + clolor depth */ + CSC_RGB_0_255_TO_RGB_16_235_10BIT, /* RGB 0-255 input to RGB + 16-235 output that is 8bit + clolor depth */ + CSC_RGB_0_255_TO_ITU601_16_235_8BIT, /* RGB 0-255 input to YCbCr + 16-235 output according + BT601 that is 8bit clolor + depth */ + CSC_RGB_0_255_TO_ITU601_16_235_10BIT, /* RGB 0-255 input to YCbCr + 16-235 output according + BT601 that is 10bit clolor + depth */ + CSC_RGB_0_255_TO_ITU709_16_235_8BIT, /* RGB 0-255 input to YCbCr + 16-235 output accroding + BT709 that is 8bit clolor + depth */ + CSC_RGB_0_255_TO_ITU709_16_235_10BIT, /* RGB 0-255 input to YCbCr + 16-235 output accroding + BT709 that is 10bit clolor + depth */ + CSC_ITU601_16_235_TO_RGB_16_235_8BIT, /* YCbCr 16-235 input to RGB + 16-235 output according + BT601 that is 8bit clolor + depth */ + CSC_ITU709_16_235_TO_RGB_16_235_8BIT, /* YCbCr 16-235 input to RGB + 16-235 output according + BT709 that is 8bit clolor + depth */ + CSC_ITU601_16_235_TO_RGB_0_255_8BIT, /* YCbCr 16-235 input to RGB + 0-255 output according + BT601 that is 8bit clolor + depth */ + CSC_ITU709_16_235_TO_RGB_0_255_8BIT /* YCbCr 16-235 input to RGB + 0-255 output according + BT709 that is 8bit clolor + depth */ +}; + +#define HDMI_SCL_RATE (100*1000) +#define DDC_I2C_EDID_ADDR 0x50 /* 0xA0/2 = 0x50 */ +#define DDC_I2C_SEG_ADDR 0x30 /* 0x60/2 = 0x30 */ +#define DDC_I2C_SCDC_ADDR 0x54 /* 0xa8/2 = 0x54 */ + +/* Register and Field Descriptions */ +/* Identification Registers */ +#define IDENTIFICATION_BASE 0x0000 + +#define DESIGN_ID 0x0000 +#define REVISION_ID 0x0001 +#define PRODUCT_ID0 0x0002 +#define PRODUCT_ID1 0x0003 + +#define CONFIG0_ID 0x0004 +#define m_PREPEN (1 << 7) +#define m_AUDSPDIF (1 << 5) +#define m_AUDI2S (1 << 4) +#define m_HDMI14 (1 << 3) +#define m_CSC (1 << 2) +#define m_CEC (1 << 1) +#define m_HDCP (1 << 0) + +#define CONFIG1_ID 0x0005 +#define m_HDMI20 (1 << 5) +#define m_CONFAPB (1 << 1) + +#define CONFIG2_ID 0x0006 +enum PHYTYPE { + HDMI_TX_PHY = 0x00, + HDMI_MHL_WITH_HEAC_PHY = 0xb2, + HDMI_MHL_PHY = 0xc2, + HDMI_3D_TX_WITH_HEAC_PHY = 0xe2, + HDMI_3D_TX_PHY = 0xf2, + HDMI2_TX_PHY = 0xf3 +}; + +#define CONFIG3_ID 0x0007 +#define m_AHB_AUD_DMA (1 << 1) +#define m_GP_AUD (1 << 0) + +/* Interrupt Registers */ +#define INTERRUPT_BASE 0x0100 + +#define IH_FC_STAT0 0x0100 +#define m_AUD_INFOFRAME (1 << 7) +#define m_AUD_CONTENT_PROTECT (1 << 6) +#define m_AUD_HBR (1 << 5) +#define m_AUD_SAMPLE (1 << 2) +#define m_AUD_CLK_REGEN (1 << 1) +#define m_NULL_PACKET (1 << 0) + +#define IH_FC_STAT1 0x0101 +#define m_GMD (1 << 7) +#define m_ISCR1 (1 << 6) +#define m_ISCR2 (1 << 5) +#define m_VSD (1 << 4) +#define m_SPD (1 << 3) +#define m_AVI_INFOFRAME (1 << 1) +#define m_GCP (1 << 0) + +#define IH_FC_STAT2 0x0102 +#define m_LOWPRIO_OVERFLOW (1 << 1) +#define m_HIGHPRIO_OVERFLOW (1 << 0) + +#define IH_AS_SATA0 0x0103 +#define m_FIFO_UNDERRUN (1 << 4) +#define m_FIFO_OVERRUN (1 << 3) +#define m_AUD_FIFO_UDFLOW_THR (1 << 2) +#define m_AUD_FIFO_UDFLOW (1 << 1) +#define m_AUD_FIFO_OVERFLOW (1 << 0) + +#define IH_PHY_STAT0 0x0104 +#define m_RX_SENSE3 (1 << 5) +#define m_RX_SENSE2 (1 << 4) +#define m_RX_SENSE1 (1 << 3) +#define m_RX_SENSE0 (1 << 2) +#define m_TX_PHY_LOCK (1 << 1) +#define m_HPD (1 << 0) + +#define IH_I2CM_STAT0 0x0105 +#define m_SCDC_READREQ (1 << 2) +#define m_I2CM_DONE (1 << 1) +#define m_I2CM_ERROR (1 << 0) + +#define IH_CEC_STAT0 0x0106 +#define m_WAKEUP (1 << 6) +#define m_ERR_FOLLOW (1 << 5) +#define m_ERR_INITIATOR (1 << 4) +#define m_ARB_LOST (1 << 3) +#define m_NACK (1 << 2) +#define m_EOM (1 << 1) +#define m_DONE (1 << 0) + +#define IH_VP_STAT0 0x0107 +#define m_FIFOFULL_REPET (1 << 7) +#define m_FIFOEMPTY_REPET (1 << 6) +#define m_FIFOFULL_PACK (1 << 5) +#define m_FIFOEMPTY_PACK (1 << 4) +#define m_FIFOFULL_REMAP (1 << 3) +#define m_FIFOEMPTY_REMAP (1 << 2) +#define m_FIFOFULL_BYPASS (1 << 1) +#define m_FIFOEMPTY_BYPASS (1 << 0) + +#define IH_I2CMPHY_STAT0 0x0108 +#define m_I2CMPHY_DONE (1 << 1) +#define m_I2CMPHY_ERR (1 << 0) + +#define IH_AHBDMAAUD_STAT0 0x0109 +#define m_AUDDMA_INT_BUFOVERRUN (1 << 6) +#define m_AUDDMA_INT_ERR (1 << 5) +#define m_AUDDMA_INT_LOST (1 << 4) +#define m_AUDDMA_INT_RETRYSPLIT (1 << 3) +#define m_AUDDMA_INT_DONE (1 << 2) +#define m_AUDDMA_INT_BUFFULL (1 << 1) +#define m_AUDDMA_INT_BUFEMPTY (1 << 0) + +#define IH_DECODE 0x0170 +#define m_IH_FC_STAT0 (1 << 7) +#define m_IH_FC_STAT1 (1 << 6) +#define m_IH_FC_STAT2_VP (1 << 5) +#define m_IH_AS_STAT0 (1 << 4) +#define m_IH_PHY (1 << 3) +#define m_IH_I2CM_STAT0 (1 << 2) +#define m_IH_CEC_STAT0 (1 << 1) +#define m_IH_AHBDMAAUD_STAT0 (1 << 0) + +#define IH_MUTE_FC_STAT0 0x0180 +#define m_AUDI_MUTE (1 << 7) +#define m_ACP_MUTE (1 << 6) +#define m_DST_MUTE (1 << 4) +#define m_OBA_MUTE (1 << 3) +#define m_AUDS_MUTE (1 << 2) +#define m_ACR_MUTE (1 << 1) +#define m_NULL_MUTE (1 << 0) + +#define IH_MUTE_FC_STAT1 0x0181 +#define m_GMD_MUTE (1 << 7) +#define m_ISCR1_MUTE (1 << 6) +#define m_ISCR2_MUTE (1 << 5) +#define m_VSD_MUTE (1 << 4) +#define m_SPD_MUTE (1 << 3) +#define m_AVI_MUTE (1 << 1) +#define m_GCP_MUTE (1 << 0) + +#define IH_MUTE_FC_STAT2 0x0182 +#define m_LPRIO_OVERFLOW_MUTE (1 << 1) +#define m_HPRIO_OVERFLOW_MUTE (1 << 0) + +#define IH_MUTE_AS_STAT0 0x0183 +#define m_FIFO_UNDERRUN_MUTE (1 << 4) +#define m_FIFO_OVERRUN_MUTE (1 << 3) +#define m_AUD_FIFO_UDF_THR_MUTE (1 << 2) +#define m_AUD_FIFO_UDF_MUTE (1 << 1) +#define m_AUD_FIFO_OVF_MUTE (1 << 0) + +#define IH_MUTE_PHY_STAT0 0x0184 +#define m_RX_SENSE3_MUTE (1 << 5) +#define m_RX_SENSE2_MUTE (1 << 4) +#define m_RX_SENSE1_MUTE (1 << 3) +#define m_RX_SENSE0_MUTE (1 << 2) +#define m_TX_PHY_LOCK_MUTE (1 << 1) +#define m_HPD_MUTE (1 << 0) + +#define IH_MUTE_I2CM_STAT0 0x0185 +#define m_SCDC_READREQ_MUTE (1 << 2) +#define v_SCDC_READREQ_MUTE(n) (((n)&0x01) << 2) +#define m_I2CM_DONE_MUTE (1 << 1) +#define v_I2CM_DONE_MUTE(n) (((n)&0x01) << 1) +#define m_I2CM_ERR_MUTE (1 << 0) +#define v_I2CM_ERR_MUTE(n) (((n)&0x01) << 0) + +#define IH_MUTE_CEC_STAT0 0x0186 +#define m_WAKEUP_MUTE (1 << 6) +#define m_ERR_FOLLOW_MUTE (1 << 5) +#define m_ERR_INITIATOR_MUTE (1 << 4) +#define m_ARB_LOST_MUTE (1 << 3) +#define m_NACK_MUTE (1 << 2) +#define m_EOM_MUTE (1 << 1) +#define m_DONE_MUTE (1 << 0) + +#define IH_MUTE_VP_STAT0 0x0187 +#define m_FIFOFULL_REP_MUTE (1 << 7) +#define m_FIFOEMPTY_REP_MUTE (1 << 6) +#define m_FIFOFULL_PACK_MUTE (1 << 5) +#define m_FIFOEMPTY_PACK_MUTE (1 << 4) +#define m_FIFOFULL_REMAP_MUTE (1 << 3) +#define m_FIFOEMPTY_REMAP_MUTE (1 << 2) +#define m_FIFOFULL_BYP_MUTE (1 << 1) +#define m_FIFOEMPTY_BYP_MUTE (1 << 0) + +#define IH_MUTE_I2CMPHY_STAT0 0x0188 +#define m_I2CMPHY_DONE_MUTE (1 << 1) +#define m_I2CMPHY_ERR_MUTE (1 << 0) + +#define IH_MUTE_AHBDMAAUD_STAT0 0x0189 +#define IH_MUTE 0x01ff + +/* Video Sampler Registers */ +#define VIDEO_SAMPLER_BASE 0x0200 + +#define TX_INVID0 0x0200 +#define m_INTERNAL_DE_GEN (1 << 7) +#define v_INTERNAL_DE_GEN(n) (((n)&0x01) << 7) +enum VIDEO_MODE { + VIDEO_RGB444_8BIT = 0x01, + VIDEO_RGB444_10BIT = 0x03, + VIDEO_RGB444_12BIT = 0x05, + VIDEO_RGB444_16BIT = 0x07, + VIDEO_YCBCR444_8BIT = 0x09, /* or YCbCr420 */ + VIDEO_YCBCR444_10BIT = 0x0b, /* or YCbCr420 */ + VIDEO_YCBCR444_12BIT = 0x0d, /* or YCbCr420 */ + VIDEO_YCBCR444_16BIT = 0x0f, /* or YCbCr420 */ + VIDEO_YCBCR422_12BIT = 0x12, + VIDEO_YCBCR422_10BIT = 0x14, + VIDEO_YCBCR422_8BIT = 0x16 +}; +#define m_VIDEO_MAPPING (0x1f << 0) +#define v_VIDEO_MAPPING(n) ((n)&0x1f) + +#define TX_INSTUFFING 0x0201 +#define m_BCBDATA_STUFF (1 << 2) +#define v_BCBDATA_STUFF(n) (((n)&0x01) << 2) +#define m_RCRDATA_STUFF (1 << 1) +#define v_RCRDATA_STUFF(n) (((n)&0x01) << 1) +#define m_GYDATA_STUFF (1 << 0) +#define v_GYDATA_STUFF(n) (((n)&0x01) << 0) + +#define TX_GYDATA0 0x0202 +#define TX_GYDATA1 0x0203 +#define TX_RCRDATA0 0x0204 +#define TX_RCRDATA1 0x0205 +#define TX_BCBDATA0 0x0206 +#define TX_BCBDATA1 0x0207 + +/* Video Packetizer Registers */ +#define VIDEO_PACKETIZER_BASE 0x0800 + +#define VP_STATUS 0x0800 +#define m_PACKING_PHASE (0x0f << 0) + +#define VP_PR_CD 0x0801 +enum COLOR_DEPTH { + COLOR_DEPTH_24BIT_DEFAULT = 0, + COLOR_DEPTH_24BIT = 0x04, + COLOR_DEPTH_30BIT, + COLOR_DEPTH_36BIT, + COLOR_DEPTH_48BIT +}; +#define m_COLOR_DEPTH (0x0f << 4) +#define v_COLOR_DEPTH(n) (((n)&0x0f) << 4) +enum PIXEL_REPET { + NO_PIXEL_REPET = 0, + PIXEL_SENT_2TIMES, + PIXEL_SENT_3TIMES, + PIXEL_SENT_4TIMES, + PIXEL_SENT_5TIMES, + PIXEL_SENT_6TIMES, + PIXEL_SENT_7TIMES, + PIXEL_SENT_8TIMES, + PIXEL_SENT_9TIMES, + PIXEL_SENT_10TIMES +}; +#define m_DESIRED_PR_FACTOR (0x0f << 0) +#define v_DESIRED_PR_FACTOR(n) (((n)&0x0f) << 0) + +#define VP_STUFF 0x0802 +#define m_IDEFAULT_PHASE (1 << 5) +#define v_IDEFAULT_PHASE(n) (((n)&0x01) << 5) +#define m_IFIX_PP_TO_LAST (1 << 4) +#define m_ICX_GOTO_P0_ST (1 << 3) +enum { + DIRECT_MODE = 0, + STUFFING_MODE +}; +#define m_YCC422_STUFFING (1 << 2) +#define v_YCC422_STUFFING(n) (((n)&0x01) << 2) +#define m_PP_STUFFING (1 << 1) +#define v_PP_STUFFING(n) (((n)&0x01) << 1) +#define m_PR_STUFFING (1 << 0) +#define v_PR_STUFFING(n) (((n)&0x01) << 0) + +#define VP_REMAP 0x0803 +enum YCC422_SIZE { + YCC422_16BIT = 0, + YCC422_20BIT, + YCC422_24BIT +}; +#define m_YCC422_SIZE (0x03 << 0) +#define v_YCC422_SIZE(n) (((n)&0x03) << 0) + +#define VP_CONF 0x0804 +#define m_BYPASS_EN (1 << 6) +#define v_BYPASS_EN(n) (((n)&0x01) << 6) +#define m_PIXEL_PACK_EN (1 << 5) +#define v_PIXEL_PACK_EN(n) (((n)&0x01) << 5) +#define m_PIXEL_REPET_EN (1 << 4) +#define v_PIXEL_REPET_EN(n) (((n)&0x01) << 4) +#define m_YCC422_EN (1 << 3) +#define v_YCC422_EN(n) (((n)&0x01) << 3) +#define m_BYPASS_SEL (1 << 2) +#define v_BYPASS_SEL(n) (((n)&0x01) << 2) +enum { + OUT_FROM_PIXEL_PACKING = 0, + OUT_FROM_YCC422_REMAP, + OUT_FROM_8BIT_BYPASS +}; +#define m_OUTPUT_SEL (0x03 << 0) +#define v_OUTPUT_SEL(n) ((n&0x03) << 0) + +#define VP_MASK 0x0807 +#define m_OINTFULL_REPET (1 << 7) +#define m_OINTEMPTY_REPET (1 << 6) +#define m_OINTFULL_PACK (1 << 5) +#define m_OINTEMPTY_PACK (1 << 4) +#define m_OINTFULL_REMAP (1 << 3) +#define m_OINTEMPTY_REMAP (1 << 2) +#define m_OINTFULL_BYPASS (1 << 1) +#define m_OINTEMPTY_BYPASS (1 << 0) + +/* Frame Composer Registers */ +#define FRAME_COMPOSER_BASE 0x1000 + +#define FC_INVIDCONF 0x1000 +#define m_FC_HDCP_KEEPOUT (1 << 7) +#define v_FC_HDCP_KEEPOUT(n) (((n)&0x01) << 7) +#define m_FC_VSYNC_POL (1 << 6) +#define v_FC_VSYNC_POL(n) (((n)&0x01) << 6) +#define m_FC_HSYNC_POL (1 << 5) +#define v_FC_HSYNC_POL(n) (((n)&0x01) << 5) +#define m_FC_DE_POL (1 << 4) +#define v_FC_DE_POL(n) (((n)&0x01) << 4) +#define m_FC_HDMI_DVI (1 << 3) +#define v_FC_HDMI_DVI(n) (((n)&0x01) << 3) +#define m_FC_VBLANK (1 << 1) +#define v_FC_VBLANK(n) (((n)&0x01) << 1) +#define m_FC_INTERLACE_MODE (1 << 0) +#define v_FC_INTERLACE_MODE(n) (((n)&0x01) << 0) + +#define FC_INHACTIV0 0x1001 + +#define FC_INHACTIV1 0x1002 +#define v_FC_HACTIVE1(n) ((n) & 0x3f) +#define m_FC_H_ACTIVE_13 (1 << 5) +#define v_FC_H_ACTIVE_13(n) (((n)&0x01) << 5) +#define m_FC_H_ACTIVE_12 (1 << 4) +#define v_FC_H_ACTIVE_12(n) (((n)&0x01) << 4) +#define m_FC_H_ACTIVE (0x0f << 0) +#define v_FC_H_ACTIVE(n) (((n)&0x0f) << 0) + +#define FC_INHBLANK0 0x1003 + +#define FC_INHBLANK1 0x1004 +#define v_FC_HBLANK1(n) ((n) & 0x1f) +#define m_FC_H_BLANK_12_11 (0x07 << 2) +#define v_FC_H_BLANK_12_11(n) (((n)&0x07) << 2) +#define m_FC_H_BLANK (0x03 << 0) +#define v_FC_H_BLANK(n) (((n)&0x03) << 0) + +#define FC_INVACTIV0 0x1005 + +#define FC_INVACTIV1 0x1006 +#define v_FC_VACTIVE1(n) ((n) & 0x1f) +#define m_FC_V_ACTIVE_12_11 (0x03 << 3) +#define v_FC_V_ACTIVE_12_11(n) (((n)&0x03) << 3) +#define m_FC_V_ACTIVE (0x07 << 0) +#define v_FC_V_ACTIVE(n) (((n)&0x07) << 0) + +#define FC_INVBLANK 0x1007 +#define FC_HSYNCINDELAY0 0x1008 + +#define FC_HSYNCINDELAY1 0x1009 +#define v_FC_HSYNCINDEAY1(n) ((n) & 0x1f) +#define m_FC_H_SYNCFP_12_11 (0x03 << 3) +#define v_FC_H_SYNCFP_12_11(n) (((n)&0x03) << 3) +#define m_FC_H_SYNCFP (0x07 << 0) +#define v_FC_H_SYNCFP(n) (((n)&0x07) << 0) + +#define FC_HSYNCINWIDTH0 0x100a + +#define FC_HSYNCINWIDTH1 0x100b +#define v_FC_HSYNCWIDTH1(n) ((n) & 0x03) +#define m_FC_HSYNC_9 (1 << 1) +#define v_FC_HSYNC_9(n) (((n)&0x01) << 1) +#define m_FC_HSYNC (1 << 0) +#define v_FC_HSYNC(n) (((n)&0x01) << 0) + +#define FC_VSYNCINDELAY 0x100c +#define FC_VSYNCINWIDTH 0x100d +#define FC_INFREQ0 0x100e +#define FC_INFREQ1 0x100f +#define FC_INFREQ2 0x1010 +#define FC_CTRLDUR 0x1011 +#define FC_EXCTRLDUR 0x1012 +#define FC_EXCTRLSPAC 0x1013 +#define FC_CH0PREAM 0x1014 +#define FC_CH1PREAM 0x1015 +#define FC_CH2PREAM 0x1016 + +#define FC_AVICONF3 0x1017 +enum YCC_QUAN_RANGE { + YQ_LIMITED_RANGE = 0, + YQ_FULL_RANGE, + RESERVED, +}; +#define m_FC_YQ (0x03 << 2) +#define v_FC_YQ(n) (((n)&0x03) << 2) +enum IT_CONTENT_TYPE { + CN_GRAPHICS = 0, + CN_PHOTO, + CN_CINEMA, + CN_GAME, +}; +#define m_FC_CN (0x03 << 0) +#define v_FC_CN(n) (((n)&0x03) << 0) + +#define FC_GCP 0x1018 +#define m_FC_DEFAULT_PHASE (1 << 2) +#define v_FC_DEFAULT_PHASE(n) (((n)&0x01) << 2) +#define m_FC_SET_AVMUTE (1 << 1) +#define v_FC_SET_AVMUTE(n) (((n)&0x01) << 1) +#define m_FC_CLR_AVMUTE (1 << 0) +#define v_FC_CLR_AVMUTE(n) (((n)&0x01) << 0) + +enum { + AVI_COLOR_MODE_RGB = 0, + AVI_COLOR_MODE_YCBCR422, + AVI_COLOR_MODE_YCBCR444, + AVI_COLOR_MODE_YCBCR420 +}; +enum { + AVI_COLORIMETRY_NO_DATA = 0, + AVI_COLORIMETRY_SMPTE_170M, + AVI_COLORIMETRY_ITU709, + AVI_COLORIMETRY_EXTENDED +}; +enum { + AVI_CODED_FRAME_ASPECT_NO_DATA, + AVI_CODED_FRAME_ASPECT_4_3, + AVI_CODED_FRAME_ASPECT_16_9 +}; +enum { + ACTIVE_ASPECT_RATE_DEFAULT = 0x08, + ACTIVE_ASPECT_RATE_4_3, + ACTIVE_ASPECT_RATE_16_9, + ACTIVE_ASPECT_RATE_14_9 +}; +enum { + AVI_QUANTIZATION_RANGE_DEFAULT = 0, + AVI_QUANTIZATION_RANGE_LIMITED, + AVI_QUANTIZATION_RANGE_FULL +}; + +#define FC_AVICONF0 0x1019 +#define m_FC_RGC_YCC_2 (1 << 7) /* use for HDMI2.0 TX */ +#define v_FC_RGC_YCC_2(n) (((n)&0x01) << 7) +#define m_FC_ACTIV_FORMAT (1 << 6) +#define v_FC_ACTIV_FORMAT(n) (((n)&0x01) << 6) +#define m_FC_SCAN_INFO (0x03 << 4) +#define v_FC_SCAN_INFO(n) (((n)&0x03) << 4) +#define m_FC_BAR_FORMAT (0x03 << 2) +#define v_FC_BAR_FORMAT(n) (((n)&0x03) << 2) +#define m_FC_RGC_YCC (0x03 << 0) +#define v_FC_RGC_YCC(n) (((n)&0x03) << 0) + +#define FC_AVICONF1 0x101a +#define m_FC_COLORIMETRY (0x03 << 6) +#define v_FC_COLORIMETRY(n) (((n)&0x03) << 6) +#define m_FC_PIC_ASPEC_RATIO (0x03 << 4) +#define v_FC_PIC_ASPEC_RATIO(n) (((n)&0x03) << 4) +#define m_FC_ACT_ASPEC_RATIO (0x0f << 0) +#define v_FC_ACT_ASPEC_RATIO(n) (((n)&0x0f) << 0) + +#define FC_AVICONF2 0x101b +#define m_FC_IT_CONTENT (1 << 7) +#define v_FC_IT_CONTENT(n) (((n)&0x01) << 7) +#define m_FC_EXT_COLORIMETRY (0x07 << 4) +#define v_FC_EXT_COLORIMETRY(n) (((n)&0x07) << 4) +#define m_FC_QUAN_RANGE (0x03 << 2) +#define v_FC_QUAN_RANGE(n) (((n)&0x03) << 2) +#define m_FC_NUN_PIC_SCALE (0x03 << 0) +#define v_FC_NUN_PIC_SCALE(n) (((n)&0x03) << 0) + +#define FC_AVIVID 0x101c +#define m_FC_AVIVID_H (1 << 7) /* use for HDMI2.0 TX */ +#define v_FC_AVIVID_H(n) (((n)&0x01) << 7) +#define m_FC_AVIVID (0x7f << 0) +#define v_FC_AVIVID(n) (((n)&0x7f) << 0) + +#define FC_AVIETB0 0x101d +#define FC_AVIETB1 0x101e +#define FC_AVISBB0 0x101f +#define FC_AVISBB1 0x1020 +#define FC_AVIELB0 0x1021 +#define FC_AVIELB1 0x1022 +#define FC_AVISRB0 0x1023 +#define FC_AVISRB1 0x1024 + +#define FC_AUDICONF0 0x1025 +#define m_FC_CHN_CNT (0x07 << 4) +#define v_FC_CHN_CNT(n) (((n)&0x07) << 4) +#define m_FC_CODING_TYEP (0x0f << 0) +#define v_FC_CODING_TYEP(n) (((n)&0x0f) << 0) + +#define FC_AUDICONF1 0x1026 +#define m_FC_SAMPLE_SIZE (0x03 << 4) +#define v_FC_SAMPLE_SIZE(n) (((n)&0x03) << 4) +#define m_FC_SAMPLE_FREQ (0x07 << 0) +#define v_FC_SAMPLE_FREQ(n) (((n)&0x07) << 0) + +#define FC_AUDICONF2 0x1027 + +#define FC_AUDICONF3 0x1028 +#define m_FC_LFE_PBL (0x03 << 5) /*only use for HDMI1.4 TX*/ +#define v_FC_LFE_PBL(n) (((n)&0x03) << 5) +#define m_FC_DM_INH (1 << 4) +#define v_FC_DM_INH(n) (((n)&0x01) << 4) +#define m_FC_LSV (0x0f << 0) +#define v_FC_LSV(n) (((n)&0x0f) << 0) + +#define FC_VSDIEEEID2 0x1029 +#define FC_VSDSIZE 0x102a +#define FC_VSDIEEEID1 0x1030 +#define FC_VSDIEEEID0 0x1031 +#define FC_VSDPAYLOAD0 0x1032 /* 0~23 */ +#define FC_SPDVENDORNAME0 0x104a /* 0~7 */ +#define FC_SPDPRODUCTNAME0 0x1052 /* 0~15 */ +#define FC_SPDDEVICEINF 0x1062 + +#define FC_AUDSCONF 0x1063 +#define m_AUD_PACK_SAMPFIT (0x0f << 4) +#define v_AUD_PACK_SAMPFIT(n) (((n)&0x0f) << 4) +#define m_AUD_PACK_LAYOUT (1 << 0) +#define v_AUD_PACK_LAYOUT(n) (((n)&0x01) << 0) + +#define FC_AUDSSTAT 0x1064 +#define FC_AUDSV 0x1065 +#define FC_AUDSU 0x1066 +#define FC_AUDSCHNLS0 0x1067 /*0~8*/ +#define FC_AUDSCHNLS1 0x1068 +#define FC_AUDSCHNLS2 0x1069 +#define FC_AUDSCHNLS3 0x106a +#define FC_AUDSCHNLS4 0x106b +#define FC_AUDSCHNLS5 0x106c +#define FC_AUDSCHNLS6 0x106d +#define FC_AUDSCHNLS7 0x106e +#define FC_AUDSCHNLS8 0x106f + +enum { + AUDIO_32K = 0x3, + AUDIO_441K = 0x0, + AUDIO_48K = 0x2, + AUDIO_882K = 0x8, + AUDIO_96K = 0xa, + AUDIO_1764K = 0xc, + AUDIO_192K = 0xe, + AUDIO_768K = 0x9, +}; +#define m_AUDIO_SAMPLE_RATE (0x0f << 0) +#define v_AUDIO_SAMPLE_RATE(n) (((n)&0x0f) << 0) +#define m_AUDIO_ORI_SAMPLE_RATE (0x0f << 4) +#define v_AUDIO_ORI_SAMPLE_RATE(n) (((~n)&0x0f) << 4) +#define m_AUDIO_WORD_LENGTH (0x0f << 0) +#define v_AUDIO_WORD_LENGTH(n) (((n)&0x0f) << 0) + +#define FC_CTRLQHIGH 0x1073 +#define FC_CTRLQLOW 0x1074 +#define FC_ACP0 0x1075 +#define FC_ACP16 0x1082 /* 16~1 */ +#define FC_ISCR1_0 0x1092 +#define FC_ISCR1_16 0x1093 /* 16~1 */ +#define FC_ISCR2_15 0x10a3 /* 15~0 */ + +#define FC_DATAUTO0 0x10b3 +#define m_SPD_AUTO (1 << 4) +#define v_SPD_AUTO(n) (((n)&0x01) << 4) +#define m_VSD_AUTO (1 << 3) +#define v_VSD_AUTO(n) (((n)&0x01) << 3) +#define m_ISCR2_AUTO (1 << 2) +#define v_ISCR2_AUTO(n) (((n)&0x01) << 2) +#define m_ISCR1_AUTO (1 << 1) +#define v_ISCR1_AUTO(n) (((n)&0x01) << 1) +#define m_ACP_AUTO (1 << 0) +#define v_ACP_AUTO(n) (((n)&0x01) << 0) + +#define FC_DATAUTO1 0x10b4 +#define FC_DATAUTO2 0x10b5 + +#define FC_DATMAN 0x10b6 +#define m_SPD_MAN (1 << 4) +#define v_SPD_MAN(n) (((n)&0x01) << 4) +#define m_VSD_MAN (1 << 3) +#define v_VSD_MAN(n) (((n)&0x01) << 3) +#define m_ISCR2_MAN (1 << 2) +#define v_ISCR2_MAN(n) (((n)&0x01) << 2) +#define m_ISCR1_MAN (1 << 1) +#define v_ISCR1_MAN(n) (((n)&0x01) << 1) +#define m_ACP_MAN (1 << 0) +#define v_ACP_MAN(n) (((n)&0x01) << 0) + +#define FC_DATAUTO3 0x10b7 + #define m_AVI_AUTO (1 << 3) + #define v_AVI_AUTO(n) (((n)&0x01) << 3) + #define m_GCP_AUTO (1 << 2) + #define v_GCP_AUTO(n) (((n)&0x01) << 2) + #define m_AAI_AUTO (1 << 1) + #define v_AAI_AUTO(n) (((n)&0x01) << 1) + #define m_ACR_AUTO (1 << 0) + #define v_ACR_AUTO(n) (((n)&0x01) << 0) +#define FC_RDRB0 0x10b8 +#define FC_RDRB1 0x10b9 +#define FC_RDRB2 0x10ba +#define FC_RDRB3 0x10bb +#define FC_RDRB4 0x10bc +#define FC_RDRB5 0x10bd +#define FC_RDRB6 0x10be +#define FC_RDRB7 0x10bf + #define m_AVI_PACKETS_PER_FRAME (0xf << 4) + #define m_AVI_PACKERS_LINE_SPACING (0xf) + #define v_AVI_PACKETS_PER_FRAME(n) (((n) & 0x0f) << 4) + #define v_AVI_PACKERS_LINE_SPACING(n) (((n) & 0x0f) << 0) +#define FC_MASK0 0x10d2 +#define FC_MASK1 0x10d6 +#define FC_MASK2 0x10da + +#define FC_PRCONF 0x10e0 +#define m_FC_PR_FACTOR (0x0f << 4) +#define v_FC_PR_FACTOR(n) (((n)&0x0f) << 4) + +#define FC_SCRAMBLER_CTRL 0x10e1 +#define m_FC_SCRAMBLE_UCP (1 << 4) +#define v_FC_SCRAMBLE_UCP(n) (((n)&0x01) << 4) +#define m_FC_SCRAMBLE_EN (1 << 0) +#define v_FC_SCRAMBLE_EN(n) (((n)&0x01) << 0) + +#define FC_GMD_STAT 0x1100 +#define FC_GMD_EN 0x1101 +#define FC_GMD_UP 0x1102 +#define FC_GMD_CONF 0x1103 +#define FC_GMD_HB 0x1104 +#define FC_GMD_PB0 0x1105 /*0~27*/ + +#define FC_DBGFORCE 0x1200 +#define m_FC_FORCEAUDIO (1 << 4) +#define v_FC_FORCEAUDIO(n) (((n)&0x01) << 4) +#define m_FC_FORCEVIDEO (1 << 0) +#define v_FC_FORCEVIDEO(n) (((n)&0x01) << 0) + +#define FC_DBGAUD0CH0 0x1201 /* aud0~aud2 ch0 */ +#define FC_DBGAUD0CH1 0x1204 /* aud0~aud2 ch1 */ +#define FC_DBGAUD0CH2 0x1207 /* aud0~aud2 ch2 */ +#define FC_DBGAUD0CH3 0x120a /* aud0~aud2 ch3 */ +#define FC_DBGAUD0CH4 0x120d /* aud0~aud2 ch4 */ +#define FC_DBGAUD0CH5 0x1210 /* aud0~aud2 ch5 */ +#define FC_DBGAUD0CH6 0x1213 /* aud0~aud2 ch6 */ +#define FC_DBGAUD0CH7 0x1216 /* aud0~aud2 ch7 */ +#define FC_DBGTMDS0 0x1219 +#define FC_DBGTMDS1 0x121a +#define FC_DBGTMDS2 0x121b + +/* HDMI Source PHY Registers */ +#define HDMI_SOURCE_PHY_BASE 0x3000 + +#define PHY_CONF0 0x3000 +#define m_POWER_DOWN_EN (1 << 7)/* no use */ +#define v_POWER_DOWN_EN(n) (((n)&0x01) << 7) +#define m_TMDS_EN (1 << 6)/* no use */ +#define v_TMDS_EN(n) (((n)&0x01) << 6) +#define m_SVSRET_SIG (1 << 5)/* depend on PHY_MHL_COMB0=1 */ +#define v_SVSRET_SIG(n) (((n)&0x01) << 5) +#define m_PDDQ_SIG (1 << 4) +/*1: power down phy; 0: power on phy */ +#define v_PDDQ_SIG(n) (((n)&0x01) << 4) +#define m_TXPWRON_SIG (1 << 3) +/*1: power on transmitter; 0: power down transmitter */ +#define v_TXPWRON_SIG(n) (((n)&0x01) << 3) +#define m_ENHPD_RXSENSE_SIG (1 << 2) +/*1: enable detect hdp & rx sense */ +#define v_ENHPD_RXSENSE_SIG(n) (((n)&0x01) << 2) +#define m_SEL_DATAEN_POL (1 << 1) +#define v_SEL_DATAEN_POL(n) (((n)&0x01) << 1) +#define m_SEL_INTERFACE (1 << 0) +#define v_SEL_INTERFACE(n) (((n)&0x01) << 0) + +#define PHY_TST0 0x3001 +#define m_TEST_CLR_SIG (1 << 5) +#define m_TEST_EN_SIG (1 << 4) +#define m_TEST_CLK_SIG (1 << 0) + +#define PHY_TST1 0x3002 +#define PHY_TST2 0x3003 +#define PHY_STAT0 0x3004 +#define PHY_INI0 0x3005 +#define PHY_MASK 0x3006 +#define PHY_POL0 0x3007 +#define m_PHY_RX_SENSE3 (1 << 7) +#define v_PHY_TX_SENSE3(n) (((n)&0x01) << 7) +#define m_PHY_RX_SENSE2 (1 << 6) +#define v_PHY_TX_SENSE2(n) (((n)&0x01) << 6) +#define m_PHY_RX_SENSE1 (1 << 5) +#define v_PHY_TX_SENSE1(n) (((n)&0x01) << 5) +#define m_PHY_RX_SENSE0 (1 << 4) +#define v_PHY_TX_SENSE0(n) (((n)&0x01) << 4) +#define m_PHY_HPD (1 << 1) +#define v_PHY_HPD (((n)&0x01) << 1) +#define m_PHY_LOCK (1 << 0) +#define v_PHY_LOCK(n) (((n)&0x01) << 0) + +#define PHY_PCLFREQ0 0x3008 +#define PHY_PCLFREQ1 0x3009 +#define PHY_PLLCFGFREQ0 0x300a +#define PHY_PLLCFGFREQ1 0x300b +#define PHY_PLLCFGFREQ2 0x300c + +/* I2C Master PHY Registers */ +#define I2C_MASTER_PHY_BASE 0x3020 + +#define PHY_I2CM_SLAVE 0x3020 +#define PHY_GEN2_ADDR 0x69 +#define PHY_HEAC_ADDR 0x49 +#define PHY_I2C_SLAVE_ADDR 0x54 + +#define PHY_I2CM_ADDRESS 0x3021 +#define PHY_I2CM_DATAO_1 0x3022 +#define PHY_I2CM_DATAO_0 0x3023 +#define PHY_I2CM_DATAI_1 0x3024 +#define PHY_I2CM_DATAI_0 0x3025 + +#define PHY_I2CM_OPERATION 0x3026 +#define m_PHY_I2CM_WRITE (1 << 4) +#define m_PHY_I2CM_READ (1 << 0) + +#define PHY_I2CM_INT 0x3027 +#define m_PHY_I2CM_DONE_INT_POL (1 << 3) +#define v_PHY_I2CM_DONE_INT_POL(n) (((n)&0x01) << 3) +#define m_PHY_I2CM_DONE_MASK (1 << 2) +#define v_PHY_I2CM_DONE_MASK(n) (((n)&0x01) << 2) +#define m_PHY_I2CM_DONE_INT (1 << 1) +#define m_PHY_I2CM_DONE_STATUS (1 << 0) + +#define PHY_I2CM_CTLINT 0x3028 +#define m_PHY_I2CM_NACK_POL (1 << 7) +#define v_PHY_I2CM_NACK_POL(n) (((n)&0x01) << 7) +#define m_PHY_I2CM_NACK_MASK (1 << 6) +#define v_PHY_I2CM_NACK_MASK(n) (((n)&0x01) << 6) +#define m_PHY_I2CM_NACK_INT (1 << 5) +#define m_PHY_I2CM_NACK_STATUS (1 << 4) +#define m_PHY_I2CM_ARB_POL (1 << 3) +#define v_PHY_I2CM_ARB_POL(n) (((n)&0x01) << 3) +#define m_PHY_I2CM_ARB_MASK (1 << 2) +#define v_PHY_I2CM_ARB_MASK(n) (((n)&0x01) << 2) +#define m_PHY_I2CM_ARB_INT (1 << 1) +#define m_PHY_I2CM_ARB_STATUS (1 << 0) + +#define PHY_I2CM_DIV 0x3029 +#define m_PHY_I2CM_FAST_STD (1 << 3) +#define v_PHY_I2CM_FAST_STD(n) (((n)&0x01) << 3) + +#define PHY_I2CM_SOFTRSTZ 0x302a +#define m_PHY_I2CM_SOFTRST (1 << 0) +#define v_PHY_I2CM_SOFTRST(n) (((n)&0x01) << 0) + +#define PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b +#define PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c +#define PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d +#define PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e +#define PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f +#define PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030 +#define PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031 +#define PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032 +#define PHY_I2CM_SDA_HOLD 0x3033 + +/* Audio Sampler Registers */ +#define AUDIO_SAMPLER_BASE 0x3100 + +#define AUD_CONF0 0x3100 +#define m_SW_AUD_FIFO_RST (1 << 7) +#define v_SW_AUD_FIFO_RST(n) (((n)&0x01) << 7) +enum { + AUDIO_SPDIF_GPA = 0, + AUDIO_I2S +}; +#define m_I2S_SEL (1 << 5) +#define v_I2S_SEL(n) (((n)&0x01) << 5) +enum { + I2S_CHANNEL_1_2 = 1, + I2S_CHANNEL_3_4 = 3, + I2S_CHANNEL_5_6 = 7, + I2S_CHANNEL_7_8 = 0xf +}; +#define m_I2S_IN_EN (0x0f << 0) +#define v_I2S_IN_EN(n) (((n)&0x0f) << 0) + +#define AUD_CONF1 0x3101 +enum I2S_MODE { + I2S_STANDARD_MODE = 0, + I2S_RIGHT_JUSTIFIED_MODE, + I2S_LEFT_JUSTIFIED_MODE, + I2S_BURST_1_MODE, + I2S_BURST_2_MODE +}; +#define m_I2S_MODE (0x07 << 5) +#define v_I2S_MODE(n) (((n)&0x07) << 5) +enum I2S_WIDTH { + I2S_16BIT_SAMPLE = 16, + I2S_17BIT_SAMPLE, + I2S_18BIT_SAMPLE, + I2S_19BIT_SAMPLE, + I2S_20BIT_SAMPLE, + I2S_21BIT_SAMPLE, + I2S_22BIT_SAMPLE, + I2S_23BIT_SAMPLE, + I2S_24BIT_SAMPLE, +}; +#define m_I2S_WIDTH (0x1f << 0) +#define v_I2S_WIDTH(n) (((n)&0x1f) << 0) + +#define AUD_INT 0x3102 +#define AUD_SPDIFINT 0x3302 +#define m_FIFO_EMPTY_MASK (1 << 3) +#define v_FIFO_EMPTY_MASK(n) (((n)&0x01) << 3) +#define m_FIFO_FULL_MASK (1 << 2) +#define v_FIFO_FULL_MASK(n) (((n)&0x01) << 2) + +#define AUD_CONF2 0x3103 +#define m_NLPCM_EN (1 << 1) +#define v_NLPCM_EN(n) (((n)&0x01) << 1) +#define m_HBR_EN (1 << 0) +#define v_HBR_EN(n) (((n)&0x01) << 0) + +#define AUD_INT1 0x3104 +#define AUD_SPDIFINT1 0x3303 +#define m_FIFO_OVERRUN_MASK (1 << 4) +#define v_FIFO_OVERRUN_MASK(n) (((n)&0x01) << 4) + +/***************N-CTS Table**************/ +/* TMDS LOWCLK: <=148.5M */ +/* TMDS MIDCLK: 297M */ +/* TMDS HIGHCLK: 594M */ +#define N_32K_LOWCLK 0x1000 +#define N_32K_MIDCLK 0x0c00 +#define N_32K_HIGHCLK 0x0c00 +#define N_441K_LOWCLK 0x1880 +#define N_441K_MIDCLK 0x1260 +#define N_441K_HIGHCLK 0x24c0 +#define N_48K_LOWCLK 0x1800 +#define N_48K_MIDCLK 0x1400 +#define N_48K_HIGHCLK 0x1800 +#define N_882K_LOWCLK 0x3100 +#define N_882K_MIDCLK 0x24c0 +#define N_882K_HIGHCLK 0x4980 +#define N_96K_LOWCLK 0x3000 +#define N_96K_MIDCLK 0x2800 +#define N_96K_HIGHCLK 0x3000 +#define N_1764K_LOWCLK 0x6200 +#define N_1764K_MIDCLK 0x4980 +#define N_1764K_HIGHCLK 0x9300 +#define N_192K_LOWCLK 0x6000 +#define N_192K_MIDCLK 0x5000 +#define N_192K_HIGHCLK 0x6000 + +#define CALC_CTS(N, TMDSCLK, FS) (((N) / 32) * (TMDSCLK) / ((FS) * 4)) +/****************************************/ + +#define AUD_N1 0x3200 +#define AUD_N2 0x3201 + +#define AUD_N3 0x3202 +#define m_NCTS_ATOMIC_WR (1 << 7) +#define v_NCTS_ATOMIC_WR(n) (((n)&0x01) << 7) +#define m_AUD_N3 (0x0f << 0) +#define v_AUD_N3(n) (((n)&0x0f) << 0) + +#define AUD_CTS1 0x3203 +#define AUD_CTS2 0x3204 + +#define AUD_CTS3 0x3205 +enum { + N_SHIFT_1 = 0, + N_SHIFT_16, + N_SHIFT_32, + N_SHIFT_64, + N_SHIFT_128, + N_SHIFT_256, + N_SHIFT_OTHERS_128 +}; +#define m_N_SHIFT (0x07 << 5) +#define v_N_SHIFT(n) (((n)&0x07) << 5) +#define m_CTS_MANUAL (1 << 4) +#define v_CTS_MANUAL(n) (((n)&0x01) << 4) +#define m_AUD_CTS3 (0x0f << 0) +#define v_AUD_CTS3(n) (((n)&0x0f) << 0) + +#define AUD_INPUTCLKFS 0x3206 +enum { + FS_128 = 0, + FS_256, + FS_512, + FS_64 = 4, + FS_OTHERS_128 +}; +#define m_LFS_FACTOR (0x07 << 0) +#define v_LFS_FACTOR(n) (((n)&0x07) << 0) + +#define AUD_SPDIF0 0x3300 +#define m_SW_SAUD_FIFO_RST (1 << 7) +#define v_SW_SAUD_FIFO_RST(n) (((n)&0x01) << 7) + +#define AUD_SPDIF1 0x3301 +enum { + PCM_LINEAR = 0, + PCM_NONLINEAR +}; +#define m_SET_NLPCM (1 << 7) +#define v_SET_NLPCM(n) (((n)&0x01) << 7) +#define m_SPDIF_HBR_MODE (1 << 6) +#define v_SPDIF_HBR_MODE(n) (((n)&0x01) << 6) +#define m_SPDIF_WIDTH (0x1f << 0) +#define v_SPDIF_WIDTH(n) (((n)&0x1f) << 0) + +/* Generic Parallel Audio Interface Registers */ +#define GP_AUDIO_INTERFACE_BASE 0x3500 + +#define GP_CONF0 0x3500 +#define GP_CONF1 0x3501 +#define GP_CONF2 0x3502 +#define GP_MASK 0x3506 + +/* Audio DMA Registers */ +#define AUDIO_DMA_BASE 0x3600 + +#define AHB_DMA_CONF0 0x3600 +#define AHB_DMA_START 0x3601 +#define AHB_DMA_STOP 0x3602 +#define AHB_DMA_THRSLD 0x3603 +#define AHB_DMA_STRADDR_SET0_0 0x3604 /* 0~3 */ +#define AHB_DMA_STPADDR_SET0_0 0x3608 /* 0~3 */ +#define AHB_DMA_BSTADDR0 0x360c /* 0~3 */ +#define AHB_DMA_MBLENGTH0 0x3610 /* 0~3 */ +#define AHB_DMA_MASK 0x3614 +#define AHB_DMA_CONF1 0x3616 +#define AHB_DMA_BUFFMASK 0x3619 +#define AHB_DMA_MASK1 0x361b +#define AHB_DMA_STATUS 0x361c +#define AHB_DMA_CONF2 0x361d +#define AHB_DMA_STRADDR_SET1_0 0x3620 /* 0~3 */ +#define AHB_DMA_STPADDR_SET1_0 0x3624 /* 0~3 */ + +/* Main Controller Registers */ +#define MAIN_CONTROLLER_BASE 0x4000 + +#define MC_CLKDIS 0x4001 +#define m_HDCPCLK_DISABLE (1 << 6) +#define v_HDCPCLK_DISABLE(n) (((n)&0x01) << 6) +#define m_CECCLK_DISABLE (1 << 5) +#define v_CECCLK_DISABLE(n) (((n)&0x01) << 5) +#define m_CSCCLK_DISABLE (1 << 4) +#define v_CSCCLK_DISABLE(n) (((n)&0x01) << 4) +#define m_AUDCLK_DISABLE (1 << 3) +#define v_AUDCLK_DISABLE(n) (((n)&0x01) << 3) +#define m_PREPCLK_DISABLE (1 << 2) +#define v_PREPCLK_DISABLE(n) (((n)&0x01) << 2) +#define m_TMDSCLK_DISABLE (1 << 1) +#define v_TMDSCLK_DISABLE(n) (((n)&0x01) << 1) +#define m_PIXELCLK_DISABLE (1 << 0) +#define v_PIXELCLK_DISABLE(n) (((n)&0x01) << 0) + +#define MC_SWRSTZREQ 0x4002 +#define m_IGPA_SWRST (1 << 7) +#define v_IGPA_SWRST(n) (((n)&0x01) << 7) +#define m_CEC_SWRST (1 << 6) +#define v_CEC_SWRST(n) (((n)&0x01) << 6) +#define m_ISPDIF_SWRST (1 << 4) +#define v_ISPDIF_SWRST(n) (((n)&0x01) << 4) +#define m_II2S_SWRST (1 << 3) +#define v_II2S_SWRST(n) (((n)&0x01) << 3) +#define m_PREP_SWRST (1 << 2) +#define v_PREP_SWRST(n) (((n)&0x01) << 2) +#define m_TMDS_SWRST (1 << 1) +#define v_TMDS_SWRST(n) (((n)&0x01) << 1) +#define m_PIXEL_SWRST (1 << 0) +#define v_PIXEL_SWRST(n) (((n)&0x01) << 0) + +#define MC_OPCTRL 0x4003 +#define m_HDCP_BLOCK_BYP (1 << 0) +#define v_HDCP_BLOCK_BYP(n) (((n)&0x01) << 0) + +#define MC_FLOWCTRL 0x4004 +#define m_FEED_THROUGH_OFF (1 << 0) +#define v_FEED_THROUGH_OFF(n) (((n)&0x01) << 0) + +#define MC_PHYRSTZ 0x4005 +#define m_PHY_RSTZ (1 << 0) +#define v_PHY_RSTZ(n) (((n)&0x01) << 0) + +#define MC_LOCKONCLOCK 0x4006 +#define m_IGPACLK_ON (1 << 7) +#define v_IGPACLK_ON(n) (((n)&0x01) << 7) +#define m_PCLK_ON (1 << 6) +#define v_PCLK_ON(n) (((n)&0x01) << 6) +#define m_TMDSCLK_ON (1 << 5) +#define v_TMDSCLK_ON(n) (((n)&0x01) << 5) +#define m_PREPCLK_ON (1 << 4) +#define v_PREPCLK_ON(n) (((n)&0x01) << 4) +#define m_I2SCLK_ON (1 << 3) +#define v_I2SCLK_ON(n) (((n)&0x01) << 3) +#define m_SPDIFCLK_ON (1 << 2) +#define v_SPDIFCLK_ON(n) (((n)&0x01) << 2) +#define m_CECCLK_ON (1 << 0) +#define v_CECCLK_ON(n) (((n)&0x01) << 0) + +#define MC_HEACPHY_RST 0x4007 +#define m_HEAC_PHY_RST (1 << 0) +#define v_HEAC_PHY_RST(n) (((n)&0x01) << 0) + +#define MC_LOCKONCLOCK_2 0x4009 +#define m_AHB_AUD_DMA_CLK (1 << 0) +#define v_AHB_AUD_DMA_CLK(n) (((n)&0x01) << 0) + +#define MC_SWRSTZREQ_2 0x400a +#define m_AHB_AUD_DMA_RST (1 << 7) +#define v_AHB_AUD_DMA_RST(n) (((n)&0x01) << 7) + +/* Color Space Converter Registers */ +#define COLOR_SPACE_CONVERTER_BASE 0x4100 + +#define CSC_CFG 0x4100 +#define m_CSC_INTPMODE (0x03 << 4) +#define v_CSC_INTPMODE(n) (((n)&0x03) << 4) +#define m_CSC_DECIMODE (0x03 << 0) +#define v_CSC_DECIMODE(n) (((n)&0x03) << 0) + +#define CSC_SCALE 0x4101 +#define m_CSC_COLOR_DEPTH (0x0f << 4) +#define v_CSC_COLOR_DEPTH(n) (((n)&0x0f) << 4) +#define m_CSC_SCALE (0x03 << 0) +#define v_CSC_SCALE(n) (((n)&0x03) << 0) + +#define CSC_COEF_A1_MSB 0x4102 +#define CSC_COEF_A1_LSB 0x4103 +#define CSC_COEF_A2_MSB 0x4104 +#define CSC_COEF_A2_LSB 0x4105 +#define CSC_COEF_A3_MSB 0x4106 +#define CSC_COEF_A3_LSB 0x4107 +#define CSC_COEF_A4_MSB 0x4108 +#define CSC_COEF_A4_LSB 0x4109 +#define CSC_COEF_B1_MSB 0x410a +#define CSC_COEF_B1_LSB 0x410b +#define CSC_COEF_B2_MSB 0x410c +#define CSC_COEF_B2_LSB 0x410d +#define CSC_COEF_B3_MSB 0x410e +#define CSC_COEF_B3_LSB 0x410f +#define CSC_COEF_B4_MSB 0x4110 +#define CSC_COEF_B4_LSB 0x4111 +#define CSC_COEF_C1_MSB 0x4112 +#define CSC_COEF_C1_LSB 0x4113 +#define CSC_COEF_C2_MSB 0x4114 +#define CSC_COEF_C2_LSB 0x4115 +#define CSC_COEF_C3_MSB 0x4116 +#define CSC_COEF_C3_LSB 0x4117 +#define CSC_COEF_C4_MSB 0x4118 +#define CSC_COEF_C4_LSB 0x4119 +#define CSC_SPARE_1 0x411a +#define CSC_SPARE_2 0x411b + +/* HDCP Encryption Engine Registers */ +#define HDCP_ENCRYPTION_ENGINE_BASE 0x5000 + +#define A_HDCPCFG0 0x5000 +#define m_HDCP_ENHANCE_LIKE (1 << 7) +#define v_HDCP_ENHANCE_LIKE(n) (((n)&0x01) << 7) +#define m_I2C_FAST_MODE (1 << 6) +#define v_I2C_FAST_MODE(n) (((n)&0x01) << 6) +#define m_ENCRYPT_BYPASS (1 << 5) +#define v_ENCRYPT_BYPASS(n) (((n)&0x01) << 5) +#define m_SYNC_RI_CHECK (1 << 4) +#define v_SYNC_RI_CHECK(n) (((n)&0x01) << 4) +#define m_AVMUTE (1 << 3) +#define m_RX_DETECT (1 << 2) +#define v_RX_DETECT(n) (((n)&0x01) << 2) +#define m_FEATURE11_EN (1 << 1) +#define v_FEATURE11_EN(n) (((n)&0x01) << 1) +#define m_HDMI_DVI (1 << 0) +#define v_HDMI_DVI(n) (((n)&0x01) << 0) + +#define A_HDCPCFG1 0x5001 +#define m_HDCP_LOCK (1 << 4) +#define v_HDCP_LOCK(n) (((n)&0x01) << 4) +#define m_SHA1_CHECK_DISABLE (1 << 3) +#define v_SHA1_CHECK_DISBALE(n) (((n)&0x01) << 3) +#define m_PH2UPSHFTENC (1 << 2) +#define v_PH2UPSHFTENC(n) (((n)&0x01) << 2) +#define m_ENCRYPT_DISBALE (1 << 1) +#define v_ENCRYPT_DISBALE(n) (((n)&0x01) << 1) +#define m_HDCP_SW_RST (1 << 0) +#define v_HDCP_SW_RST(n) (((n)&0x01) << 0) + +#define A_HDCPOBS0 0x5002 +#define m_STATE_AUTH (0x0f << 4) +#define m_SUB_STATE_AUTH (0x07 << 1) +#define m_STATE_HDCP_ENGAGED (1 << 0) + +#define A_HDCPOBS1 0x5003 +#define m_STATE_OESS (0x07 << 3) +#define m_STATE_REVO (0x07 << 0) + +#define A_HDCPOBS2 0x5004 +#define m_STATE_CIPHER (0x07 << 3) +#define m_STATE_EESS (0x07 << 0) + +#define A_HDCPOBS3 0x5005 +#define m_BCAP_REPEATER (1 << 6) +#define m_BCAP_KSVFIFO_READY (1 << 5) +#define m_BCAP_FAST_I2C (1 << 4) +#define m_BCAP_HDMI_MODE (1 << 2) +#define m_BCAP_FEATURES11 (1 << 1) +#define m_BCAP_FAST_REAUTH (1 << 0) + +#define A_APIINTCLR 0x5006 +#define A_APIINTSTAT 0x5007 +#define A_APIINTMSK 0x5008 +#define m_HDCP_ENGAGED (1 << 7) +#define m_HDCP_FAILED (1 << 6) +#define m_HDCP_I2C_NOACK (1 << 4) +#define m_HDCP_LOST_ARBI (1 << 3) +#define m_KEEP_ERR_INT (1 << 2) +#define m_KSVSHA1_CALC_INT (1 << 1) +#define m_KSV_ACCESS_INT (1 << 0) +#define v_HDCP_ENGAGED(n) (((n)&0x01) << 7) +#define v_HDCP_FAILED(n) (((n)&0x01) << 6) +#define v_HDCP_I2C_NOACK(n) (((n)&0x01) << 4) +#define v_HDCP_LOST_ARBI(n) (((n)&0x01) << 3) +#define v_KEEP_ERR_INT(n) (((n)&0x01) << 1) +#define v_KSVSHA1_CALC_INT(n) (((n)&0x01) << 1) +#define v_KSV_ACCESS_INT(n) (((n)&0x01) << 0) + +#define A_VIDPOLCFG 0x5009 +#define m_UNENCRYT_CONF (0x03 << 5) +#define v_UNENCRYT_CONF(n) (((n)&0x03) << 5) +#define m_DATAEN_POL (1 << 4) +#define v_DATAEN_POL(n) (((n)&0x01) << 4) +#define m_VSYNC_POL (1 << 3) +#define v_VSYNC_POL(n) (((n)&0x01) << 3) +#define m_HSYNC_POL (1 << 1) +#define v_HSYNC_POL(n) (((n)&0x01) << 1) + +#define A_OESSWCFG 0x500a +#define A_COREVERLSB 0x5014 +#define A_COREVERMSB 0x5015 + +#define A_KSVMEMCTRL 0x5016 +#define m_SHA1_FAIL (1 << 3) +#define v_SHA1_FAIL(n) (((n)&0x01) << 3) +#define m_KSV_UPDATE (1 << 2) +#define v_KSV_UPDATE(n) (((n)&0x01) << 2) +#define m_KSV_MEM_ACCESS (1 << 1) +#define m_KSV_MEM_REQ (1 << 0) +#define v_KSV_MEM_REQ(n) (((n)&0x01) << 0) + +#define HDCP_BSTATUS_0 0x5020 +#define m_MAX_DEVS_EXCEEDED (1 << 7) +#define m_DEVICE_COUNT (0x7f << 0) + +#define HDCP_BSTATUS_1 0x5021 +#define HDCP_M0_0 0x5022 +#define HDCP_M0_1 0x5023 +#define HDCP_M0_2 0x5024 +#define HDCP_M0_3 0x5025 +#define HDCP_M0_4 0x5026 +#define HDCP_M0_5 0x5027 +#define HDCP_M0_6 0x5028 +#define HDCP_M0_7 0x5029 +#define HDCP_KSV 0x502a /* 0~634 */ +#define HDCP_VH 0x52a5 /* 0~19 */ +#define HDCP_REVOC_SIZE_0 0x52b9 +#define HDCP_REVOC_SIZE_1 0x52ba +#define HDCP_REVOC_LIST 0x52bb /* 0~5059 */ + +/* HDCP BKSV Registers */ +#define HDCP_BKSV_BASE 0x7800 + +#define HDCPREG_BKSV0 0x7800 +#define HDCPREG_BKSV1 0x7801 +#define HDCPREG_BKSV2 0x7802 +#define HDCPREG_BKSV3 0x7803 +#define HDCPREG_BKSV4 0x7804 + +/* HDCP AN Registers */ +#define HDCP_AN_BASE 0x7805 + +#define HDCPREG_ANCONF 0x7805 +#define m_OAN_BYPASS (1 << 0) +#define v_OAN_BYPASS(n) (((n)&0x01) << 0) + +#define HDCPREG_AN0 0x7806 +#define HDCPREG_AN1 0x7807 +#define HDCPREG_AN2 0x7808 +#define HDCPREG_AN3 0x7809 +#define HDCPREG_AN4 0x780a +#define HDCPREG_AN5 0x780b +#define HDCPREG_AN6 0x780c +#define HDCPREG_AN7 0x780d + +/* Encrypted DPK Embedded Storage Registers */ +#define ENCRYPTED_DPK_EMBEDDED_BASE 0x780e + +#define HDCPREG_RMCTL 0x780e +#define m_DPK_DECRYPT_EN (1 << 0) +#define v_DPK_DECRYPT_EN(n) (((n)&0x01) << 0) + +#define HDCPREG_RMSTS 0x780f +#define m_DPK_WR_OK_STS (1 << 6) +#define m_DPK_DATA_INDEX (0x3f << 6) + +#define HDCPREG_SEED0 0x7810 +#define HDCPREG_SEED1 0x7811 +#define HDCPREG_DPK0 0x7812 +#define HDCPREG_DPK1 0x7813 +#define HDCPREG_DPK2 0x7814 +#define HDCPREG_DPK3 0x7815 +#define HDCPREG_DPK4 0x7816 +#define HDCPREG_DPK5 0x7817 +#define HDCPREG_DPK6 0x7818 + +#define HDCP2REG_BASE 0x7900 +#define HDCP2REG_ID 0x7900 +#define HDCP2REG_CTRL 0x7904 + #define m_HDCP2_HDP_OVR_VAL (1 << 5) + #define m_HDCP2_HDP_OVR_EN (1 << 4) + #define m_HDCP2_FORCE (1 << 2) + #define m_HDCP2_OVR_EN (1 << 1) + #define m_HDCP2_SWITCH_EN (1 << 0) + + #define v_HDCP2_HDP_OVR_VAL(n) (((n)&0x01) << 5) + #define v_HDCP2_HDP_OVR_EN(n) (((n)&0x01) << 4) + #define v_HDCP2_FORCE(n) (((n)&0x01) << 2) + #define v_HDCP2_OVR_EN(n) (((n)&0x01) << 1) + #define v_HDCP2_SWITCH_EN(n) (((n)&0x01) << 0) +#define HDCP2REG_CTRL1 0x7905 + #define m_HDCP2_CD_VAL (0xf << 4) + #define m_HDCP2_CD_EN (1 << 3) + #define m_HDCP2_AVMUTE_OVR_VAL (1 << 1) + #define m_HDCP2_AVMUTE_OVR_EN (1 << 0) + + #define v_HDCP2_CD_VAL(n) (((n)&0x0f) << 4) + #define v_HDCP2_CD_EN(n) (((n)&0x01) << 3) + #define v_HDCP2_AVMUTE_OVR_VAL(n) (((n)&0x01) << 1) + #define v_HDCP2_AVMUTE_OVR_EN(n) (((n)&0x01) << 0) +#define HDCP2REG_STAS 0x7908 +#define HDCP2REG_MASK 0x790c +#define HDCP2REG_STAT 0x790d +#define HDCP2REG_MUTE 0x790e + #define m_HDCP2_CAPABLE (1 << 0) + #define m_HDCP2_NOTCAPABLE (1 << 1) + #define m_HDCP2_AUTH_LOST (1 << 2) + #define m_HDCP2_AUTH_OK (1 << 3) + #define m_HDCP2_AUTH_FAIL (1 << 4) + +/* CEC Engine Registers */ +#define CEC_ENGINE_BASE 0x7d00 + +#define CEC_CTRL 0x7d00 + #define m_CEC_STANBY (1 << 4) + #define m_CEC_BC_NCK (1 << 3) + #define m_CEC_FRAME_TYPE (3 << 1) + #define m_CEC_SEND (1 << 0) + #define v_CEC_STANBY(n) ((n & 0x1) << 4) + #define v_CEC_BC_NCK(n) ((n & 0x1) << 3) + #define v_CEC_FRAME_TYPE(n) ((n & 0x3) << 1) + #define v_CEC_SEND(n) (n & 0x1) +#define CEC_MASK 0x7d02 +#define CEC_ADDR_L 0x7d05 +#define CEC_ADDR_H 0x7d06 +#define CEC_TX_CNT 0x7d07 +#define CEC_RX_CNT 0x7d08 +#define CEC_TX_DATA0 0x7d10 /* txdata0~txdata15 */ +#define CEC_RX_DATA0 0x7d20 /* rxdata0~rxdata15 */ +#define CEC_LOCK 0x7d30 +#define CEC_WKUPCTRL 0x7d31 + +/* I2C Master Registers */ +#define I2C_MASTER_BASE 0x7e00 + +#define I2CM_SLAVE 0x7e00 +#define I2CM_ADDRESS 0x7e01 +#define I2CM_DATAO 0x7e02 +#define I2CM_DATAI 0x7e03 + +#define I2CM_OPERATION 0x7e04 +#define m_I2CM_WR (1 << 4) +#define v_I2CM_WR(n) (((n)&0x01) << 4) +#define m_I2CM_RD8_EXT (1 << 3) +#define v_I2CM_RD8_EXT(n) (((n)&0x01) << 3) +#define m_I2CM_RD8 (1 << 2) +#define v_I2CM_RD8(n) (((n)&0x01) << 2) +#define m_I2CM_RD_EXT (1 << 1) +#define v_I2CM_RD_EXT(n) (((n)&0x01) << 1) +#define m_I2CM_RD (1 << 0) +#define v_I2CM_RD(n) (((n)&0x01) << 0) + +#define I2CM_INT 0x7e05 +#define m_I2CM_RD_REQ_MASK (1 << 6) +#define v_I2CM_RD_REQ_MASK(n) (((n)&0x01) << 6) +#define m_I2CM_DONE_MASK (1 << 2) +#define v_I2CM_DONE_MASK(n) (((n)&0x01) << 2) + +#define I2CM_CTLINT 0x7e06 +#define m_I2CM_NACK_MASK (1 << 6) +#define v_I2CM_NACK_MASK(n) (((n)&0x01) << 6) +#define m_I2CM_ARB_MASK (1 << 2) +#define v_I2CM_ARB_MASK(n) (((n)&0x01) << 2) + +#define I2CM_DIV 0x7e07 +enum { + STANDARD_MODE = 0, + FAST_MODE +}; +#define m_I2CM_FAST_STD_MODE (1 << 3) +#define v_I2CM_FAST_STD_MODE(n) (((n)&0x01) << 3) + +#define I2CM_SEGADDR 0x7e08 +#define m_I2CM_SEG_ADDR (0x7f << 0) +#define v_I2CM_SEG_ADDR(n) (((n)&0x7f) << 0) + +#define I2CM_SOFTRSTZ 0x7e09 +#define m_I2CM_SOFTRST (1 << 0) +#define v_I2CM_SOFTRST(n) (((n)&0x01) << 0) + +#define I2CM_SEGPTR 0x7e0a +#define I2CM_SS_SCL_HCNT_1_ADDR 0x7e0b +#define I2CM_SS_SCL_HCNT_0_ADDR 0x7e0c +#define I2CM_SS_SCL_LCNT_1_ADDR 0x7e0d +#define I2CM_SS_SCL_LCNT_0_ADDR 0x7e0e +#define I2CM_FS_SCL_HCNT_1_ADDR 0x7e0f +#define I2CM_FS_SCL_HCNT_0_ADDR 0x7e10 +#define I2CM_FS_SCL_LCNT_1_ADDR 0x7e11 +#define I2CM_FS_SCL_LCNT_0_ADDR 0x7e12 +#define I2CM_SDA_HOLD 0x7e13 + +#define I2CM_SCDC_READ_UPDATE 0x7e14 +#define m_I2CM_UPRD_VSYNC_EN (1 << 5) +#define v_I2CM_UPRD_VSYNC_EN(n) (((n)&0x01) << 5) +#define m_I2CM_READ_REQ_EN (1 << 4) +#define v_I2CM_READ_REQ_EN(n) (((n)&0x01) << 4) +#define m_I2CM_READ_UPDATE (1 << 0) +#define v_I2CM_READ_UPDATE(n) (((n)&0x01) << 0) + +#define I2CM_READ_BUFF0 0x7e20 /* buff0~buff7 */ +#define I2CM_SCDC_UPDATE0 0x7e30 +#define I2CM_SCDC_UPDATE1 0x7e31 + +/* +* HDMI TX PHY Define Start +*/ +#define PHYTX_OPMODE_PLLCFG 0x06 +enum { + PREP_DIV_BY_2 = 0, /* 16 bits */ + PREP_DIV_BY_15, /* 12 bits */ + PREP_DIV_BY_125, /* 10 bits */ + PREP_DIV_BY_1, /* 8 bits */ +}; +#define m_PREP_DIV (0x03 << 13) +#define v_PREP_DIV(n) (((n)&0x03) << 13) +enum { + TMDS_DIV_BY_1 = 0, + TMDS_DIV_NOT_USED, + TMDS_DIV_BY_3, + TMDS_DIV_BY_4, +}; +#define m_TMDS_CNTRL (0x03 << 11) +#define v_TMDS_CNTRL(n) (((n)&0x03) << 11) +enum OPMODE { + OP_HDMI_14 = 0, + OP_HDMI_20, +}; +#define m_OPMODE (0x03 << 9) +#define v_OPMODE(n) (((n)&0x03) << 9) +enum { + FBDIV2_BY_1 = 1, + FBDIV2_BY_2, + FBDIV2_BY_3, + FBDIV2_BY_4, + FBDIV2_BY_5, + FBDIV2_BY_6, +}; +#define m_FBDIV2_CNTRL (0x07 << 6) +#define v_FBDIV2_CNTRL(n) (((n)&0x07) << 6) +enum { + FBDIV1_BY_1 = 0, + FBDIV1_BY_2, + FBDIV1_BY_3, + FBDIV1_BY_4, +}; +#define m_FBDIV1_CNTRL (0x03 << 4) +#define v_FBDIV1_CNTRL(n) (((n)&0x03) << 4) +enum { + REF_DIV_BY_1 = 0, + REF_DIV_BY_2, + REF_DIV_NOT_USED, + REF_DIV_BY_4, +}; +#define m_REF_CNTRL (0x03 << 2) +#define v_REF_CNTRL(n) (((n)&0x03) << 2) +#define m_MPLL_N_CNTRL (0x03 << 0) +#define v_MPLL_N_CNTRL(n) (((n)&0x03) << 0) + +#define PHYTX_CLKSYMCTRL 0x09 +#define v_OVERRIDE(n) (0x01 << 15) +#define m_SLOPEBOOST (0x03 << 4) +#define v_SLOPEBOOST(n) (((n)&0x03) << 4) +#define m_TX_SYMON (0x01 << 3) +#define v_TX_SYMON(n) (((n)&0x01) << 3) +#define m_TX_TRAON (0x01 << 2) +#define v_TX_TRAON(n) (((n)&0x01) << 2) +#define m_TX_TRBON (0x01 << 1) +#define v_TX_TRBON(n) (((n)&0x01) << 1) +#define m_CLK_SYMON (0x01 << 0) +#define v_CLK_SYMON(n) (((n)&0x01) << 0) + +#define PHYTX_VLEVCTRL 0x0e +#define m_SUP_TXLVL (0x1f << 5) +#define v_SUP_TXLVL(n) (((n)&0x1f) << 5) +#define m_SUP_CLKLVL (0x1f << 0) +#define v_SUP_CLKLVL(n) (((n)&0x1f) << 0) + +#define PHYTX_PLLCURRCTRL 0x10 +#define m_MPLL_PROP_CNTRL (0x07 << 3) +#define v_MPLL_PROP_CNTRL(n) (((n)&0x07) << 3) +#define m_MPLL_INT_CNTRL (0x07 << 0) +#define v_MPLL_INT_CNTRL(n) (((n)&0x07) << 0) + +#define PHYTX_PLLGMPCTRL 0x15 +#define m_MPLL_GMP_CNTRL (0x03 << 0) +#define v_MPLL_GMP_CNTRL(n) (((n)&0x03) << 0) + +enum TERM_RESIS { + R50_OHMS = 0, + R5714_OHMS, + R6667_OHMS, + R80_OHMS, + R100_OHMS, + R13333_OHMS, + R200_OHMS, + ROPEN_CIRCUIT, +}; +#define PHYTX_TERM_RESIS 0x19 +#define m_TX_TERM (0x07 << 0) +#define v_TX_TERM(n) (((n)&0x07) << 0) + + +struct phy_mpll_config_tab { + u32 pix_clock; + u32 tmdsclock; + u8 pix_repet; + u8 color_depth; + u16 prep_div; + u16 tmdsmhl_cntrl; + u16 opmode; + u32 fbdiv2_cntrl; + u16 fbdiv1_cntrl; + u16 ref_cntrl; + u16 n_cntrl; + u32 prop_cntrl; + u32 int_cntrl; + u16 gmp_cntrl; +}; + +/* +* HDMI TX PHY Define End +*/ + +struct rockchip_hdmiv2_reg_table { + int reg_base; + int reg_end; +}; + +static inline u32 hdmi_readl(struct hdmi_dev *hdmi_dev, u16 offset) +{ + return readl_relaxed(hdmi_dev->regbase + (offset) * 0x04); +} + +static inline int hdmi_writel(struct hdmi_dev *hdmi_dev, u16 offset, u32 val) +{ + int ret = 0; + + writel_relaxed(val, hdmi_dev->regbase + (offset) * 0x04); + return ret; +} + +static inline int hdmi_msk_reg(struct hdmi_dev *hdmi_dev, + u16 offset, u32 msk, u32 val) +{ + int ret = 0; + u32 temp; + + temp = readl_relaxed(hdmi_dev->regbase + + (offset) * 0x04) & (0xFF - (msk)); + writel_relaxed(temp | ((val) & (msk)), + hdmi_dev->regbase + (offset) * 0x04); + return ret; +} +irqreturn_t rockchip_hdmiv2_dev_irq(int irq, void *priv); +void rockchip_hdmiv2_dev_init_ops(struct hdmi_ops *ops); +void rockchip_hdmiv2_dev_initial(struct hdmi_dev *hdmi_dev); +void rockchip_hdmiv2_cec_init(struct hdmi *hdmi); +void rockchip_hdmiv2_cec_isr(struct hdmi_dev *hdmi_dev, char cec_int); +void rockchip_hdmiv2_dump_phy_regs(struct hdmi_dev *hdmi_dev); +void rockchip_hdmiv2_hdcp_init(struct hdmi *hdmi); +#endif diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index b48edc5bb86d..31f6835dbcf7 100755 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -35,7 +35,7 @@ #include "bmp_helper.h" #if defined(CONFIG_RK_HDMI) -#include "hdmi/rk_hdmi.h" +#include "hdmi/rockchip-hdmi.h" #endif #if defined(CONFIG_ROCKCHIP_RGA) || defined(CONFIG_ROCKCHIP_RGA2) diff --git a/drivers/video/rockchip/screen/rk_screen.c b/drivers/video/rockchip/screen/rk_screen.c index 0c031275d414..558c3b2f5b27 100755 --- a/drivers/video/rockchip/screen/rk_screen.c +++ b/drivers/video/rockchip/screen/rk_screen.c @@ -2,7 +2,7 @@ #include #include #include "lcd.h" -#include "../hdmi/rk_hdmi.h" +#include "../hdmi/rockchip-hdmi.h" static struct rk_screen *rk_screen; int rk_fb_get_prmry_screen(struct rk_screen *screen) diff --git a/include/dt-bindings/rkfb/rk_fb.h b/include/dt-bindings/rkfb/rk_fb.h index 36268e43b5ae..6cf49df8b0e4 100755 --- a/include/dt-bindings/rkfb/rk_fb.h +++ b/include/dt-bindings/rkfb/rk_fb.h @@ -6,6 +6,9 @@ #define PRMRY 1 /*primary display device*/ #define EXTEND 2 /*extend display device*/ +#define DISPLAY_SOURCE_LCDC0 0 +#define DISPLAY_SOURCE_LCDC1 1 + #define NO_DUAL 0 #define ONE_DUAL 1 #define DUAL 2 diff --git a/include/linux/display-sys.h b/include/linux/display-sys.h index 28a14aac7ff0..b229b9b2bab1 100755 --- a/include/linux/display-sys.h +++ b/include/linux/display-sys.h @@ -4,6 +4,7 @@ #include #include #include +#include struct rk_display_device; @@ -20,6 +21,21 @@ enum { DISPLAY_SCALE_Y }; +enum rk_display_property { + DISPLAY_MAIN = 0, + DISPLAY_AUX +}; + + +/* HDMI mode list*/ +struct display_modelist { + struct list_head list; + struct fb_videomode mode; + unsigned int vic; + unsigned int format_3d; + unsigned int detail_3d; +}; + /* This structure defines all the properties of a Display. */ struct rk_display_driver { void (*suspend)(struct rk_display_device *, pm_message_t state); @@ -40,6 +56,10 @@ struct rk_display_ops { struct fb_videomode *mode); int (*setscale)(struct rk_display_device *, int, int); int (*getscale)(struct rk_display_device *, int); + int (*get3dmode)(struct rk_display_device *); + int (*set3dmode)(struct rk_display_device *, int); + int (*getcolor)(struct rk_display_device *, char *); + int (*setcolor)(struct rk_display_device *, const char *, int); int (*setdebug)(struct rk_display_device *, int); int (*getedidaudioinfo)(struct rk_display_device *, char *audioinfo, int len); @@ -59,6 +79,7 @@ struct rk_display_device { int idx; struct rk_display_ops *ops; int priority; + int property; struct list_head list; }; @@ -74,6 +95,8 @@ void rk_display_device_unregister(struct rk_display_device *dev); void rk_display_device_enable(struct rk_display_device *ddev); void rk_display_device_enable_other(struct rk_display_device *ddev); void rk_display_device_disable_other(struct rk_display_device *ddev); -void rk_display_device_select(int priority); +void rk_display_device_select(int property, int priority); +int display_add_videomode(const struct fb_videomode *mode, + struct list_head *head); #endif