1/* 2 * linux/arch/arm/mach-mmp/devices.c 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9#include <linux/init.h> 10#include <linux/platform_device.h> 11#include <linux/dma-mapping.h> 12#include <linux/delay.h> 13 14#include <asm/irq.h> 15#include <mach/irqs.h> 16#include <mach/devices.h> 17#include <mach/cputype.h> 18#include <mach/regs-usb.h> 19 20int __init pxa_register_device(struct pxa_device_desc *desc, 21 void *data, size_t size) 22{ 23 struct platform_device *pdev; 24 struct resource res[2 + MAX_RESOURCE_DMA]; 25 int i, ret = 0, nres = 0; 26 27 pdev = platform_device_alloc(desc->drv_name, desc->id); 28 if (pdev == NULL) 29 return -ENOMEM; 30 31 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 32 33 memset(res, 0, sizeof(res)); 34 35 if (desc->start != -1ul && desc->size > 0) { 36 res[nres].start = desc->start; 37 res[nres].end = desc->start + desc->size - 1; 38 res[nres].flags = IORESOURCE_MEM; 39 nres++; 40 } 41 42 if (desc->irq != NO_IRQ) { 43 res[nres].start = desc->irq; 44 res[nres].end = desc->irq; 45 res[nres].flags = IORESOURCE_IRQ; 46 nres++; 47 } 48 49 for (i = 0; i < MAX_RESOURCE_DMA; i++, nres++) { 50 if (desc->dma[i] == 0) 51 break; 52 53 res[nres].start = desc->dma[i]; 54 res[nres].end = desc->dma[i]; 55 res[nres].flags = IORESOURCE_DMA; 56 } 57 58 ret = platform_device_add_resources(pdev, res, nres); 59 if (ret) { 60 platform_device_put(pdev); 61 return ret; 62 } 63 64 if (data && size) { 65 ret = platform_device_add_data(pdev, data, size); 66 if (ret) { 67 platform_device_put(pdev); 68 return ret; 69 } 70 } 71 72 return platform_device_add(pdev); 73} 74 75#if IS_ENABLED(CONFIG_USB) || IS_ENABLED(CONFIG_USB_GADGET) 76 77/***************************************************************************** 78 * The registers read/write routines 79 *****************************************************************************/ 80 81static unsigned int u2o_get(void __iomem *base, unsigned int offset) 82{ 83 return readl_relaxed(base + offset); 84} 85 86static void u2o_set(void __iomem *base, unsigned int offset, 87 unsigned int value) 88{ 89 u32 reg; 90 91 reg = readl_relaxed(base + offset); 92 reg |= value; 93 writel_relaxed(reg, base + offset); 94 readl_relaxed(base + offset); 95} 96 97static void u2o_clear(void __iomem *base, unsigned int offset, 98 unsigned int value) 99{ 100 u32 reg; 101 102 reg = readl_relaxed(base + offset); 103 reg &= ~value; 104 writel_relaxed(reg, base + offset); 105 readl_relaxed(base + offset); 106} 107 108static void u2o_write(void __iomem *base, unsigned int offset, 109 unsigned int value) 110{ 111 writel_relaxed(value, base + offset); 112 readl_relaxed(base + offset); 113} 114 115#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV) 116 117#if IS_ENABLED(CONFIG_CPU_PXA910) || IS_ENABLED(CONFIG_CPU_PXA168) 118 119static DEFINE_MUTEX(phy_lock); 120static int phy_init_cnt; 121 122static int usb_phy_init_internal(void __iomem *base) 123{ 124 int loops; 125 126 pr_info("Init usb phy!!!\n"); 127 128 /* Initialize the USB PHY power */ 129 if (cpu_is_pxa910()) { 130 u2o_set(base, UTMI_CTRL, (1<<UTMI_CTRL_INPKT_DELAY_SOF_SHIFT) 131 | (1<<UTMI_CTRL_PU_REF_SHIFT)); 132 } 133 134 u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT); 135 u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT); 136 137 /* UTMI_PLL settings */ 138 u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK 139 | UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK 140 | UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK 141 | UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK); 142 143 u2o_set(base, UTMI_PLL, 0xee<<UTMI_PLL_FBDIV_SHIFT 144 | 0xb<<UTMI_PLL_REFDIV_SHIFT | 3<<UTMI_PLL_PLLVDD18_SHIFT 145 | 3<<UTMI_PLL_PLLVDD12_SHIFT | 3<<UTMI_PLL_PLLCALI12_SHIFT 146 | 1<<UTMI_PLL_ICP_SHIFT | 3<<UTMI_PLL_KVCO_SHIFT); 147 148 /* UTMI_TX */ 149 u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK 150 | UTMI_TX_TXVDD12_MASK | UTMI_TX_CK60_PHSEL_MASK 151 | UTMI_TX_IMPCAL_VTH_MASK | UTMI_TX_REG_EXT_FS_RCAL_MASK 152 | UTMI_TX_AMP_MASK); 153 u2o_set(base, UTMI_TX, 3<<UTMI_TX_TXVDD12_SHIFT 154 | 4<<UTMI_TX_CK60_PHSEL_SHIFT | 4<<UTMI_TX_IMPCAL_VTH_SHIFT 155 | 8<<UTMI_TX_REG_EXT_FS_RCAL_SHIFT | 3<<UTMI_TX_AMP_SHIFT); 156 157 /* UTMI_RX */ 158 u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK 159 | UTMI_REG_SQ_LENGTH_MASK); 160 u2o_set(base, UTMI_RX, 7<<UTMI_RX_SQ_THRESH_SHIFT 161 | 2<<UTMI_REG_SQ_LENGTH_SHIFT); 162 163 /* UTMI_IVREF */ 164 if (cpu_is_pxa168()) 165 /* fixing Microsoft Altair board interface with NEC hub issue - 166 * Set UTMI_IVREF from 0x4a3 to 0x4bf */ 167 u2o_write(base, UTMI_IVREF, 0x4bf); 168 169 /* toggle VCOCAL_START bit of UTMI_PLL */ 170 udelay(200); 171 u2o_set(base, UTMI_PLL, VCOCAL_START); 172 udelay(40); 173 u2o_clear(base, UTMI_PLL, VCOCAL_START); 174 175 /* toggle REG_RCAL_START bit of UTMI_TX */ 176 udelay(400); 177 u2o_set(base, UTMI_TX, REG_RCAL_START); 178 udelay(40); 179 u2o_clear(base, UTMI_TX, REG_RCAL_START); 180 udelay(400); 181 182 /* Make sure PHY PLL is ready */ 183 loops = 0; 184 while ((u2o_get(base, UTMI_PLL) & PLL_READY) == 0) { 185 mdelay(1); 186 loops++; 187 if (loops > 100) { 188 printk(KERN_WARNING "calibrate timeout, UTMI_PLL %x\n", 189 u2o_get(base, UTMI_PLL)); 190 break; 191 } 192 } 193 194 if (cpu_is_pxa168()) { 195 u2o_set(base, UTMI_RESERVE, 1 << 5); 196 /* Turn on UTMI PHY OTG extension */ 197 u2o_write(base, UTMI_OTG_ADDON, 1); 198 } 199 200 return 0; 201} 202 203static int usb_phy_deinit_internal(void __iomem *base) 204{ 205 pr_info("Deinit usb phy!!!\n"); 206 207 if (cpu_is_pxa168()) 208 u2o_clear(base, UTMI_OTG_ADDON, UTMI_OTG_ADDON_OTG_ON); 209 210 u2o_clear(base, UTMI_CTRL, UTMI_CTRL_RXBUF_PDWN); 211 u2o_clear(base, UTMI_CTRL, UTMI_CTRL_TXBUF_PDWN); 212 u2o_clear(base, UTMI_CTRL, UTMI_CTRL_USB_CLK_EN); 213 u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT); 214 u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT); 215 216 return 0; 217} 218 219int pxa_usb_phy_init(void __iomem *phy_reg) 220{ 221 mutex_lock(&phy_lock); 222 if (phy_init_cnt++ == 0) 223 usb_phy_init_internal(phy_reg); 224 mutex_unlock(&phy_lock); 225 return 0; 226} 227 228void pxa_usb_phy_deinit(void __iomem *phy_reg) 229{ 230 WARN_ON(phy_init_cnt == 0); 231 232 mutex_lock(&phy_lock); 233 if (--phy_init_cnt == 0) 234 usb_phy_deinit_internal(phy_reg); 235 mutex_unlock(&phy_lock); 236} 237#endif 238#endif 239#endif 240 241#if IS_ENABLED(CONFIG_USB_SUPPORT) 242static u64 usb_dma_mask = ~(u32)0; 243 244#if IS_ENABLED(CONFIG_USB_MV_UDC) 245struct resource pxa168_u2o_resources[] = { 246 /* regbase */ 247 [0] = { 248 .start = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET, 249 .end = PXA168_U2O_REGBASE + USB_REG_RANGE, 250 .flags = IORESOURCE_MEM, 251 .name = "capregs", 252 }, 253 /* phybase */ 254 [1] = { 255 .start = PXA168_U2O_PHYBASE, 256 .end = PXA168_U2O_PHYBASE + USB_PHY_RANGE, 257 .flags = IORESOURCE_MEM, 258 .name = "phyregs", 259 }, 260 [2] = { 261 .start = IRQ_PXA168_USB1, 262 .end = IRQ_PXA168_USB1, 263 .flags = IORESOURCE_IRQ, 264 }, 265}; 266 267struct platform_device pxa168_device_u2o = { 268 .name = "mv-udc", 269 .id = -1, 270 .resource = pxa168_u2o_resources, 271 .num_resources = ARRAY_SIZE(pxa168_u2o_resources), 272 .dev = { 273 .dma_mask = &usb_dma_mask, 274 .coherent_dma_mask = 0xffffffff, 275 } 276}; 277#endif /* CONFIG_USB_MV_UDC */ 278 279#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O) 280struct resource pxa168_u2oehci_resources[] = { 281 /* regbase */ 282 [0] = { 283 .start = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET, 284 .end = PXA168_U2O_REGBASE + USB_REG_RANGE, 285 .flags = IORESOURCE_MEM, 286 .name = "capregs", 287 }, 288 /* phybase */ 289 [1] = { 290 .start = PXA168_U2O_PHYBASE, 291 .end = PXA168_U2O_PHYBASE + USB_PHY_RANGE, 292 .flags = IORESOURCE_MEM, 293 .name = "phyregs", 294 }, 295 [2] = { 296 .start = IRQ_PXA168_USB1, 297 .end = IRQ_PXA168_USB1, 298 .flags = IORESOURCE_IRQ, 299 }, 300}; 301 302struct platform_device pxa168_device_u2oehci = { 303 .name = "pxa-u2oehci", 304 .id = -1, 305 .dev = { 306 .dma_mask = &usb_dma_mask, 307 .coherent_dma_mask = 0xffffffff, 308 }, 309 310 .num_resources = ARRAY_SIZE(pxa168_u2oehci_resources), 311 .resource = pxa168_u2oehci_resources, 312}; 313#endif 314 315#if IS_ENABLED(CONFIG_USB_MV_OTG) 316struct resource pxa168_u2ootg_resources[] = { 317 /* regbase */ 318 [0] = { 319 .start = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET, 320 .end = PXA168_U2O_REGBASE + USB_REG_RANGE, 321 .flags = IORESOURCE_MEM, 322 .name = "capregs", 323 }, 324 /* phybase */ 325 [1] = { 326 .start = PXA168_U2O_PHYBASE, 327 .end = PXA168_U2O_PHYBASE + USB_PHY_RANGE, 328 .flags = IORESOURCE_MEM, 329 .name = "phyregs", 330 }, 331 [2] = { 332 .start = IRQ_PXA168_USB1, 333 .end = IRQ_PXA168_USB1, 334 .flags = IORESOURCE_IRQ, 335 }, 336}; 337 338struct platform_device pxa168_device_u2ootg = { 339 .name = "mv-otg", 340 .id = -1, 341 .dev = { 342 .dma_mask = &usb_dma_mask, 343 .coherent_dma_mask = 0xffffffff, 344 }, 345 346 .num_resources = ARRAY_SIZE(pxa168_u2ootg_resources), 347 .resource = pxa168_u2ootg_resources, 348}; 349#endif /* CONFIG_USB_MV_OTG */ 350 351#endif 352