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