rk3036: add tv encoder code.
authorZheng Yang <zhengyang@rock-chips.com>
Tue, 8 Jul 2014 10:11:59 +0000 (18:11 +0800)
committerZheng Yang <zhengyang@rock-chips.com>
Tue, 8 Jul 2014 10:11:59 +0000 (18:11 +0800)
23 files changed:
arch/arm/boot/dts/rk3036-sdk.dts
arch/arm/boot/dts/rk3036.dtsi
drivers/video/rockchip/Makefile
drivers/video/rockchip/lcdc/rk3036_lcdc.c
drivers/video/rockchip/lcdc/rk3036_lcdc.h
drivers/video/rockchip/rk_fb.c
drivers/video/rockchip/tve/Kconfig
drivers/video/rockchip/tve/Makefile
drivers/video/rockchip/tve/rk3036/Kconfig [new file with mode: 0644]
drivers/video/rockchip/tve/rk3036/Makefile [new file with mode: 0644]
drivers/video/rockchip/tve/rk3036/rk3036_tve.c [new file with mode: 0644]
drivers/video/rockchip/tve/rk3036/rk3036_tve.h [new file with mode: 0644]
drivers/video/rockchip/tve/rk610/Kconfig [new file with mode: 0644]
drivers/video/rockchip/tve/rk610/Makefile [new file with mode: 0644]
drivers/video/rockchip/tve/rk610/rk610_tv.c [new file with mode: 0644]
drivers/video/rockchip/tve/rk610/rk610_tv.h [new file with mode: 0644]
drivers/video/rockchip/tve/rk610/rk610_tv_cvbs.c [new file with mode: 0644]
drivers/video/rockchip/tve/rk610/rk610_tv_ypbpr.c [new file with mode: 0644]
drivers/video/rockchip/tve/rk610_tv.c [deleted file]
drivers/video/rockchip/tve/rk610_tv.h [deleted file]
drivers/video/rockchip/tve/rk610_tv_cvbs.c [deleted file]
drivers/video/rockchip/tve/rk610_tv_ypbpr.c [deleted file]
include/linux/rk_fb.h

index 38970e29a26f68c2874dd4508bebacc4934b97c0..a95b8a11d2b1b0edce4f75b2c71d553dc839edf2 100755 (executable)
@@ -1,7 +1,8 @@
 /dts-v1/;
-
+#include <dt-bindings/rkfb/rk_fb.h>
 #include "rk3036.dtsi"
 #include "rk3036-pinctrl.dtsi"
+#include "lcd-box.dtsi"
 / {
 
        fiq-debugger {
                 //irq_gpio = <&gpio0 GPIO_A4 IRQ_TYPE_EDGE_FALLING>;
         };
 };
+
+
+&rk_screen {
+        display-timings = <&disp_timings>;
+};
+
+&lcdc {
+       status = "okay";
+};
index 8aa9102a1e897e266219f3e773d2a693edb373c0..9da50489462e052b85a4cc893957dc3d66638e17 100755 (executable)
                clock-names = "clk_usbphy1", "hclk_usb1";
        };
        
+       fb: fb{
+               compatible = "rockchip,rk-fb";
+               rockchip,disp-mode = <NO_DUAL>;
+       };
+
+       rk_screen: rk_screen{
+               compatible = "rockchip,screen";
+       };
+       
        lcdc: lcdc@10118000 {
                compatible = "rockchip,rk3036-lcdc";
                reg = <0x10118000 0x4000>;
-               interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
                clocks = <&clk_gates9 6>, <&dclk_lcdc1>, <&clk_gates9 5>;
                clock-names = "aclk_lcdc", "dclk_lcdc", "hclk_lcdc";
                status = "disabled";
        };
 
+       tve {
+               compatible = "rockchip,rk3036-tve";
+               reg = <0x10118200 0x100>;
+               status = "disabled";
+       };
+       
         vpu: vpu_service@10108000 {
                compatible = "vpu_service";
                reg = <0x10108000 0x800>;
index e03c30460300cad518d25ce34fb32cf41bce1ce9..03f76012b5334cc5e2c276c4607979966f1819d8 100755 (executable)
@@ -7,4 +7,6 @@ obj-$(CONFIG_ROCKCHIP_RGA) += rga/
 obj-$(CONFIG_ROCKCHIP_RGA2) += rga2/
 obj-$(CONFIG_RK_HDMI) += display-sys.o hdmi/
 obj-$(CONFIG_IEP) += iep/
+obj-$(CONFIG_RK_TVENCODER) += tve/
+
 
index e78ce2ea8c0826ff15483d2454e133380ff28694..526b742a1f73b60f0ee30b22fedf1d4fad0554ab 100644 (file)
 #include <linux/rockchip/grf.h>
 #include <linux/rockchip/common.h>
 #include <dt-bindings/clock/rk_system_status.h>
-
+#if defined(CONFIG_ION_ROCKCHIP)
+#include <linux/rockchip/iovmm.h>
+#include <linux/rockchip/sysmmu.h>
+#endif
 #include "rk3036_lcdc.h"
 
 static int dbg_thresd;
@@ -61,8 +64,6 @@ static struct rk_lcdc_win lcdc_win[] = {
               },
 };
 
-static void layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id, bool open);
-
 static irqreturn_t rk3036_lcdc_isr(int irq, void *dev_id)
 {
        struct lcdc_device *lcdc_dev =
@@ -169,48 +170,100 @@ static void rk_lcdc_read_reg_defalut_cfg(struct lcdc_device
        spin_unlock(&lcdc_dev->reg_lock);
 }
 
-/********do basic init*********/
-static int rk3036_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
+static int rk3036_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
 {
-       u32 mask,val;
-       struct lcdc_device *lcdc_dev = container_of(dev_drv,
-                                                          struct
-                                                          lcdc_device,
-                                                  driver);
-       if (lcdc_dev->pre_init)
-               return 0;
+       return 0;
+}
 
-       lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
-       lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
-       lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
-//     lcdc_dev->pd   = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
+static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev, struct rk_lcdc_win *win) {
        
-       if (/*IS_ERR(lcdc_dev->pd) ||*/ (IS_ERR(lcdc_dev->aclk)) ||
-           (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
-               dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
-                       lcdc_dev->id);
+       u32 mask, val;
+       
+       if(win->state == 1){
+               if(win->id == 0) {
+                       mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP;
+                       val = v_WIN0_EN(win->state) | v_WIN0_FORMAT(win->fmt_cfg) | v_WIN0_RB_SWAP(win->swap_rb);
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+                       
+                       lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
+                           v_X_SCL_FACTOR(win->scale_yrgb_x) |
+                           v_Y_SCL_FACTOR(win->scale_yrgb_y));
+                       lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
+                           v_X_SCL_FACTOR(win->scale_cbcr_x) |
+                           v_Y_SCL_FACTOR(win->scale_cbcr_y));
+                           
+                       lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_YRGB_VIR | m_CBBR_VIR,
+                            v_YRGB_VIR(win->area[0].y_vir_stride) | v_YRGB_VIR(win->area[0].uv_vir_stride));
+                       lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(win->area[0].xact) |
+                               v_ACT_HEIGHT(win->area[0].yact));
+                       lcdc_writel(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(win->area[0].dsp_stx) |
+                               v_DSP_STY(win->area[0].dsp_sty));
+                       lcdc_writel(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(win->area[0].xsize) |
+                           v_DSP_HEIGHT(win->area[0].ysize));
+                       
+                       lcdc_writel(lcdc_dev, WIN0_YRGB_MST, win->area[0].y_addr);
+                       lcdc_writel(lcdc_dev, WIN0_CBR_MST, win->area[0].uv_addr);
+               }
+               else if(win->id == 1) {
+                       mask = m_WIN1_EN | m_WIN1_FORMAT | m_WIN1_RB_SWAP;
+                       val = v_WIN1_EN(win->state) | v_WIN1_FORMAT(win->fmt_cfg) | v_WIN1_RB_SWAP(win->swap_rb);
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+                       
+                       lcdc_writel(lcdc_dev, WIN1_SCL_FACTOR_YRGB,
+                           v_X_SCL_FACTOR(win->scale_yrgb_x) |
+                           v_Y_SCL_FACTOR(win->scale_yrgb_y));
+                       
+                       lcdc_msk_reg(lcdc_dev, WIN1_VIR, m_YRGB_VIR, v_YRGB_VIR(win->area[0].y_vir_stride));
+                       lcdc_writel(lcdc_dev, WIN1_ACT_INFO, v_ACT_WIDTH(win->area[0].xact) |
+                               v_ACT_HEIGHT(win->area[0].yact));
+                       lcdc_writel(lcdc_dev, WIN1_DSP_INFO, v_DSP_WIDTH(win->area[0].xsize) |
+                           v_DSP_HEIGHT(win->area[0].ysize));
+                       lcdc_writel(lcdc_dev, WIN1_DSP_ST, v_DSP_STX(win->area[0].dsp_stx) |
+                           v_DSP_STY(win->area[0].dsp_sty));
+                           
+                       lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
+                       
+               }
+               else if(win->id == 2) {
+               }       
+       }else{
+               win->area[0].y_addr = 0;
+               win->area[0].uv_addr = 0;
+               if(win->id == 0) {
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN, v_WIN0_EN(0));
+               }
+               else if(win->id == 1)
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN, v_WIN1_EN(0));
+               else if(win->id == 2)
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_EN, v_HWC_EN(0)); 
        }
-
-       rk_disp_pwr_enable(dev_drv);
-       rk3036_lcdc_clk_enable(lcdc_dev);
-
-       /*backup reg config at uboot*/
-       rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
-
-       mask =  m_AUTO_GATING_EN;
-       val  =  v_AUTO_GATING_EN(0);
-       lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask,val);
-       lcdc_cfg_done(lcdc_dev);
-       if (dev_drv->iommu_enabled) /*disable win0 to workaround iommu pagefault*/
-               layer_enable(lcdc_dev, 0, 0);
-       lcdc_dev->pre_init = true;
-
-       return 0;
 }
 
-static int rk3036_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
+static void lcdc_layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id, bool open)
 {
-       return 0;
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on) && lcdc_dev->driver.win[win_id]->state != open) {
+               if (open) {
+                       if (!lcdc_dev->atv_layer_cnt) {
+                               dev_info(lcdc_dev->dev, "wakeup from standby!\n");
+                               lcdc_dev->standby = 0;
+                       }
+                       lcdc_dev->atv_layer_cnt++;
+               } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
+                       lcdc_dev->atv_layer_cnt--;
+               }
+               lcdc_dev->driver.win[win_id]->state = open;
+               if(!open) {
+                       lcdc_layer_update_regs(lcdc_dev, lcdc_dev->driver.win[win_id]);
+                       lcdc_cfg_done(lcdc_dev);
+               }
+               /*if no layer used,disable lcdc*/
+               if (!lcdc_dev->atv_layer_cnt) {
+                       dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
+                       lcdc_dev->standby = 1;
+               }
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
 }
 
 static int rk3036_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
@@ -225,37 +278,8 @@ static int rk3036_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
        if (likely(lcdc_dev->clk_on)) {
                lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
                             v_LCDC_STANDBY(lcdc_dev->standby));
-               lcdc_msk_reg(lcdc_dev, SYS_CTRL,
-                            m_WIN0_EN | m_WIN1_EN | m_WIN0_RB_SWAP |
-                            m_WIN1_RB_SWAP,
-                            v_WIN0_EN(win0->state) | v_WIN1_EN(win1->state) |
-                            v_WIN0_RB_SWAP(win0->swap_rb) |
-                            v_WIN1_RB_SWAP(win1->swap_rb));
-               lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
-                           v_X_SCL_FACTOR(win0->scale_yrgb_x) |
-                           v_Y_SCL_FACTOR(win0->scale_yrgb_y));
-               lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
-                           v_X_SCL_FACTOR(win0->scale_cbcr_x) |
-                           v_Y_SCL_FACTOR(win0->scale_cbcr_y));
-               lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_FORMAT, v_WIN0_FORMAT(win0->fmt_cfg));
-               lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(win0->area[0].xact) |
-                           v_ACT_HEIGHT(win0->area[0].yact));
-               lcdc_writel(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(win0->area[0].dsp_stx) |
-                           v_DSP_STY(win0->area[0].dsp_sty));
-               lcdc_writel(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(win0->area[0].xsize) |
-                           v_DSP_HEIGHT(win0->area[0].ysize));
-               lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_YRGB_VIR | m_CBBR_VIR,
-                            v_YRGB_VIR(win0->area[0].y_vir_stride) | v_YRGB_VIR(win0->area[0].uv_vir_stride));
-               lcdc_writel(lcdc_dev, WIN0_YRGB_MST, win0->area[0].y_addr);
-               lcdc_writel(lcdc_dev, WIN0_CBR_MST, win0->area[0].uv_addr);
-               lcdc_writel(lcdc_dev, WIN1_DSP_INFO, v_DSP_WIDTH(win1->area[0].xsize) |
-                           v_DSP_HEIGHT(win1->area[0].ysize));
-               lcdc_writel(lcdc_dev, WIN1_DSP_ST, v_DSP_STX(win1->area[0].dsp_stx) |
-                           v_DSP_STY(win1->area[0].dsp_sty));
-               lcdc_msk_reg(lcdc_dev, WIN1_VIR, m_YRGB_VIR, v_YRGB_VIR(win1->area[0].y_vir_stride));
-               lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_FORMAT,
-                            v_WIN1_FORMAT(win1->fmt_cfg));
-               lcdc_writel(lcdc_dev, WIN1_MST, win1->area[0].y_addr);
+               lcdc_layer_update_regs(lcdc_dev, win0);
+               lcdc_layer_update_regs(lcdc_dev, win1);
                rk3036_lcdc_alpha_cfg(lcdc_dev);
                lcdc_cfg_done(lcdc_dev);
 
@@ -324,6 +348,39 @@ static int rk3036_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
 
 }
 
+/********do basic init*********/
+static int rk3036_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev = container_of(dev_drv,
+                               struct lcdc_device, driver);
+       if (lcdc_dev->pre_init)
+               return 0;
+
+       lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
+       lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
+       lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
+//     lcdc_dev->pd   = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
+       
+       if (/*IS_ERR(lcdc_dev->pd) ||*/ (IS_ERR(lcdc_dev->aclk)) ||
+           (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
+               dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
+                       lcdc_dev->id);
+       }
+
+       rk_disp_pwr_enable(dev_drv);
+       rk3036_lcdc_clk_enable(lcdc_dev);
+
+       /*backup reg config at uboot*/
+       rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
+       lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN,v_AUTO_GATING_EN(0));
+       lcdc_cfg_done(lcdc_dev);
+       if (dev_drv->iommu_enabled) /*disable win0 to workaround iommu pagefault*/
+               lcdc_layer_enable(lcdc_dev, 0, 0);
+       lcdc_dev->pre_init = true;
+
+       return 0;
+}
+
 static int rk3036_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
 {
        int ret = -EINVAL;
@@ -360,6 +417,14 @@ static int rk3036_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                                val |= v_CORE_CLK_DIV_EN(1);
                        }
                        lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
+                       if(x_res == 720 && y_res == 576)
+                               lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE, v_TVE_MODE(TV_PAL));
+                       else if(x_res == 720 && y_res == 480)
+                               lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE, v_TVE_MODE(TV_NTSC));
+                       else {
+                               dev_err(lcdc_dev->dev, "unsupported video timing!\n");
+                               return -1;
+                       }
                        break;
                default:
                        dev_err(lcdc_dev->dev, "un supported interface!\n");
@@ -396,17 +461,34 @@ static int rk3036_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                    v_HASP(screen->mode.hsync_len + left_margin);
                lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
 
