Commit 70514bd0 authored by Ye Li's avatar Ye Li

MLK-17821-1 USB: gadget: Add the cadence USB3 gadget driver

Porting the cadence USB3 (CDNS3) driver from kernel to u-boot. We only support
the gadget (device mode), while the host mode is not supported. Users remains
to use xhci-imx8 driver for host mode.

Some changes in the CDNS3 driver porting:

1. Add match_ep call back to usb_gadget_ops. The CDNS3 gadget driver replies
   on this operation to bind the usb_ep/usb_ss_ep with the endpoint descriptor
   when function layer uses usb_ep_autoconfig to add endpoint descriptors to gadget.
   So that CDNS3 driver can know the EP information and configure the EP once the
   set configuration request is received.

2. U-boot does not have CMA, so it won't allocate uncached memory. Need to flush
   TRB and its DMA buffer before prime to usb controller and after complete transfer.

3. In core.c, we add functions to hook with u-boot. It needs uplayer like
   to pass the register base address of each part of the USB controller.

4. Force the CDNS3 gadget max speed to HS. The SuperSpeed is not supported by u-boot,
   so disable it in gadget driver. A configuration USB_CDNS3_GADGET_FORCE_HIGHSPEED is
   selected.

5. Added gadget_is_cdns3 checking to provide bcdUSB value in device descriptor.

6. Moved some new fields in usb_ep structure to usb_ss_ep, since u-boot does not have them.

