Skip to content

Commit

Permalink
usb: dwc2: gadget: Add new core parameter for low speed
Browse files Browse the repository at this point in the history
Added new core param for low speed, which can be used only when SNPSID
is equal to DWC2_CORE_FS_IOT. When LS mode is enabled, we are
restricting ep types and providing to upper layer only INTR and CTRL
endpoints.

Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
  • Loading branch information
Vardan Mikayelyan authored and Felipe Balbi committed Nov 18, 2016
1 parent 552d940 commit 38e9002
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 11 deletions.
1 change: 1 addition & 0 deletions drivers/usb/dwc2/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ struct dwc2_core_params {
int speed;
#define DWC2_SPEED_PARAM_HIGH 0
#define DWC2_SPEED_PARAM_FULL 1
#define DWC2_SPEED_PARAM_LOW 2

int enable_dynamic_fifo;
int en_multiple_tx_fifo;
Expand Down
27 changes: 21 additions & 6 deletions drivers/usb/dwc2/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -3175,7 +3175,8 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
GUSBCFG_HNPCAP);

if (hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS &&
hsotg->params.speed == DWC2_SPEED_PARAM_FULL) {
(hsotg->params.speed == DWC2_SPEED_PARAM_FULL ||
hsotg->params.speed == DWC2_SPEED_PARAM_LOW)) {
/* FS/LS Dedicated Transceiver Interface */
usbcfg |= GUSBCFG_PHYSEL;
} else {
Expand All @@ -3192,14 +3193,21 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);

dcfg |= DCFG_EPMISCNT(1);
if (hsotg->params.speed == DWC2_SPEED_PARAM_FULL) {

switch (hsotg->params.speed) {
case DWC2_SPEED_PARAM_LOW:
dcfg |= DCFG_DEVSPD_LS;
break;
case DWC2_SPEED_PARAM_FULL:
if (hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS)
dcfg |= DCFG_DEVSPD_FS48;
else
dcfg |= DCFG_DEVSPD_FS;
} else {
break;
default:
dcfg |= DCFG_DEVSPD_HS;
}

dwc2_writel(dcfg, hsotg->regs + DCFG);

/* Clear any pending OTG interrupts */
Expand Down Expand Up @@ -4388,14 +4396,21 @@ static void dwc2_hsotg_initep(struct dwc2_hsotg *hsotg,

hs_ep->parent = hsotg;
hs_ep->ep.name = hs_ep->name;
usb_ep_set_maxpacket_limit(&hs_ep->ep, epnum ? 1024 : EP0_MPS_LIMIT);

if (hsotg->params.speed == DWC2_SPEED_PARAM_LOW)
usb_ep_set_maxpacket_limit(&hs_ep->ep, 8);
else
usb_ep_set_maxpacket_limit(&hs_ep->ep,
epnum ? 1024 : EP0_MPS_LIMIT);
hs_ep->ep.ops = &dwc2_hsotg_ep_ops;

if (epnum == 0) {
hs_ep->ep.caps.type_control = true;
} else {
hs_ep->ep.caps.type_iso = true;
hs_ep->ep.caps.type_bulk = true;
if (hsotg->params.speed != DWC2_SPEED_PARAM_LOW) {
hs_ep->ep.caps.type_iso = true;
hs_ep->ep.caps.type_bulk = true;
}
hs_ep->ep.caps.type_int = true;
}

Expand Down
8 changes: 5 additions & 3 deletions drivers/usb/dwc2/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,10 @@ static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
u32 usbcfg;
int retval = 0;

if (hsotg->params.speed == DWC2_SPEED_PARAM_FULL &&
if ((hsotg->params.speed == DWC2_SPEED_PARAM_FULL ||
hsotg->params.speed == DWC2_SPEED_PARAM_LOW) &&
hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
/* If FS mode with FS PHY */
/* If FS/LS mode with FS/LS PHY */
retval = dwc2_fs_phy_init(hsotg, select_phy);
if (retval)
return retval;
Expand Down Expand Up @@ -2277,7 +2278,8 @@ static void dwc2_core_host_init(struct dwc2_hsotg *hsotg)

/* Initialize Host Configuration Register */
dwc2_init_fs_ls_pclk_sel(hsotg);
if (hsotg->params.speed == DWC2_SPEED_PARAM_FULL) {
if (hsotg->params.speed == DWC2_SPEED_PARAM_FULL ||
hsotg->params.speed == DWC2_SPEED_PARAM_LOW) {
hcfg = dwc2_readl(hsotg->regs + HCFG);
hcfg |= HCFG_FSLSSUPP;
dwc2_writel(hcfg, hsotg->regs + HCFG);
Expand Down
8 changes: 6 additions & 2 deletions drivers/usb/dwc2/params.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,14 +742,18 @@ static void dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val)
{
int valid = 1;

if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
if (DWC2_OUT_OF_BOUNDS(val, 0, 2)) {
if (val >= 0) {
dev_err(hsotg->dev, "Wrong value for speed parameter\n");
dev_err(hsotg->dev, "max_speed parameter must be 0 or 1\n");
dev_err(hsotg->dev, "max_speed parameter must be 0, 1, or 2\n");
}
valid = 0;
}

if (dwc2_is_hs_iot(hsotg) &&
val == DWC2_SPEED_PARAM_LOW)
valid = 0;

if (val == DWC2_SPEED_PARAM_HIGH &&
dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS)
valid = 0;
Expand Down

0 comments on commit 38e9002

Please sign in to comment.