示例#1
0
static int da8xx_rproc_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct rproc *rproc = platform_get_drvdata(pdev);
	struct da8xx_rproc *drproc = (struct da8xx_rproc *)rproc->priv;

	/*
	 * It's important to place the DSP in reset before going away,
	 * since a subsequent insmod of this module may enable the DSP's
	 * clock before its program/boot-address has been loaded and
	 * before this module's probe has had a chance to reset the DSP.
	 * Without the reset, the DSP can lockup permanently when it
	 * begins executing garbage.
	 */
	reset_assert(dev);

	/*
	 * The devm subsystem might end up releasing things before
	 * freeing the irq, thus allowing an interrupt to sneak in while
	 * the device is being removed.  This should prevent that.
	 */
	disable_irq(drproc->irq);

	rproc_del(rproc);
	rproc_put(rproc);

	return 0;
}
示例#2
0
int board_usb_cleanup(int index, enum usb_init_type init)
{
	/* Reset usbotg */
	reset_assert(&usbotg_reset);
	udelay(2);
	reset_deassert(&usbotg_reset);

	return 0;
}
示例#3
0
static void stm32_sdmmc2_pwron(struct stm32_sdmmc2_priv *priv)
{
	/* Reset */
	reset_assert(&priv->reset_ctl);
	udelay(2);
	reset_deassert(&priv->reset_ctl);

	udelay(1000);

	/* Set Power State to ON */
	writel(SDMMC_POWER_PWRCTRL | priv->pwr_reg_msk, priv->base + SDMMC_POWER);

	/*
	 * 1ms: required power up waiting time before starting the
	 * SD initialization sequence
	 */
	udelay(1000);
}
示例#4
0
int board_usb_init(int index, enum usb_init_type init)
{
	struct fdtdec_phandle_args args;
	struct udevice *dev;
	const void *blob = gd->fdt_blob;
	struct clk clk;
	struct phy phy;
	int node;
	int phy_provider;
	int ret;

	/* find the usb otg node */
	node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
	if (node < 0) {
		debug("Not found usb_otg device\n");
		return -ENODEV;
	}

	if (!fdtdec_get_is_enabled(blob, node)) {
		debug("stm32 usbotg is disabled in the device tree\n");
		return -ENODEV;
	}

	/* Enable clock */
	ret = fdtdec_parse_phandle_with_args(blob, node, "clocks",
					     "#clock-cells", 0, 0, &args);
	if (ret) {
		debug("usbotg has no clocks defined in the device tree\n");
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev);
	if (ret)
		return ret;

	if (args.args_count != 1) {
		debug("Can't find clock ID in the device tree\n");
		return -ENODATA;
	}

	clk.dev = dev;
	clk.id = args.args[0];

	ret = clk_enable(&clk);
	if (ret) {
		debug("Failed to enable usbotg clock\n");
		return ret;
	}

	/* Reset */
	ret = fdtdec_parse_phandle_with_args(blob, node, "resets",
					     "#reset-cells", 0, 0, &args);
	if (ret) {
		debug("usbotg has no resets defined in the device tree\n");
		goto clk_err;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev);
	if (ret || args.args_count != 1)
		goto clk_err;

	usbotg_reset.dev = dev;
	usbotg_reset.id = args.args[0];

	reset_assert(&usbotg_reset);
	udelay(2);
	reset_deassert(&usbotg_reset);

	/* Get USB PHY */
	ret = fdtdec_parse_phandle_with_args(blob, node, "phys",
					     "#phy-cells", 0, 0, &args);
	if (!ret) {
		phy_provider = fdt_parent_offset(blob, args.node);
		ret = uclass_get_device_by_of_offset(UCLASS_PHY,
						     phy_provider, &dev);
		if (ret)
			goto clk_err;

		phy.dev = dev;
		phy.id = fdtdec_get_uint(blob, args.node, "reg", -1);

		ret = generic_phy_power_on(&phy);
		if (ret) {
			debug("unable to power on the phy\n");
			goto clk_err;
		}

		ret = generic_phy_init(&phy);
		if (ret) {
			debug("failed to init usb phy\n");
			goto phy_power_err;
		}
	}

	/* Parse and store data needed for gadget */
	stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
	if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) {
		debug("usbotg: can't get base address\n");
		ret = -ENODATA;
		goto phy_init_err;
	}

	stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node,
						     "g-rx-fifo-size", 0);
	stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node,
							"g-np-tx-fifo-size", 0);
	stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node,
						     "g-tx-fifo-size", 0);
	/* Enable voltage level detector */
	if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply",
					     NULL, 0, 0, &args))) {
		if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR,
						    args.node, &dev)) {
			ret = regulator_set_enable(dev, true);
			if (ret) {
				debug("Failed to enable usb33d\n");
				goto phy_init_err;
			}
		}
	}
		/* Enable vbus sensing */
	setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO,
		     STM32MP_GGPIO_VBUS_SENSING);

	return dwc2_udc_probe(&stm32mp_otg_data);

