static int do_sdhci_init(struct sdhci_host *host) { int dev_id, flag; int err = 0; flag = host->bus_width == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE; dev_id = host->index + PERIPH_ID_SDMMC0; if (fdt_gpio_isvalid(&host->pwr_gpio)) { gpio_direction_output(host->pwr_gpio.gpio, 1); err = exynos_pinmux_config(dev_id, flag); if (err) { debug("MMC not configured\n"); return err; } } if (fdt_gpio_isvalid(&host->cd_gpio)) { gpio_direction_output(host->cd_gpio.gpio, 0xf); if (gpio_get_value(host->cd_gpio.gpio)) return -ENODEV; err = exynos_pinmux_config(dev_id, flag); if (err) { printf("external SD not configured\n"); return err; } } return s5p_sdhci_core_init(host); }
int fdtdec_set_gpio(struct fdt_gpio_state *gpio, int val) { if (!fdt_gpio_isvalid(gpio)) return -1; val = gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val; return gpio_set_value(gpio->gpio, val); }
int cros_ec_interrupt_pending(struct cros_ec_dev *dev) { /* no interrupt support : always poll */ if (!fdt_gpio_isvalid(&dev->ec_int)) return -ENOENT; return !gpio_get_value(dev->ec_int.gpio); }
void fdt_setup_gpio(struct fdt_gpio_state *gpio) { if (!fdt_gpio_isvalid(gpio)) return; if (gpio->flags & FDT_GPIO_OUTPUT) gpio_direction_output(gpio->gpio, gpio->flags & FDT_GPIO_HIGH); else gpio_direction_input(gpio->gpio); }
int fdtdec_setup_gpio(struct fdt_gpio_state *gpio) { /* * Return success if there is no GPIO defined. This is used for * optional GPIOs) */ if (!fdt_gpio_isvalid(gpio)) return 0; if (gpio_request(gpio->gpio, gpio->name)) return -1; return 0; }
void fdt_setup_gpios(struct fdt_gpio_state *gpio_list) { struct fdt_gpio_state *gpio; int i; for (i = 0, gpio = gpio_list; fdt_gpio_isvalid(gpio); i++, gpio++) { if (i > FDT_GPIO_MAX) { /* Something may have gone horribly wrong */ printf("FDT: fdt_setup_gpios: too many GPIOs\n"); return; } fdt_setup_gpio(gpio); } }
/* Put the port into host mode (this only works for OTG ports) */ static void set_host_mode(struct fdt_usb *config) { if (config->dr_mode == DR_MODE_OTG) { /* Check whether remote host from USB1 is driving VBus */ if (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS) return; /* * If not driving, we set the GPIO to enable VBUS. We assume * that the pinmux is set up correctly for this. */ if (fdt_gpio_isvalid(&config->vbus_gpio)) { fdtdec_setup_gpio(&config->vbus_gpio); gpio_direction_output(config->vbus_gpio.gpio, 1); debug("set_host_mode: GPIO %d high\n", config->vbus_gpio.gpio); } } }
int board_dp_bridge_setup(const void *blob, unsigned *wait_ms) { int ret; ret = board_dp_fill_gpios(blob); if (ret) return ret; /* Mux HPHPD to the special hotplug detect mode */ exynos_pinmux_config(PERIPH_ID_DPHPD, 0); /* Setup the GPIOs */ ret = fdtdec_setup_gpio(&local.dp_pd); if (ret) { debug("%s: Could not setup pd gpio (%d)\n", __func__, ret); return ret; } ret = fdtdec_setup_gpio(&local.dp_rst); if (ret) { debug("%s: Could not setup rst gpio (%d)\n", __func__, ret); return ret; } ret = fdtdec_setup_gpio(&local.dp_hpd); if (ret) { debug("%s: Could not setup hpd gpio (%d)\n", __func__, ret); return ret; } fdtdec_set_gpio(&local.dp_pd, 0); gpio_cfg_pin(local.dp_pd.gpio, EXYNOS_GPIO_OUTPUT); gpio_set_pull(local.dp_pd.gpio, EXYNOS_GPIO_PULL_NONE); if (fdt_gpio_isvalid(&local.dp_rst)) { fdtdec_set_gpio(&local.dp_rst, 1); gpio_cfg_pin(local.dp_rst.gpio, EXYNOS_GPIO_OUTPUT); gpio_set_pull(local.dp_rst.gpio, EXYNOS_GPIO_PULL_NONE); udelay(10); fdtdec_set_gpio(&local.dp_rst, 0); } *wait_ms = 0; return 0; }
int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor) { struct exynos_xhci *ctx = &exynos; int ret; #ifdef CONFIG_OF_CONTROL exynos_usb3_parse_dt(gd->fdt_blob, ctx); #else ctx->usb3_phy = (struct exynos_usb3_phy *)samsung_get_base_usb3_phy(); ctx->hcd = (struct xhci_hccr *)samsung_get_base_usb_xhci(); #endif ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET); #ifdef CONFIG_OF_CONTROL /* setup the Vbus gpio here */ if (fdt_gpio_isvalid(&ctx->vbus_gpio) && !fdtdec_setup_gpio(&ctx->vbus_gpio)) gpio_direction_output(ctx->vbus_gpio.gpio, 1); #endif ret = exynos_xhci_core_init(ctx); if (ret) { puts("XHCI: failed to initialize controller\n"); return -EINVAL; } *hccr = (ctx->hcd); *hcor = (struct xhci_hcor *)((uint32_t) *hccr + HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase))); debug("Exynos5-xhci: init hccr %x and hcor %x hc_length %d\n", (uint32_t)*hccr, (uint32_t)*hcor, (uint32_t)HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase))); return 0; }
/* * EHCI-initialization * Create the appropriate control structures to manage * a new EHCI host controller. */ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { struct exynos_ehci *ctx = &exynos; #ifdef CONFIG_OF_CONTROL if (exynos_usb_parse_dt(gd->fdt_blob, ctx)) { debug("Unable to parse device tree for ehci-exynos\n"); return -ENODEV; } #else ctx->usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy(); ctx->hcd = (struct ehci_hccr *)samsung_get_base_usb_ehci(); #endif #ifdef CONFIG_OF_CONTROL /* setup the Vbus gpio here */ if (fdt_gpio_isvalid(&ctx->vbus_gpio) && !fdtdec_setup_gpio(&ctx->vbus_gpio)) gpio_direction_output(ctx->vbus_gpio.gpio, 1); #endif setup_usb_phy(ctx->usb); board_usb_init(index, init); *hccr = ctx->hcd; *hcor = (struct ehci_hcor *)((uint32_t) *hccr + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); debug("Exynos5-ehci: init hccr %x and hcor %x hc_length %d\n", (uint32_t)*hccr, (uint32_t)*hcor, (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); return 0; }
/* Put the port into host mode */ static void set_host_mode(struct fdt_usb *config) { /* * If we are an OTG port, check if remote host is driving VBus and * bail out in this case. */ if (config->dr_mode == DR_MODE_OTG && (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)) return; /* * If not driving, we set the GPIO to enable VBUS. We assume * that the pinmux is set up correctly for this. */ if (fdt_gpio_isvalid(&config->vbus_gpio)) { fdtdec_setup_gpio(&config->vbus_gpio); gpio_direction_output(config->vbus_gpio.gpio, (config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW) ? 0 : 1); debug("set_host_mode: GPIO %d %s\n", config->vbus_gpio.gpio, (config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW) ? "low" : "high"); } }
int fdt_get_gpio_num(struct fdt_gpio_state *gpio) { return fdt_gpio_isvalid(gpio) ? gpio->gpio : -1; }
/* set up the ULPI USB controller with the parameters provided */ static int init_ulpi_usb_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr) { u32 val; int loop_count; struct ulpi_viewport ulpi_vp; /* set up ULPI reference clock on pllp_out4 */ clock_enable(PERIPH_ID_DEV2_OUT); clock_set_pllout(CLOCK_ID_PERIPH, PLL_OUT4, CONFIG_ULPI_REF_CLK); /* reset ULPI phy */ if (fdt_gpio_isvalid(&config->phy_reset_gpio)) { fdtdec_setup_gpio(&config->phy_reset_gpio); gpio_direction_output(config->phy_reset_gpio.gpio, 0); mdelay(5); gpio_set_value(config->phy_reset_gpio.gpio, 1); } /* Reset the usb controller */ clock_enable(config->periph_id); usbf_reset_controller(config, usbctlr); /* enable pinmux bypass */ setbits_le32(&usbctlr->ulpi_timing_ctrl_0, ULPI_CLKOUT_PINMUX_BYP | ULPI_OUTPUT_PINMUX_BYP); /* Select ULPI parallel interface */ clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, PTS_ULPI << PTS_SHIFT); /* enable ULPI transceiver */ setbits_le32(&usbctlr->susp_ctrl, ULPI_PHY_ENB); /* configure ULPI transceiver timings */ val = 0; writel(val, &usbctlr->ulpi_timing_ctrl_1); val |= ULPI_DATA_TRIMMER_SEL(4); val |= ULPI_STPDIRNXT_TRIMMER_SEL(4); val |= ULPI_DIR_TRIMMER_SEL(4); writel(val, &usbctlr->ulpi_timing_ctrl_1); udelay(10); val |= ULPI_DATA_TRIMMER_LOAD; val |= ULPI_STPDIRNXT_TRIMMER_LOAD; val |= ULPI_DIR_TRIMMER_LOAD; writel(val, &usbctlr->ulpi_timing_ctrl_1); /* set up phy for host operation with external vbus supply */ ulpi_vp.port_num = 0; ulpi_vp.viewport_addr = (u32)&usbctlr->ulpi_viewport; if (ulpi_init(&ulpi_vp)) { printf("Tegra ULPI viewport init failed\n"); return -1; } ulpi_set_vbus(&ulpi_vp, 1, 1); ulpi_set_vbus_indicator(&ulpi_vp, 1, 1, 0); /* enable wakeup events */ setbits_le32(&usbctlr->port_sc1, WKCN | WKDS | WKOC); /* Enable and wait for the phy clock to become valid in 100 ms */ setbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR); for (loop_count = 100000; loop_count != 0; loop_count--) { if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID) break; udelay(1); } if (!loop_count) return -1; clrbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR); return 0; }
/* set up the UTMI USB controller with the parameters provided */ static int init_utmi_usb_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr, const u32 timing[]) { u32 val; int loop_count; clock_enable(config->periph_id); /* Reset the usb controller */ usbf_reset_controller(config, usbctlr); /* Stop crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN low */ clrbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN); /* Follow the crystal clock disable by >100ns delay */ udelay(1); /* * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP * mux must be switched to actually use a_sess_vld threshold. */ if (fdt_gpio_isvalid(&config->vbus_gpio)) { clrsetbits_le32(&usbctlr->usb1_legacy_ctrl, VBUS_SENSE_CTL_MASK, VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT); } /* * PLL Delay CONFIGURATION settings. The following parameters control * the bring up of the plls. */ val = readl(&usbctlr->utmip_misc_cfg1); clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK, timing[PARAM_STABLE_COUNT] << UTMIP_PLLU_STABLE_COUNT_SHIFT); clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK, timing[PARAM_ACTIVE_DELAY_COUNT] << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT); writel(val, &usbctlr->utmip_misc_cfg1); /* Set PLL enable delay count and crystal frequency count */ val = readl(&usbctlr->utmip_pll_cfg1); clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK, timing[PARAM_ENABLE_DELAY_COUNT] << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT); clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK, timing[PARAM_XTAL_FREQ_COUNT] << UTMIP_XTAL_FREQ_COUNT_SHIFT); writel(val, &usbctlr->utmip_pll_cfg1); /* Setting the tracking length time */ clrsetbits_le32(&usbctlr->utmip_bias_cfg1, UTMIP_BIAS_PDTRK_COUNT_MASK, timing[PARAM_BIAS_TIME] << UTMIP_BIAS_PDTRK_COUNT_SHIFT); /* Program debounce time for VBUS to become valid */ clrsetbits_le32(&usbctlr->utmip_debounce_cfg0, UTMIP_DEBOUNCE_CFG0_MASK, timing[PARAM_DEBOUNCE_A_TIME] << UTMIP_DEBOUNCE_CFG0_SHIFT); setbits_le32(&usbctlr->utmip_tx_cfg0, UTMIP_FS_PREAMBLE_J); /* Disable battery charge enabling bit */ setbits_le32(&usbctlr->utmip_bat_chrg_cfg0, UTMIP_PD_CHRG); clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_XCVR_LSBIAS_SE); setbits_le32(&usbctlr->utmip_spare_cfg0, FUSE_SETUP_SEL); /* * Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT * Setting these fields, together with default values of the * other fields, results in programming the registers below as * follows: * UTMIP_HSRX_CFG0 = 0x9168c000 * UTMIP_HSRX_CFG1 = 0x13 */ /* Set PLL enable delay count and Crystal frequency count */ val = readl(&usbctlr->utmip_hsrx_cfg0); clrsetbits_le32(&val, UTMIP_IDLE_WAIT_MASK, utmip_idle_wait_delay << UTMIP_IDLE_WAIT_SHIFT); clrsetbits_le32(&val, UTMIP_ELASTIC_LIMIT_MASK, utmip_elastic_limit << UTMIP_ELASTIC_LIMIT_SHIFT); writel(val, &usbctlr->utmip_hsrx_cfg0); /* Configure the UTMIP_HS_SYNC_START_DLY */ clrsetbits_le32(&usbctlr->utmip_hsrx_cfg1, UTMIP_HS_SYNC_START_DLY_MASK, utmip_hs_sync_start_delay << UTMIP_HS_SYNC_START_DLY_SHIFT); /* Preceed the crystal clock disable by >100ns delay. */ udelay(1); /* Resuscitate crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN */ setbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN); /* Finished the per-controller init. */ /* De-assert UTMIP_RESET to bring out of reset. */ clrbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET); /* Wait for the phy clock to become valid in 100 ms */ for (loop_count = 100000; loop_count != 0; loop_count--) { if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID) break; udelay(1); } if (!loop_count) return -1; /* Disable ICUSB FS/LS transceiver */ clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1); /* Select UTMI parallel interface */ clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, PTS_UTMI << PTS_SHIFT); clrbits_le32(&usbctlr->port_sc1, STS); /* Deassert power down state */ clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN); clrbits_le32(&usbctlr->utmip_xcvr_cfg1, UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | UTMIP_FORCE_PDDR_POWERDOWN); return 0; }
/** * Handle the next stage of device init */ static int handle_stage(const void *blob) { debug("%s: stage %d\n", __func__, stage); /* do the things for this stage */ switch (stage) { case STAGE_START: /* Initialize the Tegra display controller */ if (tegra_display_probe(gd->fdt_blob, (void *)gd->fb_base)) { printf("%s: Failed to probe display driver\n", __func__); return -1; } /* get panel details */ if (fdt_decode_lcd(blob, &config)) { printf("No valid LCD information in device tree\n"); return -1; } /* * It is possible that the FDT has requested that the LCD be * disabled. We currently don't support this. It would require * changes to U-Boot LCD subsystem to have LCD support * compiled in but not used. An easier option might be to * still have a frame buffer, but leave the backlight off and * remove all mention of lcd in the stdout environment * variable. */ funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT); fdtdec_setup_gpio(&config.panel_vdd); fdtdec_setup_gpio(&config.lvds_shutdown); fdtdec_setup_gpio(&config.backlight_vdd); fdtdec_setup_gpio(&config.backlight_en); /* * TODO: If fdt includes output flag we can omit this code * since fdtdec_setup_gpio will do it for us. */ if (fdt_gpio_isvalid(&config.panel_vdd)) gpio_direction_output(config.panel_vdd.gpio, 0); if (fdt_gpio_isvalid(&config.lvds_shutdown)) gpio_direction_output(config.lvds_shutdown.gpio, 0); if (fdt_gpio_isvalid(&config.backlight_vdd)) gpio_direction_output(config.backlight_vdd.gpio, 0); if (fdt_gpio_isvalid(&config.backlight_en)) gpio_direction_output(config.backlight_en.gpio, 0); break; case STAGE_PANEL_VDD: if (fdt_gpio_isvalid(&config.panel_vdd)) gpio_direction_output(config.panel_vdd.gpio, 1); break; case STAGE_LVDS: if (fdt_gpio_isvalid(&config.lvds_shutdown)) gpio_set_value(config.lvds_shutdown.gpio, 1); break; case STAGE_BACKLIGHT_VDD: if (fdt_gpio_isvalid(&config.backlight_vdd)) gpio_set_value(config.backlight_vdd.gpio, 1); break; case STAGE_PWM: /* Enable PWM at 15/16 high, 32768 Hz with divider 1 */ pinmux_set_func(PINGRP_GPU, PMUX_FUNC_PWM); pinmux_tristate_disable(PINGRP_GPU); pwm_enable(config.pwm_channel, 32768, 0xdf, 1); break; case STAGE_BACKLIGHT_EN: if (fdt_gpio_isvalid(&config.backlight_en)) gpio_set_value(config.backlight_en.gpio, 1); break; case STAGE_DONE: break; } /* set up timer for next stage */ timer_next = timer_get_us(); if (stage < FDT_LCD_TIMINGS) timer_next += config.panel_timings[stage] * 1000; /* move to next stage */ stage++; return 0; }
int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp) { char id[MSG_BYTES]; struct cros_ec_dev *dev; int node = 0; *cros_ecp = NULL; do { node = fdtdec_next_compatible(blob, node, COMPAT_GOOGLE_CROS_EC); if (node < 0) { debug("%s: Node not found\n", __func__); return 0; } } while (!fdtdec_get_is_enabled(blob, node)); if (cros_ec_decode_fdt(blob, node, &dev)) { debug("%s: Failed to decode device.\n", __func__); return -CROS_EC_ERR_FDT_DECODE; } switch (dev->interface) { #ifdef CONFIG_CROS_EC_SPI case CROS_EC_IF_SPI: if (cros_ec_spi_init(dev, blob)) { debug("%s: Could not setup SPI interface\n", __func__); return -CROS_EC_ERR_DEV_INIT; } break; #endif #ifdef CONFIG_CROS_EC_I2C case CROS_EC_IF_I2C: if (cros_ec_i2c_init(dev, blob)) return -CROS_EC_ERR_DEV_INIT; break; #endif #ifdef CONFIG_CROS_EC_LPC case CROS_EC_IF_LPC: if (cros_ec_lpc_init(dev, blob)) return -CROS_EC_ERR_DEV_INIT; break; #endif #ifdef CONFIG_CROS_EC_SANDBOX case CROS_EC_IF_SANDBOX: if (cros_ec_sandbox_init(dev, blob)) return -CROS_EC_ERR_DEV_INIT; break; #endif case CROS_EC_IF_NONE: default: return 0; } /* we will poll the EC interrupt line */ fdtdec_setup_gpio(&dev->ec_int); if (fdt_gpio_isvalid(&dev->ec_int)) gpio_direction_input(dev->ec_int.gpio); if (cros_ec_check_version(dev)) { debug("%s: Could not detect CROS-EC version\n", __func__); return -CROS_EC_ERR_CHECK_VERSION; } if (cros_ec_read_id(dev, id, sizeof(id))) { debug("%s: Could not read KBC ID\n", __func__); return -CROS_EC_ERR_READ_ID; } /* Remember this device for use by the cros_ec command */ last_dev = *cros_ecp = dev; debug("Google Chrome EC CROS-EC driver ready, id '%s'\n", id); return 0; }
/* set up the UTMI USB controller with the parameters provided */ static int init_utmi_usb_controller(struct fdt_usb *config) { u32 val; int loop_count; const unsigned *timing; struct usb_ctlr *usbctlr = config->reg; struct clk_rst_ctlr *clkrst; struct usb_ctlr *usb1ctlr; clock_enable(config->periph_id); /* Reset the usb controller */ usbf_reset_controller(config, usbctlr); /* Stop crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN low */ clrbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN); /* Follow the crystal clock disable by >100ns delay */ udelay(1); /* * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP * mux must be switched to actually use a_sess_vld threshold. */ if (config->dr_mode == DR_MODE_OTG && fdt_gpio_isvalid(&config->vbus_gpio)) clrsetbits_le32(&usbctlr->usb1_legacy_ctrl, VBUS_SENSE_CTL_MASK, VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT); /* * PLL Delay CONFIGURATION settings. The following parameters control * the bring up of the plls. */ timing = get_pll_timing(); if (!controller->has_hostpc) { val = readl(&usbctlr->utmip_misc_cfg1); clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK, timing[PARAM_STABLE_COUNT] << UTMIP_PLLU_STABLE_COUNT_SHIFT); clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK, timing[PARAM_ACTIVE_DELAY_COUNT] << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT); writel(val, &usbctlr->utmip_misc_cfg1); /* Set PLL enable delay count and crystal frequency count */ val = readl(&usbctlr->utmip_pll_cfg1); clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK, timing[PARAM_ENABLE_DELAY_COUNT] << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT); clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK, timing[PARAM_XTAL_FREQ_COUNT] << UTMIP_XTAL_FREQ_COUNT_SHIFT); writel(val, &usbctlr->utmip_pll_cfg1); } else { clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; val = readl(&clkrst->crc_utmip_pll_cfg2); clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK, timing[PARAM_STABLE_COUNT] << UTMIP_PLLU_STABLE_COUNT_SHIFT); clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK, timing[PARAM_ACTIVE_DELAY_COUNT] << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT); writel(val, &clkrst->crc_utmip_pll_cfg2); /* Set PLL enable delay count and crystal frequency count */ val = readl(&clkrst->crc_utmip_pll_cfg1); clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK, timing[PARAM_ENABLE_DELAY_COUNT] << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT); clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK, timing[PARAM_XTAL_FREQ_COUNT] << UTMIP_XTAL_FREQ_COUNT_SHIFT); writel(val, &clkrst->crc_utmip_pll_cfg1); /* Disable Power Down state for PLL */ clrbits_le32(&clkrst->crc_utmip_pll_cfg1, PLLU_POWERDOWN | PLL_ENABLE_POWERDOWN | PLL_ACTIVE_POWERDOWN); /* Recommended PHY settings for EYE diagram */ val = readl(&usbctlr->utmip_xcvr_cfg0); clrsetbits_le32(&val, UTMIP_XCVR_SETUP_MASK, 0x4 << UTMIP_XCVR_SETUP_SHIFT); clrsetbits_le32(&val, UTMIP_XCVR_SETUP_MSB_MASK, 0x3 << UTMIP_XCVR_SETUP_MSB_SHIFT); clrsetbits_le32(&val, UTMIP_XCVR_HSSLEW_MSB_MASK, 0x8 << UTMIP_XCVR_HSSLEW_MSB_SHIFT); writel(val, &usbctlr->utmip_xcvr_cfg0); clrsetbits_le32(&usbctlr->utmip_xcvr_cfg1, UTMIP_XCVR_TERM_RANGE_ADJ_MASK, 0x7 << UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT); /* Some registers can be controlled from USB1 only. */ if (config->periph_id != PERIPH_ID_USBD) { clock_enable(PERIPH_ID_USBD); /* Disable Reset if in Reset state */ reset_set_enable(PERIPH_ID_USBD, 0); } usb1ctlr = (struct usb_ctlr *) ((u32)config->reg & USB1_ADDR_MASK); val = readl(&usb1ctlr->utmip_bias_cfg0); setbits_le32(&val, UTMIP_HSDISCON_LEVEL_MSB); clrsetbits_le32(&val, UTMIP_HSDISCON_LEVEL_MASK, 0x1 << UTMIP_HSDISCON_LEVEL_SHIFT); clrsetbits_le32(&val, UTMIP_HSSQUELCH_LEVEL_MASK, 0x2 << UTMIP_HSSQUELCH_LEVEL_SHIFT); writel(val, &usb1ctlr->utmip_bias_cfg0); /* Miscellaneous setting mentioned in Programming Guide */ clrbits_le32(&usbctlr->utmip_misc_cfg0, UTMIP_SUSPEND_EXIT_ON_EDGE); } /* Setting the tracking length time */ clrsetbits_le32(&usbctlr->utmip_bias_cfg1, UTMIP_BIAS_PDTRK_COUNT_MASK, timing[PARAM_BIAS_TIME] << UTMIP_BIAS_PDTRK_COUNT_SHIFT); /* Program debounce time for VBUS to become valid */ clrsetbits_le32(&usbctlr->utmip_debounce_cfg0, UTMIP_DEBOUNCE_CFG0_MASK, timing[PARAM_DEBOUNCE_A_TIME] << UTMIP_DEBOUNCE_CFG0_SHIFT); setbits_le32(&usbctlr->utmip_tx_cfg0, UTMIP_FS_PREAMBLE_J); /* Disable battery charge enabling bit */ setbits_le32(&usbctlr->utmip_bat_chrg_cfg0, UTMIP_PD_CHRG); clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_XCVR_LSBIAS_SE); setbits_le32(&usbctlr->utmip_spare_cfg0, FUSE_SETUP_SEL); /* * Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT * Setting these fields, together with default values of the * other fields, results in programming the registers below as * follows: * UTMIP_HSRX_CFG0 = 0x9168c000 * UTMIP_HSRX_CFG1 = 0x13 */ /* Set PLL enable delay count and Crystal frequency count */ val = readl(&usbctlr->utmip_hsrx_cfg0); clrsetbits_le32(&val, UTMIP_IDLE_WAIT_MASK, utmip_idle_wait_delay << UTMIP_IDLE_WAIT_SHIFT); clrsetbits_le32(&val, UTMIP_ELASTIC_LIMIT_MASK, utmip_elastic_limit << UTMIP_ELASTIC_LIMIT_SHIFT); writel(val, &usbctlr->utmip_hsrx_cfg0); /* Configure the UTMIP_HS_SYNC_START_DLY */ clrsetbits_le32(&usbctlr->utmip_hsrx_cfg1, UTMIP_HS_SYNC_START_DLY_MASK, utmip_hs_sync_start_delay << UTMIP_HS_SYNC_START_DLY_SHIFT); /* Preceed the crystal clock disable by >100ns delay. */ udelay(1); /* Resuscitate crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN */ setbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN); if (controller->has_hostpc) { if (config->periph_id == PERIPH_ID_USBD) clrbits_le32(&clkrst->crc_utmip_pll_cfg2, UTMIP_FORCE_PD_SAMP_A_POWERDOWN); if (config->periph_id == PERIPH_ID_USB3) clrbits_le32(&clkrst->crc_utmip_pll_cfg2, UTMIP_FORCE_PD_SAMP_C_POWERDOWN); } /* Finished the per-controller init. */ /* De-assert UTMIP_RESET to bring out of reset. */ clrbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET); /* Wait for the phy clock to become valid in 100 ms */ for (loop_count = 100000; loop_count != 0; loop_count--) { if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID) break; udelay(1); } if (!loop_count) return -1; /* Disable ICUSB FS/LS transceiver */ clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1); /* Select UTMI parallel interface */ clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, PTS_UTMI << PTS_SHIFT); clrbits_le32(&usbctlr->port_sc1, STS); /* Deassert power down state */ clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN); clrbits_le32(&usbctlr->utmip_xcvr_cfg1, UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | UTMIP_FORCE_PDDR_POWERDOWN); if (controller->has_hostpc) { /* * BIAS Pad Power Down is common among all 3 USB * controllers and can be controlled from USB1 only. */ usb1ctlr = (struct usb_ctlr *) ((u32)config->reg & USB1_ADDR_MASK); clrbits_le32(&usb1ctlr->utmip_bias_cfg0, UTMIP_BIASPD); udelay(25); clrbits_le32(&usb1ctlr->utmip_bias_cfg1, UTMIP_FORCE_PDTRK_POWERDOWN); } return 0; }