0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/delay.h>
0009 #include <linux/io.h>
0010 #include "common.h"
0011 #include "rcar3.h"
0012
0013 #define LPSTS 0x102
0014 #define UGCTRL 0x180
0015 #define UGCTRL2 0x184
0016 #define UGSTS 0x188
0017
0018
0019 #define LPSTS_SUSPM 0x4000
0020
0021
0022 #define UGCTRL_PLLRESET 0x00000001
0023 #define UGCTRL_CONNECT 0x00000004
0024
0025
0026
0027
0028
0029 #define UGCTRL2_RESERVED_3 0x00000001
0030 #define UGCTRL2_USB0SEL_HSUSB 0x00000020
0031 #define UGCTRL2_USB0SEL_OTG 0x00000030
0032 #define UGCTRL2_VBUSSEL 0x00000400
0033
0034
0035 #define UGSTS_LOCK 0x00000100
0036
0037 static void usbhs_write32(struct usbhs_priv *priv, u32 reg, u32 data)
0038 {
0039 iowrite32(data, priv->base + reg);
0040 }
0041
0042 static u32 usbhs_read32(struct usbhs_priv *priv, u32 reg)
0043 {
0044 return ioread32(priv->base + reg);
0045 }
0046
0047 static void usbhs_rcar3_set_ugctrl2(struct usbhs_priv *priv, u32 val)
0048 {
0049 usbhs_write32(priv, UGCTRL2, val | UGCTRL2_RESERVED_3);
0050 }
0051
0052 static int usbhs_rcar3_power_ctrl(struct platform_device *pdev,
0053 void __iomem *base, int enable)
0054 {
0055 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
0056
0057 usbhs_rcar3_set_ugctrl2(priv, UGCTRL2_USB0SEL_OTG | UGCTRL2_VBUSSEL);
0058
0059 if (enable) {
0060 usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
0061
0062 usleep_range(45, 90);
0063 } else {
0064 usbhs_bset(priv, LPSTS, LPSTS_SUSPM, 0);
0065 }
0066
0067 return 0;
0068 }
0069
0070
0071 static int usbhs_rcar3_power_and_pll_ctrl(struct platform_device *pdev,
0072 void __iomem *base, int enable)
0073 {
0074 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
0075 u32 val;
0076 int timeout = 1000;
0077
0078 if (enable) {
0079 usbhs_write32(priv, UGCTRL, 0);
0080 usbhs_rcar3_set_ugctrl2(priv,
0081 UGCTRL2_USB0SEL_OTG | UGCTRL2_VBUSSEL);
0082
0083 usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
0084 do {
0085 val = usbhs_read32(priv, UGSTS);
0086 udelay(1);
0087 } while (!(val & UGSTS_LOCK) && timeout--);
0088 usbhs_write32(priv, UGCTRL, UGCTRL_CONNECT);
0089 } else {
0090 usbhs_write32(priv, UGCTRL, 0);
0091 usbhs_bset(priv, LPSTS, LPSTS_SUSPM, 0);
0092 usbhs_write32(priv, UGCTRL, UGCTRL_PLLRESET);
0093 }
0094
0095 return 0;
0096 }
0097
0098 const struct renesas_usbhs_platform_info usbhs_rcar_gen3_plat_info = {
0099 .platform_callback = {
0100 .power_ctrl = usbhs_rcar3_power_ctrl,
0101 .get_id = usbhs_get_id_as_gadget,
0102 },
0103 .driver_param = {
0104 .has_usb_dmac = 1,
0105 .multi_clks = 1,
0106 .has_new_pipe_configs = 1,
0107 },
0108 };
0109
0110 const struct renesas_usbhs_platform_info usbhs_rcar_gen3_with_pll_plat_info = {
0111 .platform_callback = {
0112 .power_ctrl = usbhs_rcar3_power_and_pll_ctrl,
0113 .get_id = usbhs_get_id_as_gadget,
0114 },
0115 .driver_param = {
0116 .has_usb_dmac = 1,
0117 .multi_clks = 1,
0118 .has_new_pipe_configs = 1,
0119 },
0120 };