1 /* 2 * c67x00-ll-hpi.c: Cypress C67X00 USB Low level interface using HPI 3 * 4 * Copyright (C) 2006-2008 Barco N.V. 5 * Derived from the Cypress cy7c67200/300 ezusb linux driver and 6 * based on multiple host controller drivers inside the linux kernel. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 21 * MA 02110-1301 USA. 22 */ 23 24 #include <asm/byteorder.h> 25 #include <linux/delay.h> 26 #include <linux/io.h> 27 #include <linux/jiffies.h> 28 #include <linux/usb/c67x00.h> 29 #include "c67x00.h" 30 31 #define COMM_REGS 14 32 33 struct c67x00_lcp_int_data { 34 u16 regs[COMM_REGS]; 35 }; 36 37 /* -------------------------------------------------------------------------- */ 38 /* Interface definitions */ 39 40 #define COMM_ACK 0x0FED 41 #define COMM_NAK 0xDEAD 42 43 #define COMM_RESET 0xFA50 44 #define COMM_EXEC_INT 0xCE01 45 #define COMM_INT_NUM 0x01C2 46 47 /* Registers 0 to COMM_REGS-1 */ 48 #define COMM_R(x) (0x01C4 + 2 * (x)) 49 50 #define HUSB_SIE_pCurrentTDPtr(x) ((x) ? 0x01B2 : 0x01B0) 51 #define HUSB_SIE_pTDListDone_Sem(x) ((x) ? 0x01B8 : 0x01B6) 52 #define HUSB_pEOT 0x01B4 53 54 /* Software interrupts */ 55 /* 114, 115: */ 56 #define HUSB_SIE_INIT_INT(x) ((x) ? 0x0073 : 0x0072) 57 #define HUSB_RESET_INT 0x0074 58 59 #define SUSB_INIT_INT 0x0071 60 #define SUSB_INIT_INT_LOC (SUSB_INIT_INT * 2) 61 62 /* ----------------------------------------------------------------------- 63 * HPI implementation 64 * 65 * The c67x00 chip also support control via SPI or HSS serial 66 * interfaces. However, this driver assumes that register access can 67 * be performed from IRQ context. While this is a safe assumption with 68 * the HPI interface, it is not true for the serial interfaces. 69 */ 70 71 /* HPI registers */ 72 #define HPI_DATA 0 73 #define HPI_MAILBOX 1 74 #define HPI_ADDR 2 75 #define HPI_STATUS 3 76 77 /* 78 * According to CY7C67300 specification (tables 140 and 141) HPI read and 79 * write cycle duration Tcyc must be at least 6T long, where T is 1/48MHz, 80 * which is 125ns. 81 */ 82 #define HPI_T_CYC_NS 125 83 84 static inline u16 hpi_read_reg(struct c67x00_device *dev, int reg) 85 { 86 ndelay(HPI_T_CYC_NS); 87 return __raw_readw(dev->hpi.base + reg * dev->hpi.regstep); 88 } 89 90 static inline void hpi_write_reg(struct c67x00_device *dev, int reg, u16 value) 91 { 92 ndelay(HPI_T_CYC_NS); 93 __raw_writew(value, dev->hpi.base + reg * dev->hpi.regstep); 94 } 95 96 static inline u16 hpi_read_word_nolock(struct c67x00_device *dev, u16 reg) 97 { 98 hpi_write_reg(dev, HPI_ADDR, reg); 99 return hpi_read_reg(dev, HPI_DATA); 100 } 101 102 static u16 hpi_read_word(struct c67x00_device *dev, u16 reg) 103 { 104 u16 value; 105 unsigned long flags; 106 107 spin_lock_irqsave(&dev->hpi.lock, flags); 108 value = hpi_read_word_nolock(dev, reg); 109 spin_unlock_irqrestore(&dev->hpi.lock, flags); 110 111 return value; 112 } 113 114 static void hpi_write_word_nolock(struct c67x00_device *dev, u16 reg, u16 value) 115 { 116 hpi_write_reg(dev, HPI_ADDR, reg); 117 hpi_write_reg(dev, HPI_DATA, value); 118 } 119 120 static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value) 121 { 122 unsigned long flags; 123 124 spin_lock_irqsave(&dev->hpi.lock, flags); 125 hpi_write_word_nolock(dev, reg, value); 126 spin_unlock_irqrestore(&dev->hpi.lock, flags); 127 } 128 129 /* 130 * Only data is little endian, addr has cpu endianess 131 */ 132 static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, 133 __le16 *data, u16 count) 134 { 135 unsigned long flags; 136 int i; 137 138 spin_lock_irqsave(&dev->hpi.lock, flags); 139 140 hpi_write_reg(dev, HPI_ADDR, addr); 141 for (i = 0; i < count; i++) 142 hpi_write_reg(dev, HPI_DATA, le16_to_cpu(*data++)); 143 144 spin_unlock_irqrestore(&dev->hpi.lock, flags); 145 } 146 147 /* 148 * Only data is little endian, addr has cpu endianess 149 */ 150 static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, 151 __le16 *data, u16 count) 152 { 153 unsigned long flags; 154 int i; 155 156 spin_lock_irqsave(&dev->hpi.lock, flags); 157 hpi_write_reg(dev, HPI_ADDR, addr); 158 for (i = 0; i < count; i++) 159 *data++ = cpu_to_le16(hpi_read_reg(dev, HPI_DATA)); 160 161 spin_unlock_irqrestore(&dev->hpi.lock, flags); 162 } 163 164 static void hpi_set_bits(struct c67x00_device *dev, u16 reg, u16 mask) 165 { 166 u16 value; 167 unsigned long flags; 168 169 spin_lock_irqsave(&dev->hpi.lock, flags); 170 value = hpi_read_word_nolock(dev, reg); 171 hpi_write_word_nolock(dev, reg, value | mask); 172 spin_unlock_irqrestore(&dev->hpi.lock, flags); 173 } 174 175 static void hpi_clear_bits(struct c67x00_device *dev, u16 reg, u16 mask) 176 { 177 u16 value; 178 unsigned long flags; 179 180 spin_lock_irqsave(&dev->hpi.lock, flags); 181 value = hpi_read_word_nolock(dev, reg); 182 hpi_write_word_nolock(dev, reg, value & ~mask); 183 spin_unlock_irqrestore(&dev->hpi.lock, flags); 184 } 185 186 static u16 hpi_recv_mbox(struct c67x00_device *dev) 187 { 188 u16 value; 189 unsigned long flags; 190 191 spin_lock_irqsave(&dev->hpi.lock, flags); 192 value = hpi_read_reg(dev, HPI_MAILBOX); 193 spin_unlock_irqrestore(&dev->hpi.lock, flags); 194 195 return value; 196 } 197 198 static u16 hpi_send_mbox(struct c67x00_device *dev, u16 value) 199 { 200 unsigned long flags; 201 202 spin_lock_irqsave(&dev->hpi.lock, flags); 203 hpi_write_reg(dev, HPI_MAILBOX, value); 204 spin_unlock_irqrestore(&dev->hpi.lock, flags); 205 206 return value; 207 } 208 209 u16 c67x00_ll_hpi_status(struct c67x00_device *dev) 210 { 211 u16 value; 212 unsigned long flags; 213 214 spin_lock_irqsave(&dev->hpi.lock, flags); 215 value = hpi_read_reg(dev, HPI_STATUS); 216 spin_unlock_irqrestore(&dev->hpi.lock, flags); 217 218 return value; 219 } 220 221 void c67x00_ll_hpi_reg_init(struct c67x00_device *dev) 222 { 223 int i; 224 225 hpi_recv_mbox(dev); 226 c67x00_ll_hpi_status(dev); 227 hpi_write_word(dev, HPI_IRQ_ROUTING_REG, 0); 228 229 for (i = 0; i < C67X00_SIES; i++) { 230 hpi_write_word(dev, SIEMSG_REG(i), 0); 231 hpi_read_word(dev, SIEMSG_REG(i)); 232 } 233 } 234 235 void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie) 236 { 237 hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG, 238 SOFEOP_TO_HPI_EN(sie->sie_num)); 239 } 240 241 void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie) 242 { 243 hpi_clear_bits(sie->dev, HPI_IRQ_ROUTING_REG, 244 SOFEOP_TO_HPI_EN(sie->sie_num)); 245 } 246 247 /* -------------------------------------------------------------------------- */ 248 /* Transactions */ 249 250 static inline int ll_recv_msg(struct c67x00_device *dev) 251 { 252 u16 res; 253 254 res = wait_for_completion_timeout(&dev->hpi.lcp.msg_received, 5 * HZ); 255 WARN_ON(!res); 256 257 return (res == 0) ? -EIO : 0; 258 } 259 260 /* -------------------------------------------------------------------------- */ 261 /* General functions */ 262 263 u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num) 264 { 265 u16 val; 266 267 val = hpi_read_word(dev, SIEMSG_REG(sie_num)); 268 /* clear register to allow next message */ 269 hpi_write_word(dev, SIEMSG_REG(sie_num), 0); 270 271 return val; 272 } 273 274 u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie) 275 { 276 return hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)); 277 } 278 279 /** 280 * c67x00_ll_usb_clear_status - clear the USB status bits 281 */ 282 void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits) 283 { 284 hpi_write_word(sie->dev, USB_STAT_REG(sie->sie_num), bits); 285 } 286 287 u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie) 288 { 289 return hpi_read_word(sie->dev, USB_STAT_REG(sie->sie_num)); 290 } 291 292 /* -------------------------------------------------------------------------- */ 293 294 static int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr, 295 struct c67x00_lcp_int_data *data) 296 { 297 int i, rc; 298 299 mutex_lock(&dev->hpi.lcp.mutex); 300 hpi_write_word(dev, COMM_INT_NUM, nr); 301 for (i = 0; i < COMM_REGS; i++) 302 hpi_write_word(dev, COMM_R(i), data->regs[i]); 303 hpi_send_mbox(dev, COMM_EXEC_INT); 304 rc = ll_recv_msg(dev); 305 mutex_unlock(&dev->hpi.lcp.mutex); 306 307 return rc; 308 } 309 310 /* -------------------------------------------------------------------------- */ 311 /* Host specific functions */ 312 313 void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value) 314 { 315 mutex_lock(&dev->hpi.lcp.mutex); 316 hpi_write_word(dev, HUSB_pEOT, value); 317 mutex_unlock(&dev->hpi.lcp.mutex); 318 } 319 320 static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie) 321 { 322 struct c67x00_device *dev = sie->dev; 323 struct c67x00_lcp_int_data data; 324 int rc; 325 326 rc = c67x00_comm_exec_int(dev, HUSB_SIE_INIT_INT(sie->sie_num), &data); 327 BUG_ON(rc); /* No return path for error code; crash spectacularly */ 328 } 329 330 void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port) 331 { 332 struct c67x00_device *dev = sie->dev; 333 struct c67x00_lcp_int_data data; 334 int rc; 335 336 data.regs[0] = 50; /* Reset USB port for 50ms */ 337 data.regs[1] = port | (sie->sie_num << 1); 338 rc = c67x00_comm_exec_int(dev, HUSB_RESET_INT, &data); 339 BUG_ON(rc); /* No return path for error code; crash spectacularly */ 340 } 341 342 void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr) 343 { 344 hpi_write_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num), addr); 345 } 346 347 u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie) 348 { 349 return hpi_read_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num)); 350 } 351 352 u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie) 353 { 354 return hpi_read_word(sie->dev, HOST_FRAME_REG(sie->sie_num)); 355 } 356 357 void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie) 358 { 359 /* Set port into host mode */ 360 hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), HOST_MODE); 361 c67x00_ll_husb_sie_init(sie); 362 /* Clear interrupts */ 363 c67x00_ll_usb_clear_status(sie, HOST_STAT_MASK); 364 /* Check */ 365 if (!(hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)) & HOST_MODE)) 366 dev_warn(sie_dev(sie), 367 "SIE %d not set to host mode\n", sie->sie_num); 368 } 369 370 void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port) 371 { 372 /* Clear connect change */ 373 c67x00_ll_usb_clear_status(sie, PORT_CONNECT_CHANGE(port)); 374 375 /* Enable interrupts */ 376 hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG, 377 SOFEOP_TO_CPU_EN(sie->sie_num)); 378 hpi_set_bits(sie->dev, HOST_IRQ_EN_REG(sie->sie_num), 379 SOF_EOP_IRQ_EN | DONE_IRQ_EN); 380 381 /* Enable pull down transistors */ 382 hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), PORT_RES_EN(port)); 383 } 384 385 /* -------------------------------------------------------------------------- */ 386 387 void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status) 388 { 389 if ((int_status & MBX_OUT_FLG) == 0) 390 return; 391 392 dev->hpi.lcp.last_msg = hpi_recv_mbox(dev); 393 complete(&dev->hpi.lcp.msg_received); 394 } 395 396 /* -------------------------------------------------------------------------- */ 397 398 int c67x00_ll_reset(struct c67x00_device *dev) 399 { 400 int rc; 401 402 mutex_lock(&dev->hpi.lcp.mutex); 403 hpi_send_mbox(dev, COMM_RESET); 404 rc = ll_recv_msg(dev); 405 mutex_unlock(&dev->hpi.lcp.mutex); 406 407 return rc; 408 } 409 410 /* -------------------------------------------------------------------------- */ 411 412 /** 413 * c67x00_ll_write_mem_le16 - write into c67x00 memory 414 * Only data is little endian, addr has cpu endianess. 415 */ 416 void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, 417 void *data, int len) 418 { 419 u8 *buf = data; 420 421 /* Sanity check */ 422 if (addr + len > 0xffff) { 423 dev_err(&dev->pdev->dev, 424 "Trying to write beyond writable region!\n"); 425 return; 426 } 427 428 if (addr & 0x01) { 429 /* unaligned access */ 430 u16 tmp; 431 tmp = hpi_read_word(dev, addr - 1); 432 tmp = (tmp & 0x00ff) | (*buf++ << 8); 433 hpi_write_word(dev, addr - 1, tmp); 434 addr++; 435 len--; 436 } 437 438 hpi_write_words_le16(dev, addr, (__le16 *)buf, len / 2); 439 buf += len & ~0x01; 440 addr += len & ~0x01; 441 len &= 0x01; 442 443 if (len) { 444 u16 tmp; 445 tmp = hpi_read_word(dev, addr); 446 tmp = (tmp & 0xff00) | *buf; 447 hpi_write_word(dev, addr, tmp); 448 } 449 } 450 451 /** 452 * c67x00_ll_read_mem_le16 - read from c67x00 memory 453 * Only data is little endian, addr has cpu endianess. 454 */ 455 void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, 456 void *data, int len) 457 { 458 u8 *buf = data; 459 460 if (addr & 0x01) { 461 /* unaligned access */ 462 u16 tmp; 463 tmp = hpi_read_word(dev, addr - 1); 464 *buf++ = (tmp >> 8) & 0x00ff; 465 addr++; 466 len--; 467 } 468 469 hpi_read_words_le16(dev, addr, (__le16 *)buf, len / 2); 470 buf += len & ~0x01; 471 addr += len & ~0x01; 472 len &= 0x01; 473 474 if (len) { 475 u16 tmp; 476 tmp = hpi_read_word(dev, addr); 477 *buf = tmp & 0x00ff; 478 } 479 } 480 481 /* -------------------------------------------------------------------------- */ 482 483 void c67x00_ll_init(struct c67x00_device *dev) 484 { 485 mutex_init(&dev->hpi.lcp.mutex); 486 init_completion(&dev->hpi.lcp.msg_received); 487 } 488 489 void c67x00_ll_release(struct c67x00_device *dev) 490 { 491 } 492