mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-26 17:15:18 +07:00
229e368239
Now that the SPDX tag is in all USB files, that identifies the license in a specific and legally-defined manner. So the extra GPL text wording can be removed as it is no longer needed at all. This is done on a quest to remove the 700+ different ways that files in the kernel describe the GPL license text. And there's unneeded stuff like the address (sometimes incorrect) for the FSF which is never needed. No copyright headers or other non-license-description text was removed. Cc: Kevin Cernekee <cernekee@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Vladimir Zapolskiy <vz@mleia.com> Cc: Sylvain Lemieux <slemieux.tyco@gmail.com> Cc: Daniel Mack <daniel@zonque.org> Cc: Haojian Zhuang <haojian.zhuang@gmail.com> Cc: Michal Simek <michal.simek@xilinx.com> Cc: "Sören Brinkmann" <soren.brinkmann@xilinx.com> Cc: Raviteja Garimella <raviteja.garimella@broadcom.com> Cc: Romain Perier <romain.perier@collabora.com> Cc: Johan Hovold <johan@kernel.org> Cc: Al Cooper <alcooperx@gmail.com> Cc: Srinath Mannam <srinath.mannam@broadcom.com> Cc: Roger Quadros <rogerq@ti.com> Cc: Krzysztof Opasiak <k.opasiak@samsung.com> Cc: Stefan Agner <stefan@agner.ch> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: "Felix Hädicke" <felixhaedicke@web.de> Cc: Peter Chen <peter.chen@nxp.com> Cc: Allen Pais <allen.lkml@gmail.com> Cc: Yuyang Du <yuyang.du@intel.com> Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com> Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr> Acked-by: Li Yang <leoyang.li@nxp.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
288 lines
7.0 KiB
C
288 lines
7.0 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* R8A66597 UDC
|
|
*
|
|
* Copyright (C) 2007-2009 Renesas Solutions Corp.
|
|
*
|
|
* Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
|
*/
|
|
|
|
#ifndef __R8A66597_H__
|
|
#define __R8A66597_H__
|
|
|
|
#include <linux/clk.h>
|
|
#include <linux/usb/r8a66597.h>
|
|
|
|
#define R8A66597_MAX_SAMPLING 10
|
|
|
|
#define R8A66597_MAX_NUM_PIPE 8
|
|
#define R8A66597_MAX_NUM_BULK 3
|
|
#define R8A66597_MAX_NUM_ISOC 2
|
|
#define R8A66597_MAX_NUM_INT 2
|
|
|
|
#define R8A66597_BASE_PIPENUM_BULK 3
|
|
#define R8A66597_BASE_PIPENUM_ISOC 1
|
|
#define R8A66597_BASE_PIPENUM_INT 6
|
|
|
|
#define R8A66597_BASE_BUFNUM 6
|
|
#define R8A66597_MAX_BUFNUM 0x4F
|
|
|
|
#define is_bulk_pipe(pipenum) \
|
|
((pipenum >= R8A66597_BASE_PIPENUM_BULK) && \
|
|
(pipenum < (R8A66597_BASE_PIPENUM_BULK + R8A66597_MAX_NUM_BULK)))
|
|
#define is_interrupt_pipe(pipenum) \
|
|
((pipenum >= R8A66597_BASE_PIPENUM_INT) && \
|
|
(pipenum < (R8A66597_BASE_PIPENUM_INT + R8A66597_MAX_NUM_INT)))
|
|
#define is_isoc_pipe(pipenum) \
|
|
((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \
|
|
(pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC)))
|
|
|
|
#define r8a66597_is_sudmac(r8a66597) (r8a66597->pdata->sudmac)
|
|
struct r8a66597_pipe_info {
|
|
u16 pipe;
|
|
u16 epnum;
|
|
u16 maxpacket;
|
|
u16 type;
|
|
u16 interval;
|
|
u16 dir_in;
|
|
};
|
|
|
|
struct r8a66597_request {
|
|
struct usb_request req;
|
|
struct list_head queue;
|
|
};
|
|
|
|
struct r8a66597_ep {
|
|
struct usb_ep ep;
|
|
struct r8a66597 *r8a66597;
|
|
struct r8a66597_dma *dma;
|
|
|
|
struct list_head queue;
|
|
unsigned busy:1;
|
|
unsigned wedge:1;
|
|
unsigned internal_ccpl:1; /* use only control */
|
|
|
|
/* this member can able to after r8a66597_enable */
|
|
unsigned use_dma:1;
|
|
u16 pipenum;
|
|
u16 type;
|
|
|
|
/* register address */
|
|
unsigned char fifoaddr;
|
|
unsigned char fifosel;
|
|
unsigned char fifoctr;
|
|
unsigned char pipectr;
|
|
unsigned char pipetre;
|
|
unsigned char pipetrn;
|
|
};
|
|
|
|
struct r8a66597_dma {
|
|
unsigned used:1;
|
|
unsigned dir:1; /* 1 = IN(write), 0 = OUT(read) */
|
|
};
|
|
|
|
struct r8a66597 {
|
|
spinlock_t lock;
|
|
void __iomem *reg;
|
|
void __iomem *sudmac_reg;
|
|
|
|
struct clk *clk;
|
|
struct r8a66597_platdata *pdata;
|
|
|
|
struct usb_gadget gadget;
|
|
struct usb_gadget_driver *driver;
|
|
|
|
struct r8a66597_ep ep[R8A66597_MAX_NUM_PIPE];
|
|
struct r8a66597_ep *pipenum2ep[R8A66597_MAX_NUM_PIPE];
|
|
struct r8a66597_ep *epaddr2ep[16];
|
|
struct r8a66597_dma dma;
|
|
|
|
struct timer_list timer;
|
|
struct usb_request *ep0_req; /* for internal request */
|
|
u16 ep0_data; /* for internal request */
|
|
u16 old_vbus;
|
|
u16 scount;
|
|
u16 old_dvsq;
|
|
u16 device_status; /* for GET_STATUS */
|
|
|
|
/* pipe config */
|
|
unsigned char bulk;
|
|
unsigned char interrupt;
|
|
unsigned char isochronous;
|
|
unsigned char num_dma;
|
|
|
|
unsigned irq_sense_low:1;
|
|
};
|
|
|
|
#define gadget_to_r8a66597(_gadget) \
|
|
container_of(_gadget, struct r8a66597, gadget)
|
|
#define r8a66597_to_gadget(r8a66597) (&r8a66597->gadget)
|
|
#define r8a66597_to_dev(r8a66597) (r8a66597->gadget.dev.parent)
|
|
|
|
static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
|
|
{
|
|
return ioread16(r8a66597->reg + offset);
|
|
}
|
|
|
|
static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
|
|
unsigned long offset,
|
|
unsigned char *buf,
|
|
int len)
|
|
{
|
|
void __iomem *fifoaddr = r8a66597->reg + offset;
|
|
unsigned int data = 0;
|
|
int i;
|
|
|
|
if (r8a66597->pdata->on_chip) {
|
|
/* 32-bit accesses for on_chip controllers */
|
|
|
|
/* aligned buf case */
|
|
if (len >= 4 && !((unsigned long)buf & 0x03)) {
|
|
ioread32_rep(fifoaddr, buf, len / 4);
|
|
buf += len & ~0x03;
|
|
len &= 0x03;
|
|
}
|
|
|
|
/* unaligned buf case */
|
|
for (i = 0; i < len; i++) {
|
|
if (!(i & 0x03))
|
|
data = ioread32(fifoaddr);
|
|
|
|
buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
|
|
}
|
|
} else {
|
|
/* 16-bit accesses for external controllers */
|
|
|
|
/* aligned buf case */
|
|
if (len >= 2 && !((unsigned long)buf & 0x01)) {
|
|
ioread16_rep(fifoaddr, buf, len / 2);
|
|
buf += len & ~0x01;
|
|
len &= 0x01;
|
|
}
|
|
|
|
/* unaligned buf case */
|
|
for (i = 0; i < len; i++) {
|
|
if (!(i & 0x01))
|
|
data = ioread16(fifoaddr);
|
|
|
|
buf[i] = (data >> ((i & 0x01) * 8)) & 0xff;
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
|
|
unsigned long offset)
|
|
{
|
|
iowrite16(val, r8a66597->reg + offset);
|
|
}
|
|
|
|
static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
|
|
u16 val, u16 pat, unsigned long offset)
|
|
{
|
|
u16 tmp;
|
|
tmp = r8a66597_read(r8a66597, offset);
|
|
tmp = tmp & (~pat);
|
|
tmp = tmp | val;
|
|
r8a66597_write(r8a66597, tmp, offset);
|
|
}
|
|
|
|
#define r8a66597_bclr(r8a66597, val, offset) \
|
|
r8a66597_mdfy(r8a66597, 0, val, offset)
|
|
#define r8a66597_bset(r8a66597, val, offset) \
|
|
r8a66597_mdfy(r8a66597, val, 0, offset)
|
|
|
|
static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
|
|
struct r8a66597_ep *ep,
|
|
unsigned char *buf,
|
|
int len)
|
|
{
|
|
void __iomem *fifoaddr = r8a66597->reg + ep->fifoaddr;
|
|
int adj = 0;
|
|
int i;
|
|
|
|
if (r8a66597->pdata->on_chip) {
|
|
/* 32-bit access only if buf is 32-bit aligned */
|
|
if (len >= 4 && !((unsigned long)buf & 0x03)) {
|
|
iowrite32_rep(fifoaddr, buf, len / 4);
|
|
buf += len & ~0x03;
|
|
len &= 0x03;
|
|
}
|
|
} else {
|
|
/* 16-bit access only if buf is 16-bit aligned */
|
|
if (len >= 2 && !((unsigned long)buf & 0x01)) {
|
|
iowrite16_rep(fifoaddr, buf, len / 2);
|
|
buf += len & ~0x01;
|
|
len &= 0x01;
|
|
}
|
|
}
|
|
|
|
/* adjust fifo address in the little endian case */
|
|
if (!(r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)) {
|
|
if (r8a66597->pdata->on_chip)
|
|
adj = 0x03; /* 32-bit wide */
|
|
else
|
|
adj = 0x01; /* 16-bit wide */
|
|
}
|
|
|
|
if (r8a66597->pdata->wr0_shorted_to_wr1)
|
|
r8a66597_bclr(r8a66597, MBW_16, ep->fifosel);
|
|
for (i = 0; i < len; i++)
|
|
iowrite8(buf[i], fifoaddr + adj - (i & adj));
|
|
if (r8a66597->pdata->wr0_shorted_to_wr1)
|
|
r8a66597_bclr(r8a66597, MBW_16, ep->fifosel);
|
|
}
|
|
|
|
static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata)
|
|
{
|
|
u16 clock = 0;
|
|
|
|
switch (pdata->xtal) {
|
|
case R8A66597_PLATDATA_XTAL_12MHZ:
|
|
clock = XTAL12;
|
|
break;
|
|
case R8A66597_PLATDATA_XTAL_24MHZ:
|
|
clock = XTAL24;
|
|
break;
|
|
case R8A66597_PLATDATA_XTAL_48MHZ:
|
|
clock = XTAL48;
|
|
break;
|
|
default:
|
|
printk(KERN_ERR "r8a66597: platdata clock is wrong.\n");
|
|
break;
|
|
}
|
|
|
|
return clock;
|
|
}
|
|
|
|
static inline u32 r8a66597_sudmac_read(struct r8a66597 *r8a66597,
|
|
unsigned long offset)
|
|
{
|
|
return ioread32(r8a66597->sudmac_reg + offset);
|
|
}
|
|
|
|
static inline void r8a66597_sudmac_write(struct r8a66597 *r8a66597, u32 val,
|
|
unsigned long offset)
|
|
{
|
|
iowrite32(val, r8a66597->sudmac_reg + offset);
|
|
}
|
|
|
|
#define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2)
|
|
#define get_pipetre_addr(pipenum) (PIPE1TRE + (pipenum - 1) * 4)
|
|
#define get_pipetrn_addr(pipenum) (PIPE1TRN + (pipenum - 1) * 4)
|
|
|
|
#define enable_irq_ready(r8a66597, pipenum) \
|
|
enable_pipe_irq(r8a66597, pipenum, BRDYENB)
|
|
#define disable_irq_ready(r8a66597, pipenum) \
|
|
disable_pipe_irq(r8a66597, pipenum, BRDYENB)
|
|
#define enable_irq_empty(r8a66597, pipenum) \
|
|
enable_pipe_irq(r8a66597, pipenum, BEMPENB)
|
|
#define disable_irq_empty(r8a66597, pipenum) \
|
|
disable_pipe_irq(r8a66597, pipenum, BEMPENB)
|
|
#define enable_irq_nrdy(r8a66597, pipenum) \
|
|
enable_pipe_irq(r8a66597, pipenum, NRDYENB)
|
|
#define disable_irq_nrdy(r8a66597, pipenum) \
|
|
disable_pipe_irq(r8a66597, pipenum, NRDYENB)
|
|
|
|
#endif /* __R8A66597_H__ */
|
|
|