/* Initialize HS phy */ void usb_wrapper_hs_phy_init(usb_wrapper_dev_t *dev) { /* 5.a */ REG_WRITE_FIELD(dev, HS_PHY_CTRL, FREECLK_SEL, 0x0); /* 5.b */ REG_WRITE_FIELD(dev, HS_PHY_CTRL, COMMONONN, 0x1); }
/* reset SS phy */ void usb_wrapper_ss_phy_reset(usb_wrapper_dev_t *dev) { REG_WRITE_FIELD(dev, SS_PHY_CTRL, SS_PHY_RESET, 1); /* per HPG */ udelay(10); REG_WRITE_FIELD(dev, SS_PHY_CTRL, SS_PHY_RESET, 0); }
void usb_wrapper_hsonly_mode(usb_wrapper_dev_t *dev) { REG_WRITE_FIELD(dev, GENERAL_CFG, PIPE_UTMI_CLK_DIS, 0x1); udelay(1); REG_WRITE_FIELD(dev, GENERAL_CFG, PIPE_UTMI_CLK_SEL, 0x1); REG_WRITE_FIELD(dev, GENERAL_CFG, PIPE3_PHYSTATUS_SW, 0x1); udelay(1); REG_WRITE_FIELD(dev, GENERAL_CFG, PIPE_UTMI_CLK_DIS, 0x0); }
/* Configure DBM mode: by-pass or DBM */ void usb_wrapper_dbm_mode(usb_wrapper_dev_t *dev, dbm_mode_t mode) { if (mode == DBM_MODE_BYPASS) { REG_WRITE_FIELD(dev, GENERAL_CFG, DBM_EN, 0); } else { REG_WRITE_FIELD(dev, GENERAL_CFG, DBM_EN, 1); } }
/* configure SS phy as specified in HPG */ void usb_wrapper_ss_phy_configure(usb_wrapper_dev_t *dev) { /* 4.a */ REG_WRITE_FIELD(dev, SS_PHY_CTRL, REF_USE_PAD, 1); /* .b */ REG_WRITE_FIELD(dev, SS_PHY_CTRL, LANE0_PWR_PRESENT, 1); /* .c */ REG_WRITE_FIELD(dev, SS_PHY_CTRL, REF_SS_PHY_EN, 1); /* For Aragorn V1, reset value fix is required.*/ if ( (board_platform_id() == MSM8974) && (board_soc_version() < BOARD_SOC_VERSION2)) { REG_WRITE_FIELD(dev, SS_PHY_CTRL, SSC_REF_CLK_SEL, 0x108); } }
void usb_wrapper_vbus_override(usb_wrapper_dev_t *dev) { /* set extenal vbus valid select */ REG_WRITE_FIELD(dev, HS_PHY_CTRL_COMMON, VBUSVLDEXTSEL0, 0x1); /* enable D+ pullup */ REG_WRITE_FIELD(dev, HS_PHY_CTRL, VBUSVLDEXT0, 0x1); /* set otg vbus valid from hs phy to controller */ REG_WRITE_FIELD(dev, HS_PHY_CTRL, UTMI_OTG_VBUS_VALID, 0x1); /* Indicate value is driven by UTMI_OTG_VBUS_VALID bit */ REG_WRITE_FIELD(dev, HS_PHY_CTRL, SW_SESSVLD_SEL, 0x1); /* Indicate power present to SS phy */ REG_WRITE_FIELD(dev, SS_PHY_CTRL, LANE0_PWR_PRESENT, 0x1); }
/* reset device */ void dwc_device_reset(dwc_dev_t *dev) { /* start reset */ REG_WRITE_FIELD(dev, DCTL, CSFTRST, 1); /* wait until done */ while(REG_READ_FIELD(dev, DCTL, CSFTRST)); }
/* initialize global control reg for device mode operation. * sequence numbers are as described in HPG. */ void dwc_gctl_init(dwc_dev_t *dev) { /* 16. */ /* a. default value is good for RAM clock */ /* b. default value is good for Disable Debug Attach */ REG_WRITE_FIELD(dev, GCTL, DEBUGATTACH, 0); /* c & d: disable loopback/local loopback * TODO: possibly for older version. no such fields in GCTL */ /* e. no soft reset. */ REG_WRITE_FIELD(dev, GCTL, CORESOFTRESET, 0); /* f. set port capability direction: device */ REG_WRITE_FIELD(dev, GCTL, PRTCAPDIR, 0x2); /* g. set scale down value */ REG_WRITE_FIELD(dev, GCTL, FRMSCLDWN, 0x0); /* h. enable multiple attempts for SS connection */ REG_WRITE_FIELD(dev, GCTL, U2RSTECN, 1); /* i. set power down scale of snps phy */ REG_WRITE_FIELD(dev, GCTL, PWRDNSCALE, 0x2); /* j. clear SOFITPSYNC bit */ REG_WRITE_FIELD(dev, GCTL, SOFITPSYNC, 0); }
/* global reset of controller. * 1 == put in reset. 0 == out of reset */ void dwc_reset(dwc_dev_t *dev, uint8_t reset) { /* snps databook table 6-11 indicates this field to be used only for debug * purpose. use dctl.softreset instead for devide mode. * but hpg 4.4.2. 8.a says use this. */ REG_WRITE_FIELD(dev, GCTL, CORESOFTRESET, reset); /* per HPG */ udelay(100); }
/* generic api to send device command */ static void dwc_device_cmd(dwc_dev_t *dev, dwc_device_cmd_t *cmd) { uint8_t active = REG_READ_FIELD(dev, DGCMD, CMDACT); ASSERT(active); REG_WRITE(dev, DGCMDPAR, cmd->param); REG_WRITE_FIELD(dev, DGCMD, CMDTYP, cmd->cmd); /* wait until active field is cleared. */ while(!REG_READ_FIELD(dev, DGCMD, CMDACT)); if(REG_READ_FIELD(dev, DGCMD, CMDSTATUS)) { ERR("\n\n device command failed. \n\n"); ASSERT(0); } }
/* workaround #13 as described in HPG */ void usb_wrapper_workaround_13(usb_wrapper_dev_t *dev) { REG_WRITE_FIELD(dev, SS_PHY_PARAM_CTRL_1, LOS_BIAS, 0x5); }
void dwc_device_accept_u1u2(dwc_dev_t *dev) { REG_WRITE_FIELD(dev, DCTL, ACCEPTU1ENA, 1); REG_WRITE_FIELD(dev, DCTL, ACCEPTU2ENA, 1); }
void dwc_device_enable_u2(dwc_dev_t *dev, uint8_t val) { REG_WRITE_FIELD(dev, DCTL, INITU2ENA, val); }
void dwc_device_enter_test_mode(dwc_dev_t *dev) { REG_WRITE_FIELD(dev, DCTL, TSTCTL, dev->test_mode); }
/* Run/Stop device: 1 == run. 0 == stop */ void dwc_device_run(dwc_dev_t *dev, uint8_t run) { REG_WRITE_FIELD(dev, DCTL, RUN_STOP, run); }
/* set device address */ void dwc_device_set_addr(dwc_dev_t *dev, uint16_t addr) { REG_WRITE_FIELD(dev, DCFG, DEVADDR, addr); }