removed un-used/un-supported files from dwc3. These files can be added later as and when the support is added. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>master
parent
85d5e7075f
commit
97798eb96d
@ -1,120 +0,0 @@ |
||||
config USB_DWC3 |
||||
tristate "DesignWare USB3 DRD Core Support" |
||||
depends on (USB || USB_GADGET) && HAS_DMA |
||||
select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD |
||||
help |
||||
Say Y or M here if your system has a Dual Role SuperSpeed |
||||
USB controller based on the DesignWare USB3 IP Core. |
||||
|
||||
If you choose to build this driver is a dynamically linked |
||||
module, the module will be called dwc3.ko. |
||||
|
||||
if USB_DWC3 |
||||
|
||||
choice |
||||
bool "DWC3 Mode Selection" |
||||
default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET) |
||||
default USB_DWC3_HOST if (USB && !USB_GADGET) |
||||
default USB_DWC3_GADGET if (!USB && USB_GADGET) |
||||
|
||||
config USB_DWC3_HOST |
||||
bool "Host only mode" |
||||
depends on USB=y || USB=USB_DWC3 |
||||
help |
||||
Select this when you want to use DWC3 in host mode only, |
||||
thereby the gadget feature will be regressed. |
||||
|
||||
config USB_DWC3_GADGET |
||||
bool "Gadget only mode" |
||||
depends on USB_GADGET=y || USB_GADGET=USB_DWC3 |
||||
help |
||||
Select this when you want to use DWC3 in gadget mode only, |
||||
thereby the host feature will be regressed. |
||||
|
||||
config USB_DWC3_DUAL_ROLE |
||||
bool "Dual Role mode" |
||||
depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3)) |
||||
help |
||||
This is the default mode of working of DWC3 controller where |
||||
both host and gadget features are enabled. |
||||
|
||||
endchoice |
||||
|
||||
comment "Platform Glue Driver Support" |
||||
|
||||
config USB_DWC3_OMAP |
||||
tristate "Texas Instruments OMAP5 and similar Platforms" |
||||
depends on EXTCON && (ARCH_OMAP2PLUS || COMPILE_TEST) |
||||
depends on OF |
||||
default USB_DWC3 |
||||
help |
||||
Some platforms from Texas Instruments like OMAP5, DRA7xxx and |
||||
AM437x use this IP for USB2/3 functionality. |
||||
|
||||
Say 'Y' or 'M' here if you have one such device |
||||
|
||||
config USB_DWC3_EXYNOS |
||||
tristate "Samsung Exynos Platform" |
||||
depends on ARCH_EXYNOS && OF || COMPILE_TEST |
||||
default USB_DWC3 |
||||
help |
||||
Recent Exynos5 SoCs ship with one DesignWare Core USB3 IP inside, |
||||
say 'Y' or 'M' if you have one such device. |
||||
|
||||
config USB_DWC3_PCI |
||||
tristate "PCIe-based Platforms" |
||||
depends on PCI |
||||
default USB_DWC3 |
||||
help |
||||
If you're using the DesignWare Core IP with a PCIe, please say |
||||
'Y' or 'M' here. |
||||
|
||||
One such PCIe-based platform is Synopsys' PCIe HAPS model of |
||||
this IP. |
||||
|
||||
config USB_DWC3_KEYSTONE |
||||
tristate "Texas Instruments Keystone2 Platforms" |
||||
depends on ARCH_KEYSTONE || COMPILE_TEST |
||||
default USB_DWC3 |
||||
help |
||||
Support of USB2/3 functionality in TI Keystone2 platforms. |
||||
Say 'Y' or 'M' here if you have one such device |
||||
|
||||
config USB_DWC3_ST |
||||
tristate "STMicroelectronics Platforms" |
||||
depends on ARCH_STI && OF |
||||
default USB_DWC3 |
||||
help |
||||
STMicroelectronics SoCs with one DesignWare Core USB3 IP |
||||
inside (i.e. STiH407). |
||||
Say 'Y' or 'M' if you have one such device. |
||||
|
||||
config USB_DWC3_QCOM |
||||
tristate "Qualcomm Platforms" |
||||
depends on ARCH_QCOM || COMPILE_TEST |
||||
default USB_DWC3 |
||||
help |
||||
Recent Qualcomm SoCs ship with one DesignWare Core USB3 IP inside, |
||||
say 'Y' or 'M' if you have one such device. |
||||
|
||||
comment "Debugging features" |
||||
|
||||
config USB_DWC3_DEBUG |
||||
bool "Enable Debugging Messages" |
||||
help |
||||
Say Y here to enable debugging messages on DWC3 Driver. |
||||
|
||||
config USB_DWC3_VERBOSE |
||||
bool "Enable Verbose Debugging Messages" |
||||
depends on USB_DWC3_DEBUG |
||||
help |
||||
Say Y here to enable verbose debugging messages on DWC3 Driver. |
||||
|
||||
config DWC3_HOST_USB3_LPM_ENABLE |
||||
bool "Enable USB3 LPM Capability" |
||||
depends on USB_DWC3_HOST=y || USB_DWC3_DUAL_ROLE=y |
||||
default n |
||||
help |
||||
Select this when you want to enable USB3 LPM with dwc3 xhci host. |
||||
|
||||
endif |
@ -1,32 +0,0 @@ |
||||
/**
|
||||
* debug.c - DesignWare USB3 DRD Controller Debug/Trace Support |
||||
* |
||||
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
|
||||
* |
||||
* Author: Felipe Balbi <balbi@ti.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#include "debug.h" |
||||
|
||||
void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...) |
||||
{ |
||||
struct va_format vaf; |
||||
va_list args; |
||||
|
||||
va_start(args, fmt); |
||||
vaf.fmt = fmt; |
||||
vaf.va = &args; |
||||
|
||||
trace(&vaf); |
||||
|
||||
va_end(args); |
||||
} |
@ -1,228 +0,0 @@ |
||||
/**
|
||||
* debug.h - DesignWare USB3 DRD Controller Debug Header |
||||
* |
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
|
||||
* |
||||
* Authors: Felipe Balbi <balbi@ti.com>, |
||||
* Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#ifndef __DWC3_DEBUG_H |
||||
#define __DWC3_DEBUG_H |
||||
|
||||
#include "core.h" |
||||
|
||||
/**
|
||||
* dwc3_gadget_ep_cmd_string - returns endpoint command string |
||||
* @cmd: command code |
||||
*/ |
||||
static inline const char * |
||||
dwc3_gadget_ep_cmd_string(u8 cmd) |
||||
{ |
||||
switch (cmd) { |
||||
case DWC3_DEPCMD_DEPSTARTCFG: |
||||
return "Start New Configuration"; |
||||
case DWC3_DEPCMD_ENDTRANSFER: |
||||
return "End Transfer"; |
||||
case DWC3_DEPCMD_UPDATETRANSFER: |
||||
return "Update Transfer"; |
||||
case DWC3_DEPCMD_STARTTRANSFER: |
||||
return "Start Transfer"; |
||||
case DWC3_DEPCMD_CLEARSTALL: |
||||
return "Clear Stall"; |
||||
case DWC3_DEPCMD_SETSTALL: |
||||
return "Set Stall"; |
||||
case DWC3_DEPCMD_GETEPSTATE: |
||||
return "Get Endpoint State"; |
||||
case DWC3_DEPCMD_SETTRANSFRESOURCE: |
||||
return "Set Endpoint Transfer Resource"; |
||||
case DWC3_DEPCMD_SETEPCONFIG: |
||||
return "Set Endpoint Configuration"; |
||||
default: |
||||
return "UNKNOWN command"; |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
* dwc3_gadget_generic_cmd_string - returns generic command string |
||||
* @cmd: command code |
||||
*/ |
||||
static inline const char * |
||||
dwc3_gadget_generic_cmd_string(u8 cmd) |
||||
{ |
||||
switch (cmd) { |
||||
case DWC3_DGCMD_SET_LMP: |
||||
return "Set LMP"; |
||||
case DWC3_DGCMD_SET_PERIODIC_PAR: |
||||
return "Set Periodic Parameters"; |
||||
case DWC3_DGCMD_XMIT_FUNCTION: |
||||
return "Transmit Function Wake Device Notification"; |
||||
case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO: |
||||
return "Set Scratchpad Buffer Array Address Lo"; |
||||
case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI: |
||||
return "Set Scratchpad Buffer Array Address Hi"; |
||||
case DWC3_DGCMD_SELECTED_FIFO_FLUSH: |
||||
return "Selected FIFO Flush"; |
||||
case DWC3_DGCMD_ALL_FIFO_FLUSH: |
||||
return "All FIFO Flush"; |
||||
case DWC3_DGCMD_SET_ENDPOINT_NRDY: |
||||
return "Set Endpoint NRDY"; |
||||
case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK: |
||||
return "Run SoC Bus Loopback Test"; |
||||
default: |
||||
return "UNKNOWN"; |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
* dwc3_gadget_link_string - returns link name |
||||
* @link_state: link state code |
||||
*/ |
||||
static inline const char * |
||||
dwc3_gadget_link_string(enum dwc3_link_state link_state) |
||||
{ |
||||
switch (link_state) { |
||||
case DWC3_LINK_STATE_U0: |
||||
return "U0"; |
||||
case DWC3_LINK_STATE_U1: |
||||
return "U1"; |
||||
case DWC3_LINK_STATE_U2: |
||||
return "U2"; |
||||
case DWC3_LINK_STATE_U3: |
||||
return "U3"; |
||||
case DWC3_LINK_STATE_SS_DIS: |
||||
return "SS.Disabled"; |
||||
case DWC3_LINK_STATE_RX_DET: |
||||
return "RX.Detect"; |
||||
case DWC3_LINK_STATE_SS_INACT: |
||||
return "SS.Inactive"; |
||||
case DWC3_LINK_STATE_POLL: |
||||
return "Polling"; |
||||
case DWC3_LINK_STATE_RECOV: |
||||
return "Recovery"; |
||||
case DWC3_LINK_STATE_HRESET: |
||||
return "Hot Reset"; |
||||
case DWC3_LINK_STATE_CMPLY: |
||||
return "Compliance"; |
||||
case DWC3_LINK_STATE_LPBK: |
||||
return "Loopback"; |
||||
case DWC3_LINK_STATE_RESET: |
||||
return "Reset"; |
||||
case DWC3_LINK_STATE_RESUME: |
||||
return "Resume"; |
||||
default: |
||||
return "UNKNOWN link state\n"; |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
* dwc3_gadget_event_string - returns event name |
||||
* @event: the event code |
||||
*/ |
||||
static inline const char *dwc3_gadget_event_string(u8 event) |
||||
{ |
||||
switch (event) { |
||||
case DWC3_DEVICE_EVENT_DISCONNECT: |
||||
return "Disconnect"; |
||||
case DWC3_DEVICE_EVENT_RESET: |
||||
return "Reset"; |
||||
case DWC3_DEVICE_EVENT_CONNECT_DONE: |
||||
return "Connection Done"; |
||||
case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: |
||||
return "Link Status Change"; |
||||
case DWC3_DEVICE_EVENT_WAKEUP: |
||||
return "WakeUp"; |
||||
case DWC3_DEVICE_EVENT_EOPF: |
||||
return "End-Of-Frame"; |
||||
case DWC3_DEVICE_EVENT_SOF: |
||||
return "Start-Of-Frame"; |
||||
case DWC3_DEVICE_EVENT_ERRATIC_ERROR: |
||||
return "Erratic Error"; |
||||
case DWC3_DEVICE_EVENT_CMD_CMPL: |
||||
return "Command Complete"; |
||||
case DWC3_DEVICE_EVENT_OVERFLOW: |
||||
return "Overflow"; |
||||
} |
||||
|
||||
return "UNKNOWN"; |
||||
} |
||||
|
||||
/**
|
||||
* dwc3_ep_event_string - returns event name |
||||
* @event: then event code |
||||
*/ |
||||
static inline const char *dwc3_ep_event_string(u8 event) |
||||
{ |
||||
switch (event) { |
||||
case DWC3_DEPEVT_XFERCOMPLETE: |
||||
return "Transfer Complete"; |
||||
case DWC3_DEPEVT_XFERINPROGRESS: |
||||
return "Transfer In-Progress"; |
||||
case DWC3_DEPEVT_XFERNOTREADY: |
||||
return "Transfer Not Ready"; |
||||
case DWC3_DEPEVT_RXTXFIFOEVT: |
||||
return "FIFO"; |
||||
case DWC3_DEPEVT_STREAMEVT: |
||||
return "Stream"; |
||||
case DWC3_DEPEVT_EPCMDCMPLT: |
||||
return "Endpoint Command Complete"; |
||||
} |
||||
|
||||
return "UNKNOWN"; |
||||
} |
||||
|
||||
/**
|
||||
* dwc3_gadget_event_type_string - return event name |
||||
* @event: the event code |
||||
*/ |
||||
static inline const char *dwc3_gadget_event_type_string(u8 event) |
||||
{ |
||||
switch (event) { |
||||
case DWC3_DEVICE_EVENT_DISCONNECT: |
||||
return "Disconnect"; |
||||
case DWC3_DEVICE_EVENT_RESET: |
||||
return "Reset"; |
||||
case DWC3_DEVICE_EVENT_CONNECT_DONE: |
||||
return "Connect Done"; |
||||
case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: |
||||
return "Link Status Change"; |
||||
case DWC3_DEVICE_EVENT_WAKEUP: |
||||
return "Wake-Up"; |
||||
case DWC3_DEVICE_EVENT_HIBER_REQ: |
||||
return "Hibernation"; |
||||
case DWC3_DEVICE_EVENT_EOPF: |
||||
return "End of Periodic Frame"; |
||||
case DWC3_DEVICE_EVENT_SOF: |
||||
return "Start of Frame"; |
||||
case DWC3_DEVICE_EVENT_ERRATIC_ERROR: |
||||
return "Erratic Error"; |
||||
case DWC3_DEVICE_EVENT_CMD_CMPL: |
||||
return "Command Complete"; |
||||
case DWC3_DEVICE_EVENT_OVERFLOW: |
||||
return "Overflow"; |
||||
default: |
||||
return "UNKNOWN"; |
||||
} |
||||
} |
||||
|
||||
void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...); |
||||
|
||||
#ifdef CONFIG_DEBUG_FS |
||||
extern int dwc3_debugfs_init(struct dwc3 *); |
||||
extern void dwc3_debugfs_exit(struct dwc3 *); |
||||
#else |
||||
static inline int dwc3_debugfs_init(struct dwc3 *d) |
||||
{ return 0; } |
||||
static inline void dwc3_debugfs_exit(struct dwc3 *d) |
||||
{ } |
||||
#endif |
||||
#endif /* __DWC3_DEBUG_H */ |
@ -1,690 +0,0 @@ |
||||
/**
|
||||
* debugfs.c - DesignWare USB3 DRD Controller DebugFS file |
||||
* |
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
|
||||
* |
||||
* Authors: Felipe Balbi <balbi@ti.com>, |
||||
* Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#include <linux/kernel.h> |
||||
#include <linux/slab.h> |
||||
#include <linux/ptrace.h> |
||||
#include <linux/types.h> |
||||
#include <linux/spinlock.h> |
||||
#include <linux/debugfs.h> |
||||
#include <linux/seq_file.h> |
||||
#include <linux/delay.h> |
||||
#include <linux/uaccess.h> |
||||
|
||||
#include <linux/usb/ch9.h> |
||||
|
||||
#include "core.h" |
||||
#include "gadget.h" |
||||
#include "io.h" |
||||
#include "debug.h" |
||||
|
||||
#define dump_register(nm) \ |
||||
{ \
|
||||
.name = __stringify(nm), \
|
||||
.offset = DWC3_ ##nm - DWC3_GLOBALS_REGS_START, \
|
||||
} |
||||
|
||||
static const struct debugfs_reg32 dwc3_regs[] = { |
||||
dump_register(GSBUSCFG0), |
||||
dump_register(GSBUSCFG1), |
||||
dump_register(GTXTHRCFG), |
||||
dump_register(GRXTHRCFG), |
||||
dump_register(GCTL), |
||||
dump_register(GEVTEN), |
||||
dump_register(GSTS), |
||||
dump_register(GSNPSID), |
||||
dump_register(GGPIO), |
||||
dump_register(GUID), |
||||
dump_register(GUCTL), |
||||
dump_register(GBUSERRADDR0), |
||||
dump_register(GBUSERRADDR1), |
||||
dump_register(GPRTBIMAP0), |
||||
dump_register(GPRTBIMAP1), |
||||
dump_register(GHWPARAMS0), |
||||
dump_register(GHWPARAMS1), |
||||
dump_register(GHWPARAMS2), |
||||
dump_register(GHWPARAMS3), |
||||
dump_register(GHWPARAMS4), |
||||
dump_register(GHWPARAMS5), |
||||
dump_register(GHWPARAMS6), |
||||
dump_register(GHWPARAMS7), |
||||
dump_register(GDBGFIFOSPACE), |
||||
dump_register(GDBGLTSSM), |
||||
dump_register(GPRTBIMAP_HS0), |
||||
dump_register(GPRTBIMAP_HS1), |
||||
dump_register(GPRTBIMAP_FS0), |
||||
dump_register(GPRTBIMAP_FS1), |
||||
|
||||
dump_register(GUSB2PHYCFG(0)), |
||||
dump_register(GUSB2PHYCFG(1)), |
||||
dump_register(GUSB2PHYCFG(2)), |
||||
dump_register(GUSB2PHYCFG(3)), |
||||
dump_register(GUSB2PHYCFG(4)), |
||||
dump_register(GUSB2PHYCFG(5)), |
||||
dump_register(GUSB2PHYCFG(6)), |
||||
dump_register(GUSB2PHYCFG(7)), |
||||
dump_register(GUSB2PHYCFG(8)), |
||||
dump_register(GUSB2PHYCFG(9)), |
||||
dump_register(GUSB2PHYCFG(10)), |
||||
dump_register(GUSB2PHYCFG(11)), |
||||
dump_register(GUSB2PHYCFG(12)), |
||||
dump_register(GUSB2PHYCFG(13)), |
||||
dump_register(GUSB2PHYCFG(14)), |
||||
dump_register(GUSB2PHYCFG(15)), |
||||
|
||||
dump_register(GUSB2I2CCTL(0)), |
||||
dump_register(GUSB2I2CCTL(1)), |
||||
dump_register(GUSB2I2CCTL(2)), |
||||
dump_register(GUSB2I2CCTL(3)), |
||||
dump_register(GUSB2I2CCTL(4)), |
||||
dump_register(GUSB2I2CCTL(5)), |
||||
dump_register(GUSB2I2CCTL(6)), |
||||
dump_register(GUSB2I2CCTL(7)), |
||||
dump_register(GUSB2I2CCTL(8)), |
||||
dump_register(GUSB2I2CCTL(9)), |
||||
dump_register(GUSB2I2CCTL(10)), |
||||
dump_register(GUSB2I2CCTL(11)), |
||||
dump_register(GUSB2I2CCTL(12)), |
||||
dump_register(GUSB2I2CCTL(13)), |
||||
dump_register(GUSB2I2CCTL(14)), |
||||
dump_register(GUSB2I2CCTL(15)), |
||||
|
||||
dump_register(GUSB2PHYACC(0)), |
||||
dump_register(GUSB2PHYACC(1)), |
||||
dump_register(GUSB2PHYACC(2)), |
||||
dump_register(GUSB2PHYACC(3)), |
||||
dump_register(GUSB2PHYACC(4)), |
||||
dump_register(GUSB2PHYACC(5)), |
||||
dump_register(GUSB2PHYACC(6)), |
||||
dump_register(GUSB2PHYACC(7)), |
||||
dump_register(GUSB2PHYACC(8)), |
||||
dump_register(GUSB2PHYACC(9)), |
||||
dump_register(GUSB2PHYACC(10)), |
||||
dump_register(GUSB2PHYACC(11)), |
||||
dump_register(GUSB2PHYACC(12)), |
||||
dump_register(GUSB2PHYACC(13)), |
||||
dump_register(GUSB2PHYACC(14)), |
||||
dump_register(GUSB2PHYACC(15)), |
||||
|
||||
dump_register(GUSB3PIPECTL(0)), |
||||
dump_register(GUSB3PIPECTL(1)), |
||||
dump_register(GUSB3PIPECTL(2)), |
||||
dump_register(GUSB3PIPECTL(3)), |
||||
dump_register(GUSB3PIPECTL(4)), |
||||
dump_register(GUSB3PIPECTL(5)), |
||||
dump_register(GUSB3PIPECTL(6)), |
||||
dump_register(GUSB3PIPECTL(7)), |
||||
dump_register(GUSB3PIPECTL(8)), |
||||
dump_register(GUSB3PIPECTL(9)), |
||||
dump_register(GUSB3PIPECTL(10)), |
||||
dump_register(GUSB3PIPECTL(11)), |
||||
dump_register(GUSB3PIPECTL(12)), |
||||
dump_register(GUSB3PIPECTL(13)), |
||||
dump_register(GUSB3PIPECTL(14)), |
||||
dump_register(GUSB3PIPECTL(15)), |
||||
|
||||
dump_register(GTXFIFOSIZ(0)), |
||||
dump_register(GTXFIFOSIZ(1)), |
||||
dump_register(GTXFIFOSIZ(2)), |
||||
dump_register(GTXFIFOSIZ(3)), |
||||
dump_register(GTXFIFOSIZ(4)), |
||||
dump_register(GTXFIFOSIZ(5)), |
||||
dump_register(GTXFIFOSIZ(6)), |
||||
dump_register(GTXFIFOSIZ(7)), |
||||
dump_register(GTXFIFOSIZ(8)), |
||||
dump_register(GTXFIFOSIZ(9)), |
||||
dump_register(GTXFIFOSIZ(10)), |
||||
dump_register(GTXFIFOSIZ(11)), |
||||
dump_register(GTXFIFOSIZ(12)), |
||||
dump_register(GTXFIFOSIZ(13)), |
||||
dump_register(GTXFIFOSIZ(14)), |
||||
dump_register(GTXFIFOSIZ(15)), |
||||
dump_register(GTXFIFOSIZ(16)), |
||||
dump_register(GTXFIFOSIZ(17)), |
||||
dump_register(GTXFIFOSIZ(18)), |
||||
dump_register(GTXFIFOSIZ(19)), |
||||
dump_register(GTXFIFOSIZ(20)), |
||||
dump_register(GTXFIFOSIZ(21)), |
||||
dump_register(GTXFIFOSIZ(22)), |
||||
dump_register(GTXFIFOSIZ(23)), |
||||
dump_register(GTXFIFOSIZ(24)), |
||||
dump_register(GTXFIFOSIZ(25)), |
||||
dump_register(GTXFIFOSIZ(26)), |
||||
dump_register(GTXFIFOSIZ(27)), |
||||
dump_register(GTXFIFOSIZ(28)), |
||||
dump_register(GTXFIFOSIZ(29)), |
||||
dump_register(GTXFIFOSIZ(30)), |
||||
dump_register(GTXFIFOSIZ(31)), |
||||
|
||||
dump_register(GRXFIFOSIZ(0)), |
||||
dump_register(GRXFIFOSIZ(1)), |
||||
dump_register(GRXFIFOSIZ(2)), |
||||
dump_register(GRXFIFOSIZ(3)), |
||||
dump_register(GRXFIFOSIZ(4)), |
||||
dump_register(GRXFIFOSIZ(5)), |
||||
dump_register(GRXFIFOSIZ(6)), |
||||
dump_register(GRXFIFOSIZ(7)), |
||||
dump_register(GRXFIFOSIZ(8)), |
||||
dump_register(GRXFIFOSIZ(9)), |
||||
dump_register(GRXFIFOSIZ(10)), |
||||
dump_register(GRXFIFOSIZ(11)), |
||||
dump_register(GRXFIFOSIZ(12)), |
||||
dump_register(GRXFIFOSIZ(13)), |
||||
dump_register(GRXFIFOSIZ(14)), |
||||
dump_register(GRXFIFOSIZ(15)), |
||||
dump_register(GRXFIFOSIZ(16)), |
||||
dump_register(GRXFIFOSIZ(17)), |
||||
dump_register(GRXFIFOSIZ(18)), |
||||
dump_register(GRXFIFOSIZ(19)), |
||||
dump_register(GRXFIFOSIZ(20)), |
||||
dump_register(GRXFIFOSIZ(21)), |
||||
dump_register(GRXFIFOSIZ(22)), |
||||
dump_register(GRXFIFOSIZ(23)), |
||||
dump_register(GRXFIFOSIZ(24)), |
||||
dump_register(GRXFIFOSIZ(25)), |
||||
dump_register(GRXFIFOSIZ(26)), |
||||
dump_register(GRXFIFOSIZ(27)), |
||||
dump_register(GRXFIFOSIZ(28)), |
||||
dump_register(GRXFIFOSIZ(29)), |
||||
dump_register(GRXFIFOSIZ(30)), |
||||
dump_register(GRXFIFOSIZ(31)), |
||||
|
||||
dump_register(GEVNTADRLO(0)), |
||||
dump_register(GEVNTADRHI(0)), |
||||
dump_register(GEVNTSIZ(0)), |
||||
dump_register(GEVNTCOUNT(0)), |
||||
|
||||
dump_register(GHWPARAMS8), |
||||
dump_register(DCFG), |
||||
dump_register(DCTL), |
||||
dump_register(DEVTEN), |
||||
dump_register(DSTS), |
||||
dump_register(DGCMDPAR), |
||||
dump_register(DGCMD), |
||||
dump_register(DALEPENA), |
||||
|
||||
dump_register(DEPCMDPAR2(0)), |
||||
dump_register(DEPCMDPAR2(1)), |
||||
dump_register(DEPCMDPAR2(2)), |
||||
dump_register(DEPCMDPAR2(3)), |
||||
dump_register(DEPCMDPAR2(4)), |
||||
dump_register(DEPCMDPAR2(5)), |
||||
dump_register(DEPCMDPAR2(6)), |
||||
dump_register(DEPCMDPAR2(7)), |
||||
dump_register(DEPCMDPAR2(8)), |
||||
dump_register(DEPCMDPAR2(9)), |
||||
dump_register(DEPCMDPAR2(10)), |
||||
dump_register(DEPCMDPAR2(11)), |
||||
dump_register(DEPCMDPAR2(12)), |
||||
dump_register(DEPCMDPAR2(13)), |
||||
dump_register(DEPCMDPAR2(14)), |
||||
dump_register(DEPCMDPAR2(15)), |
||||
dump_register(DEPCMDPAR2(16)), |
||||
dump_register(DEPCMDPAR2(17)), |
||||
dump_register(DEPCMDPAR2(18)), |
||||
dump_register(DEPCMDPAR2(19)), |
||||
dump_register(DEPCMDPAR2(20)), |
||||
dump_register(DEPCMDPAR2(21)), |
||||
dump_register(DEPCMDPAR2(22)), |
||||
dump_register(DEPCMDPAR2(23)), |
||||
dump_register(DEPCMDPAR2(24)), |
||||
dump_register(DEPCMDPAR2(25)), |
||||
dump_register(DEPCMDPAR2(26)), |
||||
dump_register(DEPCMDPAR2(27)), |
||||
dump_register(DEPCMDPAR2(28)), |
||||
dump_register(DEPCMDPAR2(29)), |
||||
dump_register(DEPCMDPAR2(30)), |
||||
dump_register(DEPCMDPAR2(31)), |
||||
|
||||
dump_register(DEPCMDPAR1(0)), |
||||
dump_register(DEPCMDPAR1(1)), |
||||
dump_register(DEPCMDPAR1(2)), |
||||
dump_register(DEPCMDPAR1(3)), |
||||
dump_register(DEPCMDPAR1(4)), |
||||
dump_register(DEPCMDPAR1(5)), |
||||
dump_register(DEPCMDPAR1(6)), |
||||
dump_register(DEPCMDPAR1(7)), |
||||
dump_register(DEPCMDPAR1(8)), |
||||
dump_register(DEPCMDPAR1(9)), |
||||
dump_register(DEPCMDPAR1(10)), |
||||
dump_register(DEPCMDPAR1(11)), |
||||
dump_register(DEPCMDPAR1(12)), |
||||
dump_register(DEPCMDPAR1(13)), |
||||
dump_register(DEPCMDPAR1(14)), |
||||
dump_register(DEPCMDPAR1(15)), |
||||
dump_register(DEPCMDPAR1(16)), |
||||
dump_register(DEPCMDPAR1(17)), |
||||
dump_register(DEPCMDPAR1(18)), |
||||
dump_register(DEPCMDPAR1(19)), |
||||
dump_register(DEPCMDPAR1(20)), |
||||
dump_register(DEPCMDPAR1(21)), |
||||
dump_register(DEPCMDPAR1(22)), |
||||
dump_register(DEPCMDPAR1(23)), |
||||
dump_register(DEPCMDPAR1(24)), |
||||
dump_register(DEPCMDPAR1(25)), |
||||
dump_register(DEPCMDPAR1(26)), |
||||
dump_register(DEPCMDPAR1(27)), |
||||
dump_register(DEPCMDPAR1(28)), |
||||
dump_register(DEPCMDPAR1(29)), |
||||
dump_register(DEPCMDPAR1(30)), |
||||
dump_register(DEPCMDPAR1(31)), |
||||
|
||||
dump_register(DEPCMDPAR0(0)), |
||||
dump_register(DEPCMDPAR0(1)), |
||||
dump_register(DEPCMDPAR0(2)), |
||||
dump_register(DEPCMDPAR0(3)), |
||||
dump_register(DEPCMDPAR0(4)), |
||||
dump_register(DEPCMDPAR0(5)), |
||||
dump_register(DEPCMDPAR0(6)), |
||||
dump_register(DEPCMDPAR0(7)), |
||||
dump_register(DEPCMDPAR0(8)), |
||||
dump_register(DEPCMDPAR0(9)), |
||||
dump_register(DEPCMDPAR0(10)), |
||||
dump_register(DEPCMDPAR0(11)), |
||||
dump_register(DEPCMDPAR0(12)), |
||||
dump_register(DEPCMDPAR0(13)), |
||||
dump_register(DEPCMDPAR0(14)), |
||||
dump_register(DEPCMDPAR0(15)), |
||||
dump_register(DEPCMDPAR0(16)), |
||||
dump_register(DEPCMDPAR0(17)), |
||||
dump_register(DEPCMDPAR0(18)), |
||||
dump_register(DEPCMDPAR0(19)), |
||||
dump_register(DEPCMDPAR0(20)), |
||||
dump_register(DEPCMDPAR0(21)), |
||||
dump_register(DEPCMDPAR0(22)), |
||||
dump_register(DEPCMDPAR0(23)), |
||||
dump_register(DEPCMDPAR0(24)), |
||||
dump_register(DEPCMDPAR0(25)), |
||||
dump_register(DEPCMDPAR0(26)), |
||||
dump_register(DEPCMDPAR0(27)), |
||||
dump_register(DEPCMDPAR0(28)), |
||||
dump_register(DEPCMDPAR0(29)), |
||||
dump_register(DEPCMDPAR0(30)), |
||||
dump_register(DEPCMDPAR0(31)), |
||||
|
||||
dump_register(DEPCMD(0)), |
||||
dump_register(DEPCMD(1)), |
||||
dump_register(DEPCMD(2)), |
||||
dump_register(DEPCMD(3)), |
||||
dump_register(DEPCMD(4)), |
||||
dump_register(DEPCMD(5)), |
||||
dump_register(DEPCMD(6)), |
||||
dump_register(DEPCMD(7)), |
||||
dump_register(DEPCMD(8)), |
||||
dump_register(DEPCMD(9)), |
||||
dump_register(DEPCMD(10)), |
||||
dump_register(DEPCMD(11)), |
||||
dump_register(DEPCMD(12)), |
||||
dump_register(DEPCMD(13)), |
||||
dump_register(DEPCMD(14)), |
||||
dump_register(DEPCMD(15)), |
||||
dump_register(DEPCMD(16)), |
||||
dump_register(DEPCMD(17)), |
||||
dump_register(DEPCMD(18)), |
||||
dump_register(DEPCMD(19)), |
||||
dump_register(DEPCMD(20)), |
||||
dump_register(DEPCMD(21)), |
||||
dump_register(DEPCMD(22)), |
||||
dump_register(DEPCMD(23)), |
||||
dump_register(DEPCMD(24)), |
||||
dump_register(DEPCMD(25)), |
||||
dump_register(DEPCMD(26)), |
||||
dump_register(DEPCMD(27)), |
||||
dump_register(DEPCMD(28)), |
||||
dump_register(DEPCMD(29)), |
||||
dump_register(DEPCMD(30)), |
||||
dump_register(DEPCMD(31)), |
||||
|
||||
dump_register(OCFG), |
||||
dump_register(OCTL), |
||||
dump_register(OEVT), |
||||
dump_register(OEVTEN), |
||||
dump_register(OSTS), |
||||
}; |
||||
|
||||
static int dwc3_mode_show(struct seq_file *s, void *unused) |
||||
{ |
||||
struct dwc3 *dwc = s->private; |
||||
unsigned long flags; |
||||
u32 reg; |
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags); |
||||
reg = dwc3_readl(dwc->regs, DWC3_GCTL); |
||||
spin_unlock_irqrestore(&dwc->lock, flags); |
||||
|
||||
switch (DWC3_GCTL_PRTCAP(reg)) { |
||||
case DWC3_GCTL_PRTCAP_HOST: |
||||
seq_printf(s, "host\n"); |
||||
break; |
||||
case DWC3_GCTL_PRTCAP_DEVICE: |
||||
seq_printf(s, "device\n"); |
||||
break; |
||||
case DWC3_GCTL_PRTCAP_OTG: |
||||
seq_printf(s, "OTG\n"); |
||||
break; |
||||
default: |
||||
seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg)); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int dwc3_mode_open(struct inode *inode, struct file *file) |
||||
{ |
||||
return single_open(file, dwc3_mode_show, inode->i_private); |
||||
} |
||||
|
||||
static ssize_t dwc3_mode_write(struct file *file, |
||||
const char __user *ubuf, size_t count, loff_t *ppos) |
||||
{ |
||||
struct seq_file *s = file->private_data; |
||||
struct dwc3 *dwc = s->private; |
||||
unsigned long flags; |
||||
u32 mode = 0; |
||||
char buf[32]; |
||||
|
||||
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
||||
return -EFAULT; |
||||
|
||||
if (!strncmp(buf, "host", 4)) |
||||
mode |= DWC3_GCTL_PRTCAP_HOST; |
||||
|
||||
if (!strncmp(buf, "device", 6)) |
||||
mode |= DWC3_GCTL_PRTCAP_DEVICE; |
||||
|
||||
if (!strncmp(buf, "otg", 3)) |
||||
mode |= DWC3_GCTL_PRTCAP_OTG; |
||||
|
||||
if (mode) { |
||||
spin_lock_irqsave(&dwc->lock, flags); |
||||
dwc3_set_mode(dwc, mode); |
||||
spin_unlock_irqrestore(&dwc->lock, flags); |
||||
} |
||||
return count; |
||||
} |
||||
|
||||
static const struct file_operations dwc3_mode_fops = { |
||||
.open = dwc3_mode_open, |
||||
.write = dwc3_mode_write, |
||||
.read = seq_read, |
||||
.llseek = seq_lseek, |
||||
.release = single_release, |
||||
}; |
||||
|
||||
static int dwc3_testmode_show(struct seq_file *s, void *unused) |
||||
{ |
||||
struct dwc3 *dwc = s->private; |
||||
unsigned long flags; |
||||
u32 reg; |
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags); |
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
||||
reg &= DWC3_DCTL_TSTCTRL_MASK; |
||||
reg >>= 1; |
||||
spin_unlock_irqrestore(&dwc->lock, flags); |
||||
|
||||
switch (reg) { |
||||
case 0: |
||||
seq_printf(s, "no test\n"); |
||||
break; |
||||
case TEST_J: |
||||
seq_printf(s, "test_j\n"); |
||||
break; |
||||
case TEST_K: |
||||
seq_printf(s, "test_k\n"); |
||||
break; |
||||
case TEST_SE0_NAK: |
||||
seq_printf(s, "test_se0_nak\n"); |
||||
break; |
||||
case TEST_PACKET: |
||||
seq_printf(s, "test_packet\n"); |
||||
break; |
||||
case TEST_FORCE_EN: |
||||
seq_printf(s, "test_force_enable\n"); |
||||
break; |
||||
default: |
||||
seq_printf(s, "UNKNOWN %d\n", reg); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int dwc3_testmode_open(struct inode *inode, struct file *file) |
||||
{ |
||||
return single_open(file, dwc3_testmode_show, inode->i_private); |
||||
} |
||||
|
||||
static ssize_t dwc3_testmode_write(struct file *file, |
||||
const char __user *ubuf, size_t count, loff_t *ppos) |
||||
{ |
||||
struct seq_file *s = file->private_data; |
||||
struct dwc3 *dwc = s->private; |
||||
unsigned long flags; |
||||
u32 testmode = 0; |
||||
char buf[32]; |
||||
|
||||
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
||||
return -EFAULT; |
||||
|
||||
if (!strncmp(buf, "test_j", 6)) |
||||
testmode = TEST_J; |
||||
else if (!strncmp(buf, "test_k", 6)) |
||||
testmode = TEST_K; |
||||
else if (!strncmp(buf, "test_se0_nak", 12)) |
||||
testmode = TEST_SE0_NAK; |
||||
else if (!strncmp(buf, "test_packet", 11)) |
||||
testmode = TEST_PACKET; |
||||
else if (!strncmp(buf, "test_force_enable", 17)) |
||||
testmode = TEST_FORCE_EN; |
||||
else |
||||
testmode = 0; |
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags); |
||||
dwc3_gadget_set_test_mode(dwc, testmode); |
||||
spin_unlock_irqrestore(&dwc->lock, flags); |
||||
|
||||
return count; |
||||
} |
||||
|
||||
static const struct file_operations dwc3_testmode_fops = { |
||||
.open = dwc3_testmode_open, |
||||
.write = dwc3_testmode_write, |
||||
.read = seq_read, |
||||
.llseek = seq_lseek, |
||||
.release = single_release, |
||||
}; |
||||
|
||||
static int dwc3_link_state_show(struct seq_file *s, void *unused) |
||||
{ |
||||
struct dwc3 *dwc = s->private; |
||||
unsigned long flags; |
||||
enum dwc3_link_state state; |
||||
u32 reg; |
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags); |
||||
reg = dwc3_readl(dwc->regs, DWC3_DSTS); |
||||
state = DWC3_DSTS_USBLNKST(reg); |
||||
spin_unlock_irqrestore(&dwc->lock, flags); |
||||
|
||||
switch (state) { |
||||
case DWC3_LINK_STATE_U0: |
||||
seq_printf(s, "U0\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_U1: |
||||
seq_printf(s, "U1\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_U2: |
||||
seq_printf(s, "U2\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_U3: |
||||
seq_printf(s, "U3\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_SS_DIS: |
||||
seq_printf(s, "SS.Disabled\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_RX_DET: |
||||
seq_printf(s, "Rx.Detect\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_SS_INACT: |
||||
seq_printf(s, "SS.Inactive\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_POLL: |
||||
seq_printf(s, "Poll\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_RECOV: |
||||
seq_printf(s, "Recovery\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_HRESET: |
||||
seq_printf(s, "HRESET\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_CMPLY: |
||||
seq_printf(s, "Compliance\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_LPBK: |
||||
seq_printf(s, "Loopback\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_RESET: |
||||
seq_printf(s, "Reset\n"); |
||||
break; |
||||
case DWC3_LINK_STATE_RESUME: |
||||
seq_printf(s, "Resume\n"); |
||||
break; |
||||
default: |
||||
seq_printf(s, "UNKNOWN %d\n", state); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int dwc3_link_state_open(struct inode *inode, struct file *file) |
||||
{ |
||||
return single_open(file, dwc3_link_state_show, inode->i_private); |
||||
} |
||||
|
||||
static ssize_t dwc3_link_state_write(struct file *file, |
||||
const char __user *ubuf, size_t count, loff_t *ppos) |
||||
{ |
||||
struct seq_file *s = file->private_data; |
||||
struct dwc3 *dwc = s->private; |
||||
unsigned long flags; |
||||
enum dwc3_link_state state = 0; |
||||
char buf[32]; |
||||
|
||||
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
||||
return -EFAULT; |
||||
|
||||
if (!strncmp(buf, "SS.Disabled", 11)) |
||||
state = DWC3_LINK_STATE_SS_DIS; |
||||
else if (!strncmp(buf, "Rx.Detect", 9)) |
||||
state = DWC3_LINK_STATE_RX_DET; |
||||
else if (!strncmp(buf, "SS.Inactive", 11)) |
||||
state = DWC3_LINK_STATE_SS_INACT; |
||||
else if (!strncmp(buf, "Recovery", 8)) |
||||
state = DWC3_LINK_STATE_RECOV; |
||||
else if (!strncmp(buf, "Compliance", 10)) |
||||
state = DWC3_LINK_STATE_CMPLY; |
||||
else if (!strncmp(buf, "Loopback", 8)) |
||||
state = DWC3_LINK_STATE_LPBK; |
||||
else |
||||
return -EINVAL; |
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags); |
||||
dwc3_gadget_set_link_state(dwc, state); |
||||
spin_unlock_irqrestore(&dwc->lock, flags); |
||||
|
||||
return count; |
||||
} |
||||
|
||||
static const struct file_operations dwc3_link_state_fops = { |
||||
.open = dwc3_link_state_open, |
||||
.write = dwc3_link_state_write, |
||||
.read = seq_read, |
||||
.llseek = seq_lseek, |
||||
.release = single_release, |
||||
}; |
||||
|
||||
int dwc3_debugfs_init(struct dwc3 *dwc) |
||||
{ |
||||
struct dentry *root; |
||||
struct dentry *file; |
||||
int ret; |
||||
|
||||
root = debugfs_create_dir(dev_name(dwc->dev), NULL); |
||||
if (!root) { |
||||
ret = -ENOMEM; |
||||
goto err0; |
||||
} |
||||
|
||||
dwc->root = root; |
||||
|
||||
dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL); |
||||
if (!dwc->regset) { |
||||
ret = -ENOMEM; |
||||
goto err1; |
||||
} |
||||
|
||||
dwc->regset->regs = dwc3_regs; |
||||
dwc->regset->nregs = ARRAY_SIZE(dwc3_regs); |
||||
dwc->regset->base = dwc->regs; |
||||
|
||||
file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset); |
||||
if (!file) { |
||||
ret = -ENOMEM; |
||||
goto err1; |
||||
} |
||||
|
||||
if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) { |
||||
file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, |
||||
dwc, &dwc3_mode_fops); |
||||
if (!file) { |
||||
ret = -ENOMEM; |
||||
goto err1; |
||||
} |
||||
} |
||||
|
||||
if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) || |
||||
IS_ENABLED(CONFIG_USB_DWC3_GADGET)) { |
||||
file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, |
||||
dwc, &dwc3_testmode_fops); |
||||
if (!file) { |
||||
ret = -ENOMEM; |
||||
goto err1; |
||||
} |
||||
|
||||
file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, |
||||
dwc, &dwc3_link_state_fops); |
||||
if (!file) { |
||||
ret = -ENOMEM; |
||||
goto err1; |
||||
} |
||||
} |
||||
|
||||
return 0; |
||||
|
||||
err1: |
||||
debugfs_remove_recursive(root); |
||||
|
||||
err0: |
||||
return ret; |
||||
} |
||||
|
||||
void dwc3_debugfs_exit(struct dwc3 *dwc) |
||||
{ |
||||
debugfs_remove_recursive(dwc->root); |
||||
dwc->root = NULL; |
||||
} |
@ -1,301 +0,0 @@ |
||||
/**
|
||||
* dwc3-exynos.c - Samsung EXYNOS DWC3 Specific Glue layer |
||||
* |
||||
* Copyright (c) 2012 Samsung Electronics Co., Ltd. |
||||
* http://www.samsung.com
|
||||
* |
||||
* Author: Anton Tikhomirov <av.tikhomirov@samsung.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#include <linux/module.h> |
||||
#include <linux/kernel.h> |
||||
#include <linux/slab.h> |
||||
#include <linux/platform_device.h> |
||||
#include <linux/dma-mapping.h> |
||||
#include <linux/clk.h> |
||||
#include <linux/usb/otg.h> |
||||
#include <linux/usb/usb_phy_generic.h> |
||||
#include <linux/of.h> |
||||
#include <linux/of_platform.h> |
||||
#include <linux/regulator/consumer.h> |
||||
|
||||
struct dwc3_exynos { |
||||
struct platform_device *usb2_phy; |
||||
struct platform_device *usb3_phy; |
||||
struct device *dev; |
||||
|
||||
struct clk *clk; |
||||
struct clk *susp_clk; |
||||
struct clk *axius_clk; |
||||
|
||||
struct regulator *vdd33; |
||||
struct regulator *vdd10; |
||||
}; |
||||
|
||||
static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) |
||||
{ |
||||
struct usb_phy_generic_platform_data pdata; |
||||
struct platform_device *pdev; |
||||
int ret; |
||||
|
||||
memset(&pdata, 0x00, sizeof(pdata)); |
||||
|
||||
pdev = platform_device_alloc("usb_phy_generic", PLATFORM_DEVID_AUTO); |
||||
if (!pdev) |
||||
return -ENOMEM; |
||||
|
||||
exynos->usb2_phy = pdev; |
||||
pdata.type = USB_PHY_TYPE_USB2; |
||||
pdata.gpio_reset = -1; |
||||
|
||||
ret = platform_device_add_data(exynos->usb2_phy, &pdata, sizeof(pdata)); |
||||
if (ret) |
||||
goto err1; |
||||
|
||||
pdev = platform_device_alloc("usb_phy_generic", PLATFORM_DEVID_AUTO); |
||||
if (!pdev) { |
||||
ret = -ENOMEM; |
||||
goto err1; |
||||
} |
||||
|
||||
exynos->usb3_phy = pdev; |
||||
pdata.type = USB_PHY_TYPE_USB3; |
||||
|
||||
ret = platform_device_add_data(exynos->usb3_phy, &pdata, sizeof(pdata)); |
||||
if (ret) |
||||
goto err2; |
||||
|
||||
ret = platform_device_add(exynos->usb2_phy); |
||||
if (ret) |
||||
goto err2; |
||||
|
||||
ret = platform_device_add(exynos->usb3_phy); |
||||
if (ret) |
||||
goto err3; |
||||
|
||||
return 0; |
||||
|
||||
err3: |
||||
platform_device_del(exynos->usb2_phy); |
||||
|
||||
err2: |
||||
platform_device_put(exynos->usb3_phy); |
||||
|
||||
err1: |
||||
platform_device_put(exynos->usb2_phy); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int dwc3_exynos_remove_child(struct device *dev, void *unused) |
||||
{ |
||||
struct platform_device *pdev = to_platform_device(dev); |
||||
|
||||
platform_device_unregister(pdev); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int dwc3_exynos_probe(struct platform_device *pdev) |
||||
{ |
||||
struct dwc3_exynos *exynos; |
||||
struct device *dev = &pdev->dev; |
||||
struct device_node *node = dev->of_node; |
||||
|
||||
int ret; |
||||
|
||||
exynos = devm_kzalloc(dev, sizeof(*exynos), GFP_KERNEL); |
||||
if (!exynos) |
||||
return -ENOMEM; |
||||
|
||||
/*
|
||||
* Right now device-tree probed devices don't get dma_mask set. |
||||
* Since shared usb code relies on it, set it here for now. |
||||
* Once we move to full device tree support this will vanish off. |
||||
*/ |
||||
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
platform_set_drvdata(pdev, exynos); |
||||
|
||||
ret = dwc3_exynos_register_phys(exynos); |
||||
if (ret) { |
||||
dev_err(dev, "couldn't register PHYs\n"); |
||||
return ret; |
||||
} |
||||
|
||||
exynos->dev = dev; |
||||
|
||||
exynos->clk = devm_clk_get(dev, "usbdrd30"); |
||||
if (IS_ERR(exynos->clk)) { |
||||
dev_err(dev, "couldn't get clock\n"); |
||||
return -EINVAL; |
||||
} |
||||
clk_prepare_enable(exynos->clk); |
||||
|
||||
exynos->susp_clk = devm_clk_get(dev, "usbdrd30_susp_clk"); |
||||
if (IS_ERR(exynos->susp_clk)) { |
||||
dev_dbg(dev, "no suspend clk specified\n"); |
||||
exynos->susp_clk = NULL; |
||||
} |
||||
clk_prepare_enable(exynos->susp_clk); |
||||
|
||||
if (of_device_is_compatible(node, "samsung,exynos7-dwusb3")) { |
||||
exynos->axius_clk = devm_clk_get(dev, "usbdrd30_axius_clk"); |
||||
if (IS_ERR(exynos->axius_clk)) { |
||||
dev_err(dev, "no AXI UpScaler clk specified\n"); |
||||
return -ENODEV; |
||||
} |
||||
clk_prepare_enable(exynos->axius_clk); |
||||
} else { |
||||
exynos->axius_clk = NULL; |
||||
} |
||||
|
||||
exynos->vdd33 = devm_regulator_get(dev, "vdd33"); |
||||
if (IS_ERR(exynos->vdd33)) { |
||||
ret = PTR_ERR(exynos->vdd33); |
||||
goto err2; |
||||
} |
||||
ret = regulator_enable(exynos->vdd33); |
||||
if (ret) { |
||||
dev_err(dev, "Failed to enable VDD33 supply\n"); |
||||
goto err2; |
||||
} |
||||
|
||||
exynos->vdd10 = devm_regulator_get(dev, "vdd10"); |
||||
if (IS_ERR(exynos->vdd10)) { |
||||
ret = PTR_ERR(exynos->vdd10); |
||||
goto err3; |
||||
} |
||||
ret = regulator_enable(exynos->vdd10); |
||||
if (ret) { |
||||
dev_err(dev, "Failed to enable VDD10 supply\n"); |
||||
goto err3; |
||||
} |
||||
|
||||
if (node) { |
||||
ret = of_platform_populate(node, NULL, NULL, dev); |
||||
if (ret) { |
||||
dev_err(dev, "failed to add dwc3 core\n"); |
||||
goto err4; |
||||
} |
||||
} else { |
||||
dev_err(dev, "no device node, failed to add dwc3 core\n"); |
||||
ret = -ENODEV; |
||||
goto err4; |
||||
} |
||||
|
||||
return 0; |
||||
|
||||
err4: |
||||
regulator_disable(exynos->vdd10); |
||||
err3: |
||||
regulator_disable(exynos->vdd33); |
||||
err2: |
||||
clk_disable_unprepare(exynos->axius_clk); |
||||
clk_disable_unprepare(exynos->susp_clk); |
||||
clk_disable_unprepare(exynos->clk); |
||||
return ret; |
||||
} |
||||
|
||||
static int dwc3_exynos_remove(struct platform_device *pdev) |
||||
{ |
||||
struct dwc3_exynos *exynos = platform_get_drvdata(pdev); |
||||
|
||||
device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child); |
||||
platform_device_unregister(exynos->usb2_phy); |
||||
platform_device_unregister(exynos->usb3_phy); |
||||
|
||||
clk_disable_unprepare(exynos->axius_clk); |
||||
clk_disable_unprepare(exynos->susp_clk); |
||||
clk_disable_unprepare(exynos->clk); |
||||
|
||||
regulator_disable(exynos->vdd33); |
||||
regulator_disable(exynos->vdd10); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static const struct of_device_id exynos_dwc3_match[] = { |
||||
{ .compatible = "samsung,exynos5250-dwusb3" }, |
||||
{ .compatible = "samsung,exynos7-dwusb3" }, |
||||
{}, |
||||
}; |
||||
MODULE_DEVICE_TABLE(of, exynos_dwc3_match); |
||||
|
||||
#ifdef CONFIG_PM_SLEEP |
||||
static int dwc3_exynos_suspend(struct device *dev) |
||||
{ |
||||
struct dwc3_exynos *exynos = dev_get_drvdata(dev); |
||||
|
||||
clk_disable(exynos->axius_clk); |
||||
clk_disable(exynos->clk); |
||||
|
||||
regulator_disable(exynos->vdd33); |
||||
regulator_disable(exynos->vdd10); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int dwc3_exynos_resume(struct device *dev) |
||||
{ |
||||
struct dwc3_exynos *exynos = dev_get_drvdata(dev); |
||||
int ret; |
||||
|
||||
ret = regulator_enable(exynos->vdd33); |
||||
if (ret) { |
||||
dev_err(dev, "Failed to enable VDD33 supply\n"); |
||||
return ret; |
||||
} |
||||
ret = regulator_enable(exynos->vdd10); |
||||
if (ret) { |
||||
dev_err(dev, "Failed to enable VDD10 supply\n"); |
||||
return ret; |
||||
} |
||||
|
||||
clk_enable(exynos->clk); |
||||
clk_enable(exynos->axius_clk); |
||||
|
||||
/* runtime set active to reflect active state. */ |
||||
pm_runtime_disable(dev); |
||||
pm_runtime_set_active(dev); |
||||
pm_runtime_enable(dev); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static const struct dev_pm_ops dwc3_exynos_dev_pm_ops = { |
||||
SET_SYSTEM_SLEEP_PM_OPS(dwc3_exynos_suspend, dwc3_exynos_resume) |
||||
}; |
||||
|
||||
#define DEV_PM_OPS (&dwc3_exynos_dev_pm_ops) |
||||
#else |
||||
#define DEV_PM_OPS NULL |
||||
#endif /* CONFIG_PM_SLEEP */ |
||||
|
||||
static struct platform_driver dwc3_exynos_driver = { |
||||
.probe = dwc3_exynos_probe, |
||||
.remove = dwc3_exynos_remove, |
||||
.driver = { |
||||
.name = "exynos-dwc3", |
||||
.of_match_table = exynos_dwc3_match, |
||||
.pm = DEV_PM_OPS, |
||||
}, |
||||
}; |
||||
|
||||
module_platform_driver(dwc3_exynos_driver); |
||||
|
||||
MODULE_ALIAS("platform:exynos-dwc3"); |
||||
MODULE_AUTHOR("Anton Tikhomirov <av.tikhomirov@samsung.com>"); |
||||
MODULE_LICENSE("GPL v2"); |
||||
MODULE_DESCRIPTION("DesignWare USB3 EXYNOS Glue Layer"); |
@ -1,197 +0,0 @@ |
||||
/**
|
||||
* dwc3-keystone.c - Keystone Specific Glue layer |
||||
* |
||||
* Copyright (C) 2010-2013 Texas Instruments Incorporated - http://www.ti.com
|
||||
* |
||||
* Author: WingMan Kwok <w-kwok2@ti.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#include <linux/clk.h> |
||||
#include <linux/module.h> |
||||
#include <linux/kernel.h> |
||||
#include <linux/interrupt.h> |
||||
#include <linux/platform_device.h> |
||||
#include <linux/dma-mapping.h> |
||||
#include <linux/io.h> |
||||
#include <linux/of_platform.h> |
||||
|
||||
/* USBSS register offsets */ |
||||
#define USBSS_REVISION 0x0000 |
||||
#define USBSS_SYSCONFIG 0x0010 |
||||
#define USBSS_IRQ_EOI 0x0018 |
||||
#define USBSS_IRQSTATUS_RAW_0 0x0020 |
||||
#define USBSS_IRQSTATUS_0 0x0024 |
||||
#define USBSS_IRQENABLE_SET_0 0x0028 |
||||
#define USBSS_IRQENABLE_CLR_0 0x002c |
||||
|
||||
/* IRQ register bits */ |
||||
#define USBSS_IRQ_EOI_LINE(n) BIT(n) |
||||
#define USBSS_IRQ_EVENT_ST BIT(0) |
||||
#define USBSS_IRQ_COREIRQ_EN BIT(0) |
||||
#define USBSS_IRQ_COREIRQ_CLR BIT(0) |
||||
|
||||
static u64 kdwc3_dma_mask; |
||||
|
||||
struct dwc3_keystone { |
||||
struct device *dev; |
||||
struct clk *clk; |
||||
void __iomem *usbss; |
||||
}; |
||||
|
||||
static inline u32 kdwc3_readl(void __iomem *base, u32 offset) |
||||
{ |
||||
return readl(base + offset); |
||||
} |
||||
|
||||
static inline void kdwc3_writel(void __iomem *base, u32 offset, u32 value) |
||||
{ |
||||
writel(value, base + offset); |
||||
} |
||||
|
||||
static void kdwc3_enable_irqs(struct dwc3_keystone *kdwc) |
||||
{ |
||||
u32 val; |
||||
|
||||
val = kdwc3_readl(kdwc->usbss, USBSS_IRQENABLE_SET_0); |
||||
val |= USBSS_IRQ_COREIRQ_EN; |
||||
kdwc3_writel(kdwc->usbss, USBSS_IRQENABLE_SET_0, val); |
||||
} |
||||
|
||||
static void kdwc3_disable_irqs(struct dwc3_keystone *kdwc) |
||||
{ |
||||
u32 val; |
||||
|
||||
val = kdwc3_readl(kdwc->usbss, USBSS_IRQENABLE_SET_0); |
||||
val &= ~USBSS_IRQ_COREIRQ_EN; |
||||
kdwc3_writel(kdwc->usbss, USBSS_IRQENABLE_SET_0, val); |
||||
} |
||||
|
||||
static irqreturn_t dwc3_keystone_interrupt(int irq, void *_kdwc) |
||||
{ |
||||
struct dwc3_keystone *kdwc = _kdwc; |
||||
|
||||
kdwc3_writel(kdwc->usbss, USBSS_IRQENABLE_CLR_0, USBSS_IRQ_COREIRQ_CLR); |
||||
kdwc3_writel(kdwc->usbss, USBSS_IRQSTATUS_0, USBSS_IRQ_EVENT_ST); |
||||
kdwc3_writel(kdwc->usbss, USBSS_IRQENABLE_SET_0, USBSS_IRQ_COREIRQ_EN); |
||||
kdwc3_writel(kdwc->usbss, USBSS_IRQ_EOI, USBSS_IRQ_EOI_LINE(0)); |
||||
|
||||
return IRQ_HANDLED; |
||||
} |
||||
|
||||
static int kdwc3_probe(struct platform_device *pdev) |
||||
{ |
||||
struct device *dev = &pdev->dev; |
||||
struct device_node *node = pdev->dev.of_node; |
||||
struct dwc3_keystone *kdwc; |
||||
struct resource *res; |
||||
int error, irq; |
||||
|
||||
kdwc = devm_kzalloc(dev, sizeof(*kdwc), GFP_KERNEL); |
||||
if (!kdwc) |
||||
return -ENOMEM; |
||||
|
||||
platform_set_drvdata(pdev, kdwc); |
||||
|
||||
kdwc->dev = dev; |
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
||||
kdwc->usbss = devm_ioremap_resource(dev, res); |
||||
if (IS_ERR(kdwc->usbss)) |
||||
return PTR_ERR(kdwc->usbss); |
||||
|
||||
kdwc3_dma_mask = dma_get_mask(dev); |
||||
dev->dma_mask = &kdwc3_dma_mask; |
||||
|
||||
kdwc->clk = devm_clk_get(kdwc->dev, "usb"); |
||||
|
||||
error = clk_prepare_enable(kdwc->clk); |
||||
if (error < 0) { |
||||
dev_dbg(kdwc->dev, "unable to enable usb clock, err %d\n", |
||||
error); |
||||
return error; |
||||
} |
||||
|
||||
irq = platform_get_irq(pdev, 0); |
||||
if (irq < 0) { |
||||
dev_err(&pdev->dev, "missing irq\n"); |
||||
error = irq; |
||||
goto err_irq; |
||||
} |
||||
|
||||
error = devm_request_irq(dev, irq, dwc3_keystone_interrupt, IRQF_SHARED, |
||||
dev_name(dev), kdwc); |
||||
if (error) { |
||||
dev_err(dev, "failed to request IRQ #%d --> %d\n", |
||||
irq, error); |
||||
goto err_irq; |
||||
} |
||||
|
||||
kdwc3_enable_irqs(kdwc); |
||||
|
||||
error = of_platform_populate(node, NULL, NULL, dev); |
||||
if (error) { |
||||
dev_err(&pdev->dev, "failed to create dwc3 core\n"); |
||||
goto err_core; |
||||
} |
||||
|
||||
return 0; |
||||
|
||||
err_core: |
||||
kdwc3_disable_irqs(kdwc); |
||||
err_irq: |
||||
clk_disable_unprepare(kdwc->clk); |
||||
|
||||
return error; |
||||
} |
||||
|
||||
static int kdwc3_remove_core(struct device *dev, void *c) |
||||
{ |
||||
struct platform_device *pdev = to_platform_device(dev); |
||||
|
||||
platform_device_unregister(pdev); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int kdwc3_remove(struct platform_device *pdev) |
||||
{ |
||||
struct dwc3_keystone *kdwc = platform_get_drvdata(pdev); |
||||
|
||||
kdwc3_disable_irqs(kdwc); |
||||
device_for_each_child(&pdev->dev, NULL, kdwc3_remove_core); |
||||
clk_disable_unprepare(kdwc->clk); |
||||
platform_set_drvdata(pdev, NULL); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static const struct of_device_id kdwc3_of_match[] = { |
||||
{ .compatible = "ti,keystone-dwc3", }, |
||||
{}, |
||||
}; |
||||
MODULE_DEVICE_TABLE(of, kdwc3_of_match); |
||||
|
||||
static struct platform_driver kdwc3_driver = { |
||||
.probe = kdwc3_probe, |
||||
.remove = kdwc3_remove, |
||||
.driver = { |
||||
.name = "keystone-dwc3", |
||||
.of_match_table = kdwc3_of_match, |
||||
}, |
||||
}; |
||||
|
||||
module_platform_driver(kdwc3_driver); |
||||
|
||||
MODULE_ALIAS("platform:keystone-dwc3"); |
||||
MODULE_AUTHOR("WingMan Kwok <w-kwok2@ti.com>"); |
||||
MODULE_LICENSE("GPL v2"); |
||||
MODULE_DESCRIPTION("DesignWare USB3 KEYSTONE Glue Layer"); |
@ -1,272 +0,0 @@ |
||||
/**
|
||||
* dwc3-pci.c - PCI Specific glue layer |
||||
* |
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
|
||||
* |
||||
* Authors: Felipe Balbi <balbi@ti.com>, |
||||
* Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#include <linux/kernel.h> |
||||
#include <linux/module.h> |
||||
#include <linux/slab.h> |
||||
#include <linux/pci.h> |
||||
#include <linux/platform_device.h> |
||||
|
||||
#include <linux/usb/otg.h> |
||||
#include <linux/usb/usb_phy_generic.h> |
||||
|
||||
#include "platform_data.h" |
||||
|
||||
/* FIXME define these in <linux/pci_ids.h> */ |
||||
#define PCI_VENDOR_ID_SYNOPSYS 0x16c3 |
||||
#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd |
||||
#define PCI_DEVICE_ID_INTEL_BYT 0x0f37 |
||||
#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e |
||||
#define PCI_DEVICE_ID_INTEL_BSW 0x22B7 |
||||
|
||||
struct dwc3_pci { |
||||
struct device *dev; |
||||
struct platform_device *dwc3; |
||||
struct platform_device *usb2_phy; |
||||
struct platform_device *usb3_phy; |
||||
}; |
||||
|
||||
static int dwc3_pci_register_phys(struct dwc3_pci *glue) |
||||
{ |
||||
struct usb_phy_generic_platform_data pdata; |
||||
struct platform_device *pdev; |
||||
int ret; |
||||
|
||||
memset(&pdata, 0x00, sizeof(pdata)); |
||||
|
||||
pdev = platform_device_alloc("usb_phy_generic", 0); |
||||
if (!pdev) |
||||
return -ENOMEM; |
||||
|
||||
glue->usb2_phy = pdev; |
||||
pdata.type = USB_PHY_TYPE_USB2; |
||||
pdata.gpio_reset = -1; |
||||
|
||||
ret = platform_device_add_data(glue->usb2_phy, &pdata, sizeof(pdata)); |
||||
if (ret) |
||||
goto err1; |
||||
|
||||
pdev = platform_device_alloc("usb_phy_generic", 1); |
||||
if (!pdev) { |
||||
ret = -ENOMEM; |
||||
goto err1; |
||||
} |
||||
|
||||
glue->usb3_phy = pdev; |
||||
pdata.type = USB_PHY_TYPE_USB3; |
||||
|
||||
ret = platform_device_add_data(glue->usb3_phy, &pdata, sizeof(pdata)); |
||||
if (ret) |
||||
goto err2; |
||||
|
||||
ret = platform_device_add(glue->usb2_phy); |
||||
if (ret) |
||||
goto err2; |
||||
|
||||
ret = platform_device_add(glue->usb3_phy); |
||||
if (ret) |
||||
goto err3; |
||||
|
||||
return 0; |
||||
|
||||
err3: |
||||
platform_device_del(glue->usb2_phy); |
||||
|
||||
err2: |
||||
platform_device_put(glue->usb3_phy); |
||||
|
||||
err1: |
||||
platform_device_put(glue->usb2_phy); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int dwc3_pci_probe(struct pci_dev *pci, |
||||
const struct pci_device_id *id) |
||||
{ |
||||
struct resource res[2]; |
||||
struct platform_device *dwc3; |
||||
struct dwc3_pci *glue; |
||||
int ret; |
||||
struct device *dev = &pci->dev; |
||||
struct dwc3_platform_data dwc3_pdata; |
||||
|
||||
memset(&dwc3_pdata, 0x00, sizeof(dwc3_pdata)); |
||||
|
||||
glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); |
||||
if (!glue) |
||||
return -ENOMEM; |
||||
|
||||
glue->dev = dev; |
||||
|
||||
ret = pcim_enable_device(pci); |
||||
if (ret) { |
||||
dev_err(dev, "failed to enable pci device\n"); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
pci_set_master(pci); |
||||
|
||||
ret = dwc3_pci_register_phys(glue); |
||||
if (ret) { |
||||
dev_err(dev, "couldn't register PHYs\n"); |
||||
return ret; |
||||
} |
||||
|
||||
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); |
||||
if (!dwc3) { |
||||
dev_err(dev, "couldn't allocate dwc3 device\n"); |
||||
return -ENOMEM; |
||||
} |
||||
|
||||
memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); |
||||
|
||||
res[0].start = pci_resource_start(pci, 0); |
||||
res[0].end = pci_resource_end(pci, 0); |
||||
res[0].name = "dwc_usb3"; |
||||
res[0].flags = IORESOURCE_MEM; |
||||
|
||||
res[1].start = pci->irq; |
||||
res[1].name = "dwc_usb3"; |
||||
res[1].flags = IORESOURCE_IRQ; |
||||
|
||||
if (pci->vendor == PCI_VENDOR_ID_AMD && |
||||
pci->device == PCI_DEVICE_ID_AMD_NL_USB) { |
||||
dwc3_pdata.has_lpm_erratum = true; |
||||
dwc3_pdata.lpm_nyet_threshold = 0xf; |
||||
|
||||
dwc3_pdata.u2exit_lfps_quirk = true; |
||||
dwc3_pdata.u2ss_inp3_quirk = true; |
||||
dwc3_pdata.req_p1p2p3_quirk = true; |
||||
dwc3_pdata.del_p1p2p3_quirk = true; |
||||
dwc3_pdata.del_phy_power_chg_quirk = true; |
||||
dwc3_pdata.lfps_filter_quirk = true; |
||||
dwc3_pdata.rx_detect_poll_quirk = true; |
||||
|
||||
dwc3_pdata.tx_de_emphasis_quirk = true; |
||||
dwc3_pdata.tx_de_emphasis = 1; |
||||
|
||||
/*
|
||||
* FIXME these quirks should be removed when AMD NL |
||||
* taps out |
||||
*/ |
||||
dwc3_pdata.disable_scramble_quirk = true; |
||||
dwc3_pdata.dis_u3_susphy_quirk = true; |
||||
dwc3_pdata.dis_u2_susphy_quirk = true; |
||||
} |
||||
|
||||
ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); |
||||
if (ret) { |
||||
dev_err(dev, "couldn't add resources to dwc3 device\n"); |
||||
return ret; |
||||
} |
||||
|
||||
pci_set_drvdata(pci, glue); |
||||
|
||||
ret = platform_device_add_data(dwc3, &dwc3_pdata, sizeof(dwc3_pdata)); |
||||
if (ret) |
||||
goto err3; |
||||
|
||||
dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); |
||||
|
||||
dwc3->dev.dma_mask = dev->dma_mask; |
||||
dwc3->dev.dma_parms = dev->dma_parms; |
||||
dwc3->dev.parent = dev; |
||||
glue->dwc3 = dwc3; |
||||
|
||||
ret = platform_device_add(dwc3); |
||||
if (ret) { |
||||
dev_err(dev, "failed to register dwc3 device\n"); |
||||
goto err3; |
||||
} |
||||
|
||||
return 0; |
||||
|
||||
err3: |
||||
platform_device_put(dwc3); |
||||
return ret; |
||||
} |
||||
|
||||
static void dwc3_pci_remove(struct pci_dev *pci) |
||||
{ |
||||
struct dwc3_pci *glue = pci_get_drvdata(pci); |
||||
|
||||
platform_device_unregister(glue->dwc3); |
||||
platform_device_unregister(glue->usb2_phy); |
||||
platform_device_unregister(glue->usb3_phy); |
||||
} |
||||
|
||||
static const struct pci_device_id dwc3_pci_id_table[] = { |
||||
{ |
||||
PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, |
||||
PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), |
||||
}, |
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, |
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, |
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, |
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, |
||||
{ } /* Terminating Entry */ |
||||
}; |
||||
MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); |
||||
|
||||
#ifdef CONFIG_PM_SLEEP |
||||
static int dwc3_pci_suspend(struct device *dev) |
||||
{ |
||||
struct pci_dev *pci = to_pci_dev(dev); |
||||
|
||||
pci_disable_device(pci); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int dwc3_pci_resume(struct device *dev) |
||||
{ |
||||
struct pci_dev *pci = to_pci_dev(dev); |
||||
int ret; |
||||
|
||||
ret = pci_enable_device(pci); |
||||
if (ret) { |
||||
dev_err(dev, "can't re-enable device --> %d\n", ret); |
||||
return ret; |
||||
} |
||||
|
||||
pci_set_master(pci); |
||||
|
||||
return 0; |
||||
} |
||||
#endif /* CONFIG_PM_SLEEP */ |
||||
|
||||
static const struct dev_pm_ops dwc3_pci_dev_pm_ops = { |
||||
SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume) |
||||
}; |
||||
|
||||
static struct pci_driver dwc3_pci_driver = { |
||||
.name = "dwc3-pci", |
||||
.id_table = dwc3_pci_id_table, |
||||
.probe = dwc3_pci_probe, |
||||
.remove = dwc3_pci_remove, |
||||
.driver = { |
||||
.pm = &dwc3_pci_dev_pm_ops, |
||||
}, |
||||
}; |
||||
|
||||
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); |
||||
MODULE_LICENSE("GPL v2"); |
||||
MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer"); |
||||
|
||||
module_pci_driver(dwc3_pci_driver); |
@ -1,130 +0,0 @@ |
||||
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 and |
||||
* only version 2 as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#include <linux/clk.h> |
||||
#include <linux/err.h> |
||||
#include <linux/io.h> |
||||
#include <linux/module.h> |
||||
#include <linux/of.h> |
||||
#include <linux/of_platform.h> |
||||
#include <linux/platform_device.h> |
||||
|
||||
struct dwc3_qcom { |
||||
struct device *dev; |
||||
|
||||
struct clk *core_clk; |
||||
struct clk *iface_clk; |
||||
struct clk *sleep_clk; |
||||
}; |
||||
|
||||
static int dwc3_qcom_probe(struct platform_device *pdev) |
||||
{ |
||||
struct device_node *node = pdev->dev.of_node; |
||||
struct dwc3_qcom *qdwc; |
||||
int ret; |
||||
|
||||
qdwc = devm_kzalloc(&pdev->dev, sizeof(*qdwc), GFP_KERNEL); |
||||
if (!qdwc) |
||||
return -ENOMEM; |
||||
|
||||
platform_set_drvdata(pdev, qdwc); |
||||
|
||||
qdwc->dev = &pdev->dev; |
||||
|
||||
qdwc->core_clk = devm_clk_get(qdwc->dev, "core"); |
||||
if (IS_ERR(qdwc->core_clk)) { |
||||
dev_err(qdwc->dev, "failed to get core clock\n"); |
||||
return PTR_ERR(qdwc->core_clk); |
||||
} |
||||
|
||||
qdwc->iface_clk = devm_clk_get(qdwc->dev, "iface"); |
||||
if (IS_ERR(qdwc->iface_clk)) { |
||||
dev_dbg(qdwc->dev, "failed to get optional iface clock\n"); |
||||
qdwc->iface_clk = NULL; |
||||
} |
||||
|
||||
qdwc->sleep_clk = devm_clk_get(qdwc->dev, "sleep"); |
||||
if (IS_ERR(qdwc->sleep_clk)) { |
||||
dev_dbg(qdwc->dev, "failed to get optional sleep clock\n"); |
||||
qdwc->sleep_clk = NULL; |
||||
} |
||||
|
||||
ret = clk_prepare_enable(qdwc->core_clk); |
||||
if (ret) { |
||||
dev_err(qdwc->dev, "failed to enable core clock\n"); |
||||
goto err_core; |
||||
} |
||||
|
||||
ret = clk_prepare_enable(qdwc->iface_clk); |
||||
if (ret) { |
||||
dev_err(qdwc->dev, "failed to enable optional iface clock\n"); |
||||
goto err_iface; |
||||
} |
||||
|
||||
ret = clk_prepare_enable(qdwc->sleep_clk); |
||||
if (ret) { |
||||
dev_err(qdwc->dev, "failed to enable optional sleep clock\n"); |
||||
goto err_sleep; |
||||
} |
||||
|
||||
ret = of_platform_populate(node, NULL, NULL, qdwc->dev); |
||||
if (ret) { |
||||
dev_err(qdwc->dev, "failed to register core - %d\n", ret); |
||||
goto err_clks; |
||||
} |
||||
|
||||
return 0; |
||||
|
||||
err_clks: |
||||
clk_disable_unprepare(qdwc->sleep_clk); |
||||
err_sleep: |
||||
clk_disable_unprepare(qdwc->iface_clk); |
||||
err_iface: |
||||
clk_disable_unprepare(qdwc->core_clk); |
||||
err_core: |
||||
return ret; |
||||
} |
||||
|
||||
static int dwc3_qcom_remove(struct platform_device *pdev) |
||||
{ |
||||
struct dwc3_qcom *qdwc = platform_get_drvdata(pdev); |
||||
|
||||
of_platform_depopulate(&pdev->dev); |
||||
|
||||
clk_disable_unprepare(qdwc->sleep_clk); |
||||
clk_disable_unprepare(qdwc->iface_clk); |
||||
clk_disable_unprepare(qdwc->core_clk); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static const struct of_device_id of_dwc3_match[] = { |
||||
{ .compatible = "qcom,dwc3" }, |
||||
{ /* Sentinel */ } |
||||
}; |
||||
MODULE_DEVICE_TABLE(of, of_dwc3_match); |
||||
|
||||
static struct platform_driver dwc3_qcom_driver = { |
||||
.probe = dwc3_qcom_probe, |
||||
.remove = dwc3_qcom_remove, |
||||
.driver = { |
||||
.name = "qcom-dwc3", |
||||
.of_match_table = of_dwc3_match, |
||||
}, |
||||
}; |
||||
|
||||
module_platform_driver(dwc3_qcom_driver); |
||||
|
||||
MODULE_ALIAS("platform:qcom-dwc3"); |
||||
MODULE_LICENSE("GPL v2"); |
||||
MODULE_DESCRIPTION("DesignWare USB3 QCOM Glue Layer"); |
||||
MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>"); |
@ -1,367 +0,0 @@ |
||||
/**
|
||||
* dwc3-st.c Support for dwc3 platform devices on ST Microelectronics platforms |
||||
* |
||||
* This is a small driver for the dwc3 to provide the glue logic |
||||
* to configure the controller. Tested on STi platforms. |
||||
* |
||||
* Copyright (C) 2014 Stmicroelectronics |
||||
* |
||||
* Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
||||
* Contributors: Aymen Bouattay <aymen.bouattay@st.com> |
||||
* Peter Griffin <peter.griffin@linaro.org> |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* Inspired by dwc3-omap.c and dwc3-exynos.c. |
||||
*/ |
||||
|
||||
#include <linux/delay.h> |
||||
#include <linux/interrupt.h> |
||||
#include <linux/io.h> |
||||
#include <linux/ioport.h> |
||||
#include <linux/kernel.h> |
||||
#include <linux/mfd/syscon.h> |
||||
#include <linux/module.h> |
||||
#include <linux/of.h> |
||||
#include <linux/of_platform.h> |
||||
#include <linux/platform_device.h> |
||||
#include <linux/slab.h> |
||||
#include <linux/regmap.h> |
||||
#include <linux/reset.h> |
||||
#include <linux/usb/of.h> |
||||
|
||||
#include "core.h" |
||||
#include "io.h" |
||||
|
||||
/* glue registers */ |
||||
#define CLKRST_CTRL 0x00 |
||||
#define AUX_CLK_EN BIT(0) |
||||
#define SW_PIPEW_RESET_N BIT(4) |
||||
#define EXT_CFG_RESET_N BIT(8) |
||||
/*
|
||||
* 1'b0 : The host controller complies with the xHCI revision 0.96 |
||||
* 1'b1 : The host controller complies with the xHCI revision 1.0 |
||||
*/ |
||||
#define XHCI_REVISION BIT(12) |
||||
|
||||
#define USB2_VBUS_MNGMNT_SEL1 0x2C |
||||
/*
|
||||
* For all fields in USB2_VBUS_MNGMNT_SEL1 |
||||
* 2’b00 : Override value from Reg 0x30 is selected |
||||
* 2’b01 : utmiotg_<signal_name> from usb3_top is selected |
||||
* 2’b10 : pipew_<signal_name> from PIPEW instance is selected |
||||
* 2’b11 : value is 1'b0 |
||||
*/ |
||||
#define USB2_VBUS_REG30 0x0 |
||||
#define USB2_VBUS_UTMIOTG 0x1 |
||||
#define USB2_VBUS_PIPEW 0x2 |
||||
#define USB2_VBUS_ZERO 0x3 |
||||
|
||||
#define SEL_OVERRIDE_VBUSVALID(n) (n << 0) |
||||
#define SEL_OVERRIDE_POWERPRESENT(n) (n << 4) |
||||
#define SEL_OVERRIDE_BVALID(n) (n << 8) |
||||
|
||||
/* Static DRD configuration */ |
||||
#define USB3_CONTROL_MASK 0xf77 |
||||
|
||||
#define USB3_DEVICE_NOT_HOST BIT(0) |
||||
#define USB3_FORCE_VBUSVALID BIT(1) |
||||
#define USB3_DELAY_VBUSVALID BIT(2) |
||||
#define USB3_SEL_FORCE_OPMODE BIT(4) |
||||
#define USB3_FORCE_OPMODE(n) (n << 5) |
||||
#define USB3_SEL_FORCE_DPPULLDOWN2 BIT(8) |
||||
#define USB3_FORCE_DPPULLDOWN2 BIT(9) |
||||
#define USB3_SEL_FORCE_DMPULLDOWN2 BIT(10) |
||||
#define USB3_FORCE_DMPULLDOWN2 BIT(11) |
||||
|
||||
/**
|
||||
* struct st_dwc3 - dwc3-st driver private structure |
||||
* @dev: device pointer |
||||
* @glue_base: ioaddr for the glue registers |
||||
* @regmap: regmap pointer for getting syscfg |
||||
* @syscfg_reg_off: usb syscfg control offset |
||||
* @dr_mode: drd static host/device config |
||||
* @rstc_pwrdn: rest controller for powerdown signal |
||||
* @rstc_rst: reset controller for softreset signal |
||||
*/ |
||||
|
||||
struct st_dwc3 { |
||||
struct device *dev; |
||||
void __iomem *glue_base; |
||||
struct regmap *regmap; |
||||
int syscfg_reg_off; |
||||
enum usb_dr_mode dr_mode; |
||||
struct reset_control *rstc_pwrdn; |
||||
struct reset_control *rstc_rst; |
||||
}; |
||||
|
||||
static inline u32 st_dwc3_readl(void __iomem *base, u32 offset) |
||||
{ |
||||
return readl_relaxed(base + offset); |
||||
} |
||||
|
||||
static inline void st_dwc3_writel(void __iomem *base, u32 offset, u32 value) |
||||
{ |
||||
writel_relaxed(value, base + offset); |
||||
} |
||||
|
||||
/**
|
||||
* st_dwc3_drd_init: program the port |
||||
* @dwc3_data: driver private structure |
||||
* Description: this function is to program the port as either host or device |
||||
* according to the static configuration passed from devicetree. |
||||
* OTG and dual role are not yet supported! |
||||
*/ |
||||
static int st_dwc3_drd_init(struct st_dwc3 *dwc3_data) |
||||
{ |
||||
u32 val; |
||||
int err; |
||||
|
||||
err = regmap_read(dwc3_data->regmap, dwc3_data->syscfg_reg_off, &val); |
||||
if (err) |
||||
return err; |
||||
|
||||
val &= USB3_CONTROL_MASK; |
||||
|
||||
switch (dwc3_data->dr_mode) { |
||||
case USB_DR_MODE_PERIPHERAL: |
||||
|
||||
val &= ~(USB3_FORCE_VBUSVALID | USB3_DELAY_VBUSVALID |
||||
| USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3) |
||||
| USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2 |
||||
| USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2); |
||||
|
||||
val |= USB3_DEVICE_NOT_HOST; |
||||
|
||||
dev_dbg(dwc3_data->dev, "Configuring as Device\n"); |
||||
break; |
||||
|
||||
case USB_DR_MODE_HOST: |
||||
|
||||
val &= ~(USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID |
||||
| USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3) |
||||
| USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2 |
||||
| USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2); |
||||
|
||||
/*
|
||||
* USB3_DELAY_VBUSVALID is ANDed with USB_C_VBUSVALID. Thus, |
||||
* when set to ‘0‘, it can delay the arrival of VBUSVALID |
||||
* information to VBUSVLDEXT2 input of the pico PHY. |
||||
* We don't want to do that so we set the bit to '1'. |
||||
*/ |
||||
|
||||
val |= USB3_DELAY_VBUSVALID; |
||||
|
||||
dev_dbg(dwc3_data->dev, "Configuring as Host\n"); |
||||
break; |
||||
|
||||
default: |
||||
dev_err(dwc3_data->dev, "Unsupported mode of operation %d\n", |
||||
dwc3_data->dr_mode); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
return regmap_write(dwc3_data->regmap, dwc3_data->syscfg_reg_off, val); |
||||
} |
||||
|
||||
/**
|
||||
* st_dwc3_init: init the controller via glue logic |
||||
* @dwc3_data: driver private structure |
||||
*/ |
||||
static void st_dwc3_init(struct st_dwc3 *dwc3_data) |
||||
{ |
||||
u32 reg = st_dwc3_readl(dwc3_data->glue_base, CLKRST_CTRL); |
||||
|
||||
reg |= AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION; |
||||
reg &= ~SW_PIPEW_RESET_N; |
||||
st_dwc3_writel(dwc3_data->glue_base, CLKRST_CTRL, reg); |
||||
|
||||
/* configure mux for vbus, powerpresent and bvalid signals */ |
||||
reg = st_dwc3_readl(dwc3_data->glue_base, USB2_VBUS_MNGMNT_SEL1); |
||||
|
||||
reg |= SEL_OVERRIDE_VBUSVALID(USB2_VBUS_UTMIOTG) | |
||||
SEL_OVERRIDE_POWERPRESENT(USB2_VBUS_UTMIOTG) | |
||||
SEL_OVERRIDE_BVALID(USB2_VBUS_UTMIOTG); |
||||
|
||||
st_dwc3_writel(dwc3_data->glue_base, USB2_VBUS_MNGMNT_SEL1, reg); |
||||
|
||||
reg = st_dwc3_readl(dwc3_data->glue_base, CLKRST_CTRL); |
||||
reg |= SW_PIPEW_RESET_N; |
||||
st_dwc3_writel(dwc3_data->glue_base, CLKRST_CTRL, reg); |
||||
} |
||||
|
||||
static int st_dwc3_probe(struct platform_device *pdev) |
||||
{ |
||||
struct st_dwc3 *dwc3_data; |
||||
struct resource *res; |
||||
struct device *dev = &pdev->dev; |
||||
struct device_node *node = dev->of_node, *child; |
||||
struct regmap *regmap; |
||||
int ret; |
||||
|
||||
dwc3_data = devm_kzalloc(dev, sizeof(*dwc3_data), GFP_KERNEL); |
||||
if (!dwc3_data) |
||||
return -ENOMEM; |
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg-glue"); |
||||
dwc3_data->glue_base = devm_ioremap_resource(dev, res); |
||||
if (IS_ERR(dwc3_data->glue_base)) |
||||
return PTR_ERR(dwc3_data->glue_base); |
||||
|
||||
regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg"); |
||||
if (IS_ERR(regmap)) |
||||
return PTR_ERR(regmap); |
||||
|
||||
dma_set_coherent_mask(dev, dev->coherent_dma_mask); |
||||
dwc3_data->dev = dev; |
||||
dwc3_data->regmap = regmap; |
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "syscfg-reg"); |
||||
if (!res) { |
||||
ret = -ENXIO; |
||||
goto undo_platform_dev_alloc; |
||||
} |
||||
|
||||
dwc3_data->syscfg_reg_off = res->start; |
||||
|
||||
dev_vdbg(&pdev->dev, "glue-logic addr 0x%p, syscfg-reg offset 0x%x\n", |
||||
dwc3_data->glue_base, dwc3_data->syscfg_reg_off); |
||||
|
||||
dwc3_data->rstc_pwrdn = devm_reset_control_get(dev, "powerdown"); |
||||
if (IS_ERR(dwc3_data->rstc_pwrdn)) { |
||||
dev_err(&pdev->dev, "could not get power controller\n"); |
||||
ret = PTR_ERR(dwc3_data->rstc_pwrdn); |
||||
goto undo_platform_dev_alloc; |
||||
} |
||||
|
||||
/* Manage PowerDown */ |
||||
reset_control_deassert(dwc3_data->rstc_pwrdn); |
||||
|
||||
dwc3_data->rstc_rst = devm_reset_control_get(dev, "softreset"); |
||||
if (IS_ERR(dwc3_data->rstc_rst)) { |
||||
dev_err(&pdev->dev, "could not get reset controller\n"); |
||||
ret = PTR_ERR(dwc3_data->rstc_rst); |
||||
goto undo_powerdown; |
||||
} |
||||
|
||||
/* Manage SoftReset */ |
||||
reset_control_deassert(dwc3_data->rstc_rst); |
||||
|
||||
child = of_get_child_by_name(node, "dwc3"); |
||||
if (!child) { |
||||
dev_err(&pdev->dev, "failed to find dwc3 core node\n"); |
||||
ret = -ENODEV; |
||||
goto undo_softreset; |
||||
} |
||||
|
||||
dwc3_data->dr_mode = of_usb_get_dr_mode(child); |
||||
|
||||
/* Allocate and initialize the core */ |
||||
ret = of_platform_populate(node, NULL, NULL, dev); |
||||
if (ret) { |
||||
dev_err(dev, "failed to add dwc3 core\n"); |
||||
goto undo_softreset; |
||||
} |
||||
|
||||
/*
|
||||
* Configure the USB port as device or host according to the static |
||||
* configuration passed from DT. |
||||
* DRD is the only mode currently supported so this will be enhanced |
||||
* as soon as OTG is available. |
||||
*/ |
||||
ret = st_dwc3_drd_init(dwc3_data); |
||||
if (ret) { |
||||
dev_err(dev, "drd initialisation failed\n"); |
||||
goto undo_softreset; |
||||
} |
||||
|
||||
/* ST glue logic init */ |
||||
st_dwc3_init(dwc3_data); |
||||
|
||||
platform_set_drvdata(pdev, dwc3_data); |
||||
return 0; |
||||
|
||||
undo_softreset: |
||||
reset_control_assert(dwc3_data->rstc_rst); |
||||
undo_powerdown: |
||||
reset_control_assert(dwc3_data->rstc_pwrdn); |
||||
undo_platform_dev_alloc: |
||||
platform_device_put(pdev); |
||||
return ret; |
||||
} |
||||
|
||||
static int st_dwc3_remove(struct platform_device *pdev) |
||||
{ |
||||
struct st_dwc3 *dwc3_data = platform_get_drvdata(pdev); |
||||
|
||||
of_platform_depopulate(&pdev->dev); |
||||
|
||||
reset_control_assert(dwc3_data->rstc_pwrdn); |
||||
reset_control_assert(dwc3_data->rstc_rst); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
#ifdef CONFIG_PM_SLEEP |
||||
static int st_dwc3_suspend(struct device *dev) |
||||
{ |
||||
struct st_dwc3 *dwc3_data = dev_get_drvdata(dev); |
||||
|
||||
reset_control_assert(dwc3_data->rstc_pwrdn); |
||||
reset_control_assert(dwc3_data->rstc_rst); |
||||
|
||||
pinctrl_pm_select_sleep_state(dev); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int st_dwc3_resume(struct device *dev) |
||||
{ |
||||
struct st_dwc3 *dwc3_data = dev_get_drvdata(dev); |
||||
int ret; |
||||
|
||||
pinctrl_pm_select_default_state(dev); |
||||
|
||||
reset_control_deassert(dwc3_data->rstc_pwrdn); |
||||
reset_control_deassert(dwc3_data->rstc_rst); |
||||
|
||||
ret = st_dwc3_drd_init(dwc3_data); |
||||
if (ret) { |
||||
dev_err(dev, "drd initialisation failed\n"); |
||||
return ret; |
||||
} |
||||
|
||||
/* ST glue logic init */ |
||||
st_dwc3_init(dwc3_data); |
||||
|
||||
return 0; |
||||
} |
||||
#endif /* CONFIG_PM_SLEEP */ |
||||
|
||||
static SIMPLE_DEV_PM_OPS(st_dwc3_dev_pm_ops, st_dwc3_suspend, st_dwc3_resume); |
||||
|
||||
static const struct of_device_id st_dwc3_match[] = { |
||||
{ .compatible = "st,stih407-dwc3" }, |
||||
{ /* sentinel */ }, |
||||
}; |
||||
|
||||
MODULE_DEVICE_TABLE(of, st_dwc3_match); |
||||
|
||||
static struct platform_driver st_dwc3_driver = { |
||||
.probe = st_dwc3_probe, |
||||
.remove = st_dwc3_remove, |
||||
.driver = { |
||||
.name = "usb-st-dwc3", |
||||
.of_match_table = st_dwc3_match, |
||||
.pm = &st_dwc3_dev_pm_ops, |
||||
}, |
||||
}; |
||||
|
||||
module_platform_driver(st_dwc3_driver); |
||||
|
||||
MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); |
||||
MODULE_DESCRIPTION("DesignWare USB3 STi Glue Layer"); |
||||
MODULE_LICENSE("GPL v2"); |
@ -1,91 +0,0 @@ |
||||
/**
|
||||
* host.c - DesignWare USB3 DRD Controller Host Glue |
||||
* |
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
|
||||
* |
||||
* Authors: Felipe Balbi <balbi@ti.com>, |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#include <linux/platform_device.h> |
||||
#include <linux/usb/xhci_pdriver.h> |
||||
|
||||
#include "core.h" |
||||
|
||||
int dwc3_host_init(struct dwc3 *dwc) |
||||
{ |
||||
struct platform_device *xhci; |
||||
struct usb_xhci_pdata pdata; |
||||
int ret; |
||||
|
||||
xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO); |
||||
if (!xhci) { |
||||
dev_err(dwc->dev, "couldn't allocate xHCI device\n"); |
||||
return -ENOMEM; |
||||
} |
||||
|
||||
dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask); |
||||
|
||||
xhci->dev.parent = dwc->dev; |
||||
xhci->dev.dma_mask = dwc->dev->dma_mask; |
||||
xhci->dev.dma_parms = dwc->dev->dma_parms; |
||||
|
||||
dwc->xhci = xhci; |
||||
|
||||
ret = platform_device_add_resources(xhci, dwc->xhci_resources, |
||||
DWC3_XHCI_RESOURCES_NUM); |
||||
if (ret) { |
||||
dev_err(dwc->dev, "couldn't add resources to xHCI device\n"); |
||||
goto err1; |
||||
} |
||||
|
||||
memset(&pdata, 0, sizeof(pdata)); |
||||
|
||||
#ifdef CONFIG_DWC3_HOST_USB3_LPM_ENABLE |
||||
pdata.usb3_lpm_capable = 1; |
||||
#endif |
||||
|
||||
ret = platform_device_add_data(xhci, &pdata, sizeof(pdata)); |
||||
if (ret) { |
||||
dev_err(dwc->dev, "couldn't add platform data to xHCI device\n"); |
||||
goto err1; |
||||
} |
||||
|
||||
phy_create_lookup(dwc->usb2_generic_phy, "usb2-phy", |
||||
dev_name(&xhci->dev)); |
||||
phy_create_lookup(dwc->usb3_generic_phy, "usb3-phy", |
||||
dev_name(&xhci->dev)); |
||||
|
||||
ret = platform_device_add(xhci); |
||||
if (ret) { |
||||
dev_err(dwc->dev, "failed to register xHCI device\n"); |
||||
goto err2; |
||||
} |
||||
|
||||
return 0; |
||||
err2: |
||||
phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy", |
||||
dev_name(&xhci->dev)); |
||||
phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy", |
||||
dev_name(&xhci->dev)); |
||||
err1: |
||||
platform_device_put(xhci); |
||||
return ret; |
||||
} |
||||
|
||||
void dwc3_host_exit(struct dwc3 *dwc) |
||||
{ |
||||
phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy", |
||||
dev_name(&dwc->xhci->dev)); |
||||
phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy", |
||||
dev_name(&dwc->xhci->dev)); |
||||
platform_device_unregister(dwc->xhci); |
||||
} |
@ -1,47 +0,0 @@ |
||||
/**
|
||||
* platform_data.h - USB DWC3 Platform Data Support |
||||
* |
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
|
||||
* Author: Felipe Balbi <balbi@ti.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include <linux/usb/ch9.h> |
||||
#include <linux/usb/otg.h> |
||||
|
||||
struct dwc3_platform_data { |
||||
enum usb_device_speed maximum_speed; |
||||
enum usb_dr_mode dr_mode; |
||||
bool tx_fifo_resize; |
||||
|
||||
unsigned is_utmi_l1_suspend:1; |
||||
u8 hird_threshold; |
||||
|
||||
u8 lpm_nyet_threshold; |
||||
|
||||
unsigned disable_scramble_quirk:1; |
||||
unsigned has_lpm_erratum:1; |
||||
unsigned u2exit_lfps_quirk:1; |
||||
unsigned u2ss_inp3_quirk:1; |
||||
unsigned req_p1p2p3_quirk:1; |
||||
unsigned del_p1p2p3_quirk:1; |
||||
unsigned del_phy_power_chg_quirk:1; |
||||
unsigned lfps_filter_quirk:1; |
||||
unsigned rx_detect_poll_quirk:1; |
||||
unsigned dis_u3_susphy_quirk:1; |
||||
unsigned dis_u2_susphy_quirk:1; |
||||
|
||||
unsigned tx_de_emphasis_quirk:1; |
||||
unsigned tx_de_emphasis:2; |
||||
}; |
@ -1,19 +0,0 @@ |
||||
/**
|
||||
* trace.c - DesignWare USB3 DRD Controller Trace Support |
||||
* |
||||
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
|
||||
* |
||||
* Author: Felipe Balbi <balbi@ti.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#define CREATE_TRACE_POINTS |
||||
#include "trace.h" |
@ -1,247 +0,0 @@ |
||||
/**
|
||||
* trace.h - DesignWare USB3 DRD Controller Trace Support |
||||
* |
||||
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
|
||||
* |
||||
* Author: Felipe Balbi <balbi@ti.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 of |
||||
* the License as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#undef TRACE_SYSTEM |
||||
#define TRACE_SYSTEM dwc3 |
||||
|
||||
#if !defined(__DWC3_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) |
||||
#define __DWC3_TRACE_H |
||||
|
||||
#include <linux/types.h> |
||||
#include <linux/tracepoint.h> |
||||
#include <asm/byteorder.h> |
||||
#include "core.h" |
||||
#include "debug.h" |
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_msg, |
||||
TP_PROTO(struct va_format *vaf), |
||||
TP_ARGS(vaf), |
||||
TP_STRUCT__entry(__dynamic_array(char, msg, DWC3_MSG_MAX)), |
||||
TP_fast_assign( |
||||
vsnprintf(__get_str(msg), DWC3_MSG_MAX, vaf->fmt, *vaf->va); |
||||
), |
||||
TP_printk("%s", __get_str(msg)) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_msg, dwc3_readl, |
||||
TP_PROTO(struct va_format *vaf), |
||||
TP_ARGS(vaf) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_msg, dwc3_writel, |
||||
TP_PROTO(struct va_format *vaf), |
||||
TP_ARGS(vaf) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_msg, dwc3_ep0, |
||||
TP_PROTO(struct va_format *vaf), |
||||
TP_ARGS(vaf) |
||||
); |
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_event, |
||||
TP_PROTO(u32 event), |
||||
TP_ARGS(event), |
||||
TP_STRUCT__entry( |
||||
__field(u32, event) |
||||
), |
||||
TP_fast_assign( |
||||
__entry->event = event; |
||||
), |
||||
TP_printk("event %08x", __entry->event) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_event, dwc3_event, |
||||
TP_PROTO(u32 event), |
||||
TP_ARGS(event) |
||||
); |
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_ctrl, |
||||
TP_PROTO(struct usb_ctrlrequest *ctrl), |
||||
TP_ARGS(ctrl), |
||||
TP_STRUCT__entry( |
||||
__field(__u8, bRequestType) |
||||
__field(__u8, bRequest) |
||||
__field(__le16, wValue) |
||||
__field(__le16, wIndex) |
||||
__field(__le16, wLength) |
||||
), |
||||
TP_fast_assign( |
||||
__entry->bRequestType = ctrl->bRequestType; |
||||
__entry->bRequest = ctrl->bRequest; |
||||
__entry->wValue = ctrl->wValue; |
||||
__entry->wIndex = ctrl->wIndex; |
||||
__entry->wLength = ctrl->wLength; |
||||
), |
||||
TP_printk("bRequestType %02x bRequest %02x wValue %04x wIndex %04x wLength %d", |
||||
__entry->bRequestType, __entry->bRequest, |
||||
le16_to_cpu(__entry->wValue), le16_to_cpu(__entry->wIndex), |
||||
le16_to_cpu(__entry->wLength) |
||||
) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_ctrl, dwc3_ctrl_req, |
||||
TP_PROTO(struct usb_ctrlrequest *ctrl), |
||||
TP_ARGS(ctrl) |
||||
); |
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_request, |
||||
TP_PROTO(struct dwc3_request *req), |
||||
TP_ARGS(req), |
||||
TP_STRUCT__entry( |
||||
__dynamic_array(char, name, DWC3_MSG_MAX) |
||||
__field(struct dwc3_request *, req) |
||||
__field(unsigned, actual) |
||||
__field(unsigned, length) |
||||
__field(int, status) |
||||
), |
||||
TP_fast_assign( |
||||
snprintf(__get_str(name), DWC3_MSG_MAX, "%s", req->dep->name); |
||||
__entry->req = req; |
||||
__entry->actual = req->request.actual; |
||||
__entry->length = req->request.length; |
||||
__entry->status = req->request.status; |
||||
), |
||||
TP_printk("%s: req %p length %u/%u ==> %d", |
||||
__get_str(name), __entry->req, __entry->actual, __entry->length, |
||||
__entry->status |
||||
) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_request, dwc3_alloc_request, |
||||
TP_PROTO(struct dwc3_request *req), |
||||
TP_ARGS(req) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_request, dwc3_free_request, |
||||
TP_PROTO(struct dwc3_request *req), |
||||
TP_ARGS(req) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_request, dwc3_ep_queue, |
||||
TP_PROTO(struct dwc3_request *req), |
||||
TP_ARGS(req) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_request, dwc3_ep_dequeue, |
||||
TP_PROTO(struct dwc3_request *req), |
||||
TP_ARGS(req) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_request, dwc3_gadget_giveback, |
||||
TP_PROTO(struct dwc3_request *req), |
||||
TP_ARGS(req) |
||||
); |
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_generic_cmd, |
||||
TP_PROTO(unsigned int cmd, u32 param), |
||||
TP_ARGS(cmd, param), |
||||
TP_STRUCT__entry( |
||||
__field(unsigned int, cmd) |
||||
__field(u32, param) |
||||
), |
||||
TP_fast_assign( |
||||
__entry->cmd = cmd; |
||||
__entry->param = param; |
||||
), |
||||
TP_printk("cmd '%s' [%d] param %08x", |
||||
dwc3_gadget_generic_cmd_string(__entry->cmd), |
||||
__entry->cmd, __entry->param |
||||
) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_generic_cmd, dwc3_gadget_generic_cmd, |
||||
TP_PROTO(unsigned int cmd, u32 param), |
||||
TP_ARGS(cmd, param) |
||||
); |
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd, |
||||
TP_PROTO(struct dwc3_ep *dep, unsigned int cmd, |
||||
struct dwc3_gadget_ep_cmd_params *params), |
||||
TP_ARGS(dep, cmd, params), |
||||
TP_STRUCT__entry( |
||||
__dynamic_array(char, name, DWC3_MSG_MAX) |
||||
__field(unsigned int, cmd) |
||||
__field(u32, param0) |
||||
__field(u32, param1) |
||||
__field(u32, param2) |
||||
), |
||||
TP_fast_assign( |
||||
snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name); |
||||
__entry->cmd = cmd; |
||||
__entry->param0 = params->param0; |
||||
__entry->param1 = params->param1; |
||||
__entry->param2 = params->param2; |
||||
), |
||||
TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x", |
||||
__get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd), |
||||
__entry->cmd, __entry->param0, |
||||
__entry->param1, __entry->param2 |
||||
) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_gadget_ep_cmd, dwc3_gadget_ep_cmd, |
||||
TP_PROTO(struct dwc3_ep *dep, unsigned int cmd, |
||||
struct dwc3_gadget_ep_cmd_params *params), |
||||
TP_ARGS(dep, cmd, params) |
||||
); |
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_trb, |
||||
TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb), |
||||
TP_ARGS(dep, trb), |
||||
TP_STRUCT__entry( |
||||
__dynamic_array(char, name, DWC3_MSG_MAX) |
||||
__field(struct dwc3_trb *, trb) |
||||
__field(u32, bpl) |
||||
__field(u32, bph) |
||||
__field(u32, size) |
||||
__field(u32, ctrl) |
||||
), |
||||
TP_fast_assign( |
||||
snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name); |
||||
__entry->trb = trb; |
||||
__entry->bpl = trb->bpl; |
||||
__entry->bph = trb->bph; |
||||
__entry->size = trb->size; |
||||
__entry->ctrl = trb->ctrl; |
||||
), |
||||
TP_printk("%s: trb %p bph %08x bpl %08x size %08x ctrl %08x", |
||||
__get_str(name), __entry->trb, __entry->bph, __entry->bpl, |
||||
__entry->size, __entry->ctrl |
||||
) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_trb, dwc3_prepare_trb, |
||||
TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb), |
||||
TP_ARGS(dep, trb) |
||||
); |
||||
|
||||
DEFINE_EVENT(dwc3_log_trb, dwc3_complete_trb, |
||||
TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb), |
||||
TP_ARGS(dep, trb) |
||||
); |
||||
|
||||
#endif /* __DWC3_TRACE_H */ |
||||
|
||||
/* this part has to be here */ |
||||
|
||||
#undef TRACE_INCLUDE_PATH |
||||
#define TRACE_INCLUDE_PATH . |
||||
|
||||
#undef TRACE_INCLUDE_FILE |
||||
#define TRACE_INCLUDE_FILE trace |
||||
|
||||
#include <trace/define_trace.h> |
Loading…
Reference in new issue