X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=blobdiff_plain;f=drivers%2Fusb%2Fdwc_otg_310%2Fusbdev_rk3368.c;h=3272e4e99c5fcdd604c1c7f9be0d9e40f1cef616;hp=c7521a9cf9c65d3dc87949f914a900aa0a16f1ea;hb=9a47b6de548a83d198e2a92b53fe735c62832515;hpb=03b9f4949fd4c2f8813b1e8ab4546c5ff54edac5 diff --git a/drivers/usb/dwc_otg_310/usbdev_rk3368.c b/drivers/usb/dwc_otg_310/usbdev_rk3368.c index c7521a9cf9c6..3272e4e99c5f 100644 --- a/drivers/usb/dwc_otg_310/usbdev_rk3368.c +++ b/drivers/usb/dwc_otg_310/usbdev_rk3368.c @@ -1,3 +1,4 @@ +#ifdef CONFIG_ARM64 #include "usbdev_rk.h" #include "dwc_otg_regs.h" @@ -22,6 +23,9 @@ static void usb20otg_hw_init(void) /* Turn off differential receiver in suspend mode */ uoc_write(UOC_HIWORD_UPDATE(0, 1, 2), 0x798); + /* Set disconnect detection trigger point to 625mv */ + uoc_write(UOC_HIWORD_UPDATE(0x9, 0xf, 11), 0x79c); + /* other haredware init,include: * DRV_VBUS GPIO init */ if (gpio_is_valid(control_usb->otg_gpios->gpio)) @@ -31,10 +35,9 @@ static void usb20otg_hw_init(void) static void usb20otg_phy_suspend(void *pdata, int suspend) { struct dwc_otg_platform_data *usbpdata = pdata; - if (suspend) { /* enable soft control */ - uoc_write(UOC_HIWORD_UPDATE(0x55, 0x7f, 0), 0x700); + uoc_write(UOC_HIWORD_UPDATE(0x1d5, 0x1ff, 0), 0x700); usbpdata->phy_status = 1; } else { /* exit suspend */ @@ -76,7 +79,16 @@ static void usb20otg_soft_reset(void *pdata, enum rkusb_rst_flag rst_type) reset_control_deassert(rst_otg_c); reset_control_deassert(rst_otg_h); break; - + case RST_CHN_HALT: + /* PHY reset */ + uoc_write(UOC_HIWORD_UPDATE(0x1, 0x3, 0), 0x700); + reset_control_assert(rst_otg_p); + udelay(15); + uoc_write(UOC_HIWORD_UPDATE(0x2, 0x3, 0), 0x700); + udelay(1500); + reset_control_deassert(rst_otg_p); + udelay(2); + break; default: break; } @@ -87,15 +99,15 @@ static void usb20otg_clock_init(void *pdata) struct dwc_otg_platform_data *usbpdata = pdata; struct clk *ahbclk, *phyclk; - ahbclk = devm_clk_get(usbpdata->dev, "hclk_otg"); + ahbclk = devm_clk_get(usbpdata->dev, "otg"); if (IS_ERR(ahbclk)) { - dev_err(usbpdata->dev, "Failed to get hclk_usb0\n"); + dev_err(usbpdata->dev, "Failed to get otg clk\n"); return; } - phyclk = devm_clk_get(usbpdata->dev, "clk_usbphy0"); + phyclk = devm_clk_get(usbpdata->dev, "sclk_otgphy0"); if (IS_ERR(phyclk)) { - dev_err(usbpdata->dev, "Failed to get clk_usbphy0\n"); + dev_err(usbpdata->dev, "Failed to get sclk_otgphy0\n"); return; } @@ -119,7 +131,7 @@ static void usb20otg_clock_enable(void *pdata, int enable) static int usb20otg_get_status(int id) { int ret = -1; - u32 soc_status15 = uoc_read(0x4bc); + u32 soc_status15 = uoc_read(control_usb->grf_otg_st_offset); switch (id) { case USB_STATUS_BVABLID: @@ -177,10 +189,15 @@ static void usb20otg_power_enable(int enable) /* disable otg_drv power */ if (gpio_is_valid(control_usb->otg_gpios->gpio)) gpio_set_value(control_usb->otg_gpios->gpio, 0); + + rk_battery_charger_detect_cb(USB_OTG_POWER_OFF); } else if (1 == enable) { /* enable otg_drv power */ if (gpio_is_valid(control_usb->otg_gpios->gpio)) gpio_set_value(control_usb->otg_gpios->gpio, 1); + + if (!usb20otg_get_status(USB_STATUS_BVABLID)) + rk_battery_charger_detect_cb(USB_OTG_POWER_ON); } } @@ -206,8 +223,8 @@ static void usb20ehci_hw_init(void) { /* Turn off differential receiver in suspend mode */ uoc_write(UOC_HIWORD_UPDATE(0, 1, 2), 0x7b8); - /* Set disconnect detection trigger point to 600mv */ - uoc_write(UOC_HIWORD_UPDATE(1, 0xf, 11), 0x7bc); + /* Set disconnect detection trigger point to 625mv */ + uoc_write(UOC_HIWORD_UPDATE(0x9, 0xf, 11), 0x7bc); /* other haredware init,include: * DRV_VBUS GPIO init */ @@ -388,6 +405,7 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev) struct clk *hclk_usb_peri; struct regmap *grf; int gpio, ret = 0; + u32 offset; control_usb = devm_kzalloc(dev, sizeof(*control_usb), GFP_KERNEL); if (!control_usb) { @@ -403,6 +421,14 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev) } control_usb->grf = grf; + /* get the reg offset of GRF_SOC_STATUS for USB2.0 OTG */ + if (of_property_read_u32(np, "grf-offset", &offset)) { + dev_err(&pdev->dev, "missing reg property in node %s\n", + np->name); + return -EINVAL; + } + control_usb->grf_otg_st_offset = offset; + /* Init Vbus-drv GPIOs */ control_usb->host_gpios = devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL); @@ -452,8 +478,8 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev) /* Init hclk_usb_peri */ hclk_usb_peri = devm_clk_get(&pdev->dev, "hclk_usb_peri"); if (IS_ERR(hclk_usb_peri)) { - dev_err(&pdev->dev, "Failed to get hclk_usb_peri\n"); - return PTR_ERR(hclk_usb_peri); + dev_info(&pdev->dev, "no hclk_usb_peri clk specified\n"); + hclk_usb_peri = NULL; } control_usb->hclk_usb_peri = hclk_usb_peri; clk_prepare_enable(hclk_usb_peri); @@ -514,3 +540,4 @@ MODULE_ALIAS("platform: dwc_control_usb"); MODULE_AUTHOR("RockChip Inc."); MODULE_DESCRIPTION("RockChip Control Module USB Driver"); MODULE_LICENSE("GPL v2"); +#endif