2 * (C) Copyright 2013 Altera Corporation <www.altera.com>
4 * SPDX-License-Identifier: GPL-2.0+
11 #include <asm/arch/dwmmc.h>
12 #include <asm/arch/clock_manager.h>
13 #include <asm/arch/system_manager.h>
15 static const struct socfpga_clock_manager
*clock_manager_base
=
16 (void *)SOCFPGA_CLKMGR_ADDRESS
;
17 static const struct socfpga_system_manager
*system_manager_base
=
18 (void *)SOCFPGA_SYSMGR_ADDRESS
;
20 static void socfpga_dwmci_clksel(struct dwmci_host
*host
)
25 /* Disable SDMMC clock. */
26 clrbits_le32(&clock_manager_base
->per_pll
.en
,
27 CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK
);
29 /* Configures drv_sel and smpl_sel */
30 drvsel
= CONFIG_SOCFPGA_DWMMC_DRVSEL
;
31 smplsel
= CONFIG_SOCFPGA_DWMMC_SMPSEL
;
33 debug("%s: drvsel %d smplsel %d\n", __func__
, drvsel
, smplsel
);
34 writel(SYSMGR_SDMMC_CTRL_SET(smplsel
, drvsel
),
35 &system_manager_base
->sdmmcgrp_ctrl
);
37 debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__
,
38 readl(&system_manager_base
->sdmmcgrp_ctrl
));
40 /* Enable SDMMC clock */
41 setbits_le32(&clock_manager_base
->per_pll
.en
,
42 CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK
);
45 int socfpga_dwmmc_init(u32 regbase
, int bus_width
, int index
)
47 struct dwmci_host
*host
;
48 unsigned long clk
= cm_get_mmc_controller_clk_hz();
51 printf("%s: MMC clock is zero!", __func__
);
55 /* calloc for zero init */
56 host
= calloc(1, sizeof(struct dwmci_host
));
58 printf("%s: calloc() failed!\n", __func__
);
62 host
->name
= "SOCFPGA DWMMC";
63 host
->ioaddr
= (void *)regbase
;
64 host
->buswidth
= bus_width
;
65 host
->clksel
= socfpga_dwmci_clksel
;
66 host
->dev_index
= index
;
67 /* fixed clock divide by 4 which due to the SDMMC wrapper */
69 host
->fifoth_val
= MSIZE(0x2) |
70 RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH
/ 2 - 1) |
71 TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH
/ 2);
73 return add_dwmci(host
, host
->bus_hz
, 400000);