Ejemplo n.º 1
0
static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
{
	struct fixed_regulator_platdata *dev_pdata = dev_get_platdata(dev);
	int ret;

	debug("%s: dev='%s', enable=%d, delay=%d, has_gpio=%d\n", __func__,
	      dev->name, enable, dev_pdata->startup_delay_us,
	      dm_gpio_is_valid(&dev_pdata->gpio));
	/* Enable GPIO is optional */
	if (!dm_gpio_is_valid(&dev_pdata->gpio)) {
		if (!enable)
			return -ENOSYS;
		return 0;
	}

	ret = dm_gpio_set_value(&dev_pdata->gpio, enable);
	if (ret) {
		pr_err("Can't set regulator : %s gpio to: %d\n", dev->name,
		      enable);
		return ret;
	}

	if (enable && dev_pdata->startup_delay_us)
		udelay(dev_pdata->startup_delay_us);
	debug("%s: done\n", __func__);

	return 0;
}
Ejemplo n.º 2
0
static int do_sdhci_init(struct sdhci_host *host)
{
	int dev_id, flag, ret;

	flag = host->bus_width == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE;
	dev_id = host->index + PERIPH_ID_SDMMC0;

	ret = exynos_pinmux_config(dev_id, flag);
	if (ret) {
		printf("external SD not configured\n");
		return ret;
	}

	if (dm_gpio_is_valid(&host->pwr_gpio)) {
		dm_gpio_set_value(&host->pwr_gpio, 1);
		ret = exynos_pinmux_config(dev_id, flag);
		if (ret) {
			debug("MMC not configured\n");
			return ret;
		}
	}

	if (dm_gpio_is_valid(&host->cd_gpio)) {
		ret = dm_gpio_get_value(&host->cd_gpio);
		if (ret) {
			debug("no SD card detected (%d)\n", ret);
			return -ENODEV;
		}
	}

	return s5p_sdhci_core_init(host);
}
Ejemplo n.º 3
0
int board_late_init(void)
{
	struct gpio_desc gpio = {};
	int node;

	node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "st,led1");
	if (node < 0)
		return -1;

	gpio_request_by_name_nodev(offset_to_ofnode(node), "led-gpio", 0, &gpio,
				   GPIOD_IS_OUT);

	if (dm_gpio_is_valid(&gpio)) {
		dm_gpio_set_value(&gpio, 0);
		mdelay(10);
		dm_gpio_set_value(&gpio, 1);
	}

	/* read button 1*/
	node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "st,button1");
	if (node < 0)
		return -1;

	gpio_request_by_name_nodev(offset_to_ofnode(node), "button-gpio", 0,
				   &gpio, GPIOD_IS_IN);

	if (dm_gpio_is_valid(&gpio)) {
		if (dm_gpio_get_value(&gpio))
			puts("usr button is at HIGH LEVEL\n");
		else
			puts("usr button is at LOW LEVEL\n");
	}

	return 0;
}
Ejemplo n.º 4
0
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 (dm_gpio_is_valid(&host->pwr_gpio)) {
		dm_gpio_set_value(&host->pwr_gpio, 1);
		err = exynos_pinmux_config(dev_id, flag);
		if (err) {
			debug("MMC not configured\n");
			return err;
		}
	}

	if (dm_gpio_is_valid(&host->cd_gpio)) {
		if (dm_gpio_get_value(&host->cd_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);
}
Ejemplo n.º 5
0
/**
 * Handle the next stage of device init
 */
static int handle_stage(const void *blob, struct tegra_lcd_priv *priv)
{
    debug("%s: stage %d\n", __func__, priv->stage);

    /* do the things for this stage */
    switch (priv->stage) {
    case STAGE_START:
        /*
         * 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);
        break;
    case STAGE_PANEL_VDD:
        if (dm_gpio_is_valid(&priv->panel_vdd))
            dm_gpio_set_value(&priv->panel_vdd, 1);
        break;
    case STAGE_LVDS:
        if (dm_gpio_is_valid(&priv->lvds_shutdown))
            dm_gpio_set_value(&priv->lvds_shutdown, 1);
        break;
    case STAGE_BACKLIGHT_VDD:
        if (dm_gpio_is_valid(&priv->backlight_vdd))
            dm_gpio_set_value(&priv->backlight_vdd, 1);
        break;
    case STAGE_PWM:
        /* Enable PWM at 15/16 high, 32768 Hz with divider 1 */
        pinmux_set_func(PMUX_PINGRP_GPU, PMUX_FUNC_PWM);
        pinmux_tristate_disable(PMUX_PINGRP_GPU);

        pwm_set_config(priv->pwm, priv->pwm_channel, 0xdf, 0xff);
        pwm_set_enable(priv->pwm, priv->pwm_channel, true);
        break;
    case STAGE_BACKLIGHT_EN:
        if (dm_gpio_is_valid(&priv->backlight_en))
            dm_gpio_set_value(&priv->backlight_en, 1);
        break;
    case STAGE_DONE:
        break;
    }

    /* set up timer for next stage */
    priv->timer_next = timer_get_us();
    if (priv->stage < FDT_LCD_TIMINGS)
        priv->timer_next += priv->panel_timings[priv->stage] * 1000;

    /* move to next stage */
    priv->stage++;
    return 0;
}
Ejemplo n.º 6
0
static void spi_cs_deactivate(struct pic32_spi_priv *priv)
{
    if (!dm_gpio_is_valid(&priv->cs_gpio))
        return;

    dm_gpio_set_value(&priv->cs_gpio, 0);
}
Ejemplo n.º 7
0
static int atmel_spi_probe(struct udevice *bus)
{
	struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
	int ret;

	ret = atmel_spi_enable_clk(bus);
	if (ret)
		return ret;

	bus_plat->regs = (struct at91_spi *)devfdt_get_addr(bus);

#ifdef CONFIG_DM_GPIO
	struct atmel_spi_priv *priv = dev_get_priv(bus);
	int i;

	ret = gpio_request_list_by_name(bus, "cs-gpios", priv->cs_gpios,
					ARRAY_SIZE(priv->cs_gpios), 0);
	if (ret < 0) {
		pr_err("Can't get %s gpios! Error: %d", bus->name, ret);
		return ret;
	}

	for(i = 0; i < ARRAY_SIZE(priv->cs_gpios); i++) {
		if (!dm_gpio_is_valid(&priv->cs_gpios[i]))
			continue;

		dm_gpio_set_dir_flags(&priv->cs_gpios[i],
				      GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
	}
#endif

	writel(ATMEL_SPI_CR_SWRST, &bus_plat->regs->cr);

	return 0;
}
Ejemplo n.º 8
0
void reset_misc(void)
{
	struct gpio_desc gpio = {};
	int node;

	node = fdt_node_offset_by_compatible(gd->fdt_blob, 0,
			"samsung,emmc-reset");
	if (node < 0)
		return;

	gpio_request_by_name_nodev(gd->fdt_blob, node, "reset-gpio", 0, &gpio,
				   GPIOD_IS_OUT);

	if (dm_gpio_is_valid(&gpio)) {
		/*
		 * Reset eMMC
		 *
		 * FIXME: Need to optimize delay time. Minimum 1usec pulse is
		 *	  required by 'JEDEC Standard No.84-A441' (eMMC)
		 *	  document but real delay time is expected to greater
		 *	  than 1usec.
		 */
		dm_gpio_set_value(&gpio, 0);
		mdelay(10);
		dm_gpio_set_value(&gpio, 1);
	}
}
Ejemplo n.º 9
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 (dm_gpio_is_valid(&ctx->vbus_gpio))
		dm_gpio_set_value(&ctx->vbus_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;
}
Ejemplo n.º 10
0
static int xhci_usb_probe(struct udevice *dev)
{
	struct exynos_xhci_platdata *plat = dev_get_platdata(dev);
	struct exynos_xhci *ctx = dev_get_priv(dev);
	struct xhci_hcor *hcor;
	int ret;

	ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
	ctx->usb3_phy = (struct exynos_usb3_phy *)plat->phy_base;
	ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
	hcor = (struct xhci_hcor *)((uint32_t)ctx->hcd +
			HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));

	/* setup the Vbus gpio here */
	if (dm_gpio_is_valid(&plat->vbus_gpio))
		dm_gpio_set_value(&plat->vbus_gpio, 1);

	ret = exynos_xhci_core_init(ctx);
	if (ret) {
		puts("XHCI: failed to initialize controller\n");
		return -EINVAL;
	}

	return xhci_register(dev, ctx->hcd, hcor);
}
Ejemplo n.º 11
0
static int dw_mdio_reset(struct mii_dev *bus)
{
	struct udevice *dev = bus->priv;
	struct dw_eth_dev *priv = dev_get_priv(dev);
	struct dw_eth_pdata *pdata = dev_get_platdata(dev);
	int ret;

	if (!dm_gpio_is_valid(&priv->reset_gpio))
		return 0;

	/* reset the phy */
	ret = dm_gpio_set_value(&priv->reset_gpio, 0);
	if (ret)
		return ret;

	udelay(pdata->reset_delays[0]);

	ret = dm_gpio_set_value(&priv->reset_gpio, 1);
	if (ret)
		return ret;

	udelay(pdata->reset_delays[1]);

	ret = dm_gpio_set_value(&priv->reset_gpio, 0);
	if (ret)
		return ret;

	udelay(pdata->reset_delays[2]);

	return 0;
}
Ejemplo n.º 12
0
int cros_ec_interrupt_pending(struct cros_ec_dev *dev)
{
	/* no interrupt support : always poll */
	if (!dm_gpio_is_valid(&dev->ec_int))
		return -ENOENT;

	return dm_gpio_get_value(&dev->ec_int);
}
Ejemplo n.º 13
0
static int gpio_led_set_on(struct udevice *dev, int on)
{
	struct led_gpio_priv *priv = dev_get_priv(dev);

	if (!dm_gpio_is_valid(&priv->gpio))
		return -EREMOTEIO;

	return dm_gpio_set_value(&priv->gpio, on);
}
Ejemplo n.º 14
0
int cros_ec_interrupt_pending(struct udevice *dev)
{
	struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);

	/* no interrupt support : always poll */
	if (!dm_gpio_is_valid(&cdev->ec_int))
		return -ENOENT;

	return dm_gpio_get_value(&cdev->ec_int);
}
Ejemplo n.º 15
0
static int tegra_mmc_getcd(struct mmc *mmc)
{
	struct mmc_host *host = mmc->priv;

	debug("tegra_mmc_getcd called\n");

	if (dm_gpio_is_valid(&host->cd_gpio))
		return dm_gpio_get_value(&host->cd_gpio);

	return 1;
}
Ejemplo n.º 16
0
static int tegra_mmc_getcd(struct udevice *dev)
{
	struct tegra_mmc_priv *priv = dev_get_priv(dev);

	debug("tegra_mmc_getcd called\n");

	if (dm_gpio_is_valid(&priv->cd_gpio))
		return dm_gpio_get_value(&priv->cd_gpio);

	return 1;
}
Ejemplo n.º 17
0
static int stm32_sdmmc2_getcd(struct udevice *dev)
{
	struct stm32_sdmmc2_priv *priv = dev_get_priv(dev);

	debug("stm32_sdmmc2_getcd called\n");

	if (dm_gpio_is_valid(&priv->cd_gpio))
		return dm_gpio_get_value(&priv->cd_gpio);

	return 1;
}
Ejemplo n.º 18
0
static void atmel_spi_cs_deactivate(struct udevice *dev)
{
	struct udevice *bus = dev_get_parent(dev);
	struct atmel_spi_priv *priv = dev_get_priv(bus);
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
	u32 cs = slave_plat->cs;

	if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
		return;

	dm_gpio_set_value(&priv->cs_gpios[cs], 1);
}
Ejemplo n.º 19
0
void __weak board_netphy_reset(void *dev)
{
	struct pic32eth_dev *priv = dev;

	if (!dm_gpio_is_valid(&priv->rst_gpio))
		return;

	/* phy reset */
	dm_gpio_set_value(&priv->rst_gpio, 0);
	udelay(300);
	dm_gpio_set_value(&priv->rst_gpio, 1);
	udelay(300);
}
Ejemplo n.º 20
0
static enum led_state_t gpio_led_get_state(struct udevice *dev)
{
	struct led_gpio_priv *priv = dev_get_priv(dev);
	int ret;

