static int bcm6358_usbh_probe(struct udevice *dev) { struct bcm6358_usbh_priv *priv = dev_get_priv(dev); struct reset_ctl rst_ctl; int ret; priv->regs = dev_remap_addr(dev); if (!priv->regs) return -EINVAL; /* perform reset */ ret = reset_get_by_index(dev, 0, &rst_ctl); if (ret < 0) return ret; ret = reset_deassert(&rst_ctl); if (ret < 0) return ret; ret = reset_free(&rst_ctl); if (ret < 0) return ret; return 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; }
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); }
static struct device_t * sdhci_v3s_probe(struct driver_t * drv, struct dtnode_t * n) { struct sdhci_v3s_pdata_t * pdat; struct sdhci_t * sdhci; struct device_t * dev; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); char * pclk = dt_read_string(n, "clock-name", NULL); if(!search_clk(pclk)) return NULL; pdat = malloc(sizeof(struct sdhci_v3s_pdata_t)); if(!pdat) return FALSE; sdhci = malloc(sizeof(struct sdhci_t)); if(!sdhci) { free(pdat); return FALSE; } pdat->virt = virt; pdat->pclk = strdup(pclk); pdat->reset = dt_read_int(n, "reset", -1); pdat->clk = dt_read_int(n, "clk-gpio", -1); pdat->clkcfg = dt_read_int(n, "clk-gpio-config", -1); pdat->cmd = dt_read_int(n, "cmd-gpio", -1); pdat->cmdcfg = dt_read_int(n, "cmd-gpio-config", -1); pdat->dat0 = dt_read_int(n, "dat0-gpio", -1); pdat->dat0cfg = dt_read_int(n, "dat0-gpio-config", -1); pdat->dat1 = dt_read_int(n, "dat1-gpio", -1); pdat->dat1cfg = dt_read_int(n, "dat1-gpio-config", -1); pdat->dat2 = dt_read_int(n, "dat2-gpio", -1); pdat->dat2cfg = dt_read_int(n, "dat2-gpio-config", -1); pdat->dat3 = dt_read_int(n, "dat3-gpio", -1); pdat->dat3cfg = dt_read_int(n, "dat3-gpio-config", -1); pdat->dat4 = dt_read_int(n, "dat4-gpio", -1); pdat->dat4cfg = dt_read_int(n, "dat4-gpio-config", -1); pdat->dat5 = dt_read_int(n, "dat5-gpio", -1); pdat->dat5cfg = dt_read_int(n, "dat5-gpio-config", -1); pdat->dat6 = dt_read_int(n, "dat6-gpio", -1); pdat->dat6cfg = dt_read_int(n, "dat6-gpio-config", -1); pdat->dat7 = dt_read_int(n, "dat7-gpio", -1); pdat->dat7cfg = dt_read_int(n, "dat7-gpio-config", -1); pdat->cd = dt_read_int(n, "cd-gpio", -1); pdat->cdcfg = dt_read_int(n, "cd-gpio-config", -1); sdhci->name = alloc_device_name(dt_read_name(n), -1); sdhci->voltage = MMC_VDD_27_36; sdhci->width = MMC_BUS_WIDTH_4; sdhci->clock = 52 * 1000 * 1000; sdhci->removable = TRUE; sdhci->detect = sdhci_v3s_detect; sdhci->setvoltage = sdhci_v3s_setvoltage; sdhci->setwidth = sdhci_v3s_setwidth; sdhci->setclock = sdhci_v3s_setclock; sdhci->transfer = sdhci_v3s_transfer; sdhci->priv = pdat; clk_enable(pdat->pclk); if(pdat->reset >= 0) reset_deassert(pdat->reset); if(pdat->clk >= 0) { if(pdat->clkcfg >= 0) gpio_set_cfg(pdat->clk, pdat->clkcfg); gpio_set_pull(pdat->clk, GPIO_PULL_UP); } if(pdat->cmd >= 0) { if(pdat->cmdcfg >= 0) gpio_set_cfg(pdat->cmd, pdat->cmdcfg); gpio_set_pull(pdat->cmd, GPIO_PULL_UP); } if(pdat->dat0 >= 0) { if(pdat->dat0cfg >= 0) gpio_set_cfg(pdat->dat0, pdat->dat0cfg); gpio_set_pull(pdat->dat0, GPIO_PULL_UP); } if(pdat->dat1 >= 0) { if(pdat->dat1cfg >= 0) gpio_set_cfg(pdat->dat1, pdat->dat1cfg); gpio_set_pull(pdat->dat1, GPIO_PULL_UP); } if(pdat->dat2 >= 0) { if(pdat->dat2cfg >= 0) gpio_set_cfg(pdat->dat2, pdat->dat2cfg); gpio_set_pull(pdat->dat2, GPIO_PULL_UP); } if(pdat->dat3 >= 0) { if(pdat->dat3cfg >= 0) gpio_set_cfg(pdat->dat3, pdat->dat3cfg); gpio_set_pull(pdat->dat3, GPIO_PULL_UP); } if(pdat->dat4 >= 0) { if(pdat->dat4cfg >= 0) gpio_set_cfg(pdat->dat4, pdat->dat4cfg); gpio_set_pull(pdat->dat4, GPIO_PULL_UP); } if(pdat->dat5 >= 0) { if(pdat->dat5cfg >= 0) gpio_set_cfg(pdat->dat5, pdat->dat5cfg); gpio_set_pull(pdat->dat5, GPIO_PULL_UP); } if(pdat->dat6 >= 0) { if(pdat->dat6cfg >= 0) gpio_set_cfg(pdat->dat6, pdat->dat6cfg); gpio_set_pull(pdat->dat6, GPIO_PULL_UP); } if(pdat->dat7 >= 0) { if(pdat->dat7cfg >= 0) gpio_set_cfg(pdat->dat7, pdat->dat7cfg); gpio_set_pull(pdat->dat7, GPIO_PULL_UP); } if(pdat->cd >= 0) { if(pdat->cdcfg >= 0) gpio_set_cfg(pdat->cd, pdat->cdcfg); gpio_set_pull(pdat->cd, GPIO_PULL_UP); } if(!register_sdhci(&dev, sdhci)) { clk_disable(pdat->pclk); free(pdat->pclk); free_device_name(sdhci->name); free(sdhci->priv); free(sdhci); return NULL; } dev->driver = drv; return dev; }
static int ohci_usb_probe(struct udevice *dev) { struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev); struct generic_ohci *priv = dev_get_priv(dev); int i, err, ret, clock_nb, reset_nb; err = 0; priv->clock_count = 0; clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); if (clock_nb > 0) { priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), GFP_KERNEL); if (!priv->clocks) return -ENOMEM; for (i = 0; i < clock_nb; i++) { err = clk_get_by_index(dev, i, &priv->clocks[i]); if (err < 0) break; err = clk_enable(&priv->clocks[i]); if (err) { pr_err("failed to enable clock %d\n", i); clk_free(&priv->clocks[i]); goto clk_err; } priv->clock_count++; } } else if (clock_nb != -ENOENT) { pr_err("failed to get clock phandle(%d)\n", clock_nb); return clock_nb; } priv->reset_count = 0; reset_nb = dev_count_phandle_with_args(dev, "resets", "#reset-cells"); if (reset_nb > 0) { priv->resets = devm_kcalloc(dev, reset_nb, sizeof(struct reset_ctl), GFP_KERNEL); if (!priv->resets) return -ENOMEM; for (i = 0; i < reset_nb; i++) { err = reset_get_by_index(dev, i, &priv->resets[i]); if (err < 0) break; err = reset_deassert(&priv->resets[i]); if (err) { pr_err("failed to deassert reset %d\n", i); reset_free(&priv->resets[i]); goto reset_err; } priv->reset_count++; } } else if (reset_nb != -ENOENT) { pr_err("failed to get reset phandle(%d)\n", reset_nb); goto clk_err; } err = generic_phy_get_by_index(dev, 0, &priv->phy); if (err) { if (err != -ENOENT) { pr_err("failed to get usb phy\n"); goto reset_err; } } else { err = generic_phy_init(&priv->phy); if (err) { pr_err("failed to init usb phy\n"); goto reset_err; } } err = ohci_register(dev, regs); if (err) goto phy_err; return 0; phy_err: if (generic_phy_valid(&priv->phy)) { ret = generic_phy_exit(&priv->phy); if (ret) pr_err("failed to release phy\n"); } reset_err: ret = reset_release_all(priv->resets, priv->reset_count); if (ret) pr_err("failed to assert all resets\n"); clk_err: ret = clk_release_all(priv->clocks, priv->clock_count); if (ret) pr_err("failed to disable all clocks\n"); return err; }
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; }
static struct device_t * fb_f1c500s_probe(struct driver_t * drv, struct dtnode_t * n) { struct fb_f1c500s_pdata_t * pdat; struct framebuffer_t * fb; struct device_t * dev; char * clkdefe = dt_read_string(n, "clock-name-defe", NULL); char * clkdebe = dt_read_string(n, "clock-name-debe", NULL); char * clktcon = dt_read_string(n, "clock-name-tcon", NULL); int i; if(!search_clk(clkdefe) || !search_clk(clkdebe) || !search_clk(clktcon)) return NULL; pdat = malloc(sizeof(struct fb_f1c500s_pdata_t)); if(!pdat) return NULL; fb = malloc(sizeof(struct framebuffer_t)); if(!fb) { free(pdat); return NULL; } pdat->virtdefe = phys_to_virt(F1C500S_DEFE_BASE); pdat->virtdebe = phys_to_virt(F1C500S_DEBE_BASE); pdat->virttcon = phys_to_virt(F1C500S_TCON_BASE); pdat->virtgpio = phys_to_virt(F1C500S_GPIO_BASE); pdat->clkdefe = strdup(clkdefe); pdat->clkdebe = strdup(clkdebe); pdat->clktcon = strdup(clktcon); pdat->rstdefe = dt_read_int(n, "reset-defe", -1); pdat->rstdebe = dt_read_int(n, "reset-debe", -1); pdat->rsttcon = dt_read_int(n, "reset-tcon", -1); pdat->width = dt_read_int(n, "width", 320); pdat->height = dt_read_int(n, "height", 240); pdat->pwidth = dt_read_int(n, "physical-width", 216); pdat->pheight = dt_read_int(n, "physical-height", 135); pdat->bits_per_pixel = dt_read_int(n, "bits-per-pixel", 18); pdat->bytes_per_pixel = dt_read_int(n, "bytes-per-pixel", 4); pdat->index = 0; pdat->vram[0] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel); pdat->vram[1] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel); pdat->nrl = region_list_alloc(0); pdat->orl = region_list_alloc(0); pdat->timing.pixel_clock_hz = dt_read_long(n, "clock-frequency", 8000000); pdat->timing.h_front_porch = dt_read_int(n, "hfront-porch", 40); pdat->timing.h_back_porch = dt_read_int(n, "hback-porch", 87); pdat->timing.h_sync_len = dt_read_int(n, "hsync-len", 1); pdat->timing.v_front_porch = dt_read_int(n, "vfront-porch", 13); pdat->timing.v_back_porch = dt_read_int(n, "vback-porch", 31); pdat->timing.v_sync_len = dt_read_int(n, "vsync-len", 1); pdat->timing.h_sync_active = dt_read_bool(n, "hsync-active", 0); pdat->timing.v_sync_active = dt_read_bool(n, "vsync-active", 0); pdat->timing.den_active = dt_read_bool(n, "den-active", 0); pdat->timing.clk_active = dt_read_bool(n, "clk-active", 0); pdat->backlight = search_led(dt_read_string(n, "backlight", NULL)); fb->name = alloc_device_name(dt_read_name(n), dt_read_id(n)); fb->width = pdat->width; fb->height = pdat->height; fb->pwidth = pdat->pwidth; fb->pheight = pdat->pheight; fb->bytes = pdat->bytes_per_pixel; fb->setbl = fb_setbl; fb->getbl = fb_getbl; fb->create = fb_create; fb->destroy = fb_destroy; fb->present = fb_present; fb->priv = pdat; clk_enable(pdat->clkdefe); clk_enable(pdat->clkdebe); clk_enable(pdat->clktcon); if(pdat->rstdefe >= 0) reset_deassert(pdat->rstdefe); if(pdat->rstdebe >= 0) reset_deassert(pdat->rstdebe); if(pdat->rsttcon >= 0) reset_deassert(pdat->rsttcon); for(i = 0x0800; i < 0x1000; i += 4) write32(pdat->virtdebe + i, 0); fb_f1c500s_init(pdat); if(!register_framebuffer(&dev, fb)) { clk_disable(pdat->clkdefe); clk_disable(pdat->clkdebe); clk_disable(pdat->clktcon); free(pdat->clkdefe); free(pdat->clkdebe); free(pdat->clktcon); dma_free_noncoherent(pdat->vram[0]); dma_free_noncoherent(pdat->vram[1]); region_list_free(pdat->nrl); region_list_free(pdat->orl); free_device_name(fb->name); free(fb->priv); free(fb); return NULL; } dev->driver = drv; return dev; }
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); }
static int ehci_usb_probe(struct udevice *dev) { struct generic_ehci *priv = dev_get_priv(dev); struct ehci_hccr *hccr; struct ehci_hcor *hcor; int i, err, ret, clock_nb, reset_nb; err = 0; priv->clock_count = 0; clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks", "#clock-cells"); if (clock_nb > 0) { priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), GFP_KERNEL); if (!priv->clocks) return -ENOMEM; for (i = 0; i < clock_nb; i++) { err = clk_get_by_index(dev, i, &priv->clocks[i]); if (err < 0) break; err = clk_enable(&priv->clocks[i]); if (err) { pr_err("failed to enable clock %d\n", i); clk_free(&priv->clocks[i]); goto clk_err; } priv->clock_count++; } } else { if (clock_nb != -ENOENT) { pr_err("failed to get clock phandle(%d)\n", clock_nb); return clock_nb; } } priv->reset_count = 0; reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets", "#reset-cells"); if (reset_nb > 0) { priv->resets = devm_kcalloc(dev, reset_nb, sizeof(struct reset_ctl), GFP_KERNEL); if (!priv->resets) return -ENOMEM; for (i = 0; i < reset_nb; i++) { err = reset_get_by_index(dev, i, &priv->resets[i]); if (err < 0) break; if (reset_deassert(&priv->resets[i])) { pr_err("failed to deassert reset %d\n", i); reset_free(&priv->resets[i]); goto reset_err; } priv->reset_count++; } } else { if (reset_nb != -ENOENT) { pr_err("failed to get reset phandle(%d)\n", reset_nb); goto clk_err; } } err = generic_phy_get_by_index(dev, 0, &priv->phy); if (err) { if (err != -ENOENT) { pr_err("failed to get usb phy\n"); goto reset_err; } } else { err = generic_phy_init(&priv->phy); if (err) { pr_err("failed to init usb phy\n"); goto reset_err; } } hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE); hcor = (struct ehci_hcor *)((uintptr_t)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); if (err) goto phy_err; return 0; phy_err: if (generic_phy_valid(&priv->phy)) { ret = generic_phy_exit(&priv->phy); if (ret) pr_err("failed to release phy\n"); } reset_err: ret = reset_release_all(priv->resets, priv->reset_count); if (ret) pr_err("failed to assert all resets\n"); clk_err: ret = clk_release_all(priv->clocks, priv->clock_count); if (ret) pr_err("failed to disable all clocks\n"); return err; }
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; }
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; }
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; }