USB: RK3288 USB CTLR initialization
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / usbdev_rk30.c
index 183ff92250963f95a2956a0cb3e8e2dbde9055d0..864fec49293384654d6c4085c0a3406d969910ac 100755 (executable)
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include "usbdev_grf_regs.h"
 #include "usbdev_rk.h"
 #include "dwc_otg_regs.h"
 
 static struct dwc_otg_control_usb *control_usb;
 
-int usb_get_chip_id(void)
+static int usb_get_chip_id(void)
 {
        return control_usb->chip_id;
 }
 
-int dwc_otg_check_dpdm(void)
-{
-       int bus_status = 0;
-       return bus_status;
-}
-
-EXPORT_SYMBOL(dwc_otg_check_dpdm);
-
 #ifdef CONFIG_USB20_OTG
 
-void usb20otg_hw_init(void)
+static void usb20otg_hw_init(void)
 {
 #ifndef CONFIG_USB20_HOST
-       unsigned int * otg_phy_con1 = (control_usb->grf_uoc1_base + 0x8);
-       unsigned int * otg_phy_con2 = (control_usb->grf_uoc1_base + 0xc);
-       *otg_phy_con1 = (0x01<<2)|((0x01<<2)<<16);     //enable soft control
-       *otg_phy_con2 = 0x2A|(0x3F<<16);               // enter suspend
+       //enable soft control
+       control_usb->grf_uoc1_base->CON2 = (0x01<<2)|((0x01<<2)<<16);
+       // enter suspend
+       control_usb->grf_uoc1_base->CON3 = 0x2A|(0x3F<<16);
 #endif
        /* usb phy config init
         * usb phy enter usb mode */
-       unsigned int * otg_phy_con3 = (control_usb->grf_uoc0_base);
-       *otg_phy_con3 = (0x0300 << 16);
+       control_usb->grf_uoc0_base->CON0 = (0x0300 << 16);
 
        /* other haredware init,include:
         * DRV_VBUS GPIO init */
        gpio_direction_output(control_usb->otg_gpios->gpio, 0);
 }
 
-void usb20otg_phy_suspend(void* pdata, int suspend)
+static void usb20otg_phy_suspend(void* pdata, int suspend)
 {
        struct dwc_otg_platform_data *usbpdata=pdata;
-       unsigned int * otg_phy_con1 = (control_usb->grf_uoc0_base + 0x8);
-       unsigned int * otg_phy_con2 = (control_usb->grf_uoc0_base + 0xc);
 
        if(suspend){
-               *otg_phy_con1 = (0x01<<2)|((0x01<<2)<<16);      //enable soft control
-               *otg_phy_con2 = 0x2A|(0x3F<<16);                // enter suspend
+               //enable soft control
+               control_usb->grf_uoc0_base->CON2 = (0x01<<2)|((0x01<<2)<<16);
+               // enter suspend
+               control_usb->grf_uoc0_base->CON3 = 0x2A|(0x3F<<16);
                usbpdata->phy_status = 1;
        }else{
-               *otg_phy_con1 = ((0x01<<2)<<16);                // exit suspend.
+               // exit suspend.
+               control_usb->grf_uoc0_base->CON2 = ((0x01<<2)<<16);
                usbpdata->phy_status = 0;
        }
 }
 
-void usb20otg_soft_reset(void)
+static void usb20otg_soft_reset(void)
 {
 }
 
-void usb20otg_clock_init(void* pdata)
+static void usb20otg_clock_init(void* pdata)
 {
        struct dwc_otg_platform_data *usbpdata=pdata;
        struct clk* ahbclk,*phyclk;
@@ -94,7 +87,7 @@ void usb20otg_clock_init(void* pdata)
        usbpdata->ahbclk = ahbclk;
 }
 
-void usb20otg_clock_enable(void* pdata, int enable)
+static void usb20otg_clock_enable(void* pdata, int enable)
 {
        struct dwc_otg_platform_data *usbpdata=pdata;
 
@@ -107,23 +100,22 @@ void usb20otg_clock_enable(void* pdata, int enable)
        }
 }
 