-               val =
-                   v_VSYNC(screen->mode.vsync_len) | v_VERPRD(screen->mode.
-                                                              vsync_len +
-                                                              upper_margin +
-                                                              y_res +
-                                                              lower_margin);
-               lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
-
-               val = v_VAEP(screen->mode.vsync_len + upper_margin + y_res) |
-                   v_VASP(screen->mode.vsync_len + screen->mode.upper_margin);
-               lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
+               if(screen->mode.vmode == FB_VMODE_INTERLACED) {
+                       //First Field Timing
+                       lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, v_VSYNC(screen->mode.vsync_len) |
+                                   v_VERPRD(2 * (screen->mode.vsync_len + upper_margin + lower_margin) + y_res + 1));
+                       lcdc_writel(lcdc_dev,DSP_VACT_ST_END,v_VAEP(screen->mode.vsync_len + upper_margin + y_res/2)|
+                                   v_VASP(screen->mode.vsync_len + upper_margin));
+                       //Second Field Timing
+                       lcdc_writel(lcdc_dev, DSP_VS_ST_END_F1, v_VSYNC_ST_F1(screen->mode.vsync_len + upper_margin + y_res/2 + lower_margin) |
+                                   v_VSYNC_END_F1(2 * screen->mode.vsync_len + upper_margin + y_res/2 + lower_margin));
+                       lcdc_writel(lcdc_dev,DSP_VACT_ST_END_F1,v_VAEP(2 * (screen->mode.vsync_len + upper_margin) + y_res + lower_margin + 1)|
+                                   v_VASP(2 * (screen->mode.vsync_len + upper_margin) + y_res/2 + lower_margin + 1));
+                                   
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_INTERLACE_DSP_EN | m_WIN1_INTERLACE_EN | m_WIN0_YRGB_DEFLICK_EN | m_WIN0_CBR_DEFLICK_EN, 
+                               v_INTERLACE_DSP_EN(1) | v_WIN1_INTERLACE_EN(1) | v_WIN0_YRGB_DEFLICK_EN(1) | v_WIN0_CBR_DEFLICK_EN(1) );
+               } else {
+                       val = v_VSYNC(screen->mode.vsync_len) | 
+                             v_VERPRD(screen->mode.vsync_len + upper_margin + 
+                                       y_res + lower_margin);
+                       lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
+       
+                       val = v_VAEP(screen->mode.vsync_len + upper_margin + y_res) |
+                           v_VASP(screen->mode.vsync_len + screen->mode.upper_margin);
+                       lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
+                       
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_INTERLACE_DSP_EN | m_WIN1_INTERLACE_EN | m_WIN0_YRGB_DEFLICK_EN | m_WIN0_CBR_DEFLICK_EN, 
+                               v_INTERLACE_DSP_EN(0) | v_WIN1_INTERLACE_EN(0) | v_WIN0_YRGB_DEFLICK_EN(0) | v_WIN0_CBR_DEFLICK_EN(0) );
+               }               
+               
        }
        spin_unlock(&lcdc_dev->reg_lock);
 
@@ -429,35 +511,6 @@ static int rk3036_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
        return 0;
 }
 
-static void layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id, bool open)
-{
-       spin_lock(&lcdc_dev->reg_lock);
-               if (likely(lcdc_dev->clk_on)) {
-                       if (open) {
-                               if (!lcdc_dev->atv_layer_cnt) {
-                                       dev_info(lcdc_dev->dev, "wakeup from standby!\n");
-                                       lcdc_dev->standby = 0;
-                               }
-                               lcdc_dev->atv_layer_cnt++;
-                       } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
-                               lcdc_dev->atv_layer_cnt--;
-                       }
-                       lcdc_dev->driver.win[win_id]->state = open;
-                       if(win_id == 0)
-                               lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN, v_WIN0_EN(open));
-                       else if(win_id == 1)
-                               lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN, v_WIN1_EN(open));
-                       else
-                               lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_EN, v_HWC_EN(open));
-                       /*if no layer used,disable lcdc*/
-                       if (!lcdc_dev->atv_layer_cnt) {
-                               dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
-                               lcdc_dev->standby = 1;
-                       }
-               }
-               spin_unlock(&lcdc_dev->reg_lock);
-}
-
 static int rk3036_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
                            bool open)
 {
@@ -468,6 +521,20 @@ static int rk3036_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
        if ((open) && (!lcdc_dev->atv_layer_cnt)) {
                rk3036_lcdc_pre_init(dev_drv);
                rk3036_lcdc_clk_enable(lcdc_dev);
+               #if defined(CONFIG_ROCKCHIP_IOMMU)
+               if(dev_drv->iommu_enabled) {
+                       if(!dev_drv->mmu_dev) {
+                               dev_drv->mmu_dev = rockchip_get_sysmmu_device_by_compatible(dev_drv->mmu_dts_name);
+                               if (dev_drv->mmu_dev)
+                                       platform_set_sysmmu(dev_drv->mmu_dev, dev_drv->dev);
+                               else {
+                                       dev_err(dev_drv->dev, "failed to get rockchip iommu device\n");
+                                       return -1;
+                               }
+                       }
+                       iovmm_activate(dev_drv->dev);
+               }
+               #endif
                rk3036_lcdc_reg_restore(lcdc_dev);
                if (dev_drv->iommu_enabled)
                        rk3036_lcdc_mmu_en(dev_drv);
@@ -478,8 +545,9 @@ static int rk3036_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
                        rk3036_load_screen(dev_drv, 1);
                }
        }
+       
        if(win_id < ARRAY_SIZE(lcdc_win)) {
-               layer_enable(lcdc_dev, win_id, open);
+               lcdc_layer_enable(lcdc_dev, win_id, open);
        }
        else
                dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
@@ -488,6 +556,14 @@ static int rk3036_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
        if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
                rk3036_lcdc_disable_irq(lcdc_dev);
                rk3036_lcdc_reg_update(dev_drv);
+               #if defined(CONFIG_ROCKCHIP_IOMMU)
+               if (dev_drv->iommu_enabled) {
+//                     for (reg = MMU_DTE_ADDR; reg <= MMU_AUTO_GATING; reg +=4)
+//                     lcdc_readl(lcdc_dev, reg);
+                       if(dev_drv->mmu_dev)
+                               iovmm_deactivate(dev_drv->dev);
+               }
+               #endif
                rk3036_lcdc_clk_disable(lcdc_dev);
        }
        
@@ -517,9 +593,13 @@ static int rk3036_lcdc_set_par(struct rk_lcdc_driver *dev_drv,int win_id)
        }
        
        spin_lock(&lcdc_dev->reg_lock);
-       
        win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
-       win->area[0].dsp_sty = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
+       if (screen->mode.vmode == FB_VMODE_INTERLACED) {
+               win->area[0].ysize /= 2;
+               win->area[0].dsp_sty = win->area[0].ypos/2+screen->mode.upper_margin + screen->mode.vsync_len;
+       } else {
+               win->area[0].dsp_sty = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
+       }
        win->scale_yrgb_x = CalScale(win->area[0].xact, win->area[0].xsize);
        win->scale_yrgb_y = CalScale(win->area[0].yact, win->area[0].ysize);
        switch (win->format) {
@@ -584,9 +664,6 @@ static int rk3036_lcdc_set_par(struct rk_lcdc_driver *dev_drv,int win_id)
        }
        spin_unlock(&lcdc_dev->reg_lock);
        
-       if (lcdc_dev->clk_on) {
-               rk3036_lcdc_alpha_cfg(lcdc_dev);
-       }
        DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
                ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
                __func__, get_format_string(win->format, fmt), win->area[0].xact,
@@ -621,11 +698,8 @@ static int rk3036_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
        if (likely(lcdc_dev->clk_on)) {
                win->area[0].y_addr = win->area[0].smem_start+win->area[0].y_offset;
                win->area[0].uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
-               if(win_id == 0) {
-                       lcdc_writel(lcdc_dev, WIN0_YRGB_MST, win->area[0].y_addr); 
-                       lcdc_writel(lcdc_dev, WIN0_CBR_MST, win->area[0].uv_addr);
-               } else
-                       lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr); 
+               if(win->area[0].y_addr)
+                       lcdc_layer_update_regs(lcdc_dev, win);
                /*lcdc_cfg_done(lcdc_dev);*/
        }
        spin_unlock(&lcdc_dev->reg_lock);
@@ -741,6 +815,14 @@ static int rk3036_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
                lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
                             v_LCDC_STANDBY(1));
                lcdc_cfg_done(lcdc_dev);
+               #if defined(CONFIG_ROCKCHIP_IOMMU)
+               if (dev_drv->iommu_enabled) {
+//                     for (reg = MMU_DTE_ADDR; reg <= MMU_AUTO_GATING; reg +=4)
+//                     lcdc_readl(lcdc_dev, reg);
+                       if(dev_drv->mmu_dev)
+                               iovmm_deactivate(dev_drv->dev);
+               }
+               #endif
                spin_unlock(&lcdc_dev->reg_lock);
        } else {
                spin_unlock(&lcdc_dev->reg_lock);
@@ -970,7 +1052,7 @@ static int rk3036_fb_win_remap(struct rk_lcdc_driver *dev_drv,
 {
        mutex_lock(&dev_drv->fb_win_id_mutex);
        if (order == FB_DEFAULT_ORDER)
-               order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
+               order = FB0_WIN1_FB1_WIN0_FB2_WIN2;
        dev_drv->fb2_win_id = order / 100;
        dev_drv->fb1_win_id = (order / 10) % 10;
        dev_drv->fb0_win_id = order % 10;
@@ -1125,6 +1207,22 @@ static struct rk_lcdc_drv_ops lcdc_drv_ops = {
        .open_bcsh              = rk3036_lcdc_open_bcsh,
 };
 
+static int rk3036_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
+{
+       struct device_node *np = lcdc_dev->dev->of_node;
+
+#if defined(CONFIG_ROCKCHIP_IOMMU)
+       int val;
+       if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
+               lcdc_dev->driver.iommu_enabled = 0;
+       else
+               lcdc_dev->driver.iommu_enabled = val;
+#else
+       lcdc_dev->driver.iommu_enabled = 0;
+#endif
+       return 0;
+}
+
 static int rk3036_lcdc_probe(struct platform_device *pdev)
 {
        struct lcdc_device *lcdc_dev = NULL;
@@ -1141,6 +1239,7 @@ static int rk3036_lcdc_probe(struct platform_device *pdev)
        }
        platform_set_drvdata(pdev, lcdc_dev);
        lcdc_dev->dev = dev;
+       rk3036_lcdc_parse_dt(lcdc_dev);
        
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        lcdc_dev->reg_phy_base = res->start;
@@ -1176,7 +1275,11 @@ static int rk3036_lcdc_probe(struct platform_device *pdev)
                        lcdc_dev->irq, ret);
                return ret;
        }
-
+       
+       if (dev_drv->iommu_enabled) {
+               strcpy(dev_drv->mmu_dts_name, "iommu,vop_mmu");
+       }
+       
        ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
        if (ret < 0) {
                dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
@@ -1184,7 +1287,9 @@ static int rk3036_lcdc_probe(struct platform_device *pdev)
        }
        lcdc_dev->screen = dev_drv->screen0;
        
-       dev_info(dev, "lcdc%d probe ok\n", lcdc_dev->id);
+       dev_info(dev, "lcdc%d probe ok, iommu %s\n",
+               lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
+
        return 0;
 }
 
index bb0861ac8e01c07f68b68a5255a8a34506884dab..9c37f9b7a285cf2e436d0735709b0b96974bb8f6 100644 (file)
        #define v_VASP(x)               (((x)&0xfff)<<16)
 
 #define DSP_VS_ST_END_F1       (0x7C)
+       #define v_VSYNC_END_F1(x)               (((x)&0xfff)<<0)
+       #define v_VSYNC_ST_F1(x)                (((x)&0xfff)<<16)
 #define DSP_VACT_ST_END_F1     (0x80)
 
 /*BCSH Registers*/
 #define REG_CFG_DONE           (0x90)
 
 /* TV Control Registers */
-#define TV_CTRL                        (0x200)
+#define TV_CTRL                        (0x200) 
 #define TV_SYNC_TIMING         (0x204)
 #define TV_ACT_TIMING          (0x208)
 #define TV_ADJ_TIMING          (0x20c)
@@ -484,7 +486,7 @@ struct lcdc_device{
        struct clk              *aclk;                          /*lcdc share memory frequency*/
        u32 pixclock;   
 
-       u32 standby;                                            /*1:standby,0:wrok*/
+       u32 standby;                                            /*1:standby,0:work*/
 };
 
 static inline void lcdc_writel(struct lcdc_device *lcdc_dev,u32 offset,u32 v)
index bf7e6ccf35ca989802cacc85d334a70919e49ad3..e6d061fface288f702937b3fc66b52d4091372d5 100755 (executable)
@@ -378,7 +378,7 @@ int rk_fb_prase_timing_dt(struct device_node *np, struct rk_screen *screen)
                pr_err("parse display timing err\n");
                return -EINVAL;
        }
-       dt = display_timings_get(disp_timing, 0);
+       dt = display_timings_get(disp_timing, disp_timing->native_mode);
        rk_fb_video_mode_from_timing(dt, screen);
        return 0;
 
@@ -2467,6 +2467,7 @@ static int rk_fb_set_par(struct fb_info *info)
        struct rk_lcdc_win *extend_win = NULL;
        struct rk_lcdc_win *win = NULL;
        struct rk_screen *screen = dev_drv->cur_screen;
+       struct rk_screen screen_primary;
        int win_id = 0;
        u32 cblen = 0, crlen = 0;
        u16 xsize = 0, ysize = 0;       /* winx display window height/width --->LCDC_WINx_DSP_INFO */
@@ -2619,23 +2620,23 @@ static int rk_fb_set_par(struct fb_info *info)
                }
        }
 
+       rk_fb_get_prmry_screen(&screen_primary);
        win->format = fb_data_fmt;
        win->area[0].y_vir_stride = stride >> 2;
        win->area[0].uv_vir_stride = uv_stride >> 2;
-       win->area[0].xpos = xpos;
-       win->area[0].ypos = ypos;
-       win->area[0].xsize = xsize;
-       win->area[0].ysize = ysize;
+       win->area[0].xpos = xpos*screen->mode.xres/screen_primary.mode.xres;
+       win->area[0].ypos = ypos*screen->mode.yres/screen_primary.mode.yres;
+       win->area[0].xsize = screen->mode.xres*xsize/screen_primary.mode.xres;
+       win->area[0].ysize = screen->mode.yres*ysize/screen_primary.mode.yres;
 
-       win->area[0].smem_start = fix->smem_start;
-       win->area[0].cbr_start = fix->smem_start + stride * yvir;       /* fix->mmio_start; */
+//     win->area[0].smem_start = fix->smem_start;
+//     win->area[0].cbr_start = fix->smem_start+stride*yvir;//fix->mmio_start;
        win->area[0].xact = var->xres;  /* winx active window height,is a wint of vir */
        win->area[0].yact = var->yres;
        win->area[0].xvir = var->xres_virtual;  /* virtual resolution  stride --->LCDC_WINx_VIR */
        win->area[0].yvir = var->yres_virtual;
-       win->area[0].state = 1;
+
        win->area_num = 1;
-       win->state = 1;
        win->alpha_mode = 4;    /* AB_SRC_OVER; */
        win->alpha_en = ((win->format == ARGB888)
                         || (win->format == ABGR888)) ? 1 : 0;
@@ -2851,7 +2852,7 @@ void rk_direct_fb_show(struct fb_info *fbi)
        rk_fb_pan_display(&fbi->var, fbi);
 }
 EXPORT_SYMBOL(rk_direct_fb_show);