7. Remove host part codes as it is not supported by this driver.
Signed-off-by: default avatarYe Li <ye.li@nxp.com>
Acked-by: default avatarPeter Chen <peter.chen@nxp.com>
parent 2fd813fc
......@@ -675,6 +675,7 @@ libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/
libs-$(CONFIG_SYS_FSL_MMDC) += drivers/ddr/fsl/
libs-$(CONFIG_ALTERA_SDRAM) += drivers/ddr/altera/
libs-y += drivers/serial/
libs-y += drivers/usb/cdns3/
libs-y += drivers/usb/dwc3/
libs-y += drivers/usb/common/
libs-y += drivers/usb/emul/
......
......@@ -51,6 +51,8 @@ source "drivers/usb/host/Kconfig"
source "drivers/usb/dwc3/Kconfig"
source "drivers/usb/cdns3/Kconfig"
source "drivers/usb/musb-new/Kconfig"
source "drivers/usb/emul/Kconfig"
......
config USB_CDNS3
tristate "Cadence USB3 Dual-Role Controller"
depends on (USB && USB_GADGET)
help
Say Y here if your system has a cadence USB3 dual-role controller.
It supports: dual-role switch Host-only, and Peripheral-only.
When compiled dynamically, the module will be called cdns3.ko.
if USB_CDNS3
config USB_CDNS3_GADGET_FORCE_HIGHSPEED
bool
config USB_CDNS3_GADGET
bool "Cadence USB3 device controller"
depends on USB_GADGET
select USB_GADGET_DUALSPEED
select USB_CDNS3_GADGET_FORCE_HIGHSPEED
help
Say Y here to enable device controller functionality of the
cadence usb3 driver.
endif
obj-$(CONFIG_USB_CDNS3) += cdns3.o
cdns3-y := core.o
cdns3-$(CONFIG_USB_CDNS3_GADGET) += gadget.o
/*
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __DRIVERS_USB_CDNS3_NXP_H
#define __DRIVERS_USB_CDNS3_NXP_H
#define USB3_CORE_CTRL1 0x00
#define USB3_CORE_CTRL2 0x04
#define USB3_INT_REG 0x08
#define USB3_CORE_STATUS 0x0c
#define XHCI_DEBUG_LINK_ST 0x10
#define XHCI_DEBUG_BUS 0x14
#define USB3_SSPHY_CTRL1 0x40
#define USB3_SSPHY_CTRL2 0x44
#define USB3_SSPHY_STATUS 0x4c
#define USB2_PHY_CTRL1 0x50
#define USB2_PHY_CTRL2 0x54
#define USB2_PHY_STATUS 0x5c
/* Register bits definition */
/* USB3_CORE_CTRL1 */
#define SW_RESET_MASK (0x3f << 26)
#define PWR_SW_RESET (1 << 31)
#define APB_SW_RESET (1 << 30)
#define AXI_SW_RESET (1 << 29)
#define RW_SW_RESET (1 << 28)
#define PHY_SW_RESET (1 << 27)
#define PHYAHB_SW_RESET (1 << 26)
#define ALL_SW_RESET (PWR_SW_RESET | APB_SW_RESET | AXI_SW_RESET | \
RW_SW_RESET | PHY_SW_RESET | PHYAHB_SW_RESET)
#define OC_DISABLE (1 << 9)
#define MDCTRL_CLK_SEL (1 << 7)
#define MODE_STRAP_MASK (0x7)
#define DEV_MODE (1 << 2)
#define HOST_MODE (1 << 1)
#define OTG_MODE (1 << 0)
/* USB3_INT_REG */
#define CLK_125_REQ (1 << 29)
#define LPM_CLK_REQ (1 << 28)
#define DEVU3_WAEKUP_EN (1 << 14)
#define OTG_WAKEUP_EN (1 << 12)
#define DEV_INT_EN (3 << 8) /* DEV INT b9:8 */
#define HOST_INT1_EN (1 << 0) /* HOST INT b7:0 */
/* USB3_CORE_STATUS */
#define MDCTRL_CLK_STATUS (1 << 15)
#define DEV_POWER_ON_READY (1 << 13)
#define HOST_POWER_ON_READY (1 << 12)
/* USB3_SSPHY_STATUS */
#define PHY_REFCLK_REQ (1 << 0)
/* PHY register definition */
#define PHY_PMA_CMN_CTRL1 (0xC800 * 4)
#define TB_ADDR_CMN_DIAG_HSCLK_SEL (0x01e0 * 4)
#define TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR (0x0084 * 4)
#define TB_ADDR_CMN_PLL0_VCOCAL_ITER_TMR (0x0085 * 4)
#define TB_ADDR_CMN_PLL0_INTDIV (0x0094 * 4)
#define TB_ADDR_CMN_PLL0_FRACDIV (0x0095 * 4)
#define TB_ADDR_CMN_PLL0_HIGH_THR (0x0096 * 4)
#define TB_ADDR_CMN_PLL0_SS_CTRL1 (0x0098 * 4)
#define TB_ADDR_CMN_PLL0_SS_CTRL2 (0x0099 * 4)
#define TB_ADDR_CMN_PLL0_DSM_DIAG (0x0097 * 4)
#define TB_ADDR_CMN_DIAG_PLL0_OVRD (0x01c2 * 4)
#define TB_ADDR_CMN_DIAG_PLL0_FBH_OVRD (0x01c0 * 4)
#define TB_ADDR_CMN_DIAG_PLL0_FBL_OVRD (0x01c1 * 4)
#define TB_ADDR_CMN_DIAG_PLL0_V2I_TUNE (0x01C5 * 4)
#define TB_ADDR_CMN_DIAG_PLL0_CP_TUNE (0x01C6 * 4)
#define TB_ADDR_CMN_DIAG_PLL0_LF_PROG (0x01C7 * 4)
#define TB_ADDR_CMN_DIAG_PLL0_TEST_MODE (0x01c4 * 4)
#define TB_ADDR_CMN_PSM_CLK_CTRL (0x0061 * 4)
#define TB_ADDR_XCVR_DIAG_RX_LANE_CAL_RST_TMR (0x40ea * 4)
#define TB_ADDR_XCVR_PSM_RCTRL (0x4001 * 4)
#define TB_ADDR_TX_PSC_A0 (0x4100 * 4)
#define TB_ADDR_TX_PSC_A1 (0x4101 * 4)
#define TB_ADDR_TX_PSC_A2 (0x4102 * 4)
#define TB_ADDR_TX_PSC_A3 (0x4103 * 4)
#define TB_ADDR_TX_DIAG_ECTRL_OVRD (0x41f5 * 4)
#define TB_ADDR_TX_PSC_CAL (0x4106 * 4)
#define TB_ADDR_TX_PSC_RDY (0x4107 * 4)
#define TB_ADDR_RX_PSC_A0 (0x8000 * 4)
#define TB_ADDR_RX_PSC_A1 (0x8001 * 4)
#define TB_ADDR_RX_PSC_A2 (0x8002 * 4)
#define TB_ADDR_RX_PSC_A3 (0x8003 * 4)
#define TB_ADDR_RX_PSC_CAL (0x8006 * 4)
#define TB_ADDR_RX_PSC_RDY (0x8007 * 4)
#define TB_ADDR_TX_TXCC_MGNLS_MULT_000 (0x4058 * 4)
#define TB_ADDR_TX_DIAG_BGREF_PREDRV_DELAY (0x41e7 * 4)
#define TB_ADDR_RX_SLC_CU_ITER_TMR (0x80e3 * 4)
#define TB_ADDR_RX_SIGDET_HL_FILT_TMR (0x8090 * 4)
#define TB_ADDR_RX_SAMP_DAC_CTRL (0x8058 * 4)
#define TB_ADDR_RX_DIAG_SIGDET_TUNE (0x81dc * 4)
#define TB_ADDR_RX_DIAG_LFPSDET_TUNE2 (0x81df * 4)
#define TB_ADDR_RX_DIAG_BS_TM (0x81f5 * 4)
#define TB_ADDR_RX_DIAG_DFE_CTRL1 (0x81d3 * 4)
#define TB_ADDR_RX_DIAG_ILL_IQE_TRIM4 (0x81c7 * 4)
#define TB_ADDR_RX_DIAG_ILL_E_TRIM0 (0x81c2 * 4)
#define TB_ADDR_RX_DIAG_ILL_IQ_TRIM0 (0x81c1 * 4)
#define TB_ADDR_RX_DIAG_ILL_IQE_TRIM6 (0x81c9 * 4)
#define TB_ADDR_RX_DIAG_RXFE_TM3 (0x81f8 * 4)
#define TB_ADDR_RX_DIAG_RXFE_TM4 (0x81f9 * 4)
#define TB_ADDR_RX_DIAG_LFPSDET_TUNE (0x81dd * 4)
#define TB_ADDR_RX_DIAG_DFE_CTRL3 (0x81d5 * 4)
#define TB_ADDR_RX_DIAG_SC2C_DELAY (0x81e1 * 4)
#define TB_ADDR_RX_REE_VGA_GAIN_NODFE (0x81bf * 4)
#define TB_ADDR_XCVR_PSM_CAL_TMR (0x4002 * 4)
#define TB_ADDR_XCVR_PSM_A0BYP_TMR (0x4004 * 4)
#define TB_ADDR_XCVR_PSM_A0IN_TMR (0x4003 * 4)
#define TB_ADDR_XCVR_PSM_A1IN_TMR (0x4005 * 4)
#define TB_ADDR_XCVR_PSM_A2IN_TMR (0x4006 * 4)
#define TB_ADDR_XCVR_PSM_A3IN_TMR (0x4007 * 4)
#define TB_ADDR_XCVR_PSM_A4IN_TMR (0x4008 * 4)
#define TB_ADDR_XCVR_PSM_A5IN_TMR (0x4009 * 4)
#define TB_ADDR_XCVR_PSM_A0OUT_TMR (0x400a * 4)
#define TB_ADDR_XCVR_PSM_A1OUT_TMR (0x400b * 4)
#define TB_ADDR_XCVR_PSM_A2OUT_TMR (0x400c * 4)
#define TB_ADDR_XCVR_PSM_A3OUT_TMR (0x400d * 4)
#define TB_ADDR_XCVR_PSM_A4OUT_TMR (0x400e * 4)
#define TB_ADDR_XCVR_PSM_A5OUT_TMR (0x400f * 4)
#define TB_ADDR_TX_RCVDET_EN_TMR (0x4122 * 4)
#define TB_ADDR_TX_RCVDET_ST_TMR (0x4123 * 4)
#define TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR (0x40f2 * 4)
#define TB_ADDR_TX_RCVDETSC_CTRL (0x4124 * 4)
/* Register bits definition */
/* TB_ADDR_TX_RCVDETSC_CTRL */
#define RXDET_IN_P3_32KHZ (1 << 0)
/* OTG registers definition */
#define OTGSTS 0x4
#define OTGREFCLK 0xc
/* Register bits definition */
/* OTGSTS */
#define OTG_NRDY (1 << 11)
/* OTGREFCLK */
#define OTG_STB_CLK_SWITCH_EN (1 << 31)
/* xHCI registers definition */
#define XECP_PORT_CAP_REG 0x8000
#define XECP_PM_PMCSR 0x8018
#define XECP_AUX_CTRL_REG1 0x8120
/* Register bits definition */
/* XECP_PORT_CAP_REG */
#define LPM_2_STB_SWITCH_EN (1 << 25)
/* XECP_AUX_CTRL_REG1 */
#define CFG_RXDET_P3_EN (1 << 15)
/* XECP_PM_PMCSR */
#define PS_D0 (1 << 0)
#endif /* __DRIVERS_USB_CDNS3_NXP_H */
This diff is collapsed.
/*
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __DRIVERS_USB_CDNS3_CORE_H
#define __DRIVERS_USB_CDNS3_CORE_H
struct cdns3;
enum cdns3_roles {
CDNS3_ROLE_HOST = 0,
CDNS3_ROLE_GADGET,
CDNS3_ROLE_END,
};
/**
* struct cdns3_role_driver - host/gadget role driver
* @start: start this role
* @stop: stop this role
* @suspend: suspend callback for this role
* @resume: resume callback for this role
* @irq: irq handler for this role
* @name: role name string (host/gadget)
*/
struct cdns3_role_driver {
int (*start)(struct cdns3 *);
void (*stop)(struct cdns3 *);
int (*suspend)(struct cdns3 *, bool do_wakeup);
int (*resume)(struct cdns3 *, bool hibernated);
int (*irq)(struct cdns3 *);
const char *name;
};
#define CDNS3_NUM_OF_CLKS 5
/**
* struct cdns3 - Representation of Cadence USB3 DRD controller.
* @dev: pointer to Cadence device struct
* @xhci_regs: pointer to base of xhci registers
* @xhci_res: the resource for xhci
* @dev_regs: pointer to base of dev registers
* @none_core_regs: pointer to base of nxp wrapper registers
* @phy_regs: pointer to base of phy registers
* @otg_regs: pointer to base of otg registers
* @irq: irq number for controller
* @roles: array of supported roles for this controller
* @role: current role
* @host_dev: the child host device pointer for cdns3 core
* @gadget_dev: the child gadget device pointer for cdns3 core
* @usbphy: usbphy for this controller
* @cdns3_clks: Clock pointer array for cdns3 core
* @extcon: Type-C extern connector
* @extcon_nb: notifier block for Type-C extern connector
* @role_switch_wq: work queue item for role switch
* @in_lpm: the controller in low power mode
* @wakeup_int: the wakeup interrupt
*/
struct cdns3 {
struct device *dev;
void __iomem *xhci_regs;
struct resource *xhci_res;
struct usbss_dev_register_block_type __iomem *dev_regs;
void __iomem *none_core_regs;
void __iomem *phy_regs;
void __iomem *otg_regs;
int irq;
struct cdns3_role_driver *roles[CDNS3_ROLE_END];
enum cdns3_roles role;
struct device *host_dev;
struct device *gadget_dev;
struct clk *cdns3_clks[CDNS3_NUM_OF_CLKS];
int index;
struct list_head list;
};
static inline struct cdns3_role_driver *cdns3_role(struct cdns3 *cdns)
{
WARN_ON(cdns->role >= CDNS3_ROLE_END || !cdns->roles[cdns->role]);
return cdns->roles[cdns->role];
}
static inline int cdns3_role_start(struct cdns3 *cdns, enum cdns3_roles role)
{
if (role >= CDNS3_ROLE_END)
return 0;
if (!cdns->roles[role])
return -ENXIO;
cdns->role = role;
return cdns->roles[role]->start(cdns);
}
static inline void cdns3_role_stop(struct cdns3 *cdns)
{
enum cdns3_roles role = cdns->role;
if (role == CDNS3_ROLE_END)
return;
cdns->roles[role]->stop(cdns);
cdns->role = CDNS3_ROLE_END;
}
static inline void cdns3_role_irq_handler(struct cdns3 *cdns)
{
enum cdns3_roles role = cdns->role;
if (role == CDNS3_ROLE_END)
return;
cdns->roles[role]->irq(cdns);
}
#endif /* __DRIVERS_USB_CDNS3_CORE_H */
This diff is collapsed.
/*
* Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __REG_USBSS_DEV_ADDR_MAP_H__
#define __REG_USBSS_DEV_ADDR_MAP_H__
#include "dev-regs-macro.h"
struct usbss_dev_register_block_type {
uint32_t usb_conf; /* 0x0 - 0x4 */
uint32_t usb_sts; /* 0x4 - 0x8 */
uint32_t usb_cmd; /* 0x8 - 0xc */
uint32_t usb_iptn; /* 0xc - 0x10 */
uint32_t usb_lpm; /* 0x10 - 0x14 */
uint32_t usb_ien; /* 0x14 - 0x18 */
uint32_t usb_ists; /* 0x18 - 0x1c */
uint32_t ep_sel; /* 0x1c - 0x20 */
uint32_t ep_traddr; /* 0x20 - 0x24 */
uint32_t ep_cfg; /* 0x24 - 0x28 */
uint32_t ep_cmd; /* 0x28 - 0x2c */
uint32_t ep_sts; /* 0x2c - 0x30 */
uint32_t ep_sts_sid; /* 0x30 - 0x34 */
uint32_t ep_sts_en; /* 0x34 - 0x38 */
uint32_t drbl; /* 0x38 - 0x3c */
uint32_t ep_ien; /* 0x3c - 0x40 */
uint32_t ep_ists; /* 0x40 - 0x44 */
uint32_t usb_pwr; /* 0x44 - 0x48 */
uint32_t usb_conf2; /* 0x48 - 0x4c */
uint32_t usb_cap1; /* 0x4c - 0x50 */
uint32_t usb_cap2; /* 0x50 - 0x54 */
uint32_t usb_cap3; /* 0x54 - 0x58 */
uint32_t usb_cap4; /* 0x58 - 0x5c */
uint32_t usb_cap5; /* 0x5c - 0x60 */
uint32_t PAD2_73; /* 0x60 - 0x64 */
uint32_t usb_cpkt1; /* 0x64 - 0x68 */
uint32_t usb_cpkt2; /* 0x68 - 0x6c */
uint32_t usb_cpkt3; /* 0x6c - 0x70 */
char pad__0[0x90]; /* 0x70 - 0x100 */
uint32_t PAD2_78; /* 0x100 - 0x104 */
uint32_t dbg_link1; /* 0x104 - 0x108 */
uint32_t PAD2_80; /* 0x108 - 0x10c */
uint32_t PAD2_81; /* 0x10c - 0x110 */
uint32_t PAD2_82; /* 0x110 - 0x114 */
uint32_t PAD2_83; /* 0x114 - 0x118 */
uint32_t PAD2_84; /* 0x118 - 0x11c */
uint32_t PAD2_85; /* 0x11c - 0x120 */
uint32_t PAD2_86; /* 0x120 - 0x124 */
uint32_t PAD2_87; /* 0x124 - 0x128 */
uint32_t PAD2_88; /* 0x128 - 0x12c */
uint32_t PAD2_89; /* 0x12c - 0x130 */
uint32_t PAD2_90; /* 0x130 - 0x134 */
uint32_t PAD2_91; /* 0x134 - 0x138 */
uint32_t PAD2_92; /* 0x138 - 0x13c */
uint32_t PAD2_93; /* 0x13c - 0x140 */
uint32_t PAD2_94; /* 0x140 - 0x144 */
uint32_t PAD2_95; /* 0x144 - 0x148 */
uint32_t PAD2_96; /* 0x148 - 0x14c */
uint32_t PAD2_97; /* 0x14c - 0x150 */
uint32_t PAD2_98; /* 0x150 - 0x154 */
uint32_t PAD2_99; /* 0x154 - 0x158 */
uint32_t PAD2_100; /* 0x158 - 0x15c */
uint32_t PAD2_101; /* 0x15c - 0x160 */
uint32_t PAD2_102; /* 0x160 - 0x164 */
uint32_t PAD2_103; /* 0x164 - 0x168 */
uint32_t PAD2_104; /* 0x168 - 0x16c */
uint32_t PAD2_105; /* 0x16c - 0x170 */
uint32_t PAD2_106; /* 0x170 - 0x174 */
uint32_t PAD2_107; /* 0x174 - 0x178 */
uint32_t PAD2_108; /* 0x178 - 0x17c */
uint32_t PAD2_109; /* 0x17c - 0x180 */
uint32_t PAD2_110; /* 0x180 - 0x184 */
uint32_t PAD2_111; /* 0x184 - 0x188 */
uint32_t PAD2_112; /* 0x188 - 0x18c */
char pad__1[0x20]; /* 0x18c - 0x1ac */
uint32_t PAD2_114; /* 0x1ac - 0x1b0 */
uint32_t PAD2_115; /* 0x1b0 - 0x1b4 */
uint32_t PAD2_116; /* 0x1b4 - 0x1b8 */
uint32_t PAD2_117; /* 0x1b8 - 0x1bc */
uint32_t PAD2_118; /* 0x1bc - 0x1c0 */
uint32_t PAD2_119; /* 0x1c0 - 0x1c4 */
uint32_t PAD2_120; /* 0x1c4 - 0x1c8 */
uint32_t PAD2_121; /* 0x1c8 - 0x1cc */
uint32_t PAD2_122; /* 0x1cc - 0x1d0 */
uint32_t PAD2_123; /* 0x1d0 - 0x1d4 */
uint32_t PAD2_124; /* 0x1d4 - 0x1d8 */
uint32_t PAD2_125; /* 0x1d8 - 0x1dc */
uint32_t PAD2_126; /* 0x1dc - 0x1e0 */
uint32_t PAD2_127; /* 0x1e0 - 0x1e4 */
uint32_t PAD2_128; /* 0x1e4 - 0x1e8 */
uint32_t PAD2_129; /* 0x1e8 - 0x1ec */
uint32_t PAD2_130; /* 0x1ec - 0x1f0 */
uint32_t PAD2_131; /* 0x1f0 - 0x1f4 */
uint32_t PAD2_132; /* 0x1f4 - 0x1f8 */
uint32_t PAD2_133; /* 0x1f8 - 0x1fc */
uint32_t PAD2_134; /* 0x1fc - 0x200 */
uint32_t PAD2_135; /* 0x200 - 0x204 */
uint32_t PAD2_136; /* 0x204 - 0x208 */
uint32_t PAD2_137; /* 0x208 - 0x20c */
uint32_t PAD2_138; /* 0x20c - 0x210 */
uint32_t PAD2_139; /* 0x210 - 0x214 */
uint32_t PAD2_140; /* 0x214 - 0x218 */
uint32_t PAD2_141; /* 0x218 - 0x21c */
uint32_t PAD2_142; /* 0x21c - 0x220 */
uint32_t PAD2_143; /* 0x220 - 0x224 */
uint32_t PAD2_144; /* 0x224 - 0x228 */
char pad__2[0xd8]; /* 0x228 - 0x300 */
uint32_t dma_axi_ctrl; /* 0x300 - 0x304 */
uint32_t PAD2_147; /* 0x304 - 0x308 */
uint32_t PAD2_148; /* 0x308 - 0x30c */
uint32_t PAD2_149; /* 0x30c - 0x310 */
uint32_t PAD2_150; /* 0x310 - 0x314 */
};
#endif /* __REG_USBSS_DEV_ADDR_MAP_H__ */
/*
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __CDNS3_GADGET_EXPORT_H
#define __CDNS3_GADGET_EXPORT_H
#ifdef CONFIG_USB_CDNS3_GADGET
int cdns3_gadget_init(struct cdns3 *cdns);
void cdns3_gadget_remove(struct cdns3 *cdns);
#else
static inline int cdns3_gadget_init(struct cdns3 *cdns)
{
return -ENXIO;
}
static inline void cdns3_gadget_remove(struct cdns3 *cdns)
{
}
#endif
#endif /* __CDNS3_GADGET_EXPORT_H */
This diff is collapsed.
/*
* Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __DRIVERS_CDNS3_GADGET
#define __DRIVERS_CDNS3_GADGET
#include "dev-regs-map.h"
#if IS_ENABLED(CONFIG_USB_CDNS_MISC)
#include "cdns_misc.h"
#endif
#define gadget_to_usb_ss(g) \
(container_of(g, struct usb_ss_dev, gadget))
#define to_usb_ss_ep(ep) \
(container_of(ep, struct usb_ss_endpoint, endpoint))
#define ep_to_usb_ss_ep(ep) \
(container_of(ep, struct usb_ss_endpoint, endpoint))
/*-------------------------------------------------------------------------*/
/* TRB macros */
/* Common TRB fields */
#define TRB_SET_CYCLE_BIT 1uL
#define TRB_SET_CHAIN_BIT 0x10
/* offset 0 */
#define TRB_DATA_BUFFER_POINTER_MASK 0xFFFFFFFF
#define TRB_SET_DATA_BUFFER_POINTER(p) (p & TRB_DATA_BUFFER_POINTER_MASK)
/* offset 4 */
#define TRB_TRANSFER_LENGTH_MASK 0x1FFFF
#define TRB_SET_TRANSFER_LENGTH(l) (l & TRB_TRANSFER_LENGTH_MASK)
#define TRB_BURST_LENGTH_MASK 0xFF
#define TRB_SET_BURST_LENGTH(l) ((l & TRB_BURST_LENGTH_MASK) << 24)
/* offset 8 */
#define TRB_SET_INT_ON_SHORT_PACKET 0x04
#define TRB_SET_FIFO_MODE 0x08
#define TRB_SET_INT_ON_COMPLETION 0x20
#define TRB_TYPE_NORMAL 0x400
#define TRB_STREAM_ID_MASK 0xFFFF
#define TRB_SET_STREAM_ID(sid) ((sid & TRB_STREAM_ID_MASK) << 16)
/*-------------------------------------------------------------------------*/
/* Driver numeric constants */
#define DEVICE_ADDRESS_MAX 127
/* Endpoint init values */
#define ENDPOINT_MAX_PACKET_LIMIT 1024
#define ENDPOINT_MAX_STREAMS 15
#define ENDPOINT0_MAX_PACKET_LIMIT 512
/* All endpoints except EP0 */
#define USB_SS_ENDPOINTS_MAX_COUNT 30
#define USB_SS_TRBS_NUM 32
/* Standby mode */
#define STB_CLK_SWITCH_DONE_MASK 0x200
#define STB_CLK_SWITCH_EN_MASK 0x100
#define STB_CLK_SWITCH_EN_SHIFT 8
#define ENDPOINT_MAX_PACKET_SIZE_0 0
#define ENDPOINT_MAX_PACKET_SIZE_8 8
#define ENDPOINT_MAX_PACKET_SIZE_64 64
#define ENDPOINT_MAX_PACKET_SIZE_512 512
#define ENDPOINT_MAX_PACKET_SIZE_1023 1023
#define ENDPOINT_MAX_PACKET_SIZE_1024 1024
#define SS_LINK_STATE_U3 3
#define FSHS_LPM_STATE_L2 2
#define ADDR_MODULO_8 8
#define INTERRUPT_MASK 0xFFFFFFFF
#define ACTUAL_TRANSFERRED_BYTES_MASK 0x1FFFF
#define ENDPOINT_DIR_MASK 0x80
/*-------------------------------------------------------------------------*/
/**
* IS_REG_REQUIRING_ACTIVE_REF_CLOCK - Macro checks if desired
* register requires active clock, it involves such registers as:
* EP_CFG, EP_TR_ADDR, EP_CMD, EP_SEL, USB_CONF
* @usb_ss: extended gadget object
* @reg: register address
*/
#define IS_REG_REQUIRING_ACTIVE_REF_CLOCK(usb_ss, reg) (!reg || \
(reg >= &usb_ss->regs->ep_sel && reg <= &usb_ss->regs->ep_cmd))
/**
* CAST_EP_REG_POS_TO_INDEX - Macro converts bit position of ep_ists register to
* index of endpoint object in usb_ss_dev.eps[] container
* @i: bit position of endpoint for which endpoint object is required
*
* Remember that endpoint container doesn't contain default endpoint
*/
#define CAST_EP_REG_POS_TO_INDEX(i) (((i) / 16) + ((((i) % 16) - 2) * 2))
/**
* CAST_EP_ADDR_TO_INDEX - Macro converts endpoint address to
* index of endpoint object in usb_ss_dev.eps[] container
* @ep_addr: endpoint address for which endpoint object is required
*
* Remember that endpoint container doesn't contain default endpoint
*/
#define CAST_EP_ADDR_TO_INDEX(ep_addr) \
(((ep_addr & 0x7F) - 1) + ((ep_addr & 0x80) ? 1 : 0))
/**
* CAST_EP_ADDR_TO_BIT_POS - Macro converts endpoint address to
* bit position in ep_ists register
* @ep_addr: endpoint address for which bit position is required
*
* Remember that endpoint container doesn't contain default endpoint
*/
#define CAST_EP_ADDR_TO_BIT_POS(ep_addr) \
(((uint32_t)1 << (ep_addr & 0x7F)) << ((ep_addr & 0x80) ? 16 : 0))
#define CAST_INDEX_TO_EP_ADDR(index) \
((index / 2 + 1) | ((index % 2) ? 0x80 : 0x00))
/*-------------------------------------------------------------------------*/
/* Used structs */
struct usb_ss_trb {
u32 offset0;
u32 offset4;
u32 offset8;
};
struct usb_ss_dev;
struct usb_ep_caps {
unsigned type_control:1;
unsigned type_iso:1;
unsigned type_bulk:1;
unsigned type_int:1;
unsigned dir_in:1;
unsigned dir_out:1;
};
struct usb_ss_endpoint {
struct usb_ep endpoint;
struct list_head request_list;
struct list_head ep_match_pending_list;
struct usb_ss_trb *trb_pool;
dma_addr_t trb_pool_dma;
struct usb_ss_dev *usb_ss;
char name[20];
int hw_pending_flag;
int stalled_flag;
int wedge_flag;
void *cpu_addr;
dma_addr_t dma_addr;
u8 dir;
u8 num;
u8 type;
u8 address;
bool used;
bool enabled;
struct usb_ep_caps caps;
};
struct usb_ss_dev {
struct device dev;
struct usbss_dev_register_block_type __iomem *regs;
struct usb_gadget gadget;
struct usb_gadget_driver *gadget_driver;
dma_addr_t setup_dma;
dma_addr_t trb_ep0_dma;
u32 *trb_ep0;
u8 *setup;
struct usb_ss_endpoint *eps[USB_SS_ENDPOINTS_MAX_COUNT];
int ep_nums;
struct usb_request *actual_ep0_request;
int ep0_data_dir;
int hw_configured_flag;
int wake_up_flag;
u16 isoch_delay;
spinlock_t lock;
unsigned is_connected:1;
unsigned in_standby_mode:1;
u32 usb_ien;
u32 ep_ien;
int setup_pending;
struct device *sysdev;
bool start_gadget; /* The device mode is enabled */
struct list_head ep_match_list;
};
#define OTG_STS_SELECTOR 0xF000 /* OTG status selector */
#endif /* __DRIVERS_CDNS3_GADGET */
/*
* Copyright (C) 2016 Cadence Design Systems - https://www.cadence.com/
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef __DRIVERS_USB_CDNS_IO_H
#define __DRIVERS_USB_CDNS_IO_H
#include <linux/io.h>
static inline u32 cdns_readl(uint32_t __iomem *reg)
{
u32 value = 0;
value = readl(reg);
return value;
}
static inline void cdns_writel(uint32_t __iomem *reg, u32 value)
{
writel(value, reg);
}
static inline void cdns_flush_cache(uintptr_t addr, int length)
{
flush_dcache_range(addr, addr + ROUND(length, ARCH_DMA_MINALIGN));
}
#endif /* __DRIVERS_USB_CDNS_IO_H */
/*
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0
*
*/
#ifndef __CDNS3_LINUX_COMPAT__
#define __CDNS3_LINUX_COMPAT__
#define pr_debug(format, arg...) debug(format, ##arg)
#define WARN(val, format, arg...) debug(format, ##arg)
#define dev_WARN(dev, format, arg...) debug(format, ##arg)
#define WARN_ON_ONCE(val) debug("Error %d\n", val)
static inline void *devm_kzalloc(struct device *dev, unsigned int size,
unsigned int flags)
{
return kzalloc(size, flags);