-int usb20otg_get_status(int id)
+static int usb20otg_get_status(int id)
 {
        int ret = -1;
-       unsigned int usbgrf_status = *(unsigned int*)(control_usb->grf_soc_status0);
 
        switch(id){
                case USB_STATUS_BVABLID:
                        // bvalid in grf
-                       ret = (usbgrf_status &(1<<10));
+                       ret = control_usb->grf_soc_status0_rk3188->otg_bvalid;
                        break;
                case USB_STATUS_DPDM:
                        // dpdm in grf
-                       ret = (usbgrf_status &(3<<11));
+                       ret = control_usb->grf_soc_status0_rk3188->otg_linestate;
                        break;
                case USB_STATUS_ID:
                        // id in grf
-                       ret = (usbgrf_status &(1<<13));
+                       ret = control_usb->grf_soc_status0_rk3188->otg_iddig;
                        break;
                default:
                        break;
@@ -133,25 +125,24 @@ int usb20otg_get_status(int id)
 }
 
 #ifdef CONFIG_RK_USB_UART
-void dwc_otg_uart_mode(void* pdata, int enter_usb_uart_mode)
+static void dwc_otg_uart_mode(void* pdata, int enter_usb_uart_mode)
 {
-       unsigned int * otg_phy_con1 = (unsigned int*)(control_usb->grf_uoc0_base);
-
        if(1 == enter_usb_uart_mode){
                /* enter uart mode
                 * note: can't disable otg here! If otg disable, the ID change
                 * interrupt can't be triggered when otg cable connect without
                 * device.At the same time, uart can't be used normally
                 */
-               *otg_phy_con1 = (0x0300 | (0x0300 << 16));      //bypass dm
+               /* bypass dm, enter uart mode */
+               control_usb->grf_uoc0_base->CON0 = (0x0300 | (0x0300 << 16));
        }else if(0 == enter_usb_uart_mode){
                /* enter usb mode */
-               *otg_phy_con1 = (0x0300 << 16);                 //bypass dm disable
+               control_usb->grf_uoc0_base->CON0 = (0x0300 << 16);
        }
 }
 #endif
 
-void usb20otg_power_enable(int enable)
+static void usb20otg_power_enable(int enable)
 {
        if(0 == enable){//disable otg_drv power
                gpio_set_value(control_usb->otg_gpios->gpio, 0);
@@ -160,7 +151,7 @@ void usb20otg_power_enable(int enable)
        }
 }
 
-struct dwc_otg_platform_data usb20otg_pdata = {
+struct dwc_otg_platform_data usb20otg_pdata_rk3188 = {
        .phyclk = NULL,
        .ahbclk = NULL,
        .busclk = NULL,
@@ -181,7 +172,7 @@ struct dwc_otg_platform_data usb20otg_pdata = {
 #endif
 
 #ifdef CONFIG_USB20_HOST
-void usb20host_hw_init(void)
+static void usb20host_hw_init(void)
 {
        /* usb phy config init */
 
@@ -191,27 +182,28 @@ void usb20host_hw_init(void)
 
 }
 
-void usb20host_phy_suspend(void* pdata, int suspend)
+static void usb20host_phy_suspend(void* pdata, int suspend)
 {
        struct dwc_otg_platform_data *usbpdata=pdata;
-       unsigned int * otg_phy_con1 = (unsigned int*)(control_usb->grf_uoc1_base + 0x8);
-       unsigned int * otg_phy_con2 = (unsigned int*)(control_usb->grf_uoc1_base + 0xc);
 
        if(suspend){
-               *otg_phy_con1 =  (0x01<<2)|((0x01<<2)<<16);     // enable soft control
-               *otg_phy_con2 =  0x2A|(0x3F<<16);               // enter suspend
+               // enable soft control
+               control_usb->grf_uoc1_base->CON2 = (0x01<<2)|((0x01<<2)<<16);
+               // enter suspend
+               control_usb->grf_uoc1_base->CON3 = 0x2A|(0x3F<<16); 
                usbpdata->phy_status = 1;
        }else{
-               *otg_phy_con1 = ((0x01<<2)<<16);                // exit suspend.
+               //exit suspend.
+               control_usb->grf_uoc1_base->CON2 = ((0x01<<2)<<16);
                usbpdata->phy_status = 0;
        }
 }
 
-void usb20host_soft_reset(void)
+static void usb20host_soft_reset(void)
 {
 }
 
-void usb20host_clock_init(void* pdata)
+static void usb20host_clock_init(void* pdata)
 {
        struct dwc_otg_platform_data *usbpdata=pdata;
        struct clk* ahbclk,*phyclk;
@@ -232,7 +224,7 @@ void usb20host_clock_init(void* pdata)
        usbpdata->ahbclk = ahbclk;
 }
 
-void usb20host_clock_enable(void* pdata, int enable)
+static void usb20host_clock_enable(void* pdata, int enable)
 {
        struct dwc_otg_platform_data *usbpdata=pdata;
 
@@ -245,23 +237,22 @@ void usb20host_clock_enable(void* pdata, int enable)
        }
 }
 
-int usb20host_get_status(int id)
+static int usb20host_get_status(int id)
 {
        int ret = -1;
-       unsigned int usbgrf_status = *(unsigned int*)(control_usb->grf_soc_status0);
 
        switch(id){
                case USB_STATUS_BVABLID:
                        // bvalid in grf
-                       ret = (usbgrf_status &(1<<17));
+                       ret = control_usb->grf_soc_status0_rk3188->uhost_bvalid;
                        break;
                case USB_STATUS_DPDM:
                        // dpdm in grf
-                       ret = (usbgrf_status &(3<<18));
+                       ret = control_usb->grf_soc_status0_rk3188->uhost_linestate;
                        break;
                case USB_STATUS_ID:
                        // id in grf
-                       ret = (usbgrf_status &(1<<20));
+                       ret = control_usb->grf_soc_status0_rk3188->uhost_iddig;
                        break;
                default:
                        break;
@@ -270,7 +261,7 @@ int usb20host_get_status(int id)
        return ret;
 }
 
-void usb20host_power_enable(int enable)
+static void usb20host_power_enable(int enable)
 {
        if(0 == enable){//disable host_drv power
                //do not disable power in default
@@ -279,7 +270,7 @@ void usb20host_power_enable(int enable)
        }
 }
 
-struct dwc_otg_platform_data usb20host_pdata = {
+struct dwc_otg_platform_data usb20host_pdata_rk3188 = {
        .phyclk = NULL,
        .ahbclk = NULL,
        .busclk = NULL,
@@ -296,31 +287,26 @@ struct dwc_otg_platform_data usb20host_pdata = {
 #endif
 
 #ifdef CONFIG_USB_EHCI_RKHSIC
-void rk_hsic_hw_init(void)
+static void rk_hsic_hw_init(void)
 {
-       unsigned int * phy_con0 = (control_usb->grf_uoc0_base);
-       unsigned int * phy_con1 = (control_usb->grf_uoc1_base);
-       unsigned int * phy_con2 = (control_usb->grf_uoc2_base);
-       unsigned int * phy_con3 = (control_usb->grf_uoc3_base);
-
        // usb phy config init
        // hsic phy config init, set hsicphy_txsrtune
-       *phy_con2 = ((0xf<<6)<<16)|(0xf<<6);
+       control_usb->grf_uoc2_base->CON0 = ((0xf<<6)<<16)|(0xf<<6);
 
        /* other haredware init
         * set common_on, in suspend mode, otg/host PLL blocks remain powered
-        * for RK3168 set *phy_con0 = (1<<16)|0;
-        * for Rk3188 set *phy_con1 = (1<<16)|0;
+        * for RK3168 set control_usb->grf_uoc0_base->CON0 = (1<<16)|0;
+        * for Rk3188 set control_usb->grf_uoc1_base->CON0 = (1<<16)|0;
         */
-       *phy_con1 = (1<<16)|0;
+       control_usb->grf_uoc1_base->CON0 = (1<<16)|0;
 
        /* change INCR to INCR16 or INCR8(beats less than 16)
         * or INCR4(beats less than 8) or SINGLE(beats less than 4)
         */
-       *phy_con3 = 0x00ff00bc;
+       control_usb->grf_uoc3_base->CON0 = 0x00ff00bc;
 }
 
-void rk_hsic_clock_init(void* pdata)
+static void rk_hsic_clock_init(void* pdata)
 {
        /* By default, hsicphy_480m's parent is otg phy 480MHz clk
         * rk3188 must use host phy 480MHz clk, because if otg bypass
@@ -360,7 +346,7 @@ void rk_hsic_clock_init(void* pdata)
        usbpdata->hsic_phy_12m = phyclk12m_hsic;
 }
 
-void rk_hsic_clock_enable(void* pdata, int enable)
+static void rk_hsic_clock_enable(void* pdata, int enable)
 {
        struct rkehci_platform_data *usbpdata=pdata;
 
@@ -379,12 +365,12 @@ void rk_hsic_clock_enable(void* pdata, int enable)
        }
 }
 
-void rk_hsic_soft_reset(void)
+static void rk_hsic_soft_reset(void)
 {
 
 }
 
-struct rkehci_platform_data rkhsic_pdata = {
+struct rkehci_platform_data rkhsic_pdata_rk3188 = {
        .hclk_hsic = NULL,
        .hsic_phy_12m = NULL,
        .hsic_phy_480m = NULL,
@@ -409,13 +395,8 @@ inline static void do_wakeup(struct work_struct *work)
 /********** handler for bvalid irq **********/
 static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
 {
-       unsigned int * phy_con0;
-
        /* clear irq */
-       if( usb_get_chip_id() == RK3188_USB_CTLR){
-               phy_con0 = (control_usb->grf_uoc0_base + 0xc);
-               *phy_con0 = (1 << 31) | (1 << 15);
-       }
+       control_usb->grf_uoc0_base->CON3 = (1 << 31) | (1 << 15);
 
 #ifdef CONFIG_RK_USB_UART
        /* usb otg dp/dm switch to usb phy */
@@ -430,28 +411,11 @@ static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-/********** handler for otg id rise and fall edge **********/
-static irqreturn_t id_irq_handler(int irq, void *dev_id)
-{
-       /* clear irq */
-       if( usb_get_chip_id() == RK3288_USB_CTLR){
-
-       }
-
-#ifdef CONFIG_RK_USB_DETECT_BY_OTG_BVALID
-       wake_lock_timeout(&control_usb->usb_wakelock, WAKE_LOCK_TIMEOUT);
-       schedule_delayed_work(&control_usb->usb_det_wakeup_work, HZ/10);
-#endif
-
-       return IRQ_HANDLED;
-}
-
-/************* register bvalid and otg_id irq **************/
+/************* register bvalid irq **************/
 static int otg_irq_detect_init(struct platform_device *pdev)
 {
        int ret = 0;
        int irq = 0;
-       unsigned int * phy_con0;
 
 #ifdef CONFIG_RK_USB_DETECT_BY_OTG_BVALID
        wake_lock_init(&control_usb->usb_wakelock, WAKE_LOCK_SUSPEND, "usb_detect");
@@ -467,29 +431,7 @@ static int otg_irq_detect_init(struct platform_device *pdev)
                }
 
                /* clear & enable bvalid irq */
-               if( usb_get_chip_id() == RK3188_USB_CTLR){
-                       phy_con0 = (control_usb->grf_uoc0_base + 0xc);
-                       *phy_con0 = (3 << 30) | (3 << 14);
-               }
-
-#ifdef CONFIG_RK_USB_DETECT_BY_OTG_BVALID
-               enable_irq_wake(irq);
-#endif
-       }
-
-       irq = platform_get_irq_byname(pdev, "otg_id");
-       if (irq > 0) {
-               ret = request_irq(irq, id_irq_handler, 0, "otg_id", NULL);
-               if(ret < 0){
-                       dev_err(&pdev->dev, "request_irq %d failed!\n", irq);
-                       return ret;
-               }
-
-               /* clear & enable otg_id change irq */
-               /* for rk3026 & rk3288 enable and clear id_fall_irq & id_rise_irq*/
-               if( usb_get_chip_id() == RK3288_USB_CTLR){
-
-               }
+               control_usb->grf_uoc0_base->CON3 = (3 << 30) | (3 << 14);
 
 #ifdef CONFIG_RK_USB_DETECT_BY_OTG_BVALID
                enable_irq_wake(irq);
@@ -503,71 +445,65 @@ static int usb_grf_ioremap(struct platform_device *pdev)
 {
        int ret = 0;
        struct resource *res;
+       void *grf_soc_status0;
+       void *grf_uoc0_base;
+       void *grf_uoc1_base;
+       void *grf_uoc2_base;
+       void *grf_uoc3_base;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                                "GRF_SOC_STATUS0");
-       control_usb->grf_soc_status0 = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(control_usb->grf_soc_status0)){
-               ret = PTR_ERR(control_usb->grf_soc_status0);
+       grf_soc_status0 = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(grf_soc_status0)){
+               ret = PTR_ERR(grf_soc_status0);
                return ret;
        }
+       control_usb->grf_soc_status0_rk3188 = (pGRF_SOC_STATUS_RK3188)grf_soc_status0;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                                "GRF_UOC0_BASE");
-       control_usb->grf_uoc0_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(control_usb->grf_uoc0_base)){
-               ret = PTR_ERR(control_usb->grf_uoc0_base);
+       grf_uoc0_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(grf_uoc0_base)){
+               ret = PTR_ERR(grf_uoc0_base);
                return ret;
        }
+       control_usb->grf_uoc0_base = (pGRF_UOC0_REG)grf_uoc0_base;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                                "GRF_UOC1_BASE");
-       control_usb->grf_uoc1_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(control_usb->grf_uoc1_base)){
-               ret = PTR_ERR(control_usb->grf_uoc1_base);
+       grf_uoc1_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(grf_uoc1_base)){
+               ret = PTR_ERR(grf_uoc1_base);
                return ret;
        }
+       control_usb->grf_uoc1_base = (pGRF_UOC1_REG)grf_uoc1_base;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                                "GRF_UOC2_BASE");
-       control_usb->grf_uoc2_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(control_usb->grf_uoc2_base)){
-               ret = PTR_ERR(control_usb->grf_uoc2_base);
+       grf_uoc2_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(grf_uoc2_base)){
+               ret = PTR_ERR(grf_uoc2_base);
                return ret;
        }
+       control_usb->grf_uoc2_base = (pGRF_UOC2_REG)grf_uoc2_base;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                                "GRF_UOC3_BASE");
-       control_usb->grf_uoc3_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(control_usb->grf_uoc3_base)){
-               ret = PTR_ERR(control_usb->grf_uoc3_base);
+       grf_uoc3_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(grf_uoc3_base)){
+               ret = PTR_ERR(grf_uoc3_base);
                return ret;
        }
