Merge branch develop-3.10 into develop-3.10-next
authorHuang, Tao <huangtao@rock-chips.com>
Fri, 12 Dec 2014 06:12:56 +0000 (14:12 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Fri, 12 Dec 2014 06:12:56 +0000 (14:12 +0800)
21 files changed:
arch/arm/Makefile
arch/arm/boot/dts/rk312x.dtsi
arch/arm/boot/dts/rk3288-p977.dts
arch/arm/boot/dts/rk3288-p977_8846.dts
arch/arm/boot/dts/rk3288-tb.dts
arch/arm/boot/dts/rk3288-tb_8846.dts
arch/arm/boot/dts/rk3288.dtsi
arch/arm/configs/rockchip_defconfig
arch/arm/mach-rockchip/common.c
arch/arm/mach-rockchip/rk312x.c
arch/arm/mach-rockchip/rk3288.c
drivers/clk/rockchip/clk-pll.c
drivers/media/video/Kconfig
drivers/usb/dwc_otg_310/usbdev_rk.h
drivers/usb/dwc_otg_310/usbdev_rk3126.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-rockchip.c
drivers/video/rockchip/bmp_helper.c
drivers/video/rockchip/rk_fb.c
include/linux/rockchip/common.h
logo_kernel.bmp [new file with mode: 0644]

index f5658251771c9e44bc8a5cc9bbe7fc5e3a1f58f8..3d88c39670fd8ec287325c8b13780b7e363b728e 100644 (file)
@@ -340,6 +340,7 @@ kernel.img: zImage
        @echo '  Image:  kernel.img (with $*.dtb) is ready'
 
 LOGO := $(notdir $(wildcard $(srctree)/logo.bmp))
+LOGO_KERNEL := $(notdir $(wildcard $(srctree)/logo_kernel.bmp))
 %.img: %.dtb kernel.img $(LOGO)
-       $(Q)$(srctree)/resource_tool $(objtree)/arch/arm/boot/dts/$*.dtb $(LOGO)
-       @echo '  Image:  resource.img (with $*.dtb $(LOGO)) is ready'
+       $(Q)$(srctree)/resource_tool $(objtree)/arch/arm/boot/dts/$*.dtb $(LOGO) $(LOGO_KERNEL)
+       @echo '  Image:  resource.img (with $*.dtb $(LOGO) $(LOGO_KERNEL)) is ready'
index bfd45e82e295a099cbee55092c806a1dbec2b983..062f7df90ac13d1967d13ce98507b27507e3e668 100755 (executable)
                rockchip,usb-mode = <0>;
        };
 
