Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: r8a66597-hcd: Add support for SH7366 USB host

R8A66597 is similar to SH7366 USB 2.0 Host/Function module. It can
support SH7366 USB host by changing several R8A66597 code.

Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Yoshihiro Shimoda and committed by
Greg Kroah-Hartman
9424ea29 29fab0cd

+129 -37
+6
drivers/usb/host/Kconfig
··· 260 260 To compile this driver as a module, choose M here: the 261 261 module will be called r8a66597-hcd. 262 262 263 + config SUPERH_ON_CHIP_R8A66597 264 + boolean "Enable SuperH on-chip USB like the R8A66597" 265 + depends on USB_R8A66597_HCD && CPU_SUBTYPE_SH7366 266 + help 267 + Renesas SuperH processor has USB like the R8A66597. 268 + This driver supported processor is SH7366.
+78 -37
drivers/usb/host/r8a66597-hcd.c
··· 51 51 static const char hcd_name[] = "r8a66597_hcd"; 52 52 53 53 /* module parameters */ 54 + #if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 54 55 static unsigned short clock = XTAL12; 55 56 module_param(clock, ushort, 0644); 56 57 MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " 57 58 "(default=0)"); 59 + #endif 58 60 59 61 static unsigned short vif = LDRV; 60 62 module_param(vif, ushort, 0644); ··· 108 106 r8a66597_write(r8a66597, val, devadd_reg); 109 107 } 110 108 111 - static int enable_controller(struct r8a66597 *r8a66597) 109 + static int r8a66597_clock_enable(struct r8a66597 *r8a66597) 112 110 { 113 111 u16 tmp; 114 112 int i = 0; 115 113 114 + #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 115 + do { 116 + r8a66597_write(r8a66597, SCKE, SYSCFG0); 117 + tmp = r8a66597_read(r8a66597, SYSCFG0); 118 + if (i++ > 1000) { 119 + err("register access fail."); 120 + return -ENXIO; 121 + } 122 + } while ((tmp & SCKE) != SCKE); 123 + r8a66597_write(r8a66597, 0x04, 0x02); 124 + #else 116 125 do { 117 126 r8a66597_write(r8a66597, USBE, SYSCFG0); 118 127 tmp = r8a66597_read(r8a66597, SYSCFG0); ··· 145 132 return -ENXIO; 146 133 } 147 134 } while ((tmp & SCKE) != SCKE); 135 + #endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ 148 136 149 - r8a66597_bset(r8a66597, DCFM | DRPD, SYSCFG0); 150 - r8a66597_bset(r8a66597, DRPD, SYSCFG1); 137 + return 0; 138 + } 139 + 140 + static void r8a66597_clock_disable(struct r8a66597 *r8a66597) 141 + { 142 + r8a66597_bclr(r8a66597, SCKE, SYSCFG0); 143 + udelay(1); 144 + #if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 145 + r8a66597_bclr(r8a66597, PLLC, SYSCFG0); 146 + r8a66597_bclr(r8a66597, XCKE, SYSCFG0); 147 + r8a66597_bclr(r8a66597, USBE, SYSCFG0); 148 + #endif 149 + } 150 + 151 + static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port) 152 + { 153 + u16 val; 154 + 155 + val = port ? DRPD : DCFM | DRPD; 156 + r8a66597_bset(r8a66597, val, get_syscfg_reg(port)); 157 + r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); 158 + 159 + r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, get_dmacfg_reg(port)); 160 + r8a66597_bclr(r8a66597, DTCHE, get_intenb_reg(port)); 161 + r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); 162 + } 163 + 164 + static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port) 165 + { 166 + u16 val, tmp; 167 + 168 + r8a66597_write(r8a66597, 0, get_intenb_reg(port)); 169 + r8a66597_write(r8a66597, 0, get_intsts_reg(port)); 170 + 171 + r8a66597_port_power(r8a66597, port, 0); 172 + 173 + do { 174 + tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS; 175 + udelay(640); 176 + } while (tmp == EDGESTS); 177 + 178 + val = port ? DRPD : DCFM | DRPD; 179 + r8a66597_bclr(r8a66597, val, get_syscfg_reg(port)); 180 + r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port)); 181 + } 182 + 183 + static int enable_controller(struct r8a66597 *r8a66597) 184 + { 185 + int ret, port; 186 + 187 + ret = r8a66597_clock_enable(r8a66597); 188 + if (ret < 0) 189 + return ret; 151 190 152 191 r8a66597_bset(r8a66597, vif & LDRV, PINCFG); 153 - r8a66597_bset(r8a66597, HSE, SYSCFG0); 154 - r8a66597_bset(r8a66597, HSE, SYSCFG1); 155 192 r8a66597_bset(r8a66597, USBE, SYSCFG0); 156 193 157 194 r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0); ··· 209 146 r8a66597_bset(r8a66597, BRDY0, BRDYENB); 210 147 r8a66597_bset(r8a66597, BEMP0, BEMPENB); 211 148 212 - r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA0CFG); 213 - r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA1CFG); 214 - 215 149 r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL); 216 150 r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL); 217 151 r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL); 218 - 219 152 r8a66597_bset(r8a66597, TRNENSEL, SOFCFG); 220 153 221 154 r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1); 222 - r8a66597_bclr(r8a66597, DTCHE, INTENB1); 223 - r8a66597_bset(r8a66597, ATTCHE, INTENB1); 224 - r8a66597_bclr(r8a66597, DTCHE, INTENB2); 225 - r8a66597_bset(r8a66597, ATTCHE, INTENB2); 155 + 156 + for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) 157 + r8a66597_enable_port(r8a66597, port); 226 158 227 159 return 0; 228 160 } 229 161 230 162 static void disable_controller(struct r8a66597 *r8a66597) 231 163 { 232 - u16 tmp; 164 + int port; 233 165 234 166 r8a66597_write(r8a66597, 0, INTENB0); 235 - r8a66597_write(r8a66597, 0, INTENB1); 236 - r8a66597_write(r8a66597, 0, INTENB2); 237 167 r8a66597_write(r8a66597, 0, INTSTS0); 238 - r8a66597_write(r8a66597, 0, INTSTS1); 239 - r8a66597_write(r8a66597, 0, INTSTS2); 240 168 241 - r8a66597_port_power(r8a66597, 0, 0); 242 - r8a66597_port_power(r8a66597, 1, 0); 169 + for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) 170 + r8a66597_disable_port(r8a66597, port); 243 171 244 - do { 245 - tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS; 246 - udelay(640); 247 - } while (tmp == EDGESTS); 248 - 249 - r8a66597_bclr(r8a66597, DCFM | DRPD, SYSCFG0); 250 - r8a66597_bclr(r8a66597, DRPD, SYSCFG1); 251 - r8a66597_bclr(r8a66597, HSE, SYSCFG0); 252 - r8a66597_bclr(r8a66597, HSE, SYSCFG1); 253 - 254 - r8a66597_bclr(r8a66597, SCKE, SYSCFG0); 255 - udelay(1); 256 - r8a66597_bclr(r8a66597, PLLC, SYSCFG0); 257 - r8a66597_bclr(r8a66597, XCKE, SYSCFG0); 258 - r8a66597_bclr(r8a66597, USBE, SYSCFG0); 172 + r8a66597_clock_disable(r8a66597); 259 173 } 260 174 261 175 static int get_parent_r8a66597_address(struct r8a66597 *r8a66597, ··· 751 711 struct r8a66597_pipe *pipe, 752 712 struct urb *urb) 753 713 { 714 + #if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 754 715 int i; 755 716 struct r8a66597_pipe_info *info = &pipe->info; 756 717 ··· 779 738 break; 780 739 } 781 740 } 741 + #endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ 782 742 } 783 743 784 744 /* this function must be called with interrupt disabled */ ··· 1096 1054 r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); 1097 1055 r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); 1098 1056 r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); 1099 - r8a66597_write(r8a66597, BCLR, CFIFOCTR); 1100 - r8a66597_write(r8a66597, BVAL, CFIFOCTR); 1057 + r8a66597_write(r8a66597, BCLR | BVAL, CFIFOCTR); 1101 1058 enable_irq_empty(r8a66597, 0); 1102 1059 } else { 1103 1060 r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG);
+45
drivers/usb/host/r8a66597.h
··· 187 187 #define REW 0x4000 /* b14: Buffer rewind */ 188 188 #define DCLRM 0x2000 /* b13: DMA buffer clear mode */ 189 189 #define DREQE 0x1000 /* b12: DREQ output enable */ 190 + #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 191 + #define MBW 0x0800 192 + #else 190 193 #define MBW 0x0400 /* b10: Maximum bit width for FIFO access */ 194 + #endif 191 195 #define MBW_8 0x0000 /* 8bit */ 192 196 #define MBW_16 0x0400 /* 16bit */ 193 197 #define BIGEND 0x0100 /* b8: Big endian mode */ ··· 399 395 #define R8A66597_MAX_NUM_PIPE 10 400 396 #define R8A66597_BUF_BSIZE 8 401 397 #define R8A66597_MAX_DEVICE 10 398 + #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 399 + #define R8A66597_MAX_ROOT_HUB 1 400 + #else 402 401 #define R8A66597_MAX_ROOT_HUB 2 402 + #endif 403 403 #define R8A66597_MAX_SAMPLING 5 404 404 #define R8A66597_RH_POLL_TIME 10 405 405 #define R8A66597_MAX_DMA_CHANNEL 2 ··· 538 530 unsigned long offset, u16 *buf, 539 531 int len) 540 532 { 533 + #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 534 + unsigned long fifoaddr = r8a66597->reg + offset; 535 + unsigned long count; 536 + 537 + count = len / 4; 538 + insl(fifoaddr, buf, count); 539 + 540 + if (len & 0x00000003) { 541 + unsigned long tmp = inl(fifoaddr); 542 + memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03); 543 + } 544 + #else 541 545 len = (len + 1) / 2; 542 546 insw(r8a66597->reg + offset, buf, len); 547 + #endif 543 548 } 544 549 545 550 static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, ··· 566 545 int len) 567 546 { 568 547 unsigned long fifoaddr = r8a66597->reg + offset; 548 + #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 549 + unsigned long count; 550 + unsigned char *pb; 551 + int i; 552 + 553 + count = len / 4; 554 + outsl(fifoaddr, buf, count); 555 + 556 + if (len & 0x00000003) { 557 + pb = (unsigned char *)buf + count * 4; 558 + for (i = 0; i < (len & 0x00000003); i++) { 559 + if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND) 560 + outb(pb[i], fifoaddr + i); 561 + else 562 + outb(pb[i], fifoaddr + 3 - i); 563 + } 564 + } 565 + #else 569 566 int odd = len & 0x0001; 570 567 571 568 len = len / 2; ··· 592 553 buf = &buf[len]; 593 554 outb((unsigned char)*buf, fifoaddr); 594 555 } 556 + #endif 595 557 } 596 558 597 559 static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, ··· 623 583 static inline unsigned long get_dvstctr_reg(int port) 624 584 { 625 585 return port == 0 ? DVSTCTR0 : DVSTCTR1; 586 + } 587 + 588 + static inline unsigned long get_dmacfg_reg(int port) 589 + { 590 + return port == 0 ? DMA0CFG : DMA1CFG; 626 591 } 627 592 628 593 static inline unsigned long get_intenb_reg(int port)