phy_init_err:
	generic_phy_exit(&phy);

phy_power_err:
	generic_phy_power_off(&phy);

clk_err:
	clk_disable(&clk);

	return ret;
}
示例#5
0
static int da8xx_rproc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct da8xx_rproc *drproc;
	struct rproc *rproc;
	struct irq_data *irq_data;
	struct resource *bootreg_res;
	struct resource *chipsig_res;
	struct clk *dsp_clk;
	void __iomem *chipsig;
	void __iomem *bootreg;
	int irq;
	int ret;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(dev, "platform_get_irq(pdev, 0) error: %d\n", irq);
		return irq;
	}

	irq_data = irq_get_irq_data(irq);
	if (!irq_data) {
		dev_err(dev, "irq_get_irq_data(%d): NULL\n", irq);
		return -EINVAL;
	}

	bootreg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	bootreg = devm_ioremap_resource(dev, bootreg_res);
	if (IS_ERR(bootreg))
		return PTR_ERR(bootreg);

	chipsig_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	chipsig = devm_ioremap_resource(dev, chipsig_res);
	if (IS_ERR(chipsig))
		return PTR_ERR(chipsig);

	dsp_clk = devm_clk_get(dev, NULL);
	if (IS_ERR(dsp_clk)) {
		dev_err(dev, "clk_get error: %ld\n", PTR_ERR(dsp_clk));

		return PTR_ERR(dsp_clk);
	}

	rproc = rproc_alloc(dev, "dsp", &da8xx_rproc_ops, da8xx_fw_name,
		sizeof(*drproc));
	if (!rproc)
		return -ENOMEM;

	drproc = rproc->priv;
	drproc->rproc = rproc;
	rproc->has_iommu = false;

	platform_set_drvdata(pdev, rproc);

	/* everything the ISR needs is now setup, so hook it up */
	ret = devm_request_threaded_irq(dev, irq, da8xx_rproc_callback,
					handle_event, 0, "da8xx-remoteproc",
					rproc);
	if (ret) {
		dev_err(dev, "devm_request_threaded_irq error: %d\n", ret);
		goto free_rproc;
	}

	/*
	 * rproc_add() can end up enabling the DSP's clk with the DSP
	 * *not* in reset, but da8xx_rproc_start() needs the DSP to be
	 * held in reset at the time it is called.
	 */
	ret = reset_assert(dev);
	if (ret)
		goto free_rproc;

	drproc->chipsig = chipsig;
	drproc->bootreg = bootreg;
	drproc->ack_fxn = irq_data->chip->irq_ack;
	drproc->irq_data = irq_data;
	drproc->irq = irq;
	drproc->dsp_clk = dsp_clk;

	ret = rproc_add(rproc);
	if (ret) {
		dev_err(dev, "rproc_add failed: %d\n", ret);
		goto free_rproc;
	}

	return 0;

