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 33struct 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 84static 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 90static 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 96static 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 102static 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 114static 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 120static 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 */ 132static 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 */ 150static 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 164static 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 175static 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 186static 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 198static 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 209u16 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 221void 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 235void 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 241void 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 250static 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 263u16 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 274u16 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 */ 282void 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 287u16 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 294static 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 313void 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 320static 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 330void 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 342void 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 347u16 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 352u16 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 357void 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 370void 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 387void 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 398int 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 */ 416void 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 */ 455void 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 483void 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 489void c67x00_ll_release(struct c67x00_device *dev) 490{ 491} 492