	if (!dm_gpio_is_valid(&priv->gpio))
		return -EREMOTEIO;
	ret = dm_gpio_get_value(&priv->gpio);
	if (ret < 0)
		return ret;

	return ret ? LEDST_ON : LEDST_OFF;
}
Ejemplo n.º 21
0
static int vf_usb_ofdata_to_platdata(struct udevice *dev)
{
	struct ehci_vf_priv_data *priv = dev_get_priv(dev);
	const void *dt_blob = gd->fdt_blob;
	int node = dev_of_offset(dev);
	const char *mode;

	priv->portnr = dev->seq;

	priv->ehci = (struct usb_ehci *)devfdt_get_addr(dev);
	mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
	if (mode) {
		if (0 == strcmp(mode, "host")) {
			priv->dr_mode = DR_MODE_HOST;
			priv->init_type = USB_INIT_HOST;
		} else if (0 == strcmp(mode, "peripheral")) {
			priv->dr_mode = DR_MODE_DEVICE;
			priv->init_type = USB_INIT_DEVICE;
		} else if (0 == strcmp(mode, "otg")) {
			priv->dr_mode = DR_MODE_OTG;
			/*
			 * We set init_type to device by default when OTG
			 * mode is requested. If a valid gpio is provided
			 * we will switch the init_type based on the state
			 * of the gpio pin.
			 */
			priv->init_type = USB_INIT_DEVICE;
		} else {
			debug("%s: Cannot decode dr_mode '%s'\n",
			      __func__, mode);
			return -EINVAL;
		}
	} else {
		priv->dr_mode = DR_MODE_HOST;
		priv->init_type = USB_INIT_HOST;
	}

	if (priv->dr_mode == DR_MODE_OTG) {
		gpio_request_by_name_nodev(offset_to_ofnode(node),
					   "fsl,cdet-gpio", 0, &priv->cdet_gpio,
					   GPIOD_IS_IN);
		if (dm_gpio_is_valid(&priv->cdet_gpio)) {
			if (dm_gpio_get_value(&priv->cdet_gpio))
				priv->init_type = USB_INIT_DEVICE;
			else
				priv->init_type = USB_INIT_HOST;
		}
	}

	return 0;
}
Ejemplo n.º 22
0
static int do_mmc_init(int dev_index, bool removable)
{
	struct mmc_host *host;
	struct mmc *mmc;

	/* DT should have been read & host config filled in */
	host = &mmc_host[dev_index];
	if (!host->enabled)
		return -1;

	debug(" do_mmc_init: index %d, bus width %d pwr_gpio %d cd_gpio %d\n",
	      dev_index, host->width, gpio_get_number(&host->pwr_gpio),
	      gpio_get_number(&host->cd_gpio));

	host->clock = 0;
	clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000);

	if (dm_gpio_is_valid(&host->pwr_gpio))
		dm_gpio_set_value(&host->pwr_gpio, 1);

	memset(&host->cfg, 0, sizeof(host->cfg));

	host->cfg.name = "Tegra SD/MMC";
	host->cfg.ops = &tegra_mmc_ops;

	host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
	host->cfg.host_caps = 0;
	if (host->width == 8)
		host->cfg.host_caps |= MMC_MODE_8BIT;
	if (host->width >= 4)
		host->cfg.host_caps |= MMC_MODE_4BIT;
	host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;

	/*
	 * min freq is for card identification, and is the highest
	 *  low-speed SDIO card frequency (actually 400KHz)
	 * max freq is highest HS eMMC clock as per the SD/MMC spec
	 *  (actually 52MHz)
	 */
	host->cfg.f_min = 375000;
	host->cfg.f_max = 48000000;

	host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;

	mmc = mmc_create(&host->cfg, host);
	mmc->block_dev.removable = removable;
	if (mmc == NULL)
		return -1;

	return 0;
}
Ejemplo n.º 23
0
static void atmel_spi_cs_activate(struct udevice *dev)
{
#ifdef CONFIG_DM_GPIO
	struct udevice *bus = dev_get_parent(dev);
	struct atmel_spi_priv *priv = dev_get_priv(bus);
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
	u32 cs = slave_plat->cs;

	if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
		return;

	dm_gpio_set_value(&priv->cs_gpios[cs], 0);
#endif
}
Ejemplo n.º 24
0
static int led_gpio_remove(struct udevice *dev)
{
	/*
	 * The GPIO driver may have already been removed. We will need to
	 * address this more generally.
	 */
#ifndef CONFIG_SANDBOX
	struct led_gpio_priv *priv = dev_get_priv(dev);

	if (dm_gpio_is_valid(&priv->gpio))
		dm_gpio_free(dev, &priv->gpio);
#endif

	return 0;
}
Ejemplo n.º 25
0
static int check_reserved(const struct gpio_desc *desc, const char *func)
{
	struct gpio_dev_priv *uc_priv;

	if (!dm_gpio_is_valid(desc))
		return -ENOENT;

	uc_priv = dev_get_uclass_priv(desc->dev);
	if (!uc_priv->name[desc->offset]) {
		printf("%s: %s: error: gpio %s%d not reserved\n",
		       desc->dev->name, func,
		       uc_priv->bank_name ? uc_priv->bank_name : "",
		       desc->offset);
		return -EBUSY;
	}

	return 0;
}
Ejemplo n.º 26
0
/* Set up VBUS for host/device mode */
static void set_up_vbus(struct fdt_usb *config, enum usb_init_type init)
{
	/*
	 * If we are an OTG port initializing in host mode,
	 * check if remote host is driving VBus and bail out in this case.
	 */
	if (init == USB_INIT_HOST &&
	    config->dr_mode == DR_MODE_OTG &&
	    (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)) {
		printf("tegrausb: VBUS input active; not enabling as host\n");
		return;
	}

	if (dm_gpio_is_valid(&config->vbus_gpio)) {
		int vbus_value;

		vbus_value = (init == USB_INIT_HOST);
		dm_gpio_set_value(&config->vbus_gpio, vbus_value);

		debug("set_up_vbus: GPIO %d %d\n",
		      gpio_get_number(&config->vbus_gpio), vbus_value);
	}
}
Ejemplo n.º 27
0
static int gpio_led_set_state(struct udevice *dev, enum led_state_t state)
{
	struct led_gpio_priv *priv = dev_get_priv(dev);
	int ret;

	if (!dm_gpio_is_valid(&priv->gpio))
		return -EREMOTEIO;
	switch (state) {
	case LEDST_OFF:
	case LEDST_ON:
		break;
	case LEDST_TOGGLE:
		ret = dm_gpio_get_value(&priv->gpio);
		if (ret < 0)
			return ret;
		state = !ret;
		break;
	default:
		return -ENOSYS;
	}

	return dm_gpio_set_value(&priv->gpio, state);
}
Ejemplo n.º 28
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 (dm_gpio_is_valid(&ctx->vbus_gpio))
		dm_gpio_set_value(&ctx->vbus_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;
}
Ejemplo n.º 29
0
int board_prepare_usb(enum usb_init_type type)
{
	static struct udevice *pmic_gpio;
	static struct gpio_desc hub_reset, usb_sel;
	int ret = 0, node;

	if (!pmic_gpio) {
		ret = uclass_get_device_by_name(UCLASS_GPIO,
						"pm8916_gpios@c000",
						&pmic_gpio);
		if (ret < 0) {
			printf("Failed to find pm8916_gpios@c000 node.\n");
			return ret;
		}
	}

	/* Try to request gpios needed to start usb host on dragonboard */
	if (!dm_gpio_is_valid(&hub_reset)) {
		node = fdt_subnode_offset(gd->fdt_blob,
					  dev_of_offset(pmic_gpio),
					  "usb_hub_reset_pm");
		if (node < 0) {
			printf("Failed to find usb_hub_reset_pm dt node.\n");
			return node;
		}
		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
						 "gpios", 0, &hub_reset, 0);
		if (ret < 0) {
			printf("Failed to request usb_hub_reset_pm gpio.\n");
			return ret;
		}
	}

	if (!dm_gpio_is_valid(&usb_sel)) {
		node = fdt_subnode_offset(gd->fdt_blob,
					  dev_of_offset(pmic_gpio),
					  "usb_sw_sel_pm");
		if (node < 0) {
			printf("Failed to find usb_sw_sel_pm dt node.\n");
			return 0;
		}
		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
						 "gpios", 0, &usb_sel, 0);
		if (ret < 0) {
			printf("Failed to request usb_sw_sel_pm gpio.\n");
			return ret;
		}
	}

	if (type == USB_INIT_HOST) {
		/* Start USB Hub */
		dm_gpio_set_dir_flags(&hub_reset,
				      GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
		mdelay(100);
		/* Switch usb to host connectors */
		dm_gpio_set_dir_flags(&usb_sel,
				      GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
		mdelay(100);
	} else { /* Device */
		/* Disable hub */
		dm_gpio_set_dir_flags(&hub_reset, GPIOD_IS_OUT);
		/* Switch back to device connector */
		dm_gpio_set_dir_flags(&usb_sel, GPIOD_IS_OUT);
	}

	return 0;
}
Ejemplo n.º 30
0
/* set up the UTMI USB controller with the parameters provided */
static int init_utmi_usb_controller(struct fdt_usb *config,
				    enum usb_init_type init)
{
	struct fdt_usb_controller *controller;
	u32 b_sess_valid_mask, 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);

	b_sess_valid_mask = (VBUS_B_SESS_VLD_SW_VALUE | VBUS_B_SESS_VLD_SW_EN);
	clrsetbits_le32(&usbctlr->phy_vbus_sensors, b_sess_valid_mask,
			(init == USB_INIT_DEVICE) ? b_sess_valid_mask : 0);

	/*
	 * 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 &&
	    dm_gpio_is_valid(&config->vbus_gpio))
		clrsetbits_le32(&usbctlr->usb1_legacy_ctrl,
			VBUS_SENSE_CTL_MASK,
			VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);

	controller = &fdt_usb_controllers[config->type];
	debug("controller=%p, type=%d\n", controller, config->type);

	/*
	 * PLL Delay CONFIGURATION settings. The following parameters control
	 * the bring up of the plls.
	 */
	timing = get_pll_timing(controller);

	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 *)
			((unsigned long)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);

	if (timing[PARAM_DEBOUNCE_A_TIME] > 0xFFFF) {
		clrsetbits_le32(&usbctlr->utmip_debounce_cfg0,
				UTMIP_DEBOUNCE_CFG0_MASK,
				(timing[PARAM_DEBOUNCE_A_TIME] >> 1)
				<< UTMIP_DEBOUNCE_CFG0_SHIFT);
		clrsetbits_le32(&usbctlr->utmip_bias_cfg1,
				UTMIP_BIAS_DEBOUNCE_TIMESCALE_MASK,
				1 << UTMIP_BIAS_DEBOUNCE_TIMESCALE_SHIFT);
	}