free_rproc:
	rproc_put(rproc);

	return ret;
}
示例#6
0
static int tegra_mmc_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct tegra_mmc_plat *plat = dev_get_platdata(dev);
	struct tegra_mmc_priv *priv = dev_get_priv(dev);
	struct mmc_config *cfg = &plat->cfg;
	int bus_width, ret;

	cfg->name = dev->name;

	bus_width = dev_read_u32_default(dev, "bus-width", 1);

	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
	cfg->host_caps = 0;
	if (bus_width == 8)
		cfg->host_caps |= MMC_MODE_8BIT;
	if (bus_width >= 4)
		cfg->host_caps |= MMC_MODE_4BIT;
	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)
	 */
	cfg->f_min = 375000;
	cfg->f_max = 48000000;

	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;

	priv->reg = (void *)dev_read_addr(dev);

	ret = reset_get_by_name(dev, "sdhci", &priv->reset_ctl);
	if (ret) {
		debug("reset_get_by_name() failed: %d\n", ret);
		return ret;
	}
	ret = clk_get_by_index(dev, 0, &priv->clk);
	if (ret) {
		debug("clk_get_by_index() failed: %d\n", ret);
		return ret;
	}

	ret = reset_assert(&priv->reset_ctl);
	if (ret)
		return ret;
	ret = clk_enable(&priv->clk);
	if (ret)
		return ret;
	ret = clk_set_rate(&priv->clk, 20000000);
	if (IS_ERR_VALUE(ret))
		return ret;
	ret = reset_deassert(&priv->reset_ctl);
	if (ret)
		return ret;

	/* These GPIOs are optional */
	gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN);
	gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN);
	gpio_request_by_name(dev, "power-gpios", 0, &priv->pwr_gpio,
			     GPIOD_IS_OUT);
	if (dm_gpio_is_valid(&priv->pwr_gpio))
		dm_gpio_set_value(&priv->pwr_gpio, 1);

	upriv->mmc = &plat->mmc;

	return tegra_mmc_init(dev);
}
示例#7
0
static int tegra_mmc_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct tegra_mmc_priv *priv = dev_get_priv(dev);
	int bus_width, ret;

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

	bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width",
				   1);

	priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
	priv->cfg.host_caps = 0;
	if (bus_width == 8)
		priv->cfg.host_caps |= MMC_MODE_8BIT;
	if (bus_width >= 4)
		priv->cfg.host_caps |= MMC_MODE_4BIT;
	priv->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)
	 */
	priv->cfg.f_min = 375000;
	priv->cfg.f_max = 48000000;

	priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;

	priv->reg = (void *)dev_get_addr(dev);

	ret = reset_get_by_name(dev, "sdhci", &priv->reset_ctl);
	if (ret) {
		debug("reset_get_by_name() failed: %d\n", ret);
		return ret;
	}
	ret = clk_get_by_index(dev, 0, &priv->clk);
	if (ret) {
		debug("clk_get_by_index() failed: %d\n", ret);
		return ret;
	}

	ret = reset_assert(&priv->reset_ctl);
	if (ret)
		return ret;
	ret = clk_enable(&priv->clk);
	if (ret)
		return ret;
	ret = clk_set_rate(&priv->clk, 20000000);
	if (IS_ERR_VALUE(ret))
		return ret;
	ret = reset_deassert(&priv->reset_ctl);
	if (ret)
		return ret;

	/* These GPIOs are optional */
	gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
			     GPIOD_IS_IN);
	gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio,
			     GPIOD_IS_IN);
	gpio_request_by_name(dev, "power-gpios", 0,
			     &priv->pwr_gpio, GPIOD_IS_OUT);
	if (dm_gpio_is_valid(&priv->pwr_gpio))
		dm_gpio_set_value(&priv->pwr_gpio, 1);

	priv->mmc = mmc_create(&priv->cfg, priv);
	if (priv->mmc == NULL)
		return -1;

	priv->mmc->dev = dev;
	upriv->mmc = priv->mmc;

	return 0;
}
示例#8
0
文件: tegra_mmc.c 项目: eesuda/u-boot
static int do_mmc_init(int dev_index, bool removable)
{
	struct mmc_host *host;
	struct mmc *mmc;
#ifdef CONFIG_TEGRA186
	int ret;
#endif

	/* 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;

#ifdef CONFIG_TEGRA186
	ret = reset_assert(&host->reset_ctl);
	if (ret)
		return ret;
	ret = clk_enable(&host->clk);
	if (ret)
		return ret;
	ret = clk_set_rate(&host->clk, 20000000);
	if (IS_ERR_VALUE(ret))
		return ret;
	ret = reset_deassert(&host->reset_ctl);
	if (ret)
		return ret;
#else
	clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000);
#endif

	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;
}
示例#9
0
static int stm32_qspi_probe(struct udevice *bus)
{
	struct stm32_qspi_priv *priv = dev_get_priv(bus);
	struct resource res;
	struct clk clk;
	struct reset_ctl reset_ctl;
	int ret;

	ret = dev_read_resource_byname(bus, "qspi", &res);
	if (ret) {
		dev_err(bus, "can't get regs base addresses(ret = %d)!\n", ret);
		return ret;
	}

	priv->regs = (struct stm32_qspi_regs *)res.start;

	ret = dev_read_resource_byname(bus, "qspi_mm", &res);
	if (ret) {
		dev_err(bus, "can't get mmap base address(ret = %d)!\n", ret);
		return ret;
	}

	priv->mm_base = (void __iomem *)res.start;

	priv->mm_size = resource_size(&res);
	if (priv->mm_size > STM32_QSPI_MAX_MMAP_SZ)
		return -EINVAL;

	debug("%s: regs=<0x%p> mapped=<0x%p> mapped_size=<0x%lx>\n",
	      __func__, priv->regs, priv->mm_base, priv->mm_size);

	ret = clk_get_by_index(bus, 0, &clk);
	if (ret < 0)
		return ret;

	ret = clk_enable(&clk);
	if (ret) {
		dev_err(bus, "failed to enable clock\n");
		return ret;
	}

	priv->clock_rate = clk_get_rate(&clk);
	if (priv->clock_rate < 0) {
		clk_disable(&clk);
		return priv->clock_rate;
	}

	ret = reset_get_by_index(bus, 0, &reset_ctl);
	if (ret) {
		if (ret != -ENOENT) {
			dev_err(bus, "failed to get reset\n");
			clk_disable(&clk);
			return ret;
		}
	} else {
		/* Reset QSPI controller */
		reset_assert(&reset_ctl);
		udelay(2);
		reset_deassert(&reset_ctl);
	}

	priv->cs_used = -1;

	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT);

	/* Set dcr fsize to max address */
	setbits_le32(&priv->regs->dcr,
		     STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT);

	return 0;
}