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