Commit 498d1a62db4374c9d6223771bcbe8ae612a0f59f
Committed by
Marek Vasut
1 parent
036ba54f5b
Exists in
v2017.01-smarct4x
and in
37 other branches
arm: socfpga: mmc: Pick the clock from clock manager
Make the SoCFPGA MMC stub pick clock via the clock manager frequency accessors instead of hard-coding the frequency. Also fix calloc() misuse. Signed-off-by: Pavel Machek <pavel@denx.de> Signed-off-by: Marek Vasut <marex@denx.de> Cc: Chin Liang See <clsee@altera.com> Cc: Dinh Nguyen <dinguyen@altera.com> Cc: Albert Aribaud <albert.u.boot@aribaud.net> Cc: Tom Rini <trini@ti.com> Cc: Wolfgang Denk <wd@denx.de> Cc: Pavel Machek <pavel@denx.de> Acked-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Showing 1 changed file with 11 additions and 4 deletions Inline Diff
drivers/mmc/socfpga_dw_mmc.c
1 | /* | 1 | /* |
2 | * (C) Copyright 2013 Altera Corporation <www.altera.com> | 2 | * (C) Copyright 2013 Altera Corporation <www.altera.com> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <common.h> | 7 | #include <common.h> |
8 | #include <malloc.h> | 8 | #include <malloc.h> |
9 | #include <dwmmc.h> | 9 | #include <dwmmc.h> |
10 | #include <errno.h> | ||
10 | #include <asm/arch/dwmmc.h> | 11 | #include <asm/arch/dwmmc.h> |
11 | #include <asm/arch/clock_manager.h> | 12 | #include <asm/arch/clock_manager.h> |
12 | #include <asm/arch/system_manager.h> | 13 | #include <asm/arch/system_manager.h> |
13 | 14 | ||
14 | static const struct socfpga_clock_manager *clock_manager_base = | 15 | static const struct socfpga_clock_manager *clock_manager_base = |
15 | (void *)SOCFPGA_CLKMGR_ADDRESS; | 16 | (void *)SOCFPGA_CLKMGR_ADDRESS; |
16 | static const struct socfpga_system_manager *system_manager_base = | 17 | static const struct socfpga_system_manager *system_manager_base = |
17 | (void *)SOCFPGA_SYSMGR_ADDRESS; | 18 | (void *)SOCFPGA_SYSMGR_ADDRESS; |
18 | 19 | ||
19 | static void socfpga_dwmci_clksel(struct dwmci_host *host) | 20 | static void socfpga_dwmci_clksel(struct dwmci_host *host) |
20 | { | 21 | { |
21 | unsigned int drvsel; | 22 | unsigned int drvsel; |
22 | unsigned int smplsel; | 23 | unsigned int smplsel; |
23 | 24 | ||
24 | /* Disable SDMMC clock. */ | 25 | /* Disable SDMMC clock. */ |
25 | clrbits_le32(&clock_manager_base->per_pll.en, | 26 | clrbits_le32(&clock_manager_base->per_pll.en, |
26 | CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); | 27 | CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); |
27 | 28 | ||
28 | /* Configures drv_sel and smpl_sel */ | 29 | /* Configures drv_sel and smpl_sel */ |
29 | drvsel = CONFIG_SOCFPGA_DWMMC_DRVSEL; | 30 | drvsel = CONFIG_SOCFPGA_DWMMC_DRVSEL; |
30 | smplsel = CONFIG_SOCFPGA_DWMMC_SMPSEL; | 31 | smplsel = CONFIG_SOCFPGA_DWMMC_SMPSEL; |
31 | 32 | ||
32 | debug("%s: drvsel %d smplsel %d\n", __func__, drvsel, smplsel); | 33 | debug("%s: drvsel %d smplsel %d\n", __func__, drvsel, smplsel); |
33 | writel(SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel), | 34 | writel(SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel), |
34 | &system_manager_base->sdmmcgrp_ctrl); | 35 | &system_manager_base->sdmmcgrp_ctrl); |
35 | 36 | ||
36 | debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__, | 37 | debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__, |
37 | readl(&system_manager_base->sdmmcgrp_ctrl)); | 38 | readl(&system_manager_base->sdmmcgrp_ctrl)); |
38 | 39 | ||
39 | /* Enable SDMMC clock */ | 40 | /* Enable SDMMC clock */ |
40 | setbits_le32(&clock_manager_base->per_pll.en, | 41 | setbits_le32(&clock_manager_base->per_pll.en, |
41 | CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); | 42 | CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); |
42 | } | 43 | } |
43 | 44 | ||
44 | int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) | 45 | int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) |
45 | { | 46 | { |
46 | struct dwmci_host *host; | 47 | struct dwmci_host *host; |
48 | unsigned long clk = cm_get_mmc_controller_clk_hz(); | ||
47 | 49 | ||
50 | if (clk == 0) { | ||
51 | printf("%s: MMC clock is zero!", __func__); | ||
52 | return -EINVAL; | ||
53 | } | ||
54 | |||
48 | /* calloc for zero init */ | 55 | /* calloc for zero init */ |
49 | host = calloc(sizeof(struct dwmci_host), 1); | 56 | host = calloc(1, sizeof(struct dwmci_host)); |
50 | if (!host) { | 57 | if (!host) { |
51 | printf("dwmci_host calloc fail!\n"); | 58 | printf("%s: calloc() failed!\n", __func__); |
52 | return -1; | 59 | return -ENOMEM; |
53 | } | 60 | } |
54 | 61 | ||
55 | host->name = "SOCFPGA DWMMC"; | 62 | host->name = "SOCFPGA DWMMC"; |
56 | host->ioaddr = (void *)regbase; | 63 | host->ioaddr = (void *)regbase; |
57 | host->buswidth = bus_width; | 64 | host->buswidth = bus_width; |
58 | host->clksel = socfpga_dwmci_clksel; | 65 | host->clksel = socfpga_dwmci_clksel; |
59 | host->dev_index = index; | 66 | host->dev_index = index; |
60 | /* fixed clock divide by 4 which due to the SDMMC wrapper */ | 67 | /* fixed clock divide by 4 which due to the SDMMC wrapper */ |
61 | host->bus_hz = CONFIG_SOCFPGA_DWMMC_BUS_HZ; | 68 | host->bus_hz = clk; |
62 | host->fifoth_val = MSIZE(0x2) | | 69 | host->fifoth_val = MSIZE(0x2) | |
63 | RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) | | 70 | RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) | |
64 | TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2); | 71 | TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2); |
65 | 72 | ||
66 | return add_dwmci(host, host->bus_hz, 400000); | 73 | return add_dwmci(host, host->bus_hz, 400000); |
67 | } | 74 | } |
68 | 75 | ||
69 | 76 |