+       control_usb->grf_uoc3_base = (pGRF_UOC3_REG)grf_uoc3_base;
 
        return ret;
 }
 
 #ifdef CONFIG_OF
-static struct platform_device_id rk_usb_devtype[] = {
-       {
-               .name = "rk3188-usb",
-               .driver_data = RK3188_USB_CTLR,
-       },
-       {
-               .name = "rk3288-usb",
-               .driver_data = RK3288_USB_CTLR,
-       },
-       { },
-};
-MODULE_DEVICE_TABLE(platform, rk_usb_devtype);
 
 static const struct of_device_id dwc_otg_control_usb_id_table[] = {
-       {       .compatible = "rockchip,rk3188-dwc-control-usb",
-               .data = &rk_usb_devtype[RK3188_USB_CTLR],
-       },
        {
-               .compatible = "rockchip,rk3288-dwc-control-usb",
-               .data = &rk_usb_devtype[RK3288_USB_CTLR],
+               .compatible = "rockchip,rk3188-dwc-control-usb",
        },
        { },
 };
@@ -580,15 +516,6 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev)
        struct device_node *np = pdev->dev.of_node;
        struct clk* hclk_usb_peri;
        int ret = 0;
-       const struct of_device_id *match =
-               of_match_device(of_match_ptr(dwc_otg_control_usb_id_table), &pdev->dev);
-
-       if (match)
-               pdev->id_entry = match->data;
-       else{
-               ret = -EINVAL;
-               goto err1;
-       }
 
        control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),GFP_KERNEL);
        if (!control_usb) {
@@ -597,7 +524,7 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev)
                goto err1;
        }
 
-       control_usb->chip_id = pdev->id_entry->driver_data;
+       control_usb->chip_id = RK3188_USB_CTLR;
 
        hclk_usb_peri = devm_clk_get(&pdev->dev, "hclk_usb_peri");
        if (IS_ERR(hclk_usb_peri)) {
@@ -605,6 +532,7 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev)
                ret = -EINVAL;
                goto err1;
        }
+
        control_usb->hclk_usb_peri = hclk_usb_peri;
        clk_prepare_enable(hclk_usb_peri);
 
@@ -672,11 +600,10 @@ static struct platform_driver dwc_otg_control_usb_driver = {
        .probe          = dwc_otg_control_usb_probe,
        .remove         = dwc_otg_control_usb_remove,
        .driver         = {
-               .name   = "dwc-control-usb",
+               .name   = "rk3188-dwc-control-usb",
                .owner  = THIS_MODULE,
                .of_match_table = of_match_ptr(dwc_otg_control_usb_id_table),
        },
-       .id_table       = rk_usb_devtype,
 };
 
 static int __init dwc_otg_control_usb_init(void)