Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * c67x00-ll-hpi.c: Cypress C67X00 USB Low level interface using HPI
0004  *
0005  * Copyright (C) 2006-2008 Barco N.V.
0006  *    Derived from the Cypress cy7c67200/300 ezusb linux driver and
0007  *    based on multiple host controller drivers inside the linux kernel.
0008  */
0009 
0010 #include <asm/byteorder.h>
0011 #include <linux/delay.h>
0012 #include <linux/io.h>
0013 #include <linux/jiffies.h>
0014 #include <linux/usb/c67x00.h>
0015 #include "c67x00.h"
0016 
0017 #define COMM_REGS 14
0018 
0019 struct c67x00_lcp_int_data {
0020     u16 regs[COMM_REGS];
0021 };
0022 
0023 /* -------------------------------------------------------------------------- */
0024 /* Interface definitions */
0025 
0026 #define COMM_ACK            0x0FED
0027 #define COMM_NAK            0xDEAD
0028 
0029 #define COMM_RESET          0xFA50
0030 #define COMM_EXEC_INT           0xCE01
0031 #define COMM_INT_NUM            0x01C2
0032 
0033 /* Registers 0 to COMM_REGS-1 */
0034 #define COMM_R(x)           (0x01C4 + 2 * (x))
0035 
0036 #define HUSB_SIE_pCurrentTDPtr(x)   ((x) ? 0x01B2 : 0x01B0)
0037 #define HUSB_SIE_pTDListDone_Sem(x) ((x) ? 0x01B8 : 0x01B6)
0038 #define HUSB_pEOT           0x01B4
0039 
0040 /* Software interrupts */
0041 /* 114, 115: */
0042 #define HUSB_SIE_INIT_INT(x)        ((x) ? 0x0073 : 0x0072)
0043 #define HUSB_RESET_INT          0x0074
0044 
0045 #define SUSB_INIT_INT           0x0071
0046 #define SUSB_INIT_INT_LOC       (SUSB_INIT_INT * 2)
0047 
0048 /* -----------------------------------------------------------------------
0049  * HPI implementation
0050  *
0051  * The c67x00 chip also support control via SPI or HSS serial
0052  * interfaces. However, this driver assumes that register access can
0053  * be performed from IRQ context. While this is a safe assumption with
0054  * the HPI interface, it is not true for the serial interfaces.
0055  */
0056 
0057 /* HPI registers */
0058 #define HPI_DATA    0
0059 #define HPI_MAILBOX 1
0060 #define HPI_ADDR    2
0061 #define HPI_STATUS  3
0062 
0063 /*
0064  * According to CY7C67300 specification (tables 140 and 141) HPI read and
0065  * write cycle duration Tcyc must be at least 6T long, where T is 1/48MHz,
0066  * which is 125ns.
0067  */
0068 #define HPI_T_CYC_NS    125
0069 
0070 static inline u16 hpi_read_reg(struct c67x00_device *dev, int reg)
0071 {
0072     ndelay(HPI_T_CYC_NS);
0073     return __raw_readw(dev->hpi.base + reg * dev->hpi.regstep);
0074 }
0075 
0076 static inline void hpi_write_reg(struct c67x00_device *dev, int reg, u16 value)
0077 {
0078     ndelay(HPI_T_CYC_NS);
0079     __raw_writew(value, dev->hpi.base + reg * dev->hpi.regstep);
0080 }
0081 
0082 static inline u16 hpi_read_word_nolock(struct c67x00_device *dev, u16 reg)
0083 {
0084     hpi_write_reg(dev, HPI_ADDR, reg);
0085     return hpi_read_reg(dev, HPI_DATA);
0086 }
0087 
0088 static u16 hpi_read_word(struct c67x00_device *dev, u16 reg)
0089 {
0090     u16 value;
0091     unsigned long flags;
0092 
0093     spin_lock_irqsave(&dev->hpi.lock, flags);
0094     value = hpi_read_word_nolock(dev, reg);
0095     spin_unlock_irqrestore(&dev->hpi.lock, flags);
0096 
0097     return value;
0098 }
0099 
0100 static void hpi_write_word_nolock(struct c67x00_device *dev, u16 reg, u16 value)
0101 {
0102     hpi_write_reg(dev, HPI_ADDR, reg);
0103     hpi_write_reg(dev, HPI_DATA, value);
0104 }
0105 
0106 static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value)
0107 {
0108     unsigned long flags;
0109 
0110     spin_lock_irqsave(&dev->hpi.lock, flags);
0111     hpi_write_word_nolock(dev, reg, value);
0112     spin_unlock_irqrestore(&dev->hpi.lock, flags);
0113 }
0114 
0115 /*
0116  * Only data is little endian, addr has cpu endianess
0117  */
0118 static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr,
0119                  __le16 *data, u16 count)
0120 {
0121     unsigned long flags;
0122     int i;
0123 
0124     spin_lock_irqsave(&dev->hpi.lock, flags);
0125 
0126     hpi_write_reg(dev, HPI_ADDR, addr);
0127     for (i = 0; i < count; i++)
0128         hpi_write_reg(dev, HPI_DATA, le16_to_cpu(*data++));
0129 
0130     spin_unlock_irqrestore(&dev->hpi.lock, flags);
0131 }
0132 
0133 /*
0134  * Only data is little endian, addr has cpu endianess
0135  */
0136 static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr,
0137                 __le16 *data, u16 count)
0138 {
0139     unsigned long flags;
0140     int i;
0141 
0142     spin_lock_irqsave(&dev->hpi.lock, flags);
0143     hpi_write_reg(dev, HPI_ADDR, addr);
0144     for (i = 0; i < count; i++)
0145         *data++ = cpu_to_le16(hpi_read_reg(dev, HPI_DATA));
0146 
0147     spin_unlock_irqrestore(&dev->hpi.lock, flags);
0148 }
0149 
0150 static void hpi_set_bits(struct c67x00_device *dev, u16 reg, u16 mask)
0151 {
0152     u16 value;
0153     unsigned long flags;
0154 
0155     spin_lock_irqsave(&dev->hpi.lock, flags);
0156     value = hpi_read_word_nolock(dev, reg);
0157     hpi_write_word_nolock(dev, reg, value | mask);
0158     spin_unlock_irqrestore(&dev->hpi.lock, flags);
0159 }
0160 
0161 static void hpi_clear_bits(struct c67x00_device *dev, u16 reg, u16 mask)
0162 {
0163     u16 value;
0164     unsigned long flags;
0165 
0166     spin_lock_irqsave(&dev->hpi.lock, flags);
0167     value = hpi_read_word_nolock(dev, reg);
0168     hpi_write_word_nolock(dev, reg, value & ~mask);
0169     spin_unlock_irqrestore(&dev->hpi.lock, flags);
0170 }
0171 
0172 static u16 hpi_recv_mbox(struct c67x00_device *dev)
0173 {
0174     u16 value;
0175     unsigned long flags;
0176 
0177     spin_lock_irqsave(&dev->hpi.lock, flags);
0178     value = hpi_read_reg(dev, HPI_MAILBOX);
0179     spin_unlock_irqrestore(&dev->hpi.lock, flags);
0180 
0181     return value;
0182 }
0183 
0184 static u16 hpi_send_mbox(struct c67x00_device *dev, u16 value)
0185 {
0186     unsigned long flags;
0187 
0188     spin_lock_irqsave(&dev->hpi.lock, flags);
0189     hpi_write_reg(dev, HPI_MAILBOX, value);
0190     spin_unlock_irqrestore(&dev->hpi.lock, flags);
0191 
0192     return value;
0193 }
0194 
0195 u16 c67x00_ll_hpi_status(struct c67x00_device *dev)
0196 {
0197     u16 value;
0198     unsigned long flags;
0199 
0200     spin_lock_irqsave(&dev->hpi.lock, flags);
0201     value = hpi_read_reg(dev, HPI_STATUS);
0202     spin_unlock_irqrestore(&dev->hpi.lock, flags);
0203 
0204     return value;
0205 }
0206 
0207 void c67x00_ll_hpi_reg_init(struct c67x00_device *dev)
0208 {
0209     int i;
0210 
0211     hpi_recv_mbox(dev);
0212     c67x00_ll_hpi_status(dev);
0213     hpi_write_word(dev, HPI_IRQ_ROUTING_REG, 0);
0214 
0215     for (i = 0; i < C67X00_SIES; i++) {
0216         hpi_write_word(dev, SIEMSG_REG(i), 0);
0217         hpi_read_word(dev, SIEMSG_REG(i));
0218     }
0219 }
0220 
0221 void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie)
0222 {
0223     hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG,
0224              SOFEOP_TO_HPI_EN(sie->sie_num));
0225 }
0226 
0227 void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie)
0228 {
0229     hpi_clear_bits(sie->dev, HPI_IRQ_ROUTING_REG,
0230                SOFEOP_TO_HPI_EN(sie->sie_num));
0231 }
0232 
0233 /* -------------------------------------------------------------------------- */
0234 /* Transactions */
0235 
0236 static inline int ll_recv_msg(struct c67x00_device *dev)
0237 {
0238     u16 res;
0239 
0240     res = wait_for_completion_timeout(&dev->hpi.lcp.msg_received, 5 * HZ);
0241     WARN_ON(!res);
0242 
0243     return (res == 0) ? -EIO : 0;
0244 }
0245 
0246 /* -------------------------------------------------------------------------- */
0247 /* General functions */
0248 
0249 u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num)
0250 {
0251     u16 val;
0252 
0253     val = hpi_read_word(dev, SIEMSG_REG(sie_num));
0254     /* clear register to allow next message */
0255     hpi_write_word(dev, SIEMSG_REG(sie_num), 0);
0256 
0257     return val;
0258 }
0259 
0260 u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie)
0261 {
0262     return hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num));
0263 }
0264 
0265 /*
0266  * c67x00_ll_usb_clear_status - clear the USB status bits
0267  */
0268 void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits)
0269 {
0270     hpi_write_word(sie->dev, USB_STAT_REG(sie->sie_num), bits);
0271 }
0272 
0273 u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie)
0274 {
0275     return hpi_read_word(sie->dev, USB_STAT_REG(sie->sie_num));
0276 }
0277 
0278 /* -------------------------------------------------------------------------- */
0279 
0280 static int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr,
0281                 struct c67x00_lcp_int_data *data)
0282 {
0283     int i, rc;
0284 
0285     mutex_lock(&dev->hpi.lcp.mutex);
0286     hpi_write_word(dev, COMM_INT_NUM, nr);
0287     for (i = 0; i < COMM_REGS; i++)
0288         hpi_write_word(dev, COMM_R(i), data->regs[i]);
0289     hpi_send_mbox(dev, COMM_EXEC_INT);
0290     rc = ll_recv_msg(dev);
0291     mutex_unlock(&dev->hpi.lcp.mutex);
0292 
0293     return rc;
0294 }
0295 
0296 /* -------------------------------------------------------------------------- */
0297 /* Host specific functions */
0298 
0299 void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value)
0300 {
0301     mutex_lock(&dev->hpi.lcp.mutex);
0302     hpi_write_word(dev, HUSB_pEOT, value);
0303     mutex_unlock(&dev->hpi.lcp.mutex);
0304 }
0305 
0306 static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie)
0307 {
0308     struct c67x00_device *dev = sie->dev;
0309     struct c67x00_lcp_int_data data;
0310     int rc;
0311 
0312     rc = c67x00_comm_exec_int(dev, HUSB_SIE_INIT_INT(sie->sie_num), &data);
0313     BUG_ON(rc); /* No return path for error code; crash spectacularly */
0314 }
0315 
0316 void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port)
0317 {
0318     struct c67x00_device *dev = sie->dev;
0319     struct c67x00_lcp_int_data data;
0320     int rc;
0321 
0322     data.regs[0] = 50;  /* Reset USB port for 50ms */
0323     data.regs[1] = port | (sie->sie_num << 1);
0324     rc = c67x00_comm_exec_int(dev, HUSB_RESET_INT, &data);
0325     BUG_ON(rc); /* No return path for error code; crash spectacularly */
0326 }
0327 
0328 void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr)
0329 {
0330     hpi_write_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num), addr);
0331 }
0332 
0333 u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie)
0334 {
0335     return hpi_read_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num));
0336 }
0337 
0338 u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie)
0339 {
0340     return hpi_read_word(sie->dev, HOST_FRAME_REG(sie->sie_num));
0341 }
0342 
0343 void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie)
0344 {
0345     /* Set port into host mode */
0346     hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), HOST_MODE);
0347     c67x00_ll_husb_sie_init(sie);
0348     /* Clear interrupts */
0349     c67x00_ll_usb_clear_status(sie, HOST_STAT_MASK);
0350     /* Check */
0351     if (!(hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)) & HOST_MODE))
0352         dev_warn(sie_dev(sie),
0353              "SIE %d not set to host mode\n", sie->sie_num);
0354 }
0355 
0356 void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port)
0357 {
0358     /* Clear connect change */
0359     c67x00_ll_usb_clear_status(sie, PORT_CONNECT_CHANGE(port));
0360 
0361     /* Enable interrupts */
0362     hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG,
0363              SOFEOP_TO_CPU_EN(sie->sie_num));
0364     hpi_set_bits(sie->dev, HOST_IRQ_EN_REG(sie->sie_num),
0365              SOF_EOP_IRQ_EN | DONE_IRQ_EN);
0366 
0367     /* Enable pull down transistors */
0368     hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), PORT_RES_EN(port));
0369 }
0370 
0371 /* -------------------------------------------------------------------------- */
0372 
0373 void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status)
0374 {
0375     if ((int_status & MBX_OUT_FLG) == 0)
0376         return;
0377 
0378     dev->hpi.lcp.last_msg = hpi_recv_mbox(dev);
0379     complete(&dev->hpi.lcp.msg_received);
0380 }
0381 
0382 /* -------------------------------------------------------------------------- */
0383 
0384 int c67x00_ll_reset(struct c67x00_device *dev)
0385 {
0386     int rc;
0387 
0388     mutex_lock(&dev->hpi.lcp.mutex);
0389     hpi_send_mbox(dev, COMM_RESET);
0390     rc = ll_recv_msg(dev);
0391     mutex_unlock(&dev->hpi.lcp.mutex);
0392 
0393     return rc;
0394 }
0395 
0396 /* -------------------------------------------------------------------------- */
0397 
0398 /*
0399  * c67x00_ll_write_mem_le16 - write into c67x00 memory
0400  * Only data is little endian, addr has cpu endianess.
0401  */
0402 void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr,
0403                   void *data, int len)
0404 {
0405     u8 *buf = data;
0406 
0407     /* Sanity check */
0408     if (addr + len > 0xffff) {
0409         dev_err(&dev->pdev->dev,
0410             "Trying to write beyond writable region!\n");
0411         return;
0412     }
0413 
0414     if (addr & 0x01) {
0415         /* unaligned access */
0416         u16 tmp;
0417         tmp = hpi_read_word(dev, addr - 1);
0418         tmp = (tmp & 0x00ff) | (*buf++ << 8);
0419         hpi_write_word(dev, addr - 1, tmp);
0420         addr++;
0421         len--;
0422     }
0423 
0424     hpi_write_words_le16(dev, addr, (__le16 *)buf, len / 2);
0425     buf += len & ~0x01;
0426     addr += len & ~0x01;
0427     len &= 0x01;
0428 
0429     if (len) {
0430         u16 tmp;
0431         tmp = hpi_read_word(dev, addr);
0432         tmp = (tmp & 0xff00) | *buf;
0433         hpi_write_word(dev, addr, tmp);
0434     }
0435 }
0436 
0437 /*
0438  * c67x00_ll_read_mem_le16 - read from c67x00 memory
0439  * Only data is little endian, addr has cpu endianess.
0440  */
0441 void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr,
0442                  void *data, int len)
0443 {
0444     u8 *buf = data;
0445 
0446     if (addr & 0x01) {
0447         /* unaligned access */
0448         u16 tmp;
0449         tmp = hpi_read_word(dev, addr - 1);
0450         *buf++ = (tmp >> 8) & 0x00ff;
0451         addr++;
0452         len--;
0453     }
0454 
0455     hpi_read_words_le16(dev, addr, (__le16 *)buf, len / 2);
0456     buf += len & ~0x01;
0457     addr += len & ~0x01;
0458     len &= 0x01;
0459 
0460     if (len) {
0461         u16 tmp;
0462         tmp = hpi_read_word(dev, addr);
0463         *buf = tmp & 0x00ff;
0464     }
0465 }
0466 
0467 /* -------------------------------------------------------------------------- */
0468 
0469 void c67x00_ll_init(struct c67x00_device *dev)
0470 {
0471     mutex_init(&dev->hpi.lcp.mutex);
0472     init_completion(&dev->hpi.lcp.msg_received);
0473 }
0474 
0475 void c67x00_ll_release(struct c67x00_device *dev)
0476 {
0477 }