-
+#if 0
 static int set_xact_yact_for_hdmi(struct fb_var_screeninfo *pmy_var,
                                  struct fb_var_screeninfo *hdmi_var)
 {
@@ -2868,7 +2869,7 @@ static int set_xact_yact_for_hdmi(struct fb_var_screeninfo *pmy_var,
        return 0;
 
 }
-
+#endif
 int rk_fb_dpi_open(bool open)
 {
        struct rk_lcdc_driver *dev_drv = NULL;
@@ -2899,7 +2900,109 @@ int rk_fb_dpi_status(void)
        
        return ret;
 }
+#if 1
+/*
+ *function:this function will be called by display device, enable/disable lcdc
+ *screen: screen timing to be set to lcdc
+ *enable: 0 disable lcdc; 1 enable change lcdc timing; 2 just enable dclk
+ *lcdc_id: the lcdc id the display device attached ,0 or 1
+ */
+int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id)
+{
+       struct rk_fb *rk_fb =  platform_get_drvdata(fb_pdev);
+       struct fb_info *info = NULL;
+       struct rk_lcdc_driver *dev_drv = NULL;
+       char name[6];
+       int i, win_id;
+       
+       if(screen == NULL)
+               return -ENODEV;
+       
+       printk("\n%s lcdc_id %d type %d enable %d\n", __FUNCTION__, lcdc_id, screen->type, enable);
+       
+       sprintf(name, "lcdc%d",lcdc_id);
+       for(i = 0; i < rk_fb->num_lcdc; i++) {
+               if(!strcmp(rk_fb->lcdc_dev_drv[i]->name, name)) {
+                       dev_drv = rk_fb->lcdc_dev_drv[i];
+                       break;
+               }
+       }
+       if(i == rk_fb->num_lcdc) {
+               printk(KERN_ERR "%s driver not found!", name);
+               return -ENODEV;
+       }
+       
+       if(enable == 2 /*&& dev_drv->enable*/)
+               return 0;
+       
+       if(!enable)
+       {
+               // if screen type is different, we do not disable lcdc.
+               if( dev_drv->cur_screen->type != screen->type )
+                       return 0;
+                       
+               for(i = 0; i < dev_drv->lcdc_win_num; i++) {
+                       //disable the layer which attached to this device
+                       if(dev_drv->win[i] && dev_drv->win[i]->state)
+                               dev_drv->ops->open(dev_drv, i, 0);
+               }
+               
+//             dev_drv->enable = enable;
+               return 0;
+       }
+       else
+               memcpy(dev_drv->cur_screen, screen, sizeof(struct rk_screen));
+               
+//     dev_drv->enable = enable;
+
+//     ret = dev_drv->ops->load_screen(dev_drv, 1);
+//     
+//     if(enable != 1) return 0;
+               
+       for(i = 0; i < dev_drv->lcdc_win_num; i++) {
+               #ifdef DUAL_LCDC_MAP_TO_SAME_FB
+               info = rk_fb->fb[i];
+               dev_drv1 = (struct rk_lcdc_driver *)info->par;
+               if(dev_drv1 != dev_drv) {
+                       info->par = dev_drv;
+//                     dev_drv->overlay = dev_drv1->overlay;
+                       dev_drv->overscan = dev_drv1->overscan;
+                       dev_drv->vsync_info.active = dev_drv1->vsync_info.active;
+               }
+               memcpy(dev_drv->cur_screen, screen, sizeof(struct rk_screen));
+               #else
+               info = rk_fb->fb[dev_drv->fb_index_base + i];
+               #endif
+               win_id = dev_drv->ops->fb_get_win_id(dev_drv,info->fix.id);
+//             printk("%s win id %d\n", info->fix.id, win_id);
+               if(dev_drv->win[win_id]) {
+                       #ifdef DUAL_LCDC_MAP_TO_SAME_FB
+                       if(dev_drv1 && dev_drv1->win[win_id]) {
+                               dev_drv->win[win_id]->logicalstate = dev_drv1->win[win_id]->logicalstate;
+                               memcpy(dev_drv->win[win_id]->area, dev_drv1->win[win_id]->area, RK_WIN_MAX_AREA * sizeof(struct rk_lcdc_win_area));
+//                             dev_drv->win[win_id]->area[0] = dev_drv1->win[win_id]->area[0];
+//                             printk("%s win id %d state %d\n", info->fix.id, win_id, dev_drv->win[win_id]->logicalstate);
+                       }
+                       #endif
+                       printk("%s win id %d state %d\n", info->fix.id, win_id, dev_drv->win[win_id]->logicalstate);
+                       if( dev_drv->win[win_id]->logicalstate ) {
+                               dev_drv->ops->open(dev_drv, win_id, 1);
+                               if(win_id == 1) {
+                                       dev_drv->ops->load_screen(dev_drv, 1);
+                               }
+                               info->var.activate |= FB_ACTIVATE_FORCE;
+                               info->fbops->fb_set_par(info);
+                               info->fbops->fb_pan_display(&info->var, info);
+                       }
+//                     else
+//                             dev_drv->ops->open(dev_drv, win_id, 0);
+               }
+       }
+       printk("\n%s lcdc_id %d type %d enable %d done\n\n", __FUNCTION__, lcdc_id, screen->type, enable);
+       return 0;
 
+}
+#else
 /*
  * function:this function will be called by hdmi,when
  *             hdmi plug in/out
@@ -3043,7 +3146,7 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id)
        return 0;
 
 }
-
+#endif
 /*
  * function:this function current only called by hdmi for
  *     scale the display
@@ -3326,12 +3429,17 @@ static int init_lcdc_device_driver(struct rk_fb *rk_fb,
        mutex_init(&dev_drv->fb_win_id_mutex);
        dev_drv->ops->fb_win_remap(dev_drv, FB_DEFAULT_ORDER);
        dev_drv->first_frame = 1;
+       dev_drv->overscan.left = 100;
+       dev_drv->overscan.top = 100;
+       dev_drv->overscan.right = 100;
+       dev_drv->overscan.bottom = 100;
        rk_disp_pwr_ctr_parse_dt(dev_drv);
        if (dev_drv->prop == PRMRY) {
-               dev_drv->ops->set_dsp_cabc(dev_drv, dev_drv->cabc_mode);
+               if(dev_drv->ops->set_dsp_cabc)
+                       dev_drv->ops->set_dsp_cabc(dev_drv, dev_drv->cabc_mode);
                rk_fb_set_prmry_screen(screen);
-               rk_fb_get_prmry_screen(screen);
        }
+       rk_fb_get_prmry_screen(screen);
        dev_drv->trsm_ops = rk_fb_trsm_ops_get(screen->type);
 
        return 0;
@@ -3384,9 +3492,9 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv,
        struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
        struct fb_info *fbi;
        int i = 0, ret = 0, index = 0;
-#if defined(CONFIG_ROCKCHIP_IOMMU)
-       struct device *mmu_dev = NULL;
-#endif
+//#if defined(CONFIG_ROCKCHIP_IOMMU)
+//     struct device *mmu_dev = NULL;
+//#endif
        if (rk_fb->num_lcdc == RK30_MAX_LCDC_SUPPORT)
                return -ENXIO;
 
@@ -3491,6 +3599,7 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv,
        if (dev_drv->prop == PRMRY) {
                struct fb_info *main_fbi = rk_fb->fb[0];
                main_fbi->fbops->fb_open(main_fbi, 1);
+/*
 #if defined(CONFIG_ROCKCHIP_IOMMU)
                if (dev_drv->iommu_enabled) {
                        mmu_dev =
@@ -3505,6 +3614,7 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv,
                                        "failed to get rockchip iommu device\n");
                }
 #endif
+*/
                rk_fb_alloc_buffer(main_fbi, 0);        /* only alloc memory for main fb */
                if (support_uboot_display()) {
                        if (dev_drv->iommu_enabled) {
index 74eaf28651be5d671687fb8031fbbd8f99b0a0b5..e165ee3250ef6f1d5b7943bfeaf040bb4330a37c 100644 (file)
@@ -1,14 +1,13 @@
-config RK610_TVOUT
-       bool "RK610(Jetta) tvout support"
-       depends on MFD_RK610
-       default n
+#
+# TV Encoder drivers configuration
+#
+
+menuconfig RK_TVENCODER
+       bool "Rockchip TV Encoder support"
+       depends on FB_ROCKCHIP
        help
-               Support Jetta(RK610) to output YPbPr and CVBS.
-               
-config RK610_TVOUT_YPbPr
-       bool "support YPbPr output"
-       depends on RK610_TVOUT
+               Support RockChip TV Encoder if you say y here.
+
+source "drivers/video/rockchip/tve/rk3036/Kconfig"
+source "drivers/video/rockchip/tve/rk610/Kconfig"
 
-config RK610_TVOUT_CVBS
-       bool "support CVBS output"
-       depends on RK610_TVOUT
index b7d457326d26caab608033da6be0614a1662335e..ea651687c417dfbfaeb287163db85b305ccd98bd 100644 (file)
@@ -1,6 +1,5 @@
 #
-# Makefile for the jetta tv control.
+# Makefile for tv encoder.
 #
-obj-$(CONFIG_RK610_TVOUT)                      += rk610_tv.o
-obj-$(CONFIG_RK610_TVOUT_YPbPr)                += rk610_tv_ypbpr.o
-obj-$(CONFIG_RK610_TVOUT_CVBS)         += rk610_tv_cvbs.o
\ No newline at end of file
+obj-$(CONFIG_RK610_TVOUT)              += rk610/
+obj-$(CONFIG_RK3036_TV_ENCODER)                += rk3036/
diff --git a/drivers/video/rockchip/tve/rk3036/Kconfig b/drivers/video/rockchip/tve/rk3036/Kconfig
new file mode 100644 (file)
index 0000000..c39ed5d
--- /dev/null
@@ -0,0 +1,7 @@
+config RK3036_TV_ENCODER
+       bool "rk3036 tv encoder support"
+       depends on LCDC_RK3036
+       default n
+       help
+               Support RK3036 output CVBS.
+
diff --git a/drivers/video/rockchip/tve/rk3036/Makefile b/drivers/video/rockchip/tve/rk3036/Makefile
new file mode 100644 (file)
index 0000000..850404a
--- /dev/null
@@ -0,0 +1,4 @@
+#
+# Makefile for the rk3036 tv encoder control.
+#
+obj-$(CONFIG_RK3036_TV_ENCODER)        += rk3036_tve.o
diff --git a/drivers/video/rockchip/tve/rk3036/rk3036_tve.c b/drivers/video/rockchip/tve/rk3036/rk3036_tve.c
new file mode 100644 (file)
index 0000000..ebe29da
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * rk3036_tve.c 
+ *
+ * Driver for rockchip rk3036 tv encoder control
+ * Copyright (C) 2014 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/rk_fb.h>
+#include <linux/display-sys.h>
+#include <linux/rockchip/grf.h>
+#include <linux/rockchip/iomap.h>
+#include "rk3036_tve.h"
+
+
+static const struct fb_videomode rk3036_cvbs_mode [] = {
+       /*      name            refresh xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI            flag*/
+       {       "NTSC",         60,     720,    480,    27000000,       69,     12,     19,     2,      63,     3,      0,      FB_VMODE_INTERLACED,    0},
+       {       "PAL",          50,     720,    576,    27000000,       57,     19,     19,     0,      62,     3,      0,      FB_VMODE_INTERLACED,    0},
+};
+
+static struct rk3036_tve *rk3036_tve = NULL;
+
+#define tve_writel(offset, v)  writel_relaxed(v, rk3036_tve->regbase + offset);
+#define tve_readl(offset, v)   readl_relaxed(v, rk3036_tve->regbase + offset);
+
+static void dac_enable(bool enable)
+{
+       u32 mask, val;
+       if(enable) {
+               mask = m_VBG_EN | m_DAC_EN;
+               val = mask;
+       } else {
+               mask = m_VBG_EN | m_DAC_EN;
+               val = 0;
+       }
+       grf_writel(RK3036_GRF_SOC_CON3, (mask << 16) | val);
+}
+
+static void tve_set_mode (int mode)
+{
+       tve_writel(TV_RESET, v_RESET(1));
+       udelay(100);
+       tve_writel(TV_RESET, v_RESET(0));
+       
+       tve_writel(TV_CTRL, v_CVBS_MODE(mode) | v_CLK_UPSTREAM_EN(2) | 
+                       v_TIMING_EN(2) | v_LUMA_FILTER_GAIN(0) | 
+                       v_LUMA_FILTER_UPSAMPLE(1) | v_CSC_PATH(0) );
+       tve_writel(TV_LUMA_FILTER0, 0x02ff0000);
+       tve_writel(TV_LUMA_FILTER1, 0xF40202fd);
+       tve_writel(TV_LUMA_FILTER2, 0xF332d919);
+       
+       if(mode == TVOUT_CVBS_NTSC) {
+               tve_writel(TV_ROUTING, v_DAC_SENSE_EN(0) | v_Y_IRE_7_5(0) | 
+                       v_Y_AGC_PULSE_ON(1) | v_Y_VIDEO_ON(1) | 
+                       v_Y_SYNC_ON(1) | v_PIC_MODE(mode));
+               tve_writel(TV_BW_CTRL, v_CHROMA_BW(BP_FILTER_NTSC) | v_COLOR_DIFF_BW(COLOR_DIFF_FILTER_BW_1_3));
+               tve_writel(TV_SATURATION, 0x0052543C);
+               tve_writel(TV_BRIGHTNESS_CONTRAST, 0x00008300);
+               
+               tve_writel(TV_FREQ_SC,  0x21F07BD7);
+               tve_writel(TV_SYNC_TIMING, 0x00C07a81);
+               tve_writel(TV_ADJ_TIMING, 0x96B40000);
+               tve_writel(TV_ACT_ST,   0x001500D6);
+               tve_writel(TV_ACT_TIMING, 0x169800FC);
+
+       } else if (mode == TVOUT_CVBS_PAL) {
+               tve_writel(TV_ROUTING, v_DAC_SENSE_EN(0) | v_Y_IRE_7_5(1) | 
+                       v_Y_AGC_PULSE_ON(1) | v_Y_VIDEO_ON(1) | 
+                       v_Y_SYNC_ON(1) | v_CVBS_MODE(mode));
+               tve_writel(TV_BW_CTRL, v_CHROMA_BW(BP_FILTER_PAL) | v_COLOR_DIFF_BW(COLOR_DIFF_FILTER_BW_1_3));
+               tve_writel(TV_SATURATION, 0x002e553c);
+               tve_writel(TV_BRIGHTNESS_CONTRAST, 0x00007579);
+               
+               tve_writel(TV_FREQ_SC,  0x2A098ACB);
+               tve_writel(TV_SYNC_TIMING, 0x00C28381);
+               tve_writel(TV_ADJ_TIMING, 0xB6C00880);
+               tve_writel(TV_ACT_ST,   0x001500F6);
+               tve_writel(TV_ACT_TIMING, 0x2694011D);
+       }
+}
+
+static int tve_switch_fb(const struct fb_videomode *modedb, int enable)
+{      
+       struct rk_screen *screen;
+       
+       if(modedb == NULL)
+               return -1;
+       screen =  kzalloc(sizeof(struct rk_screen), GFP_KERNEL);
+       if(screen == NULL)
+               return -1;
+       
+       memset(screen, 0, sizeof(struct rk_screen));    
+       /* screen type & face */
+       screen->type = SCREEN_TVOUT;
+       screen->face = OUT_P888;
+       
+       screen->mode = *modedb;
+       
+       /* Pin polarity */
+       if(FB_SYNC_HOR_HIGH_ACT & modedb->sync)
+               screen->pin_hsync = 1;
+       else
+               screen->pin_hsync = 0;
+       if(FB_SYNC_VERT_HIGH_ACT & modedb->sync)
+               screen->pin_vsync = 1;
+       else
+               screen->pin_vsync = 0;
+               
+       screen->pin_den = 0;
+       screen->pin_dclk = 1;
+       screen->pixelrepeat = 1;
+       
+       /* Swap rule */
+       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; 
+       
+       rk_fb_switch_screen(screen, enable, 0);
+
+       kfree(screen);
+       if(enable) {
+               if(screen->mode.yres == 480)
+                       tve_set_mode(TVOUT_CVBS_NTSC);
+               else
+                       tve_set_mode(TVOUT_CVBS_PAL);
+       }
+       return 0;
+}
+
+static int cvbs_set_enable(struct rk_display_device *device, int enable)
+{
+       if(rk3036_tve->enable != enable)
+       {
+               rk3036_tve->enable = enable;
+               if(rk3036_tve->suspend)
+                       return 0;
+               
+               if(enable == 0) {
+                       dac_enable(false);
+                       tve_switch_fb(rk3036_tve->mode, 0);
+               }
+               else if(enable == 1) {
+                       tve_switch_fb(rk3036_tve->mode, 1);
+                       dac_enable(true);
+               }
+       }
+       return 0;
+}
+
+static int cvbs_get_enable(struct rk_display_device *device)
+{
+       return rk3036_tve->enable;
+}
+
+static int cvbs_get_status(struct rk_display_device *device)
+{
+       return 1;
+}
+
+static int cvbs_get_modelist(struct rk_display_device *device, struct list_head **modelist)
+{
+       *modelist = &(rk3036_tve->modelist);
+       return 0;
+}
+
+static int cvbs_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+       int i;
+
+       for(i = 0; i < ARRAY_SIZE(rk3036_cvbs_mode); i++)
+       {
+               if(fb_mode_is_equal(&rk3036_cvbs_mode[i], mode))
+               {       
+                       if( rk3036_tve->mode != &rk3036_cvbs_mode[i] ) {
+                               rk3036_tve->mode = (struct fb_videomode *)&rk3036_cvbs_mode[i];
+                               if(rk3036_tve->enable && !rk3036_tve->suspend)
+                                       dac_enable(false);
+                                       tve_switch_fb(rk3036_tve->mode, 1);
+                                       dac_enable(true);
+                       }
+                       return 0;
+               }
+       }
+       
+       return -1;
+}
+
+static int cvbs_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+       *mode = *(rk3036_tve->mode);
+       return 0;
+}
+
+static struct rk_display_ops cvbs_display_ops = {
+       .setenable = cvbs_set_enable,
+       .getenable = cvbs_get_enable,
+       .getstatus = cvbs_get_status,
+       .getmodelist = cvbs_get_modelist,
+       .setmode = cvbs_set_mode,
+       .getmode = cvbs_get_mode,
+};
+
+static int display_cvbs_probe(struct rk_display_device *device, void *devdata)
+{
+       device->owner = THIS_MODULE;
+       strcpy(device->type, "TV");
+       device->name = "cvbs";
+       device->priority = DISPLAY_PRIORITY_TV;
+       device->priv_data = devdata;
+       device->ops = &cvbs_display_ops;
+       return 1;
+}
+
+static struct rk_display_driver display_cvbs = {
+       .probe = display_cvbs_probe,
+};
+
+static int rk3036_tve_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       int i;
+       
+       rk3036_tve = devm_kzalloc(&pdev->dev, sizeof(struct rk3036_tve), 
+                                       GFP_KERNEL);
+       if(!rk3036_tve) {
+               dev_err(&pdev->dev, "rk3036 tv encoder device kmalloc fail!");
+               return -ENOMEM;
+       }
+       platform_set_drvdata(pdev, rk3036_tve);
+       rk3036_tve->dev = &pdev->dev;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rk3036_tve->reg_phy_base = res->start;
+       rk3036_tve->len = resource_size(res);
+       rk3036_tve->regbase = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(rk3036_tve->regbase)) {
+               dev_err(&pdev->dev, "rk3036 tv encoder device map registers failed!");
+               return PTR_ERR(rk3036_tve->regbase);
+       }       
+       
+       INIT_LIST_HEAD(&(rk3036_tve->modelist));
+       for(i = 0; i < ARRAY_SIZE(rk3036_cvbs_mode); i++)
+               fb_add_videomode(&rk3036_cvbs_mode[i], &(rk3036_tve->modelist));
+
+       rk3036_tve->ddev = rk_display_device_register(&display_cvbs, &pdev->dev, NULL);
+       rk_display_device_enable(rk3036_tve->ddev);
+       
+       dev_info(&pdev->dev, "rk3036 tv encoder probe ok\n");
+       return 0;
+}
+
+static void rk3036_tve_shutdown(struct platform_device *pdev)
+{
+       
+}
+
+#if defined(CONFIG_OF)
+static const struct of_device_id rk3036_tve_dt_ids[] = {
+       {.compatible = "rockchip,rk3036-tve",},
+       {}
+};
+#endif
+
+static struct platform_driver rk3036_tve_driver = {
+       .probe = rk3036_tve_probe,
+       .remove = NULL,
+       .driver = {
+               .name = "rk3036-tve",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(rk3036_tve_dt_ids),
+       },
+       .shutdown = rk3036_tve_shutdown,
+};
+
+static int __init rk3036_tve_init(void)
+{
+       return platform_driver_register(&rk3036_tve_driver);
+}
+
+static void __exit rk3036_tve_exit(void)
+{
+    platform_driver_unregister(&rk3036_tve_driver);
+}
+
+module_init(rk3036_tve_init);
+module_exit(rk3036_tve_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("ROCKCHIP RK3036 TV Encoder ");
+MODULE_LICENSE("GPL");
\ No newline at end of file
diff --git a/drivers/video/rockchip/tve/rk3036/rk3036_tve.h b/drivers/video/rockchip/tve/rk3036/rk3036_tve.h
new file mode 100644 (file)
index 0000000..d36573e
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef __RK3036_TVE_H__
+#define __RK3036_TVE_H__
+
+#define TV_CTRL                        (0x00)
+       #define m_CVBS_MODE                     (1 << 24)
+       #define m_CLK_UPSTREAM_EN               (3 << 18)
+       #define m_TIMING_EN                     (3 << 16)
+       #define m_LUMA_FILTER_GAIN              (3 << 9)
+       #define m_LUMA_FILTER_BW                (1 << 8)
+       #define m_CSC_PATH                      (3 << 1)
+       
+       #define v_CVBS_MODE(x)                  ( (x & 1) << 24)
+       #define v_CLK_UPSTREAM_EN(x)            ( (x & 3) << 18)
+       #define v_TIMING_EN(x)                  ( (x & 3) << 16)
+       #define v_LUMA_FILTER_GAIN(x)           ( (x & 3) << 9)
+       #define v_LUMA_FILTER_UPSAMPLE(x)       ( (x & 1) << 8)
+       #define v_CSC_PATH(x)                   ( (x & 3) << 1)
+       
+#define TV_SYNC_TIMING         (0x04)
+#define TV_ACT_TIMING          (0x08)
+#define TV_ADJ_TIMING          (0x0c)
+#define TV_FREQ_SC             (0x10)
+#define TV_LUMA_FILTER0                (0x14)
+#define TV_LUMA_FILTER1                (0x18)
+#define TV_LUMA_FILTER2                (0x1C)
+#define TV_ACT_ST              (0x34)
+#define TV_ROUTING             (0x38)
+       #define m_DAC_SENSE_EN          (1 << 27)
+       #define m_Y_IRE_7_5             (1 << 19)
+       #define m_Y_AGC_PULSE_ON        (1 << 15)
+       #define m_Y_VIDEO_ON            (1 << 11)
+       #define m_Y_SYNC_ON             (1 << 7)
+       #define m_MONO_EN               (1 << 2)
+       #define m_PIC_MODE              (1 << 1)
+       
+       #define v_DAC_SENSE_EN(x)       ( (x & 1) << 27)
+       #define v_Y_IRE_7_5(x)          ( (x & 1) << 19)
+       #define v_Y_AGC_PULSE_ON(x)     ( (x & 1) << 15)
+       #define v_Y_VIDEO_ON(x)         ( (x & 1) << 11)
+       #define v_Y_SYNC_ON(x)          ( (x & 1) << 7)
+       #define v_MONO_EN(x)            ( (x & 1) << 2)
+       #define v_PIC_MODE(x)           ( (x & 1) << 1)
+       
+#define TV_SYNC_ADJUST         (0x50)
+#define TV_STATUS              (0x54)
+#define TV_RESET               (0x68)
+       #define m_RESET                 (1 << 1);
+       #define v_RESET(x)              ( (x & 1) << 1)
+#define TV_SATURATION          (0x78)
+#define TV_BW_CTRL             (0x8C)
+       #define m_CHROMA_BW     (3 << 4)
+       #define m_COLOR_DIFF_BW (0xf)
+       
+       enum {
+               BP_FILTER_PASS = 0,
+               BP_FILTER_NTSC,
+               BP_FILTER_PAL,
+       };
+       enum {
+               COLOR_DIFF_FILTER_OFF = 0,
+               COLOR_DIFF_FILTER_BW_0_6,
+               COLOR_DIFF_FILTER_BW_1_3,
+               COLOR_DIFF_FILTER_BW_2_0
+       };
+       
+       #define v_CHROMA_BW(x)          ((3 & x) << 4)
+       #define v_COLOR_DIFF_BW(x)      (0xF & x)
+       
+#define TV_BRIGHTNESS_CONTRAST (0x90)
+
+#define m_EXTREF_EN            (1 << 0)
+#define m_VBG_EN               (1 << 1)
+#define m_DAC_EN               (1 << 2)
+#define m_SENSE_EN             (1 << 3)
+#define m_BIAS_EN              (7 << 4)
+#define m_DAC_GAIN             (0x3f << 7)
+
+enum {
+       TVOUT_CVBS_NTSC = 0,
+       TVOUT_CVBS_PAL,
+};
+
+#define TVOUT_DEAULT TVOUT_CVBS_PAL
+
+#define grf_writel(offset, v)  do{ writel_relaxed(v, RK_GRF_VIRT + offset);dsb();} while (0)
+
+struct rk3036_tve {
+       struct device                   *dev;   
+       void __iomem                    *regbase;
+       u32                             reg_phy_base;   /* physical basic address of register*/
+       u32                             len;            /* physical map length of register*/
+       
+       struct rk_display_device        *ddev;
+       unsigned int                    enable;
+       unsigned int                    suspend;
+       struct fb_videomode             *mode;
+       struct list_head                modelist;
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/video/rockchip/tve/rk610/Kconfig b/drivers/video/rockchip/tve/rk610/Kconfig
new file mode 100644 (file)
index 0000000..74eaf28
--- /dev/null
@@ -0,0 +1,14 @@
+config RK610_TVOUT
+       bool "RK610(Jetta) tvout support"
+       depends on MFD_RK610
+       default n
+       help
+               Support Jetta(RK610) to output YPbPr and CVBS.
+               
+config RK610_TVOUT_YPbPr
+       bool "support YPbPr output"
+       depends on RK610_TVOUT
+
+config RK610_TVOUT_CVBS
+       bool "support CVBS output"
+       depends on RK610_TVOUT
diff --git a/drivers/video/rockchip/tve/rk610/Makefile b/drivers/video/rockchip/tve/rk610/Makefile
new file mode 100644 (file)
index 0000000..b7d4573
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the jetta tv control.
+#
+obj-$(CONFIG_RK610_TVOUT)                      += rk610_tv.o
+obj-$(CONFIG_RK610_TVOUT_YPbPr)                += rk610_tv_ypbpr.o
+obj-$(CONFIG_RK610_TVOUT_CVBS)         += rk610_tv_cvbs.o
\ No newline at end of file
diff --git a/drivers/video/rockchip/tve/rk610/rk610_tv.c b/drivers/video/rockchip/tve/rk610/rk610_tv.c
new file mode 100644 (file)
index 0000000..83a6cec
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * rk610_tv.c 
+ *
+ * Driver for rockchip rk610 tv control
+ *  Copyright (C) 2009 
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <asm/uaccess.h>
+#include "rk610_tv.h"
+#include "../../rk29_fb.h"
+
+#define DRV_NAME "rk610_tvout"
+#define RK610_I2C_RATE     100*1000
+
+volatile int rk610_tv_output_status = RK610_TVOUT_DEAULT;
+static struct i2c_client *rk610_tv_i2c_client = NULL;
+
+int rk610_tv_wirte_reg(u8 reg, u8 data)
+{
+    int ret;
+       if(rk610_tv_i2c_client == NULL)
+               return -1;
+    ret = i2c_master_reg8_send(rk610_tv_i2c_client, reg, &data, 1, RK610_I2C_RATE);
+       if (ret > 0)
+               ret = 0;
+       return ret;
+}
+
+int rk610_switch_fb(const struct fb_videomode *modedb, int tv_mode)
+{      
+       struct rk_screen *screen;
+       
+       if(modedb == NULL)
+               return -1;
+       screen =  kzalloc(sizeof(struct rk_screen), GFP_KERNEL);
+       if(screen == NULL)
+               return -1;
+       
+       memset(screen, 0, sizeof(struct rk_screen));    
+       /* screen type & face */
+    screen->type = SCREEN_HDMI;
+       screen->mode = modedb->vmode;
+       screen->face = modedb->flag;
+       /* Screen size */
+       screen->x_res = modedb->xres;
+    screen->y_res = modedb->yres;
+
+    /* Timing */
+    screen->pixclock = modedb->pixclock;
+
+       screen->lcdc_aclk = 500000000;
+       screen->left_margin = modedb->left_margin;
+       screen->right_margin = modedb->right_margin;
+       screen->hsync_len = modedb->hsync_len;
+       screen->upper_margin = modedb->upper_margin;
+       screen->lower_margin = modedb->lower_margin;
+       screen->vsync_len = modedb->vsync_len;
+
+       /* Pin polarity */
+       if(FB_SYNC_HOR_HIGH_ACT & modedb->sync)
+               screen->pin_hsync = 1;
+       else
+               screen->pin_hsync = 0;
+       if(FB_SYNC_VERT_HIGH_ACT & modedb->sync)
+               screen->pin_vsync = 1;
+       else
+               screen->pin_vsync = 0;  
+       screen->pin_den = 0;
+       screen->pin_dclk = 0;
+
+       /* Swap rule */
+    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;    
+    
+    switch(tv_mode)
+       {
+#ifdef CONFIG_RK610_TVOUT_CVBS
+               case TVOUT_CVBS_NTSC:
+               case TVOUT_CVBS_PAL:
+            screen->init = rk610_tv_cvbs_init;;
+               break;
+#endif
+
+#ifdef CONFIG_RK610_TVOUT_YPbPr
+               case TVOUT_YPbPr_720x480p_60:
+               case TVOUT_YPbPr_720x576p_50:
+               case TVOUT_YPbPr_1280x720p_50:
+               case TVOUT_YPbPr_1280x720p_60:
+               //case TVOUT_YPbPr_1920x1080i_50:
+               case TVOUT_YPbPr_1920x1080i_60:
+               case TVOUT_YPbPr_1920x1080p_50:
+               case TVOUT_YPbPr_1920x1080p_60:
+                       screen->init = rk610_tv_ypbpr_init;
+                       break;
+#endif
+               default:{
+                       kfree(screen);
+                       return -1;
+               }
+               break;
+       }
+       rk610_tv_output_status = tv_mode;
+       FB_Switch_Screen(screen, 1);
+       kfree(screen);
+       return 0;
+}
+
+int rk610_tv_standby(int type)
+{
+       int ret;
+
+       switch(type)
+       {
+               #ifdef CONFIG_RK610_TVOUT_CVBS
+               case RK610_TVOUT_CVBS:
+                       if(rk610_cvbs_monspecs.enable == 0)
+                               return 0;
+                       #ifdef CONFIG_RK610_TVOUT_YPbPr
+                       if(rk610_ypbpr_monspecs.enable == 1)
+                               return 0;
+                       #endif
+                       break;
+               #endif
+               #ifdef CONFIG_RK610_TVOUT_YPbPr
+               case RK610_TVOUT_YPBPR:
+                       if(rk610_ypbpr_monspecs.enable == 0)
+                               return 0;
+                       #ifdef CONFIG_RK610_TVOUT_CVBS
+                       if(rk610_cvbs_monspecs.enable == 1)
+                               return 0;
+                       #endif
+                       break;
+               #endif
+               default:
+                       break;
+       }
+
+       ret = rk610_tv_wirte_reg(TVE_POWERCR, 0);
+       if(ret < 0){
+               printk("[%s] rk610_tv_wirte_reg err!\n", __FUNCTION__);
+               return ret;
+       }
+       
+       ret = rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, 0);
+       if(ret < 0){
+               printk("[%s] rk610_control_send_byte err!\n", __FUNCTION__);
+               return ret;
+       }
+       return 0;
+}
+
+static int rk610_tv_probe(struct i2c_client *client,const struct i2c_device_id *id)
+{
+       int rc = 0;
+       
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               rc = -ENODEV;
+               goto failout;
+       }
+       rk610_tv_i2c_client = client;
+
+#ifdef CONFIG_RK610_TVOUT_YPbPr
+       rk610_register_display_ypbpr(&client->dev);
+       if(rk610_tv_output_status > TVOUT_CVBS_PAL)
+               rk_display_device_enable(rk610_ypbpr_monspecs.ddev);
+#endif
+
+#ifdef CONFIG_RK610_TVOUT_CVBS
+       rk610_register_display_cvbs(&client->dev);
+       if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60)
+               rk_display_device_enable(rk610_cvbs_monspecs.ddev);
+#endif
+       
+    printk(KERN_INFO "rk610_tv ver 1.0 probe ok\n");
+    return 0;
+failout:
+       kfree(client);
+       return rc;
+}
+
+static int rk610_tv_remove(struct i2c_client *client)
+{
+       return 0;
+}
+
+
+static const struct i2c_device_id rk610_tv_id[] = {
+       { DRV_NAME, 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, rk610_tv_id);
+
+static struct i2c_driver rk610_tv_driver = {
+       .driver         = {
+               .name   = DRV_NAME,
+       },
+       .id_table = rk610_tv_id,
+       .probe = rk610_tv_probe,
+       .remove = rk610_tv_remove,
+};
+
+static int __init rk610_tv_init(void)
+{
+       int ret = 0;
+       ret = i2c_add_driver(&rk610_tv_driver);
+       if(ret < 0){
+               printk("i2c_add_driver err, ret = %d\n", ret);
+       }
+       return ret;
+}
+
+static void __exit rk610_tv_exit(void)
+{
+    i2c_del_driver(&rk610_tv_driver);
+}
+
+module_init(rk610_tv_init);
+//late_initcall(rk610_tv_init);
+module_exit(rk610_tv_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("ROCKCHIP RK610 TV Output");
+MODULE_LICENSE("GPL");
+
+
diff --git a/drivers/video/rockchip/tve/rk610/rk610_tv.h b/drivers/video/rockchip/tve/rk610/rk610_tv.h
new file mode 100644 (file)
index 0000000..ead23a8
--- /dev/null
@@ -0,0 +1,131 @@
+#ifndef _RK610_TV_H
+#define _RK610_TV_H
+#include <linux/display-sys.h>
+#include <linux/rk_fb.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#ifdef CONFIG_ARCH_RK29
+#include <mach/rk29_iomap.h>
+#endif
+#include "../screen/screen.h"
+#include "../../rk29_fb.h"
+#include <linux/mfd/rk610_core.h>
+
+#define TVE_VFCR               0x00
+       #define TVE_VFCR_ENABLE_SUBCARRIER_RESET        0 << 6
+       #define TVE_VFCR_DISABLE_SUBCARRIER_RESET       1 << 6
+       #define TVE_VFCR_VIN_RANGE_16_235                       0 << 3
+       #define TVE_VFCR_VIN_RANGE_1_254                        1 << 3
+       #define TVE_VFCR_BLACK_7_5_IRE                          0 << 2
+       #define TVE_VFCR_BLACK_0_IRE                            1 << 2
+       #define TVE_VFCR_NTSC                                           0
+       #define TVE_VFCR_PAL_M                                          1
+       #define TVE_VFCR_PAL_B_N                                        2
+       #define TVE_VFCR_PAL_NC                                         3
+
+#define TVE_VINCR              0x01
+       #define TVE_VINCR_PIX_DATA_DELAY(n)                     (n << 5)
+       #define TVE_VINCR_H_SYNC_POLARITY_NEGTIVE       0 << 4
+       #define TVE_VINCR_H_SYNC_POLARITY_POSITIVE      1 << 4
+       #define TVE_VINCR_V_SYNC_POLARITY_NEGTIVE       0 << 3
+       #define TVE_VINCR_V_SYNC_POLARITY_POSITIVE      1 << 3
+enum {
+       INPUT_FORMAT_BT601_SLAVE = 0,
+       INPUT_FORMAT_BT656,
+       INPUT_FORMAT_BT601_MASTER,
+       INPUT_FORMAT_INTERNAL_COLLOR_BAR
+};
+       #define TVE_VINCR_INPUT_FORMAT(n)                       (n << 1)
+       #define TVE_VINCR_VSYNC_FUNCTION_VSYNC          0
+       #define TVE_VINCR_VSYNC_FUNCTION_FIELD          1
+
+#define TVE_VOUTCR             0x02
+       #define TVE_VOUTCR_OUTPUT_CVBS                          0 << 6
+       #define TVE_VOUTCR_OUTPUT_YPBPR                         1 << 6
+       #define TVE_VOUTCR_OUTPUT_ENABLE_BLUE           1 << 5
+       #define TVE_VOUTCR_OUTPUT_ENABLE_BLACK          1 << 4
+       #define TVE_VOUTCR_DISABLE_CVBS_COLOR           1 << 3
+       #define TVE_VOUTCR_CVBS_Y2C_DELAY(n)                            (n << 0)
+
+#define TVE_POWERCR            0x03
+       #define TVE_PIX_CLK_INVERSE_ENABLE                      1 << 4
+       #define TVE_DAC_CLK_INVERSE_DISABLE                     1 << 3
+       #define TVE_DAC_Y_ENABLE                                        1 << 2
+       #define TVE_DAC_U_ENABLE                                        1 << 1
+       #define TVE_DAC_V_ENABLE                                        1 << 0
+
+#define TVE_HDTVCR             0x05
+       #define TVE_RESET                                                       1 << 7
+       #define TVE_FILTER(n)                                           (n << 5)
+       #define TVE_COLOR_CONVERT_REC601                        0 << 4
+       #define TVE_COLOR_CONVERT_REC709                        1 << 4
+       #define TVE_INPUT_DATA_RGB                                      0 << 3
+       #define TVE_INPUT_DATA_YUV                                      1 << 3
+       #define TVE_OUTPUT_50HZ                                         0 << 2
+       #define TVE_OUTPUT_60HZ                                         1 << 2
+       #define TVE_OUTPUT_MODE_PAL_NTSC                        0
+       #define TVE_OUTPUT_MODE_576P                            1
+       #define TVE_OUTPUT_MODE_480P                            2
+       #define TVE_OUTPUT_MODE_720P                            3
+
+#define TVE_YADJCR             0x06
+       #define TVE_OUTPUT_MODE_1080P                           1 << 6
+       #define TVE_OUTPUT_MODE_1080I                           1 << 5
+       #define TVE_Y_ADJ_VALUE(n)                                      n
+#define TVE_YCBADJCR   0x07
+#define TVE_YCRADJCR   0x08
+
+/******************* TVOUT OUTPUT TYPE **********************/
+struct rk610_monspecs {
+       struct rk_display_device        *ddev;
+       unsigned int                            enable;
+       struct fb_videomode                     *mode;
+       struct list_head                        modelist;
+       unsigned int                            mode_set;
+};
+
+enum {
+       TVOUT_CVBS_NTSC = 1,
+       TVOUT_CVBS_PAL,
+       TVOUT_YPbPr_720x480p_60,
+       TVOUT_YPbPr_720x576p_50,
+       TVOUT_YPbPr_1280x720p_50,
+       TVOUT_YPbPr_1280x720p_60,
+       //TVOUT_YPbPr_1920x1080i_50,
+       TVOUT_YPbPr_1920x1080i_60,
+       TVOUT_YPbPr_1920x1080p_50,
+       TVOUT_YPbPr_1920x1080p_60
+};
+
+#define RK610_TVOUT_DEAULT TVOUT_CVBS_NTSC
+
+enum {
+       RK610_TVOUT_CVBS = 0,
+       RK610_TVOUT_YC,
+       RK610_TVOUT_YPBPR,
+};
+
+extern volatile int rk610_tv_output_status;
+extern struct rk_display_ops rk610_display_ops;
+
+extern int FB_Switch_Screen( struct rk_screen *screen, u32 enable );
+
+extern int rk610_tv_wirte_reg(u8 reg, u8 data);
+extern int rk610_tv_standby(int type);
+extern int rk610_switch_fb(const struct fb_videomode *modedb, int tv_mode);
+extern int rk610_register_display(struct device *parent);
+
+#ifdef CONFIG_RK610_TVOUT_YPbPr
+extern int rk610_tv_ypbpr_init(void);
+extern int rk610_register_display_ypbpr(struct device *parent);
+extern struct rk610_monspecs rk610_ypbpr_monspecs;
+#endif
+
+#ifdef CONFIG_RK610_TVOUT_CVBS
+extern int rk610_tv_cvbs_init(void);
+extern int rk610_register_display_cvbs(struct device *parent);
+extern struct rk610_monspecs rk610_cvbs_monspecs;
+#endif
+
+#endif
+
diff --git a/drivers/video/rockchip/tve/rk610/rk610_tv_cvbs.c b/drivers/video/rockchip/tve/rk610/rk610_tv_cvbs.c
new file mode 100644 (file)
index 0000000..ea0fe8a
--- /dev/null
@@ -0,0 +1,209 @@
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/display-sys.h>
+#include "rk610_tv.h"
+
+
+#ifdef CONFIG_DISPLAY_KEY_LED_CONTROL
+#define RK610_LED_CVBS_PIN     RK29_PIN4_PD3
+#else
+#define RK610_LED_CVBS_PIN     INVALID_GPIO
+#endif
+
+#ifdef USE_RGB2CCIR
+static const struct fb_videomode rk610_cvbs_mode [] = {
+               //name                          refresh         xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag
+       {       "NTSC",                         60,                     720,    480,    27000000,       116,    16,             25,             14,             6,              6,              0,                      1,              OUT_P888        },
+       {       "PAL",                          50,                     720,    576,    27000000,       126,    12,             37,             6,              6,              6,              0,                      1,              OUT_P888        },
+};
+#else
+static const struct fb_videomode rk610_cvbs_mode [] = {
+               //name                          refresh         xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag
+       {       "NTSC",                         60,                     720,    480,    27000000,       116,    16,             16,             3,              6,              3,              0,                      1,              OUT_CCIR656     },
+       {       "PAL",                          50,                     720,    576,    27000000,       126,    12,             19,             2,              6,              3,              0,                      1,              OUT_CCIR656     },
+};
+#endif
+
+struct rk610_monspecs rk610_cvbs_monspecs;
+
+
+int rk610_tv_cvbs_init(void)
+{
+       unsigned char TVE_Regs[9];
+       unsigned char TVE_CON_Reg;
+       int ret, i;
+       
+       rk610_tv_wirte_reg(TVE_HDTVCR, TVE_RESET);
+
+       memset(TVE_Regs, 0, 9);
+       TVE_CON_Reg = TVE_CONTROL_CVBS_3_CHANNEL_ENALBE;
+       TVE_Regs[TVE_VINCR]     =       TVE_VINCR_PIX_DATA_DELAY(0) | TVE_VINCR_H_SYNC_POLARITY_NEGTIVE | TVE_VINCR_V_SYNC_POLARITY_NEGTIVE | TVE_VINCR_VSYNC_FUNCTION_VSYNC;
+       TVE_Regs[TVE_POWERCR]   =       TVE_DAC_Y_ENABLE | TVE_DAC_U_ENABLE | TVE_DAC_V_ENABLE;
+       TVE_Regs[TVE_VOUTCR]    =       TVE_VOUTCR_OUTPUT_CVBS;
+       TVE_Regs[TVE_YADJCR]    =       0x17;
+       TVE_Regs[TVE_YCBADJCR]  =       0x10;
+       TVE_Regs[TVE_YCRADJCR]  =       0x10;
+       
+       switch(rk610_tv_output_status) {
+               case TVOUT_CVBS_NTSC:
+                       TVE_Regs[TVE_VFCR]              = TVE_VFCR_ENABLE_SUBCARRIER_RESET | TVE_VFCR_VIN_RANGE_16_235 | TVE_VFCR_BLACK_7_5_IRE | TVE_VFCR_NTSC;
+                       #ifdef USE_RGB2CCIR
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_MODE_PAL_NTSC;
+                       TVE_CON_Reg |= RGB2CCIR_INPUT_DATA_FORMAT(0) | RGB2CCIR_RGB_SWAP_DISABLE | RGB2CCIR_INPUT_PROGRESSIVE | RGB2CCIR_CVBS_NTSC | RGB2CCIR_ENABLE;
+                       #else
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_MODE_PAL_NTSC;
+                       #endif                  
+                       break;
+               case TVOUT_CVBS_PAL:
+                       TVE_Regs[TVE_VFCR]              = TVE_VFCR_ENABLE_SUBCARRIER_RESET | TVE_VFCR_VIN_RANGE_16_235 | TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_B_N;               
+                       #ifdef USE_RGB2CCIR
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_MODE_PAL_NTSC;
+                       TVE_CON_Reg |= RGB2CCIR_INPUT_DATA_FORMAT(0) | RGB2CCIR_RGB_SWAP_DISABLE | RGB2CCIR_INPUT_PROGRESSIVE | RGB2CCIR_CVBS_PAL | RGB2CCIR_ENABLE;
+                       #else
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_MODE_PAL_NTSC;
+                       #endif                  
+                       break;
+               default:
+                       return -1;
+       }
+       
+       for(i = 0; i < sizeof(TVE_Regs); i++){
+//             printk(KERN_ERR "reg[%d] = 0x%02x\n", i, TVE_Regs[i]);
+               ret = rk610_tv_wirte_reg(i, TVE_Regs[i]);
+               if(ret < 0){
+                       printk(KERN_ERR "rk610_tv_wirte_reg %d err!\n", i);
+                       return ret;
+               }
+       }
+//     printk(KERN_ERR "TVE_CON_Reg = 0x%02x\n", TVE_CON_Reg);
+       rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, TVE_CON_Reg);
+       #ifdef USE_RGB2CCIR
+       rk610_control_send_byte(RK610_CONTROL_REG_CCIR_RESET, 0x01);
+       #endif
+       return 0;
+}
+
+static int rk610_cvbs_set_enable(struct rk_display_device *device, int enable)
+{
+       if(rk610_cvbs_monspecs.enable != enable || rk610_cvbs_monspecs.mode_set != rk610_tv_output_status)
+       {
+               if(enable == 0)
+               {
+                       rk610_tv_standby(RK610_TVOUT_CVBS);
+                       rk610_cvbs_monspecs.enable = 0;
+                       if(RK610_LED_CVBS_PIN != INVALID_GPIO)
+                               gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_HIGH);
+               }
+               else if(enable == 1)
+               {
+                       rk610_switch_fb(rk610_cvbs_monspecs.mode, rk610_cvbs_monspecs.mode_set);
+                       rk610_cvbs_monspecs.enable = 1;
+                       if(RK610_LED_CVBS_PIN != INVALID_GPIO)
+                               gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_LOW);
+               }
+       }
+       return 0;
+}
+
+static int rk610_cvbs_get_enable(struct rk_display_device *device)
+{
+       return rk610_cvbs_monspecs.enable;
+}
+
+static int rk610_cvbs_get_status(struct rk_display_device *device)
+{
+       if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60)
+               return 1;
+       else
+               return 0;
+}
+
+static int rk610_cvbs_get_modelist(struct rk_display_device *device, struct list_head **modelist)
+{
+       *modelist = &(rk610_cvbs_monspecs.modelist);
+       return 0;
+}
+
+static int rk610_cvbs_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+       int i;
+
+       for(i = 0; i < ARRAY_SIZE(rk610_cvbs_mode); i++)
+       {
+               if(fb_mode_is_equal(&rk610_cvbs_mode[i], mode))
+               {       
+                       if( ((i + 1) != rk610_tv_output_status) )
+                       {
+                               rk610_cvbs_monspecs.mode_set = i + 1;
+                               rk610_cvbs_monspecs.mode = (struct fb_videomode *)&rk610_cvbs_mode[i];
+                       }
+                       return 0;
+               }
+       }
+       
+       return -1;
+}
+
+static int rk610_cvbs_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+       *mode = *(rk610_cvbs_monspecs.mode);
+       return 0;
+}
+
+static struct rk_display_ops rk610_cvbs_display_ops = {
+       .setenable = rk610_cvbs_set_enable,
+       .getenable = rk610_cvbs_get_enable,
+       .getstatus = rk610_cvbs_get_status,
+       .getmodelist = rk610_cvbs_get_modelist,
+       .setmode = rk610_cvbs_set_mode,
+       .getmode = rk610_cvbs_get_mode,
+};
+
+static int rk610_display_cvbs_probe(struct rk_display_device *device, void *devdata)
+{
+       device->owner = THIS_MODULE;
+       strcpy(device->type, "TV");
+       device->priority = DISPLAY_PRIORITY_TV;
+       device->priv_data = devdata;
+       device->ops = &rk610_cvbs_display_ops;
+       return 1;
+}
+
+static struct rk_display_driver display_rk610_cvbs = {
+       .probe = rk610_display_cvbs_probe,
+};
+
+int rk610_register_display_cvbs(struct device *parent)
+{
+       int i;
+       
+       memset(&rk610_cvbs_monspecs, 0, sizeof(struct rk610_monspecs));
+       INIT_LIST_HEAD(&rk610_cvbs_monspecs.modelist);
+       for(i = 0; i < ARRAY_SIZE(rk610_cvbs_mode); i++)
+               fb_add_videomode(&rk610_cvbs_mode[i], &rk610_cvbs_monspecs.modelist);
+       if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60) {
+               rk610_cvbs_monspecs.mode = (struct fb_videomode *)&(rk610_cvbs_mode[rk610_tv_output_status - 1]);
+               rk610_cvbs_monspecs.mode_set = rk610_tv_output_status;
+       }
+       else {
+               rk610_cvbs_monspecs.mode = (struct fb_videomode *)&(rk610_cvbs_mode[0]);
+               rk610_cvbs_monspecs.mode_set = TVOUT_CVBS_NTSC;
+       }
+       rk610_cvbs_monspecs.ddev = rk_display_device_register(&display_rk610_cvbs, parent, NULL);
+       if(RK610_LED_CVBS_PIN != INVALID_GPIO)
+    {        
+        if(gpio_request(RK610_LED_CVBS_PIN, NULL) != 0)
+        {
+            gpio_free(RK610_LED_CVBS_PIN);
+            dev_err(rk610_cvbs_monspecs.ddev->dev, ">>>>>> RK610_LED_CVBS_PIN gpio_request err \n ");
+            return -1;
+        }
+               gpio_pull_updown(RK610_LED_CVBS_PIN,GPIOPullUp);
+               gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_HIGH);
+    }
+       return 0;
+}
diff --git a/drivers/video/rockchip/tve/rk610/rk610_tv_ypbpr.c b/drivers/video/rockchip/tve/rk610/rk610_tv_ypbpr.c
new file mode 100644 (file)
index 0000000..af74126
--- /dev/null
@@ -0,0 +1,229 @@
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/display-sys.h>
+#include "rk610_tv.h"
+
+
+#ifdef CONFIG_DISPLAY_KEY_LED_CONTROL
+#define RK610_LED_YPbPr_PIN    RK29_PIN4_PD5
+#else
+#define RK610_LED_YPbPr_PIN    INVALID_GPIO
+#endif
+#define E(fmt, arg...) printk("<3>!!!%s:%d: " fmt, __FILE__, __LINE__, ##arg)
+
+static const struct fb_videomode rk610_YPbPr_mode [] = {
+               //name                          refresh         xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag
+       {       "YPbPr480p",            60,                     720,    480,    27000000,       55,             19,             37,             5,              64,             5,              0,                      0,              OUT_P888        },
+       {       "YPbPr576p",            50,                     720,    576,    27000000,       68,             12,             39,             5,              64,             5,              0,                      0,              OUT_P888        },
+       {       "YPbPr720p@50",         50,                     1280,   720,    74250000,       600,    0,              20,             5,              100,    5,              0,                      0,              OUT_P888        },
+       {       "YPbPr720p@60",         60,                     1280,   720,    74250000,       270,    0,              20,             5,              100,    5,              0,                      0,              OUT_P888        },
+       //{     "YPbPr1080i@50",        50,                     1920,   1080,   148500000,      620,    0,              15,             2,              100,    5,              0,                      1,              OUT_CCIR656     },
+       {       "YPbPr1080i@60",        60,                     1920,   1080,   148500000,      180,    0,              15,             2,              100,    5,              0,                      1,              OUT_CCIR656     },
+       {       "YPbPr1080p@50",        50,                     1920,   1080,   148500000,      620,    0,              36,             4,              100,    5,              0,                      0,              OUT_P888        },
+       {       "YPbPr1080p@60",        60,                     1920,   1080,   148500000,      180,    0,              36,             4,              100,    5,              0,                      0,              OUT_P888        },
+};
+
+struct rk610_monspecs rk610_ypbpr_monspecs;
+
+int rk610_tv_ypbpr_init(void)
+{
+       unsigned char TVE_Regs[9];
+       unsigned char TVE_CON_Reg;
+       int i, ret;
+       
+       rk610_tv_wirte_reg(TVE_HDTVCR, TVE_RESET);
+       memset(TVE_Regs, 0, 9); 
+       
+       TVE_CON_Reg = 0x00;
+       
+       TVE_Regs[TVE_VINCR]     =       TVE_VINCR_PIX_DATA_DELAY(0) | TVE_VINCR_H_SYNC_POLARITY_NEGTIVE | TVE_VINCR_V_SYNC_POLARITY_NEGTIVE | TVE_VINCR_VSYNC_FUNCTION_VSYNC;
+       TVE_Regs[TVE_POWERCR]   =       TVE_DAC_CLK_INVERSE_DISABLE | TVE_DAC_Y_ENABLE | TVE_DAC_U_ENABLE | TVE_DAC_V_ENABLE;
+       TVE_Regs[TVE_VOUTCR]    =       TVE_VOUTCR_OUTPUT_YPBPR;
+       TVE_Regs[TVE_YADJCR]    =       0x17;
+       TVE_Regs[TVE_YCBADJCR]  =       0x10;
+       TVE_Regs[TVE_YCRADJCR]  =       0x10;
+       
+       switch(rk610_tv_output_status)
+       {
+               case TVOUT_YPbPr_720x480p_60:
+                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE;
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_60HZ | TVE_OUTPUT_MODE_480P;
+                       break;
+               case TVOUT_YPbPr_720x576p_50:
+                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_50HZ | TVE_OUTPUT_MODE_576P;
+                       break;
+               case TVOUT_YPbPr_1280x720p_50:
+                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_50HZ | TVE_OUTPUT_MODE_720P;
+                       break;
+               case TVOUT_YPbPr_1280x720p_60:
+                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_60HZ | TVE_OUTPUT_MODE_720P;
+                       break;
+               /*case TVOUT_YPbPr_1920x1080i_50:
+                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_50HZ;
+                       TVE_Regs[TVE_YADJCR]    |=      TVE_OUTPUT_MODE_1080I;
+                       break;
+                       */
+               case TVOUT_YPbPr_1920x1080i_60:
+                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_60HZ;
+                       TVE_Regs[TVE_YADJCR]    |=      TVE_OUTPUT_MODE_1080I;
+                       break;
+               case TVOUT_YPbPr_1920x1080p_50:
+                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_50HZ;
+                       TVE_Regs[TVE_YADJCR]    |=      TVE_OUTPUT_MODE_1080P;
+                       break;
+               case TVOUT_YPbPr_1920x1080p_60:
+                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_60HZ;
+                       TVE_Regs[TVE_YADJCR]    |=      TVE_OUTPUT_MODE_1080P;
+                       break;
+               default:
+                       return -1;
+       }
+       
+       rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, TVE_CON_Reg);
+       
+       for(i = 0; i < sizeof(TVE_Regs); i++){
+//             printk(KERN_ERR "reg[%d] = 0x%02x\n", i, TVE_Regs[i]);
+               ret = rk610_tv_wirte_reg(i, TVE_Regs[i]);
+               if(ret < 0){
+                       E("rk610_tv_wirte_reg %d err!\n", i);
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+static int rk610_ypbpr_set_enable(struct rk_display_device *device, int enable)
+{
+       if(rk610_ypbpr_monspecs.enable != enable || rk610_ypbpr_monspecs.mode_set != rk610_tv_output_status)
+       {
+               if(enable == 0)
+               {
+                       rk610_tv_standby(RK610_TVOUT_YPBPR);
+                       rk610_ypbpr_monspecs.enable = 0;
+                       if(RK610_LED_YPbPr_PIN != INVALID_GPIO)
+                               gpio_direction_output(RK610_LED_YPbPr_PIN, GPIO_HIGH);
+               }
+               else if(enable == 1)
+               {
+                       rk610_switch_fb(rk610_ypbpr_monspecs.mode, rk610_ypbpr_monspecs.mode_set);
+                       rk610_ypbpr_monspecs.enable = 1;
+                       if(RK610_LED_YPbPr_PIN != INVALID_GPIO)
+                               gpio_direction_output(RK610_LED_YPbPr_PIN, GPIO_LOW);
+               }
+       }
+       return 0;
+}
+
+static int rk610_ypbpr_get_enable(struct rk_display_device *device)
+{
+       return rk610_ypbpr_monspecs.enable;
+}
+
+static int rk610_ypbpr_get_status(struct rk_display_device *device)
+{
+       if(rk610_tv_output_status > TVOUT_CVBS_PAL)
+               return 1;
+       else
+               return 0;
+}
+
+static int rk610_ypbpr_get_modelist(struct rk_display_device *device, struct list_head **modelist)
+{
+       *modelist = &(rk610_ypbpr_monspecs.modelist);
+       return 0;
+}
+
+static int rk610_ypbpr_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+       int i;
+
+       for(i = 0; i < ARRAY_SIZE(rk610_YPbPr_mode); i++)
+       {
+               if(fb_mode_is_equal(&rk610_YPbPr_mode[i], mode))
+               {       
+                       if( (i + 3) != rk610_tv_output_status )
+                       {
+                               rk610_ypbpr_monspecs.mode_set = i + 3;
+                               rk610_ypbpr_monspecs.mode = (struct fb_videomode *)&rk610_YPbPr_mode[i];
+                       }
+                       return 0;
+               }
+       }
+       
+       return -1;
+}
+
+static int rk610_ypbpr_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+       *mode = *(rk610_ypbpr_monspecs.mode);
+       return 0;
+}
+
+static struct rk_display_ops rk610_ypbpr_display_ops = {
+       .setenable = rk610_ypbpr_set_enable,
+       .getenable = rk610_ypbpr_get_enable,
+       .getstatus = rk610_ypbpr_get_status,
+       .getmodelist = rk610_ypbpr_get_modelist,
+       .setmode = rk610_ypbpr_set_mode,
+       .getmode = rk610_ypbpr_get_mode,
+};
+
+static int rk610_display_YPbPr_probe(struct rk_display_device *device, void *devdata)
+{
+       device->owner = THIS_MODULE;
+       strcpy(device->type, "YPbPr");
+       device->priority = DISPLAY_PRIORITY_YPbPr;
+       device->priv_data = devdata;
+       device->ops = &rk610_ypbpr_display_ops;
+       return 1;
+}
+
+static struct rk_display_driver display_rk610_YPbPr = {
+       .probe = rk610_display_YPbPr_probe,
+};
+
+int rk610_register_display_ypbpr(struct device *parent)
+{
+       int i;
+       
+       memset(&rk610_ypbpr_monspecs, 0, sizeof(struct rk610_monspecs));
+       INIT_LIST_HEAD(&rk610_ypbpr_monspecs.modelist);
+       for(i = 0; i < ARRAY_SIZE(rk610_YPbPr_mode); i++)
+               fb_add_videomode(&rk610_YPbPr_mode[i], &rk610_ypbpr_monspecs.modelist);
+       if(rk610_tv_output_status > TVOUT_CVBS_PAL) {
+               rk610_ypbpr_monspecs.mode = (struct fb_videomode *)&(rk610_YPbPr_mode[rk610_tv_output_status - 3]);
+               rk610_ypbpr_monspecs.mode_set = rk610_tv_output_status;
+       }
+       else {
+               rk610_ypbpr_monspecs.mode = (struct fb_videomode *)&(rk610_YPbPr_mode[3]);
+               rk610_ypbpr_monspecs.mode_set = TVOUT_YPbPr_1280x720p_60;
+       }
+       rk610_ypbpr_monspecs.ddev = rk_display_device_register(&display_rk610_YPbPr, parent, NULL);
+       if(RK610_LED_YPbPr_PIN != INVALID_GPIO)
+    {        
+        if(gpio_request(RK610_LED_YPbPr_PIN, NULL) != 0)
+        {
+            gpio_free(RK610_LED_YPbPr_PIN);
+            dev_err(rk610_ypbpr_monspecs.ddev->dev, ">>>>>> RK610_LED_YPbPr_PIN gpio_request err \n ");
+            return -1;
+        }
+               gpio_pull_updown(RK610_LED_YPbPr_PIN,GPIOPullUp);
+               gpio_direction_output(RK610_LED_YPbPr_PIN, GPIO_HIGH);
+    }
+       return 0;
+}
diff --git a/drivers/video/rockchip/tve/rk610_tv.c b/drivers/video/rockchip/tve/rk610_tv.c
deleted file mode 100644 (file)
index 83a6cec..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * rk610_tv.c 
- *
- * Driver for rockchip rk610 tv control
- *  Copyright (C) 2009 
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *
- */
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/fcntl.h>
-#include <linux/fs.h>
-#include <linux/fb.h>
-#include <linux/console.h>
-#include <asm/uaccess.h>
-#include "rk610_tv.h"
-#include "../../rk29_fb.h"
-
-#define DRV_NAME "rk610_tvout"
-#define RK610_I2C_RATE     100*1000
-
-volatile int rk610_tv_output_status = RK610_TVOUT_DEAULT;
-static struct i2c_client *rk610_tv_i2c_client = NULL;
-
-int rk610_tv_wirte_reg(u8 reg, u8 data)
-{
-    int ret;
-       if(rk610_tv_i2c_client == NULL)
-               return -1;
-    ret = i2c_master_reg8_send(rk610_tv_i2c_client, reg, &data, 1, RK610_I2C_RATE);
-       if (ret > 0)
-               ret = 0;
-       return ret;
-}
-
-int rk610_switch_fb(const struct fb_videomode *modedb, int tv_mode)
-{      
-       struct rk_screen *screen;
-       
-       if(modedb == NULL)
-               return -1;
-       screen =  kzalloc(sizeof(struct rk_screen), GFP_KERNEL);
-       if(screen == NULL)
-               return -1;
-       
-       memset(screen, 0, sizeof(struct rk_screen));    
-       /* screen type & face */
-    screen->type = SCREEN_HDMI;
-       screen->mode = modedb->vmode;
-       screen->face = modedb->flag;
-       /* Screen size */
-       screen->x_res = modedb->xres;
-    screen->y_res = modedb->yres;
-
-    /* Timing */
-    screen->pixclock = modedb->pixclock;
-
-       screen->lcdc_aclk = 500000000;
-       screen->left_margin = modedb->left_margin;
-       screen->right_margin = modedb->right_margin;
-       screen->hsync_len = modedb->hsync_len;
-       screen->upper_margin = modedb->upper_margin;
-       screen->lower_margin = modedb->lower_margin;
-       screen->vsync_len = modedb->vsync_len;
-
-       /* Pin polarity */
-       if(FB_SYNC_HOR_HIGH_ACT & modedb->sync)
-               screen->pin_hsync = 1;
-       else
-               screen->pin_hsync = 0;
-       if(FB_SYNC_VERT_HIGH_ACT & modedb->sync)
-               screen->pin_vsync = 1;
-       else
-               screen->pin_vsync = 0;  
-       screen->pin_den = 0;
-       screen->pin_dclk = 0;
-
-       /* Swap rule */
-    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;    
-    
-    switch(tv_mode)
-       {
-#ifdef CONFIG_RK610_TVOUT_CVBS
-               case TVOUT_CVBS_NTSC:
-               case TVOUT_CVBS_PAL:
-            screen->init = rk610_tv_cvbs_init;;
-               break;
-#endif
-
-#ifdef CONFIG_RK610_TVOUT_YPbPr
-               case TVOUT_YPbPr_720x480p_60:
-               case TVOUT_YPbPr_720x576p_50:
-               case TVOUT_YPbPr_1280x720p_50:
-               case TVOUT_YPbPr_1280x720p_60:
-               //case TVOUT_YPbPr_1920x1080i_50:
-               case TVOUT_YPbPr_1920x1080i_60:
-               case TVOUT_YPbPr_1920x1080p_50:
-               case TVOUT_YPbPr_1920x1080p_60:
-                       screen->init = rk610_tv_ypbpr_init;
-                       break;
-#endif
-               default:{
-                       kfree(screen);
-                       return -1;
-               }
-               break;
-       }
-       rk610_tv_output_status = tv_mode;
-       FB_Switch_Screen(screen, 1);
-       kfree(screen);
-       return 0;
-}
-
-int rk610_tv_standby(int type)
-{
-       int ret;
-
-       switch(type)
-       {
-               #ifdef CONFIG_RK610_TVOUT_CVBS
-               case RK610_TVOUT_CVBS:
-                       if(rk610_cvbs_monspecs.enable == 0)
-                               return 0;
-                       #ifdef CONFIG_RK610_TVOUT_YPbPr
-                       if(rk610_ypbpr_monspecs.enable == 1)
-                               return 0;
-                       #endif
-                       break;
-               #endif
-               #ifdef CONFIG_RK610_TVOUT_YPbPr
-               case RK610_TVOUT_YPBPR:
-                       if(rk610_ypbpr_monspecs.enable == 0)
-                               return 0;
-                       #ifdef CONFIG_RK610_TVOUT_CVBS
-                       if(rk610_cvbs_monspecs.enable == 1)
-                               return 0;
-                       #endif
-                       break;
-               #endif
-               default:
-                       break;
-       }
-
-       ret = rk610_tv_wirte_reg(TVE_POWERCR, 0);
-       if(ret < 0){
-               printk("[%s] rk610_tv_wirte_reg err!\n", __FUNCTION__);
-               return ret;
-       }
-       
-       ret = rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, 0);
-       if(ret < 0){
-               printk("[%s] rk610_control_send_byte err!\n", __FUNCTION__);
-               return ret;
-       }
-       return 0;
-}
-
-static int rk610_tv_probe(struct i2c_client *client,const struct i2c_device_id *id)
-{
-       int rc = 0;
-       
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-               rc = -ENODEV;
-               goto failout;
-       }
-       rk610_tv_i2c_client = client;
-
-#ifdef CONFIG_RK610_TVOUT_YPbPr
-       rk610_register_display_ypbpr(&client->dev);
-       if(rk610_tv_output_status > TVOUT_CVBS_PAL)
-               rk_display_device_enable(rk610_ypbpr_monspecs.ddev);
-#endif
-
-#ifdef CONFIG_RK610_TVOUT_CVBS
-       rk610_register_display_cvbs(&client->dev);
-       if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60)
-               rk_display_device_enable(rk610_cvbs_monspecs.ddev);
-#endif
-       
-    printk(KERN_INFO "rk610_tv ver 1.0 probe ok\n");
-    return 0;
-failout:
-       kfree(client);
-       return rc;
-}
-
-static int rk610_tv_remove(struct i2c_client *client)
-{
-       return 0;
-}
-
-
-static const struct i2c_device_id rk610_tv_id[] = {
-       { DRV_NAME, 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, rk610_tv_id);
-
-static struct i2c_driver rk610_tv_driver = {
-       .driver         = {
-               .name   = DRV_NAME,
-       },
-       .id_table = rk610_tv_id,
-       .probe = rk610_tv_probe,
-       .remove = rk610_tv_remove,
-};
-
-static int __init rk610_tv_init(void)
-{
-       int ret = 0;
-       ret = i2c_add_driver(&rk610_tv_driver);
-       if(ret < 0){
-               printk("i2c_add_driver err, ret = %d\n", ret);
-       }
-       return ret;
-}
-
-static void __exit rk610_tv_exit(void)
-{
-    i2c_del_driver(&rk610_tv_driver);
-}
-
-module_init(rk610_tv_init);
-//late_initcall(rk610_tv_init);
-module_exit(rk610_tv_exit);
-
-/* Module information */
-MODULE_DESCRIPTION("ROCKCHIP RK610 TV Output");
-MODULE_LICENSE("GPL");
-
-
diff --git a/drivers/video/rockchip/tve/rk610_tv.h b/drivers/video/rockchip/tve/rk610_tv.h
deleted file mode 100644 (file)
index ead23a8..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef _RK610_TV_H
-#define _RK610_TV_H
-#include <linux/display-sys.h>
-#include <linux/rk_fb.h>
-#include <mach/board.h>
-#include <mach/gpio.h>
-#ifdef CONFIG_ARCH_RK29
-#include <mach/rk29_iomap.h>
-#endif
-#include "../screen/screen.h"
-#include "../../rk29_fb.h"
-#include <linux/mfd/rk610_core.h>
-
-#define TVE_VFCR               0x00
-       #define TVE_VFCR_ENABLE_SUBCARRIER_RESET        0 << 6
-       #define TVE_VFCR_DISABLE_SUBCARRIER_RESET       1 << 6
-       #define TVE_VFCR_VIN_RANGE_16_235                       0 << 3
-       #define TVE_VFCR_VIN_RANGE_1_254                        1 << 3
-       #define TVE_VFCR_BLACK_7_5_IRE                          0 << 2
-       #define TVE_VFCR_BLACK_0_IRE                            1 << 2
-       #define TVE_VFCR_NTSC                                           0
-       #define TVE_VFCR_PAL_M                                          1
-       #define TVE_VFCR_PAL_B_N                                        2
-       #define TVE_VFCR_PAL_NC                                         3
-
-#define TVE_VINCR              0x01
-       #define TVE_VINCR_PIX_DATA_DELAY(n)                     (n << 5)
-       #define TVE_VINCR_H_SYNC_POLARITY_NEGTIVE       0 << 4
-       #define TVE_VINCR_H_SYNC_POLARITY_POSITIVE      1 << 4
-       #define TVE_VINCR_V_SYNC_POLARITY_NEGTIVE       0 << 3
-       #define TVE_VINCR_V_SYNC_POLARITY_POSITIVE      1 << 3
-enum {
-       INPUT_FORMAT_BT601_SLAVE = 0,
-       INPUT_FORMAT_BT656,
-       INPUT_FORMAT_BT601_MASTER,
-       INPUT_FORMAT_INTERNAL_COLLOR_BAR
-};
-       #define TVE_VINCR_INPUT_FORMAT(n)                       (n << 1)
-       #define TVE_VINCR_VSYNC_FUNCTION_VSYNC          0
-       #define TVE_VINCR_VSYNC_FUNCTION_FIELD          1
-
-#define TVE_VOUTCR             0x02
-       #define TVE_VOUTCR_OUTPUT_CVBS                          0 << 6
-       #define TVE_VOUTCR_OUTPUT_YPBPR                         1 << 6
-       #define TVE_VOUTCR_OUTPUT_ENABLE_BLUE           1 << 5
-       #define TVE_VOUTCR_OUTPUT_ENABLE_BLACK          1 << 4
-       #define TVE_VOUTCR_DISABLE_CVBS_COLOR           1 << 3
-       #define TVE_VOUTCR_CVBS_Y2C_DELAY(n)                            (n << 0)
-
-#define TVE_POWERCR            0x03
-       #define TVE_PIX_CLK_INVERSE_ENABLE                      1 << 4
-       #define TVE_DAC_CLK_INVERSE_DISABLE                     1 << 3
-       #define TVE_DAC_Y_ENABLE                                        1 << 2
-       #define TVE_DAC_U_ENABLE                                        1 << 1
-       #define TVE_DAC_V_ENABLE                                        1 << 0
-
-#define TVE_HDTVCR             0x05
-       #define TVE_RESET                                                       1 << 7
-       #define TVE_FILTER(n)                                           (n << 5)
-       #define TVE_COLOR_CONVERT_REC601                        0 << 4
-       #define TVE_COLOR_CONVERT_REC709                        1 << 4
-       #define TVE_INPUT_DATA_RGB                                      0 << 3
-       #define TVE_INPUT_DATA_YUV                                      1 << 3
-       #define TVE_OUTPUT_50HZ                                         0 << 2
-       #define TVE_OUTPUT_60HZ                                         1 << 2
-       #define TVE_OUTPUT_MODE_PAL_NTSC                        0
-       #define TVE_OUTPUT_MODE_576P                            1
-       #define TVE_OUTPUT_MODE_480P                            2
-       #define TVE_OUTPUT_MODE_720P                            3
-
-#define TVE_YADJCR             0x06
-       #define TVE_OUTPUT_MODE_1080P                           1 << 6
-       #define TVE_OUTPUT_MODE_1080I                           1 << 5
-       #define TVE_Y_ADJ_VALUE(n)                                      n
-#define TVE_YCBADJCR   0x07
-#define TVE_YCRADJCR   0x08
-
-/******************* TVOUT OUTPUT TYPE **********************/
-struct rk610_monspecs {
-       struct rk_display_device        *ddev;
-       unsigned int                            enable;
-       struct fb_videomode                     *mode;
-       struct list_head                        modelist;
-       unsigned int                            mode_set;
-};
-
-enum {
-       TVOUT_CVBS_NTSC = 1,
-       TVOUT_CVBS_PAL,
-       TVOUT_YPbPr_720x480p_60,
-       TVOUT_YPbPr_720x576p_50,
-       TVOUT_YPbPr_1280x720p_50,
-       TVOUT_YPbPr_1280x720p_60,
-       //TVOUT_YPbPr_1920x1080i_50,
-       TVOUT_YPbPr_1920x1080i_60,
-       TVOUT_YPbPr_1920x1080p_50,
-       TVOUT_YPbPr_1920x1080p_60
-};
-
-#define RK610_TVOUT_DEAULT TVOUT_CVBS_NTSC
-
-enum {
-       RK610_TVOUT_CVBS = 0,
-       RK610_TVOUT_YC,
-       RK610_TVOUT_YPBPR,
-};
-
-extern volatile int rk610_tv_output_status;
-extern struct rk_display_ops rk610_display_ops;
-
-extern int FB_Switch_Screen( struct rk_screen *screen, u32 enable );
-
-extern int rk610_tv_wirte_reg(u8 reg, u8 data);
-extern int rk610_tv_standby(int type);
-extern int rk610_switch_fb(const struct fb_videomode *modedb, int tv_mode);
-extern int rk610_register_display(struct device *parent);
-
-#ifdef CONFIG_RK610_TVOUT_YPbPr
-extern int rk610_tv_ypbpr_init(void);
-extern int rk610_register_display_ypbpr(struct device *parent);
-extern struct rk610_monspecs rk610_ypbpr_monspecs;
-#endif
-
-#ifdef CONFIG_RK610_TVOUT_CVBS
-extern int rk610_tv_cvbs_init(void);
-extern int rk610_register_display_cvbs(struct device *parent);
-extern struct rk610_monspecs rk610_cvbs_monspecs;
-#endif
-
-#endif
-
diff --git a/drivers/video/rockchip/tve/rk610_tv_cvbs.c b/drivers/video/rockchip/tve/rk610_tv_cvbs.c
deleted file mode 100644 (file)
index ea0fe8a..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/display-sys.h>
-#include "rk610_tv.h"
-
-
-#ifdef CONFIG_DISPLAY_KEY_LED_CONTROL
-#define RK610_LED_CVBS_PIN     RK29_PIN4_PD3
-#else
-#define RK610_LED_CVBS_PIN     INVALID_GPIO
-#endif
-
-#ifdef USE_RGB2CCIR
-static const struct fb_videomode rk610_cvbs_mode [] = {
-               //name                          refresh         xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag
-       {       "NTSC",                         60,                     720,    480,    27000000,       116,    16,             25,             14,             6,              6,              0,                      1,              OUT_P888        },
-       {       "PAL",                          50,                     720,    576,    27000000,       126,    12,             37,             6,              6,              6,              0,                      1,              OUT_P888        },
-};
-#else
-static const struct fb_videomode rk610_cvbs_mode [] = {
-               //name                          refresh         xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag
-       {       "NTSC",                         60,                     720,    480,    27000000,       116,    16,             16,             3,              6,              3,              0,                      1,              OUT_CCIR656     },
-       {       "PAL",                          50,                     720,    576,    27000000,       126,    12,             19,             2,              6,              3,              0,                      1,              OUT_CCIR656     },
-};
-#endif
-
-struct rk610_monspecs rk610_cvbs_monspecs;
-
-
-int rk610_tv_cvbs_init(void)
-{
-       unsigned char TVE_Regs[9];
-       unsigned char TVE_CON_Reg;
-       int ret, i;
-       
-       rk610_tv_wirte_reg(TVE_HDTVCR, TVE_RESET);
-
-       memset(TVE_Regs, 0, 9);
-       TVE_CON_Reg = TVE_CONTROL_CVBS_3_CHANNEL_ENALBE;
-       TVE_Regs[TVE_VINCR]     =       TVE_VINCR_PIX_DATA_DELAY(0) | TVE_VINCR_H_SYNC_POLARITY_NEGTIVE | TVE_VINCR_V_SYNC_POLARITY_NEGTIVE | TVE_VINCR_VSYNC_FUNCTION_VSYNC;
-       TVE_Regs[TVE_POWERCR]   =       TVE_DAC_Y_ENABLE | TVE_DAC_U_ENABLE | TVE_DAC_V_ENABLE;
-       TVE_Regs[TVE_VOUTCR]    =       TVE_VOUTCR_OUTPUT_CVBS;
-       TVE_Regs[TVE_YADJCR]    =       0x17;
-       TVE_Regs[TVE_YCBADJCR]  =       0x10;
-       TVE_Regs[TVE_YCRADJCR]  =       0x10;
-       
-       switch(rk610_tv_output_status) {
-               case TVOUT_CVBS_NTSC:
-                       TVE_Regs[TVE_VFCR]              = TVE_VFCR_ENABLE_SUBCARRIER_RESET | TVE_VFCR_VIN_RANGE_16_235 | TVE_VFCR_BLACK_7_5_IRE | TVE_VFCR_NTSC;
-                       #ifdef USE_RGB2CCIR
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_MODE_PAL_NTSC;
-                       TVE_CON_Reg |= RGB2CCIR_INPUT_DATA_FORMAT(0) | RGB2CCIR_RGB_SWAP_DISABLE | RGB2CCIR_INPUT_PROGRESSIVE | RGB2CCIR_CVBS_NTSC | RGB2CCIR_ENABLE;
-                       #else
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_MODE_PAL_NTSC;
-                       #endif                  
-                       break;
-               case TVOUT_CVBS_PAL:
-                       TVE_Regs[TVE_VFCR]              = TVE_VFCR_ENABLE_SUBCARRIER_RESET | TVE_VFCR_VIN_RANGE_16_235 | TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_B_N;               
-                       #ifdef USE_RGB2CCIR
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_MODE_PAL_NTSC;
-                       TVE_CON_Reg |= RGB2CCIR_INPUT_DATA_FORMAT(0) | RGB2CCIR_RGB_SWAP_DISABLE | RGB2CCIR_INPUT_PROGRESSIVE | RGB2CCIR_CVBS_PAL | RGB2CCIR_ENABLE;
-                       #else
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_MODE_PAL_NTSC;
-                       #endif                  
-                       break;
-               default:
-                       return -1;
-       }
-       
-       for(i = 0; i < sizeof(TVE_Regs); i++){
-//             printk(KERN_ERR "reg[%d] = 0x%02x\n", i, TVE_Regs[i]);
-               ret = rk610_tv_wirte_reg(i, TVE_Regs[i]);
-               if(ret < 0){
-                       printk(KERN_ERR "rk610_tv_wirte_reg %d err!\n", i);
-                       return ret;
-               }
-       }
-//     printk(KERN_ERR "TVE_CON_Reg = 0x%02x\n", TVE_CON_Reg);
-       rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, TVE_CON_Reg);
-       #ifdef USE_RGB2CCIR
-       rk610_control_send_byte(RK610_CONTROL_REG_CCIR_RESET, 0x01);
-       #endif
-       return 0;
-}
-
-static int rk610_cvbs_set_enable(struct rk_display_device *device, int enable)
-{
-       if(rk610_cvbs_monspecs.enable != enable || rk610_cvbs_monspecs.mode_set != rk610_tv_output_status)
-       {
-               if(enable == 0)
-               {
-                       rk610_tv_standby(RK610_TVOUT_CVBS);
-                       rk610_cvbs_monspecs.enable = 0;
-                       if(RK610_LED_CVBS_PIN != INVALID_GPIO)
-                               gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_HIGH);
-               }
-               else if(enable == 1)
-               {
-                       rk610_switch_fb(rk610_cvbs_monspecs.mode, rk610_cvbs_monspecs.mode_set);
-                       rk610_cvbs_monspecs.enable = 1;
-                       if(RK610_LED_CVBS_PIN != INVALID_GPIO)
-                               gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_LOW);
-               }
-       }
-       return 0;
-}
-
-static int rk610_cvbs_get_enable(struct rk_display_device *device)
-{
-       return rk610_cvbs_monspecs.enable;
-}
-
-static int rk610_cvbs_get_status(struct rk_display_device *device)
-{
-       if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60)
-               return 1;
-       else
-               return 0;
-}
-
-static int rk610_cvbs_get_modelist(struct rk_display_device *device, struct list_head **modelist)
-{
-       *modelist = &(rk610_cvbs_monspecs.modelist);
-       return 0;
-}
-
-static int rk610_cvbs_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
-{
-       int i;
-
-       for(i = 0; i < ARRAY_SIZE(rk610_cvbs_mode); i++)
-       {
-               if(fb_mode_is_equal(&rk610_cvbs_mode[i], mode))
-               {       
-                       if( ((i + 1) != rk610_tv_output_status) )
-                       {
-                               rk610_cvbs_monspecs.mode_set = i + 1;
-                               rk610_cvbs_monspecs.mode = (struct fb_videomode *)&rk610_cvbs_mode[i];
-                       }
-                       return 0;
-               }
-       }
-       
-       return -1;
-}
-
-static int rk610_cvbs_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
-{
-       *mode = *(rk610_cvbs_monspecs.mode);
-       return 0;
-}
-
-static struct rk_display_ops rk610_cvbs_display_ops = {
-       .setenable = rk610_cvbs_set_enable,
-       .getenable = rk610_cvbs_get_enable,
-       .getstatus = rk610_cvbs_get_status,
-       .getmodelist = rk610_cvbs_get_modelist,
-       .setmode = rk610_cvbs_set_mode,
-       .getmode = rk610_cvbs_get_mode,
-};
-
-static int rk610_display_cvbs_probe(struct rk_display_device *device, void *devdata)
-{
-       device->owner = THIS_MODULE;
-       strcpy(device->type, "TV");
-       device->priority = DISPLAY_PRIORITY_TV;
-       device->priv_data = devdata;
-       device->ops = &rk610_cvbs_display_ops;
-       return 1;
-}
-
-static struct rk_display_driver display_rk610_cvbs = {
-       .probe = rk610_display_cvbs_probe,
-};
-
-int rk610_register_display_cvbs(struct device *parent)
-{
-       int i;
-       
-       memset(&rk610_cvbs_monspecs, 0, sizeof(struct rk610_monspecs));
-       INIT_LIST_HEAD(&rk610_cvbs_monspecs.modelist);
-       for(i = 0; i < ARRAY_SIZE(rk610_cvbs_mode); i++)
-               fb_add_videomode(&rk610_cvbs_mode[i], &rk610_cvbs_monspecs.modelist);
-       if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60) {
-               rk610_cvbs_monspecs.mode = (struct fb_videomode *)&(rk610_cvbs_mode[rk610_tv_output_status - 1]);
-               rk610_cvbs_monspecs.mode_set = rk610_tv_output_status;
-       }
-       else {
-               rk610_cvbs_monspecs.mode = (struct fb_videomode *)&(rk610_cvbs_mode[0]);
-               rk610_cvbs_monspecs.mode_set = TVOUT_CVBS_NTSC;
-       }
-       rk610_cvbs_monspecs.ddev = rk_display_device_register(&display_rk610_cvbs, parent, NULL);
-       if(RK610_LED_CVBS_PIN != INVALID_GPIO)
-    {        
-        if(gpio_request(RK610_LED_CVBS_PIN, NULL) != 0)
-        {
-            gpio_free(RK610_LED_CVBS_PIN);
-            dev_err(rk610_cvbs_monspecs.ddev->dev, ">>>>>> RK610_LED_CVBS_PIN gpio_request err \n ");
-            return -1;
-        }
-               gpio_pull_updown(RK610_LED_CVBS_PIN,GPIOPullUp);
-               gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_HIGH);
-    }
-       return 0;
-}
diff --git a/drivers/video/rockchip/tve/rk610_tv_ypbpr.c b/drivers/video/rockchip/tve/rk610_tv_ypbpr.c
deleted file mode 100644 (file)
index af74126..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/display-sys.h>
-#include "rk610_tv.h"
-
-
-#ifdef CONFIG_DISPLAY_KEY_LED_CONTROL
-#define RK610_LED_YPbPr_PIN    RK29_PIN4_PD5
-#else
-#define RK610_LED_YPbPr_PIN    INVALID_GPIO
-#endif
-#define E(fmt, arg...) printk("<3>!!!%s:%d: " fmt, __FILE__, __LINE__, ##arg)
-
-static const struct fb_videomode rk610_YPbPr_mode [] = {
-               //name                          refresh         xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag
-       {       "YPbPr480p",            60,                     720,    480,    27000000,       55,             19,             37,             5,              64,             5,              0,                      0,              OUT_P888        },
-       {       "YPbPr576p",            50,                     720,    576,    27000000,       68,             12,             39,             5,              64,             5,              0,                      0,              OUT_P888        },
-       {       "YPbPr720p@50",         50,                     1280,   720,    74250000,       600,    0,              20,             5,              100,    5,              0,                      0,              OUT_P888        },
-       {       "YPbPr720p@60",         60,                     1280,   720,    74250000,       270,    0,              20,             5,              100,    5,              0,                      0,              OUT_P888        },
-       //{     "YPbPr1080i@50",        50,                     1920,   1080,   148500000,      620,    0,              15,             2,              100,    5,              0,                      1,              OUT_CCIR656     },
-       {       "YPbPr1080i@60",        60,                     1920,   1080,   148500000,      180,    0,              15,             2,              100,    5,              0,                      1,              OUT_CCIR656     },
-       {       "YPbPr1080p@50",        50,                     1920,   1080,   148500000,      620,    0,              36,             4,              100,    5,              0,                      0,              OUT_P888        },
-       {       "YPbPr1080p@60",        60,                     1920,   1080,   148500000,      180,    0,              36,             4,              100,    5,              0,                      0,              OUT_P888        },
-};
-
-struct rk610_monspecs rk610_ypbpr_monspecs;
-
-int rk610_tv_ypbpr_init(void)
-{
-       unsigned char TVE_Regs[9];
-       unsigned char TVE_CON_Reg;
-       int i, ret;
-       
-       rk610_tv_wirte_reg(TVE_HDTVCR, TVE_RESET);
-       memset(TVE_Regs, 0, 9); 
-       
-       TVE_CON_Reg = 0x00;
-       
-       TVE_Regs[TVE_VINCR]     =       TVE_VINCR_PIX_DATA_DELAY(0) | TVE_VINCR_H_SYNC_POLARITY_NEGTIVE | TVE_VINCR_V_SYNC_POLARITY_NEGTIVE | TVE_VINCR_VSYNC_FUNCTION_VSYNC;
-       TVE_Regs[TVE_POWERCR]   =       TVE_DAC_CLK_INVERSE_DISABLE | TVE_DAC_Y_ENABLE | TVE_DAC_U_ENABLE | TVE_DAC_V_ENABLE;
-       TVE_Regs[TVE_VOUTCR]    =       TVE_VOUTCR_OUTPUT_YPBPR;
-       TVE_Regs[TVE_YADJCR]    =       0x17;
-       TVE_Regs[TVE_YCBADJCR]  =       0x10;
-       TVE_Regs[TVE_YCRADJCR]  =       0x10;
-       
-       switch(rk610_tv_output_status)
-       {
-               case TVOUT_YPbPr_720x480p_60:
-                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE;
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_60HZ | TVE_OUTPUT_MODE_480P;
-                       break;
-               case TVOUT_YPbPr_720x576p_50:
-                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_50HZ | TVE_OUTPUT_MODE_576P;
-                       break;
-               case TVOUT_YPbPr_1280x720p_50:
-                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_50HZ | TVE_OUTPUT_MODE_720P;
-                       break;
-               case TVOUT_YPbPr_1280x720p_60:
-                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_60HZ | TVE_OUTPUT_MODE_720P;
-                       break;
-               /*case TVOUT_YPbPr_1920x1080i_50:
-                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_50HZ;
-                       TVE_Regs[TVE_YADJCR]    |=      TVE_OUTPUT_MODE_1080I;
-                       break;
-                       */
-               case TVOUT_YPbPr_1920x1080i_60:
-                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_60HZ;
-                       TVE_Regs[TVE_YADJCR]    |=      TVE_OUTPUT_MODE_1080I;
-                       break;
-               case TVOUT_YPbPr_1920x1080p_50:
-                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_50HZ;
-                       TVE_Regs[TVE_YADJCR]    |=      TVE_OUTPUT_MODE_1080P;
-                       break;
-               case TVOUT_YPbPr_1920x1080p_60:
-                       TVE_Regs[TVE_VFCR]              =       TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
-                       TVE_Regs[TVE_VINCR]             |=      TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
-                       TVE_Regs[TVE_HDTVCR]    =       TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_60HZ;
-                       TVE_Regs[TVE_YADJCR]    |=      TVE_OUTPUT_MODE_1080P;
-                       break;
-               default:
-                       return -1;
-       }
-       
-       rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, TVE_CON_Reg);
-       
-       for(i = 0; i < sizeof(TVE_Regs); i++){
-//             printk(KERN_ERR "reg[%d] = 0x%02x\n", i, TVE_Regs[i]);
-               ret = rk610_tv_wirte_reg(i, TVE_Regs[i]);
-               if(ret < 0){
-                       E("rk610_tv_wirte_reg %d err!\n", i);
-                       return ret;
-               }
-       }
-       return 0;
-}
-
-static int rk610_ypbpr_set_enable(struct rk_display_device *device, int enable)
-{
-       if(rk610_ypbpr_monspecs.enable != enable || rk610_ypbpr_monspecs.mode_set != rk610_tv_output_status)
-       {
-               if(enable == 0)
-               {
-                       rk610_tv_standby(RK610_TVOUT_YPBPR);
-                       rk610_ypbpr_monspecs.enable = 0;
-                       if(RK610_LED_YPbPr_PIN != INVALID_GPIO)
-                               gpio_direction_output(RK610_LED_YPbPr_PIN, GPIO_HIGH);
-               }
-               else if(enable == 1)
-               {
-                       rk610_switch_fb(rk610_ypbpr_monspecs.mode, rk610_ypbpr_monspecs.mode_set);
-                       rk610_ypbpr_monspecs.enable = 1;
-                       if(RK610_LED_YPbPr_PIN != INVALID_GPIO)
-                               gpio_direction_output(RK610_LED_YPbPr_PIN, GPIO_LOW);
-               }
-       }
-       return 0;
-}
-
-static int rk610_ypbpr_get_enable(struct rk_display_device *device)
-{
-       return rk610_ypbpr_monspecs.enable;
-}
-
-static int rk610_ypbpr_get_status(struct rk_display_device *device)
-{
-       if(rk610_tv_output_status > TVOUT_CVBS_PAL)
-               return 1;
-       else
-               return 0;
-}
-
-static int rk610_ypbpr_get_modelist(struct rk_display_device *device, struct list_head **modelist)
-{
-       *modelist = &(rk610_ypbpr_monspecs.modelist);
-       return 0;
-}
-
-static int rk610_ypbpr_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
-{
-       int i;
-
-       for(i = 0; i < ARRAY_SIZE(rk610_YPbPr_mode); i++)
-       {
-               if(fb_mode_is_equal(&rk610_YPbPr_mode[i], mode))
-               {       
-                       if( (i + 3) != rk610_tv_output_status )
-                       {
-                               rk610_ypbpr_monspecs.mode_set = i + 3;
-                               rk610_ypbpr_monspecs.mode = (struct fb_videomode *)&rk610_YPbPr_mode[i];
-                       }
-                       return 0;
-               }
-       }
-       
-       return -1;
-}
-
-static int rk610_ypbpr_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
-{
-       *mode = *(rk610_ypbpr_monspecs.mode);
-       return 0;
-}
-
-static struct rk_display_ops rk610_ypbpr_display_ops = {
-       .setenable = rk610_ypbpr_set_enable,
-       .getenable = rk610_ypbpr_get_enable,
-       .getstatus = rk610_ypbpr_get_status,
-       .getmodelist = rk610_ypbpr_get_modelist,
-       .setmode = rk610_ypbpr_set_mode,
-       .getmode = rk610_ypbpr_get_mode,
-};
-
-static int rk610_display_YPbPr_probe(struct rk_display_device *device, void *devdata)
-{
-       device->owner = THIS_MODULE;
-       strcpy(device->type, "YPbPr");
-       device->priority = DISPLAY_PRIORITY_YPbPr;
-       device->priv_data = devdata;
-       device->ops = &rk610_ypbpr_display_ops;
-       return 1;
-}
-
-static struct rk_display_driver display_rk610_YPbPr = {
-       .probe = rk610_display_YPbPr_probe,
-};
-
-int rk610_register_display_ypbpr(struct device *parent)
-{
-       int i;
-       
-       memset(&rk610_ypbpr_monspecs, 0, sizeof(struct rk610_monspecs));
-       INIT_LIST_HEAD(&rk610_ypbpr_monspecs.modelist);
-       for(i = 0; i < ARRAY_SIZE(rk610_YPbPr_mode); i++)
-               fb_add_videomode(&rk610_YPbPr_mode[i], &rk610_ypbpr_monspecs.modelist);
-       if(rk610_tv_output_status > TVOUT_CVBS_PAL) {
-               rk610_ypbpr_monspecs.mode = (struct fb_videomode *)&(rk610_YPbPr_mode[rk610_tv_output_status - 3]);
-               rk610_ypbpr_monspecs.mode_set = rk610_tv_output_status;
-       }
-       else {
-               rk610_ypbpr_monspecs.mode = (struct fb_videomode *)&(rk610_YPbPr_mode[3]);
-               rk610_ypbpr_monspecs.mode_set = TVOUT_YPbPr_1280x720p_60;
-       }
-       rk610_ypbpr_monspecs.ddev = rk_display_device_register(&display_rk610_YPbPr, parent, NULL);
-       if(RK610_LED_YPbPr_PIN != INVALID_GPIO)
-    {        
-        if(gpio_request(RK610_LED_YPbPr_PIN, NULL) != 0)
-        {
-            gpio_free(RK610_LED_YPbPr_PIN);
-            dev_err(rk610_ypbpr_monspecs.ddev->dev, ">>>>>> RK610_LED_YPbPr_PIN gpio_request err \n ");
-            return -1;
-        }
-               gpio_pull_updown(RK610_LED_YPbPr_PIN,GPIOPullUp);
-               gpio_direction_output(RK610_LED_YPbPr_PIN, GPIO_HIGH);
-    }
-       return 0;
-}
index 37da53946f80d740fa2e1fa6cce80770f77d4be1..da1e03cae33ad908daf8c08d69c368c5a56ecfdc 100755 (executable)
@@ -342,6 +342,7 @@ struct rk_lcdc_win_area{
 struct rk_lcdc_win {
        char name[5];
        int id;
+       u32 logicalstate;
        bool state;             /*on or off*/
        bool last_state;                /*on or off*/
        u32 pseudo_pal[16];
@@ -546,8 +547,11 @@ struct rk_lcdc_driver {
        char fb1_win_id;
        char fb2_win_id;
        char fb3_win_id;
+       
        char mmu_dts_name[40];
+       struct device *mmu_dev;
        int iommu_enabled;
+       
        struct rk_fb_reg_area_data reg_area_data;
        struct mutex fb_win_id_mutex;
 
@@ -576,7 +580,7 @@ struct rk_lcdc_driver {
 #ifdef CONFIG_DRM_ROCKCHIP
        void (*irq_call_back)(struct rk_lcdc_driver *driver);
 #endif
-
+       struct overscan overscan;
 };
 
 /*disp_mode: dual display mode