-       usb1: usb@101c0000 {
-               compatible = "rockchip,rk3126_usb20_host";
-               reg = <0x101c0000 0x40000>;
+       ehci: usb@101c0000 {
+               compatible = "rockchip,rk3126_ehci";
+               reg = <0x101c0000 0x20000>;
                interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&clk_gates1 6>, <&clk_gates10 14>;
-               clock-names = "clk_usbphy1", "hclk_usb1";
+               clocks = <&clk_gates1 6>, <&clk_gates7 3>, <&clk_gates10 14>;
+               clock-names = "clk_usbphy1", "hclk_hoct0_3126","hclk_host0_3126b";
                resets = <&reset RK3128_RST_USBOTG1>, <&reset RK3128_RST_UTMI1>,
                                <&reset RK3128_RST_OTGC1>;
                reset-names = "host_ahb", "host_phy", "host_controller";
        };
 
+       ohci: usb@101e0000 {
+               compatible = "rockchip,rk3126_ohci";
+               reg = <0x101e0000 0x20000>;
+               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
        fb: fb{
                compatible = "rockchip,rk-fb";
                rockchip,disp-mode = <ONE_DUAL>;
index cb6e92fbff7de7eaeafe486212092d6cd22ebda5..405e3022c5814cc756032db497dc50b7976df213 100755 (executable)
 &sdmmc0_vdd_domain{
        regulator-name = "vcc_sd";                      
        };
-&ion_cma {
-       reg = <0x40000000 0x20000000>; /* 512MB */
-};
index f4b403189b5c12852a9df17b1e96a2200f5e1d64..4e20b449b67524fb5f935b145dc95d4c2408f07a 100755 (executable)
 &sdmmc0_vdd_domain{
        regulator-name = "vcc_sd";                      
        };
-&ion_cma {
-       reg = <0x40000000 0x20000000>; /* 512MB */
-};
index 12c24d322a5ff693164ef74fbb300b4dbc06748a..fde9d45df930678a1e922a34244c3a19144a03b4 100755 (executable)
        regulator-name = "vcc_sd";                      
        };
 
-&ion_cma {
-       reg = <0x40000000 0x28000000>; /* 640MB */
-};
-
 &dwc_control_usb {
        usb_uart {
                status = "disabled";
index e8e718edb33730ab6b2ac7c3cd9604a1fed6b548..0c2c19a17d18d9977e152f0b0ee3f11743da5039 100644 (file)
        regulator-name = "vcc_sd";                      
        };
 
-&ion_cma {
-       reg = <0x40000000 0x28000000>; /* 640MB */
-};
-
 &dwc_control_usb {
        usb_uart {
                status = "disabled";
index 2e893ea2bc6d46fcabf5cdab741dd357014ef864..742d12a890a67da239835a21eabb69572bb237d0 100755 (executable)
                ion_cma: rockchip,ion-heap@1 { /* CMA HEAP */
                        compatible = "rockchip,ion-heap";
                        rockchip,ion_heap = <1>;
-                       reg = <0x00000000 0x20000000>; /* 512MB */
+                       reg = <0x00000000 0x28000000>; /* 640MB */
                };
                rockchip,ion-heap@3 { /* VMALLOC HEAP */
                        compatible = "rockchip,ion-heap";
                interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&clk_gates13 5>, <&clk_gates7 6>;
                clock-names = "clk_usbphy3", "hclk_usb3";
+               status = "disabled";
        };
 
        hsic: hsic@ff5c0000 {
index 44ade9ccc0eae7b2dfdb1cf0d3a7b6f4e5b42f4e..eabe53d9da84119bdc6931f805b995079cf3e75c 100644 (file)
@@ -391,7 +391,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_CAMSYS_DRV=y
 CONFIG_FLASHLIGHT=y
 CONFIG_LEDS_RT8547=y
-# CONFIG_RK30_CAMERA_ONEFRAME is not set
+CONFIG_RK30_CAMERA_ONEFRAME=y
 CONFIG_MALI_MIDGARD=m
 CONFIG_MALI_MIDGARD_DVFS=y
 CONFIG_MALI_MIDGARD_RT_PM=y
@@ -509,6 +509,8 @@ CONFIG_USB_HIDDEV=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_RK=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_RK=y
 CONFIG_USB_ACM=y
 CONFIG_USB_PRINTER=y
 CONFIG_USB_STORAGE=y
index 82b574275fc922739d4f0a319ef54f48e0a20c49..a3d129a0a2728c9be80a85ce4a28e2d14ab37fea 100755 (executable)
@@ -26,6 +26,7 @@
 #endif
 #include <linux/rockchip/common.h>
 #include <linux/rockchip/pmu.h>
+#include <linux/memblock.h>
 #include "cpu_axi.h"
 #include "loader.h"
 #include "sram.h"
@@ -298,3 +299,62 @@ static int __init rockchip_jtag_enable(char *__unused)
        return 1;
 }
 __setup("rockchip_jtag", rockchip_jtag_enable);
+
+phys_addr_t uboot_logo_base=0;
+phys_addr_t uboot_logo_size=0;
+phys_addr_t uboot_logo_offset=0;
+
+void __init rockchip_uboot_mem_reserve(void)
+{
+       if (uboot_logo_size) {
+               if (!memblock_is_region_reserved(uboot_logo_base, uboot_logo_size)
+                       && !memblock_reserve(uboot_logo_base, uboot_logo_size)){
+                       pr_info("%s: reserve %zx@%zx for uboot logo\n", __func__,
+                               uboot_logo_size, uboot_logo_base);
+               } else {
+                       pr_err("%s: reserve of %zx@%zx failed\n", __func__,
+                              uboot_logo_size, uboot_logo_base);
+               }
+       }
+}
+
+static int __init rockchip_uboot_logo_setup(char *p)
+{
+       char *endp;
+
+       uboot_logo_size = memparse(p, &endp);
+       if (*endp == '@') {
+               uboot_logo_base = memparse(endp + 1, &endp);
+               if (*endp == ':') {
+                       uboot_logo_offset = memparse(endp + 1, NULL);
+               }
+       }
+
+       pr_info("%s: mem: %zx@%zx, offset:%zx\n", __func__,
+               uboot_logo_size, uboot_logo_base, uboot_logo_offset);
+
+       return 0;
+}
+early_param("uboot_logo", rockchip_uboot_logo_setup);
+
+static int __init rockchip_uboot_mem_late_init(void)
+{
+       phys_addr_t addr = 0;
+       phys_addr_t end = 0;
+
+       if (uboot_logo_size) {
+               addr = PAGE_ALIGN(uboot_logo_base);
+               end = (uboot_logo_base+uboot_logo_size)&PAGE_MASK;
+
+               pr_info("%s: Freeing uboot logo memory: %zx@%zx\n", __func__,
+                       uboot_logo_size, uboot_logo_base);
+
+               memblock_free(uboot_logo_base, uboot_logo_size);
+
+               for (; addr < end; addr += PAGE_SIZE)
+                       free_reserved_page(pfn_to_page(addr >> PAGE_SHIFT));
+       }
+
+       return 0;
+}
+late_initcall(rockchip_uboot_mem_late_init);
index 6ff7f52c9548162ac7add2be1ed3c9f7caf37a5c..aaef664d42f9509b8dc3e37dd71f36f5b8fa1c53 100755 (executable)
@@ -353,6 +353,9 @@ static void __init rk312x_dt_init_timer(void)
 
 static void __init rk312x_reserve(void)
 {
+       /* reserve memory for uboot */
+       rockchip_uboot_mem_reserve();
+
        /* reserve memory for ION */
        rockchip_ion_reserve();
 }
index 100327c3129d7aab25ef2866918a9c2bffe55340..d44709321c6235fcd2cc69093600ffd2a542663e 100755 (executable)
@@ -435,6 +435,9 @@ static void __init rk3288_dt_init_timer(void)
 
 static void __init rk3288_reserve(void)
 {
+       /* reserve memory for uboot */
+       rockchip_uboot_mem_reserve();
+
        /* reserve memory for ION */
        rockchip_ion_reserve();
 }
index 760b54aca9750b19eb0a20166940cbd59df15d53..776445b1b232aebed5b3db7220e47e9a4bd49f1a 100755 (executable)
@@ -1038,100 +1038,89 @@ static const struct clk_ops clk_pll_ops_3188plus = {
 
 static u32 clk_gcd(u32 numerator, u32 denominator)
 {
-        u32 a, b;
-
-        if (!numerator || !denominator)
-                return 0;
-        if (numerator > denominator) {
-                a = numerator;
-                b = denominator;
-        } else {
-                a = denominator;
-                b = numerator;
-        }
-        while (b != 0) {
-                int r = b;
-                b = a % b;
-                a = r;
-        }
-
-        return a;
+       u32 a, b;
+
+       if (!numerator || !denominator)
+               return 0;
+       if (numerator > denominator) {
+               a = numerator;
+               b = denominator;
+       } else {
+               a = denominator;
+               b = numerator;
+       }
+       while (b != 0) {
+               int r = b;
+
+               b = a % b;
+               a = r;
+       }
+
+       return a;
 }
 
-/* FIXME: calc using u64 */
 static int pll_clk_get_best_set(unsigned long fin_hz, unsigned long fout_hz,
                                u32 *best_nr, u32 *best_nf, u32 *best_no)
 {
-        u32 nr, nf, no, nonr;
-        u32 nr_out, nf_out, no_out;
-        u32 n;
-        u32 YFfenzi;
-        u32 YFfenmu;
-        u64 fref, fvco, fout;
-        u32 gcd_val = 0;
-
-
-        nr_out = PLL_NR_MAX + 1;
-        no_out = 0;
-
-//     printk("pll_clk_get_set fin=%lu,fout=%lu\n", fin_hz, fout_hz);
-        if(!fin_hz || !fout_hz || fout_hz == fin_hz)
-                return -EINVAL;
-        gcd_val = clk_gcd(fin_hz, fout_hz);
-
-//      printk("gcd_val = %d\n",gcd_val);
-
-        YFfenzi = fout_hz / gcd_val;
-        YFfenmu = fin_hz / gcd_val;
-
-//      printk("YFfenzi = %d, YFfenmu = %d\n",YFfenzi,YFfenmu);
-
-       for(n = 1;; n++) {
-              nf = YFfenzi * n;
-              nonr = YFfenmu * n;
-              if(nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
-                      break;
-              for(no = 1; no <= PLL_NO_MAX; no++) {
-                      if(!(no == 1 || !(no % 2)))
-                              continue;
-
-                      if(nonr % no)
-                              continue;
-                      nr = nonr / no;
-
-                      if(nr > PLL_NR_MAX) //PLL_NR_MAX
-                              continue;
-
-                      fref = fin_hz / nr;
-                      if(fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
-                              continue;
-
-                      fvco = fref * nf;
-                      if(fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
-                              continue;
-                      fout = fvco / no;
-                      if(fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
-                              continue;
-
-                      /* output all available PLL settings */
-                      //printk("nr=%d,\tnf=%d,\tno=%d\n",nr,nf,no);
-                      //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr,nf,no);
-
-                      /* select the best from all available PLL settings */
-                      if((nr < nr_out) || ((nr == nr_out)&&(no > no_out)))
-                      {
-                              nr_out = nr;
-                              nf_out = nf;
-                              no_out = no;
-                      }
-              }
-
-       }
-
-        /* output the best PLL setting */
-        if((nr_out <= PLL_NR_MAX) && (no_out > 0)){
-                //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr_out,nf_out,no_out);
-               if(best_nr && best_nf && best_no){
+       u32 nr, nf, no, nonr;
+       u32 nr_out, nf_out, no_out;
+       u32 n;
+       u32 YFfenzi;
+       u32 YFfenmu;
+       u64 fref, fvco, fout;
+       u32 gcd_val = 0;
+
+       nr_out = PLL_NR_MAX + 1;
+       no_out = 0;
+
+       if (!fin_hz || !fout_hz || fout_hz == fin_hz)
+               return -EINVAL;
+       gcd_val = clk_gcd(fin_hz, fout_hz);
+
+       YFfenzi = fout_hz / gcd_val;
+       YFfenmu = fin_hz / gcd_val;
+
+       for (n = 1;; n++) {
+               nf = YFfenzi * n;
+               nonr = YFfenmu * n;
+               if (nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
+                       break;
+
+               for (no = 1; no <= PLL_NO_MAX; no++) {
+                       if (!(no == 1 || !(no % 2)))
+                               continue;
+
+                       if (nonr % no)
+                               continue;
+                       nr = nonr / no;
+
+                       if (nr > PLL_NR_MAX)
+                               continue;
+
+                       fref = fin_hz / nr;
+                       if (fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
+                               continue;
+
+                       fvco = fref * nf;
+                       if (fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
+                               continue;
+
+                       fout = fvco / no;
+                       if (fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
+                               continue;
+
+                       /* select the best from all available PLL settings */
+                       if ((no > no_out) || ((no == no_out) && (nr < nr_out))) {
+                               nr_out = nr;
+                               nf_out = nf;
+                               no_out = no;
+                       }
+               }
+       }
+
+       /* output the best PLL setting */
+       if ((nr_out <= PLL_NR_MAX) && (no_out > 0)) {
+               if (best_nr && best_nf && best_no) {
                        *best_nr = nr_out;
                        *best_nf = nf_out;
                        *best_no = no_out;
index 6a92b1a916ed40af2ae494cb5449c95336e007ec..a26568d9804c419ed6cde48b7f1f3bd7ce85bcfc 100644 (file)
@@ -1,7 +1,5 @@
 config ROCK_CHIP_SOC_CAMERA
        tristate "rockchip supported soc cameras "
-       select SOC_CAMERA
-       select VIDEOBUF_DMA_CONTIG
        default y
        
 menu "rockchip camera sensor interface driver"
@@ -14,10 +12,14 @@ menu "rockchip camera sensor interface driver"
        config RK30_CAMERA_ONEFRAME
                tristate "rk30_camera_oneframe"
                depends on ROCKCHIP_CAMERA_SENSOR_INTERFACE
-               default y
+               select SOC_CAMERA
+       select VIDEOBUF_DMA_CONTIG
+               default n
                
        config RK30_CAMERA_PINGPONG
                tristate "rk30_camera_pingpong"
                depends on ROCKCHIP_CAMERA_SENSOR_INTERFACE
-               
+               select SOC_CAMERA
+       select VIDEOBUF_DMA_CONTIG
+               default n
 endmenu                
index 682d8a627fd1461a92dd574a2704643ab76627b5..16ef6d78c54b246fd0a5ff0128bb711c0bedb72d 100755 (executable)
@@ -70,6 +70,7 @@ extern struct dwc_otg_platform_data usb20host_pdata_rk3036;
 extern struct dwc_otg_platform_data usb20otg_pdata_rk3126;
 extern struct dwc_otg_platform_data usb20host_pdata_rk3126;
 extern struct dwc_otg_platform_data usb20ohci_pdata_rk3126;
+extern struct rkehci_platform_data usb20ehci_pdata_rk3126;
 
 struct dwc_otg_platform_data {
        void *privdata;
index 628bd69749541997b71fe14c456ba6542748bd5a..67676c492cc1133302296675ea7d2fb815c548d2 100755 (executable)
@@ -213,7 +213,7 @@ struct dwc_otg_platform_data usb20otg_pdata_rk3126 = {
 };
 #endif
 
-#ifdef CONFIG_USB20_HOST
+#if defined(CONFIG_USB20_HOST) || defined(CONFIG_USB_EHCI_RK)
 static void usb20host_hw_init(void)
 {
        /* Turn off differential receiver in suspend mode */
@@ -382,6 +382,115 @@ struct dwc_otg_platform_data usb20host_pdata_rk3126 = {
 };
 #endif
 
+#ifdef CONFIG_USB_EHCI_RK
+static void usb20ehci_phy_suspend(void *pdata, int suspend)
+{
+       struct rkehci_platform_data *usbpdata = pdata;
+
+       if (suspend) {
+               /* enable soft control */
+               writel(UOC_HIWORD_UPDATE(0x1d5, 0x1ff, 0),
+                      RK_GRF_VIRT + RK312X_GRF_UOC1_CON5);
+               usbpdata->phy_status = 1;
+       } else {
+               /* exit suspend */
+               writel(UOC_HIWORD_UPDATE(0x0, 0x1, 0),
+                      RK_GRF_VIRT + RK312X_GRF_UOC1_CON5);
+               usbpdata->phy_status = 0;
+       }
+}
+
+static void usb20ehci_soft_reset(void *pdata, enum rkusb_rst_flag rst_type)
+{
+       struct rkehci_platform_data *usbpdata = pdata;
+       struct reset_control *rst_host_h, *rst_host_p, *rst_host_c;
+
+       rst_host_h = devm_reset_control_get(usbpdata->dev, "host_ahb");
+       rst_host_p = devm_reset_control_get(usbpdata->dev, "host_phy");
+       rst_host_c = devm_reset_control_get(usbpdata->dev, "host_controller");
+       if (IS_ERR(rst_host_h) || IS_ERR(rst_host_p) || IS_ERR(rst_host_c)) {
+               dev_err(usbpdata->dev, "Fail to get reset control from dts\n");
+               return;
+       }
+
+       switch(rst_type) {
+       case RST_POR:
+               /* PHY reset */
+               writel(UOC_HIWORD_UPDATE(0x1, 0x3, 0),
+                          RK_GRF_VIRT + RK312X_GRF_UOC1_CON5);
+               reset_control_assert(rst_host_p);
+               udelay(15);
+               writel(UOC_HIWORD_UPDATE(0x2, 0x3, 0),
+                          RK_GRF_VIRT + RK312X_GRF_UOC1_CON5);
+
+               udelay(1500);
+               reset_control_deassert(rst_host_p);
+
+               /* Controller reset */
+               reset_control_assert(rst_host_c);
+               reset_control_assert(rst_host_h);
+
+               udelay(5);
+
+               reset_control_deassert(rst_host_c);
+               reset_control_deassert(rst_host_h);
+               break;
+
+       default:
+               break;
+       }
+}
+
+static void usb20ehci_clock_init(void *pdata)
+{
+       struct rkehci_platform_data *usbpdata = pdata;
+       struct clk *ahbclk, *phyclk;
+
+       if (soc_is_rk3126b())
+               ahbclk = devm_clk_get(usbpdata->dev, "hclk_hoct0_3126b");
+       else
+               ahbclk = devm_clk_get(usbpdata->dev, "hclk_hoct0_3126");
+       if (IS_ERR(ahbclk)) {
+               dev_err(usbpdata->dev, "Failed to get hclk_usb1\n");
+               return;
+       }
+
+       phyclk = devm_clk_get(usbpdata->dev, "clk_usbphy1");
+       if (IS_ERR(phyclk)) {
+               dev_err(usbpdata->dev, "Failed to get clk_usbphy1\n");
+               return;
+       }
+
+       usbpdata->phyclk = phyclk;
+       usbpdata->ahbclk = ahbclk;
+}
+
+static void usb20ehci_clock_enable(void *pdata, int enable)
+{
+       struct rkehci_platform_data *usbpdata = pdata;
+
+       if (enable) {
+               clk_prepare_enable(usbpdata->ahbclk);
+               clk_prepare_enable(usbpdata->phyclk);
+       } else {
+               clk_disable_unprepare(usbpdata->ahbclk);
+               clk_disable_unprepare(usbpdata->phyclk);
+       }
+}
+
+struct rkehci_platform_data usb20ehci_pdata_rk3126 = {
+       .phyclk = NULL,
+       .ahbclk = NULL,
+       .phy_status = 0,
+       .hw_init = usb20host_hw_init,
+       .phy_suspend = usb20ehci_phy_suspend,
+       .soft_reset = usb20ehci_soft_reset,
+       .clock_init = usb20ehci_clock_init,
+       .clock_enable = usb20ehci_clock_enable,
+       .get_status = usb20host_get_status,
+};
+#endif
+
 struct dwc_otg_platform_data usb20ohci_pdata_rk3126;
 
 #ifdef CONFIG_OF
index d412e135c27d38efc5b6a30a9a1e28588c7541ac..ca6289b4b7ade64a5387dec6f8bb2ba025e7f0cf 100644 (file)
@@ -285,12 +285,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
                                t2 |= PORT_WKOC_E | PORT_WKCONN_E;
                }
 
-#ifdef CONFIG_USB_EHCI_RK
-               /* RK3288 do not support OHCI controller, so clear PORT_OWNER
-                * here, otherwise EHCI can't be used anymore. wlf@20140325 */
-               t2 &= ~PORT_OWNER;
-#endif
-
                if (t1 != t2) {
                        ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
                                port + 1, t1, t2);
@@ -1059,12 +1053,6 @@ static int ehci_hub_control (
                                ehci_dbg (ehci,
                                        "port %d low speed --> companion\n",
                                        wIndex + 1);
-#ifdef CONFIG_USB_EHCI_RK
-                               /* RK3288 do not support OHCI controller, so can't set PORT_OWNER
-                                * here, otherwise EHCI can't be used anymore. wlf@20140325 */
-                               retval = -ENODEV;
-                               break;
-#endif
                                temp |= PORT_OWNER;
                        } else {
                                ehci_vdbg (ehci, "port %d reset\n", wIndex + 1);
index 4e4be699691856e7f83a4638f7316676f1e67eee..874f8008150e6ae65170cb51b1d4107f4ba9adef 100755 (executable)
@@ -68,11 +68,7 @@ static void rk_ehci_hcd_enable(struct work_struct *work)
                }
 
                EHCI_PRINT("%s, disable host controller\n", __func__);
-               usb_remove_hcd(hcd);
 
-               /* reset cru and reinitialize EHCI controller */
-               pldata->soft_reset(pldata, RST_RECNT);
-               usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
                if (pldata->phy_suspend)
                        pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
                /* do not disable EHCI clk, otherwise RK3288
@@ -253,6 +249,10 @@ static struct of_device_id rk_ehci_of_match[] = {
         .compatible = "rockchip,rk3288_rk_ehci_host",
         .data = &rkehci_pdata_rk3288,
         },
+       {
+        .compatible = "rockchip,rk3126_ehci",
+        .data = &usb20ehci_pdata_rk3126,
+        },
        {},
 };
 
@@ -458,14 +458,36 @@ static const struct ehci_driver_overrides rk_overrides __initdata = {
        .extra_priv_size = sizeof(struct rk_ehci_hcd),
 };
 
+static void rk32_ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
+{
+       struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
+       u32     *status_reg = &ehci->regs->port_status[--portnum];
+       u32     portsc;
+
+       portsc = ehci_readl(ehci, status_reg);
+       portsc &= ~(PORT_OWNER | PORT_RWC_BITS);
+
+       ehci_writel(ehci, portsc, status_reg);
+}
+
 static int __init ehci_rk_init(void)
 {
        if (usb_disabled())
                return -ENODEV;
 
        ehci_init_driver(&rk_ehci_hc_driver, &rk_overrides);
+
+       /*
+        * Work-around: RK3288 do not support OHCI controller, so our
+        * vendor-spec ehci driver has to prevent handing off this port to
+        * OHCI by standard ehci-hub driver, put PORT_OWNER back to 0 manually.
+        */
+       if (cpu_is_rk3288())
+               rk_ehci_hc_driver.relinquish_port = rk32_ehci_relinquish_port;
+
        return platform_driver_register(&rk_ehci_driver);
 }
+
 module_init(ehci_rk_init);
 
 static void __exit ehci_rk_cleanup(void)
index 75e8c3ae1aedd4f9e8d876eb9f586c6224f25c92..aa4f4f072917fb9e1e2707b3b9f048497a19b907 100755 (executable)
@@ -344,6 +344,11 @@ int bmpdecoder(void *bmp_addr, void *pdst, int *width, int *height, int *bits)
 
        memcpy(&header, src, sizeof(header));
        src += sizeof(header);
+
+       if (header.type != 0x4d42) {
+               pr_err("not bmp file type[%x], can't support\n", header.type);
+               return -1;
+       }
        memcpy(&infoheader, src, sizeof(infoheader));
        *width = infoheader.width;
        *height = infoheader.height;
index cf41a1635959398fba88042f9ea63a2c2a07dda5..be3e5cf80c4b718f608427c0a064a06ef393383a 100755 (executable)
@@ -24,6 +24,7 @@
 #include <linux/kthread.h>
 #include <linux/fb.h>
 #include <linux/init.h>
+#include <linux/vmalloc.h>
 #include <asm/div64.h>
 #include <linux/uaccess.h>
 #include <linux/rk_fb.h>
@@ -67,16 +68,9 @@ int (*video_data_to_mirroring) (struct fb_info *info, u32 yuv_phy[2]);
 EXPORT_SYMBOL(video_data_to_mirroring);
 #endif
 
-static uint32_t kernel_logo_addr;
-static int __init kernel_logo_setup(char *str)
-{
-       if(str) {
-               sscanf(str, "%x", &kernel_logo_addr);
-       }
-
-       return 0;
-}
-early_param("kernel_logo", kernel_logo_setup);
+extern phys_addr_t uboot_logo_base;
+extern phys_addr_t uboot_logo_size;
+extern phys_addr_t uboot_logo_offset;
 static struct rk_fb_trsm_ops *trsm_lvds_ops;
 static struct rk_fb_trsm_ops *trsm_edp_ops;
 static struct rk_fb_trsm_ops *trsm_mipi_ops;
@@ -847,8 +841,6 @@ static int get_extend_fb_id(struct fb_info *info)
                fb_id = 3;
        else if (!strcmp(id, "fb4") && (dev_drv->lcdc_win_num > 4))
                fb_id = 4;
-       else
-               dev_err(dev_drv->dev, "get_extend_fb_id info error\n");
        return fb_id;
 }
 
@@ -3582,9 +3574,6 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id)
                        dev_drv->ops->dsp_black(dev_drv, 1);
                if (dev_drv->ops->set_screen_scaler)
                        dev_drv->ops->set_screen_scaler(dev_drv, dev_drv->screen0, 0);
-       } else if ((rk_fb->disp_mode == NO_DUAL) && (enable)) {
-               if (dev_drv->ops->dsp_black)
-                       dev_drv->ops->dsp_black(dev_drv, 1);
        }
 
        if (!enable) {
@@ -3593,8 +3582,7 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id)
                        return 0;
 
                /* if used one lcdc to dual disp, no need to close win */
-               if ((rk_fb->disp_mode == ONE_DUAL) ||
-                   (rk_fb->disp_mode == NO_DUAL)) {
+               if (rk_fb->disp_mode == ONE_DUAL) {
                        dev_drv->cur_screen = dev_drv->screen0;
                        dev_drv->ops->load_screen(dev_drv, 1);
 
@@ -3656,8 +3644,7 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id)
                                        info->var.activate |= FB_ACTIVATE_FORCE;
                                        if (rk_fb->disp_mode == DUAL) {
                                                rk_fb_update_ext_info(info, pmy_info, 1);
-                                       } else if ((rk_fb->disp_mode == ONE_DUAL) ||
-                                                  (rk_fb->disp_mode == NO_DUAL)) {
+                                       } else if (rk_fb->disp_mode == ONE_DUAL) {
                                                info->var.grayscale &= 0xff;
                                                info->var.grayscale |=
                                                        (dev_drv->cur_screen->xsize << 8) +
@@ -4178,17 +4165,50 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv,
                rk_fb_alloc_buffer(main_fbi, 0);        /* only alloc memory for main fb */
                dev_drv->uboot_logo = support_uboot_display();
 
-               if (kernel_logo_addr) {
+               if (uboot_logo_offset && uboot_logo_base) {
                        struct rk_lcdc_win *win = dev_drv->win[0];
-                       char *addr = phys_to_virt(kernel_logo_addr);
                        int width, height, bits;
+                       phys_addr_t start = uboot_logo_base + uboot_logo_offset;
+                       unsigned int size = uboot_logo_size - uboot_logo_offset;
+                       unsigned int nr_pages;
+                       struct page **pages;
+                       char *vaddr;
+                       int i = 0;
+
+                       nr_pages = size >> PAGE_SHIFT;
+                       pages = kzalloc(sizeof(struct page) * nr_pages,
+                                       GFP_KERNEL);
+                       while (i < nr_pages) {
+                               pages[i] = phys_to_page(start);
+                               start += PAGE_SIZE;
+                               i++;
+                       }
+                       vaddr = vmap(pages, nr_pages, VM_MAP,
+                                       pgprot_writecombine(PAGE_KERNEL));
+                       if (!vaddr) {
+                               pr_err("failed to vmap phy addr %x\n",
+                                       uboot_logo_base + uboot_logo_offset);
+                               return -1;
+                       }
+
+                       if(bmpdecoder(vaddr, main_fbi->screen_base, &width,
+                                     &height, &bits)) {
+                               kfree(pages);
+                               vunmap(vaddr);
+                               return 0;
+                       }
+                       kfree(pages);
+                       vunmap(vaddr);
+                       if (width > main_fbi->var.xres ||
+                           height > main_fbi->var.yres) {
+                               pr_err("ERROR: logo size out of screen range");
+                               return 0;
+                       }
 
-                       bmpdecoder(addr, main_fbi->screen_base,
-                                  &width, &height, &bits);
                        win->area[0].format = rk_fb_data_fmt(0, bits);
                        win->area[0].y_vir_stride = width * bits >> 5;
                        win->area[0].xpos = (main_fbi->var.xres - width) >> 1;
-                       win->area[0].ypos = (main_fbi->var.yres - height) >> 1;;
+                       win->area[0].ypos = (main_fbi->var.yres - height) >> 1;
                        win->area[0].xsize = width;
                        win->area[0].ysize = height;
                        win->area[0].xact = width;
index cf51a1ce95c1b4d3bdcc4b95e8bf37deb4c01b78..282e25bdfbc05be21dd28eefc7e005c211def753 100644 (file)
@@ -58,6 +58,7 @@ void rockchip_restart_get_boot_mode(const char *cmd, u32 *flag, u32 *mode);
 void __init rockchip_efuse_init(void);
 void __init rockchip_suspend_init(void);
 void __init rockchip_ion_reserve(void);
+void __init rockchip_uboot_mem_reserve(void);
 
 enum rockchip_pm_policy {
        ROCKCHIP_PM_POLICY_PERFORMANCE = 0,
diff --git a/logo_kernel.bmp b/logo_kernel.bmp
new file mode 100644 (file)
index 0000000..2717218
Binary files /dev/null and b/logo_kernel.bmp differ