1/* 2 * powertv-usb.c 3 * 4 * Description: ASIC-specific USB device setup and shutdown 5 * 6 * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. 7 * Copyright (C) 2009 Cisco Systems, Inc. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 * Author: Ken Eppinett 24 * David Schleef <ds@schleef.org> 25 * 26 * NOTE: The bootloader allocates persistent memory at an address which is 27 * 16 MiB below the end of the highest address in KSEG0. All fixed 28 * address memory reservations must avoid this region. 29 */ 30 31#include <linux/kernel.h> 32#include <linux/ioport.h> 33#include <linux/platform_device.h> 34#include <asm/mach-powertv/asic.h> 35#include <asm/mach-powertv/interrupts.h> 36 37/* misc_clk_ctl1 values */ 38#define MCC1_30MHZ_POWERUP_SELECT (1 << 14) 39#define MCC1_DIV9 (1 << 13) 40#define MCC1_ETHMIPS_POWERUP_SELECT (1 << 11) 41#define MCC1_USB_POWERUP_SELECT (1 << 1) 42#define MCC1_CLOCK108_POWERUP_SELECT (1 << 0) 43 44/* Possible values for clock select */ 45#define MCC1_USB_CLOCK_HIGH_Z (0 << 4) 46#define MCC1_USB_CLOCK_48MHZ (1 << 4) 47#define MCC1_USB_CLOCK_24MHZ (2 << 4) 48#define MCC1_USB_CLOCK_6MHZ (3 << 4) 49 50#define MCC1_CONFIG (MCC1_30MHZ_POWERUP_SELECT | \ 51 MCC1_DIV9 | \ 52 MCC1_ETHMIPS_POWERUP_SELECT | \ 53 MCC1_USB_POWERUP_SELECT | \ 54 MCC1_CLOCK108_POWERUP_SELECT) 55 56/* misc_clk_ctl2 values */ 57#define MCC2_GMII_GCLK_TO_PAD (1 << 31) 58#define MCC2_ETHER125_0_CLOCK_SELECT (1 << 29) 59#define MCC2_RMII_0_CLOCK_SELECT (1 << 28) 60#define MCC2_GMII_TX0_CLOCK_SELECT (1 << 27) 61#define MCC2_GMII_RX0_CLOCK_SELECT (1 << 26) 62#define MCC2_ETHER125_1_CLOCK_SELECT (1 << 24) 63#define MCC2_RMII_1_CLOCK_SELECT (1 << 23) 64#define MCC2_GMII_TX1_CLOCK_SELECT (1 << 22) 65#define MCC2_GMII_RX1_CLOCK_SELECT (1 << 21) 66#define MCC2_ETHER125_2_CLOCK_SELECT (1 << 19) 67#define MCC2_RMII_2_CLOCK_SELECT (1 << 18) 68#define MCC2_GMII_TX2_CLOCK_SELECT (1 << 17) 69#define MCC2_GMII_RX2_CLOCK_SELECT (1 << 16) 70 71#define ETHER_CLK_CONFIG (MCC2_GMII_GCLK_TO_PAD | \ 72 MCC2_ETHER125_0_CLOCK_SELECT | \ 73 MCC2_RMII_0_CLOCK_SELECT | \ 74 MCC2_GMII_TX0_CLOCK_SELECT | \ 75 MCC2_GMII_RX0_CLOCK_SELECT | \ 76 MCC2_ETHER125_1_CLOCK_SELECT | \ 77 MCC2_RMII_1_CLOCK_SELECT | \ 78 MCC2_GMII_TX1_CLOCK_SELECT | \ 79 MCC2_GMII_RX1_CLOCK_SELECT | \ 80 MCC2_ETHER125_2_CLOCK_SELECT | \ 81 MCC2_RMII_2_CLOCK_SELECT | \ 82 MCC2_GMII_TX2_CLOCK_SELECT | \ 83 MCC2_GMII_RX2_CLOCK_SELECT) 84 85/* misc_clk_ctl2 definitions for Gaia */ 86#define FSX4A_REF_SELECT (1 << 16) 87#define FSX4B_REF_SELECT (1 << 17) 88#define FSX4C_REF_SELECT (1 << 18) 89#define DDR_PLL_REF_SELECT (1 << 19) 90#define MIPS_PLL_REF_SELECT (1 << 20) 91 92/* Definitions for the QAM frequency select register FS432X4A4_QAM_CTL */ 93#define QAM_FS_SDIV_SHIFT 29 94#define QAM_FS_MD_SHIFT 24 95#define QAM_FS_MD_MASK 0x1f /* Cut down to 5 bits */ 96#define QAM_FS_PE_SHIFT 8 97 98#define QAM_FS_DISABLE_DIVIDE_BY_3 (1 << 5) 99#define QAM_FS_ENABLE_PROGRAM (1 << 4) 100#define QAM_FS_ENABLE_OUTPUT (1 << 3) 101#define QAM_FS_SELECT_TEST_BYPASS (1 << 2) 102#define QAM_FS_DISABLE_DIGITAL_STANDBY (1 << 1) 103#define QAM_FS_CHOOSE_FS (1 << 0) 104 105/* Definitions for fs432x4a_ctl register */ 106#define QAM_FS_NSDIV_54MHZ (1 << 2) 107 108/* Definitions for bcm1_usb2_ctl register */ 109#define BCM1_USB2_CTL_BISTOK (1 << 11) 110#define BCM1_USB2_CTL_PORT2_SHIFT_JK (1 << 7) 111#define BCM1_USB2_CTL_PORT1_SHIFT_JK (1 << 6) 112#define BCM1_USB2_CTL_PORT2_FAST_EDGE (1 << 5) 113#define BCM1_USB2_CTL_PORT1_FAST_EDGE (1 << 4) 114#define BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH (1 << 1) 115#define BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH (1 << 0) 116 117/* Definitions for crt_spare register */ 118#define CRT_SPARE_PORT2_SHIFT_JK (1 << 21) 119#define CRT_SPARE_PORT1_SHIFT_JK (1 << 20) 120#define CRT_SPARE_PORT2_FAST_EDGE (1 << 19) 121#define CRT_SPARE_PORT1_FAST_EDGE (1 << 18) 122#define CRT_SPARE_DIVIDE_BY_9_FROM_432 (1 << 17) 123#define CRT_SPARE_USB_DIVIDE_BY_9 (1 << 16) 124 125/* Definitions for usb2_stbus_obc register */ 126#define USB_STBUS_OBC_STORE32_LOAD32 0x3 127 128/* Definitions for usb2_stbus_mess_size register */ 129#define USB2_STBUS_MESS_SIZE_2 0x1 /* 2 packets */ 130 131/* Definitions for usb2_stbus_chunk_size register */ 132#define USB2_STBUS_CHUNK_SIZE_2 0x1 /* 2 packets */ 133 134/* Definitions for usb2_strap register */ 135#define USB2_STRAP_HFREQ_SELECT 0x1 136 137/* 138 * USB Host Resource Definition 139 */ 140 141static struct resource ehci_resources[] = { 142 { 143 .parent = &asic_resource, 144 .start = 0, 145 .end = 0xff, 146 .flags = IORESOURCE_MEM, 147 }, 148 { 149 .start = irq_usbehci, 150 .end = irq_usbehci, 151 .flags = IORESOURCE_IRQ, 152 }, 153}; 154 155static u64 ehci_dmamask = 0xffffffffULL; 156 157static struct platform_device ehci_device = { 158 .name = "powertv-ehci", 159 .id = 0, 160 .num_resources = 2, 161 .resource = ehci_resources, 162 .dev = { 163 .dma_mask = &ehci_dmamask, 164 .coherent_dma_mask = 0xffffffff, 165 }, 166}; 167 168static struct resource ohci_resources[] = { 169 { 170 .parent = &asic_resource, 171 .start = 0, 172 .end = 0xff, 173 .flags = IORESOURCE_MEM, 174 }, 175 { 176 .start = irq_usbohci, 177 .end = irq_usbohci, 178 .flags = IORESOURCE_IRQ, 179 }, 180}; 181 182static u64 ohci_dmamask = 0xffffffffULL; 183 184static struct platform_device ohci_device = { 185 .name = "powertv-ohci", 186 .id = 0, 187 .num_resources = 2, 188 .resource = ohci_resources, 189 .dev = { 190 .dma_mask = &ohci_dmamask, 191 .coherent_dma_mask = 0xffffffff, 192 }, 193}; 194 195static unsigned usb_users; 196static DEFINE_SPINLOCK(usb_regs_lock); 197 198/* 199 * 200 * fs_update - set frequency synthesizer for USB 201 * @pe_bits Phase tap setting 202 * @md_bits Coarse selector bus for algorithm of phase tap 203 * @sdiv_bits Output divider setting 204 * @disable_div_by_3 Either QAM_FS_DISABLE_DIVIDE_BY_3 or zero 205 * @standby Either QAM_FS_DISABLE_DIGITAL_STANDBY or zero 206 * 207 * QAM frequency selection code, which affects the frequency at which USB 208 * runs. The frequency is calculated as: 209 * 2^15 * ndiv * Fin 210 * Fout = ------------------------------------------------------------ 211 * (sdiv * (ipe * (1 + md/32) - (ipe - 2^15)*(1 + (md + 1)/32))) 212 * where: 213 * Fin 54 MHz 214 * ndiv QAM_FS_NSDIV_54MHZ ? 8 : 16 215 * sdiv 1 << (sdiv_bits + 1) 216 * ipe Same as pe_bits 217 * md A five-bit, two's-complement integer (range [-16, 15]), which 218 * is the lower 5 bits of md_bits. 219 */ 220static void fs_update(u32 pe_bits, int md_bits, u32 sdiv_bits, 221 u32 disable_div_by_3, u32 standby) 222{ 223 u32 val; 224 225 val = ((sdiv_bits << QAM_FS_SDIV_SHIFT) | 226 ((md_bits & QAM_FS_MD_MASK) << QAM_FS_MD_SHIFT) | 227 (pe_bits << QAM_FS_PE_SHIFT) | 228 QAM_FS_ENABLE_OUTPUT | 229 standby | 230 disable_div_by_3); 231 asic_write(val, fs432x4b4_usb_ctl); 232 asic_write(val | QAM_FS_ENABLE_PROGRAM, fs432x4b4_usb_ctl); 233 asic_write(val | QAM_FS_ENABLE_PROGRAM | QAM_FS_CHOOSE_FS, 234 fs432x4b4_usb_ctl); 235} 236 237/* 238 * usb_eye_configure - for optimizing the shape USB eye waveform 239 * @set: Bits to set in the register 240 * @clear: Bits to clear in the register; each bit with a one will 241 * be set in the register, zero bits will not be modified 242 */ 243static void usb_eye_configure(u32 set, u32 clear) 244{ 245 u32 old; 246 247 old = asic_read(crt_spare); 248 old |= set; 249 old &= ~clear; 250 asic_write(old, crt_spare); 251} 252 253/* 254 * platform_configure_usb - usb configuration based on platform type. 255 */ 256static void platform_configure_usb(void) 257{ 258 u32 bcm1_usb2_ctl_value; 259 enum asic_type asic_type; 260 unsigned long flags; 261 262 spin_lock_irqsave(&usb_regs_lock, flags); 263 usb_users++; 264 265 if (usb_users != 1) { 266 spin_unlock_irqrestore(&usb_regs_lock, flags); 267 return; 268 } 269 270 asic_type = platform_get_asic(); 271 272 switch (asic_type) { 273 case ASIC_ZEUS: 274 fs_update(0x0000, -15, 0x02, 0, 0); 275 bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | 276 BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; 277 break; 278 279 case ASIC_CRONUS: 280 case ASIC_CRONUSLITE: 281 usb_eye_configure(0, CRT_SPARE_USB_DIVIDE_BY_9); 282 fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3, 283 QAM_FS_DISABLE_DIGITAL_STANDBY); 284 bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | 285 BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; 286 break; 287 288 case ASIC_CALLIOPE: 289 fs_update(0x0000, -15, 0x02, QAM_FS_DISABLE_DIVIDE_BY_3, 290 QAM_FS_DISABLE_DIGITAL_STANDBY); 291 292 switch (platform_get_family()) { 293 case FAMILY_1500VZE: 294 break; 295 296 case FAMILY_1500VZF: 297 usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK | 298 CRT_SPARE_PORT1_SHIFT_JK | 299 CRT_SPARE_PORT2_FAST_EDGE | 300 CRT_SPARE_PORT1_FAST_EDGE, 0); 301 break; 302 303 default: 304 usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK | 305 CRT_SPARE_PORT1_SHIFT_JK, 0); 306 break; 307 } 308 309 bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK | 310 BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | 311 BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; 312 break; 313 314 case ASIC_GAIA: 315 fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3, 316 QAM_FS_DISABLE_DIGITAL_STANDBY); 317 bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK | 318 BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | 319 BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; 320 break; 321 322 default: 323 pr_err("Unknown ASIC type: %d\n", asic_type); 324 bcm1_usb2_ctl_value = 0; 325 break; 326 } 327 328 /* turn on USB power */ 329 asic_write(0, usb2_strap); 330 /* Enable all OHCI interrupts */ 331 asic_write(bcm1_usb2_ctl_value, usb2_control); 332 /* usb2_stbus_obc store32/load32 */ 333 asic_write(USB_STBUS_OBC_STORE32_LOAD32, usb2_stbus_obc); 334 /* usb2_stbus_mess_size 2 packets */ 335 asic_write(USB2_STBUS_MESS_SIZE_2, usb2_stbus_mess_size); 336 /* usb2_stbus_chunk_size 2 packets */ 337 asic_write(USB2_STBUS_CHUNK_SIZE_2, usb2_stbus_chunk_size); 338 spin_unlock_irqrestore(&usb_regs_lock, flags); 339} 340 341static void platform_unconfigure_usb(void) 342{ 343 unsigned long flags; 344 345 spin_lock_irqsave(&usb_regs_lock, flags); 346 usb_users--; 347 if (usb_users == 0) 348 asic_write(USB2_STRAP_HFREQ_SELECT, usb2_strap); 349 spin_unlock_irqrestore(&usb_regs_lock, flags); 350} 351 352/* 353 * Set up the USB EHCI interface 354 */ 355void platform_configure_usb_ehci() 356{ 357 platform_configure_usb(); 358} 359EXPORT_SYMBOL(platform_configure_usb_ehci); 360 361/* 362 * Set up the USB OHCI interface 363 */ 364void platform_configure_usb_ohci() 365{ 366 platform_configure_usb(); 367} 368EXPORT_SYMBOL(platform_configure_usb_ohci); 369 370/* 371 * Shut the USB EHCI interface down 372 */ 373void platform_unconfigure_usb_ehci() 374{ 375 platform_unconfigure_usb(); 376} 377EXPORT_SYMBOL(platform_unconfigure_usb_ehci); 378 379/* 380 * Shut the USB OHCI interface down 381 */ 382void platform_unconfigure_usb_ohci() 383{ 384 platform_unconfigure_usb(); 385} 386EXPORT_SYMBOL(platform_unconfigure_usb_ohci); 387 388/** 389 * platform_devices_init - sets up USB device resourse. 390 */ 391int __init platform_usb_devices_init(struct platform_device **ehci_dev, 392 struct platform_device **ohci_dev) 393{ 394 *ehci_dev = &ehci_device; 395 ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase); 396 ehci_resources[0].end += ehci_resources[0].start; 397 398 *ohci_dev = &ohci_device; 399 ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision); 400 ohci_resources[0].end += ohci_resources[0].start; 401 402 return 0; 403} 404