mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
mmc: dw_mmc: Probe the MMC from OF
Rework the driver to probe the MMC controller from Device Tree and make it mandatory. There is no longer support for probing from the ancient qts-generated header files. This patch now also removes previous temporary workaround. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Dinh Nguyen <dinguyen@opensource.altera.com> Cc: Pantelis Antoniou <panto@antoniou-consulting.com> Cc: Tom Rini <trini@konsulko.com>
This commit is contained in:
parent
6015f8f1b6
commit
129adf5bf4
5 changed files with 72 additions and 22 deletions
|
@ -7,6 +7,6 @@
|
||||||
#ifndef _SOCFPGA_DWMMC_H_
|
#ifndef _SOCFPGA_DWMMC_H_
|
||||||
#define _SOCFPGA_DWMMC_H_
|
#define _SOCFPGA_DWMMC_H_
|
||||||
|
|
||||||
extern int socfpga_dwmmc_init(u32 regbase, int bus_width, int index);
|
int socfpga_dwmmc_init(const void *blob);
|
||||||
|
|
||||||
#endif /* _SOCFPGA_SDMMC_H_ */
|
#endif /* _SOCFPGA_SDMMC_H_ */
|
||||||
|
|
|
@ -125,14 +125,7 @@ int cpu_eth_init(bd_t *bis)
|
||||||
*/
|
*/
|
||||||
int cpu_mmc_init(bd_t *bis)
|
int cpu_mmc_init(bd_t *bis)
|
||||||
{
|
{
|
||||||
/*
|
return socfpga_dwmmc_init(gd->fdt_blob);
|
||||||
* FIXME: Temporarily define CONFIG_HPS_SDMMC_BUSWIDTH to prevent breakage
|
|
||||||
* due to missing patches in u-boot/master . The upcoming patch will
|
|
||||||
* switch this to OF probing, so this whole block will go away.
|
|
||||||
*/
|
|
||||||
#define CONFIG_HPS_SDMMC_BUSWIDTH 8
|
|
||||||
return socfpga_dwmmc_init(SOCFPGA_SDMMC_ADDRESS,
|
|
||||||
CONFIG_HPS_SDMMC_BUSWIDTH, 0);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
|
#include <libfdt.h>
|
||||||
#include <dwmmc.h>
|
#include <dwmmc.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <asm/arch/dwmmc.h>
|
#include <asm/arch/dwmmc.h>
|
||||||
|
@ -42,34 +44,87 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host)
|
||||||
CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
|
CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int socfpga_dwmmc_init(u32 regbase, int bus_width, int index)
|
static int socfpga_dwmci_of_probe(const void *blob, int node, const int idx)
|
||||||
{
|
{
|
||||||
|
/* FIXME: probe from DT eventually too/ */
|
||||||
|
const unsigned long clk = cm_get_mmc_controller_clk_hz();
|
||||||
|
|
||||||
struct dwmci_host *host;
|
struct dwmci_host *host;
|
||||||
unsigned long clk = cm_get_mmc_controller_clk_hz();
|
fdt_addr_t reg_base;
|
||||||
|
int bus_width, fifo_depth;
|
||||||
|
|
||||||
if (clk == 0) {
|
if (clk == 0) {
|
||||||
printf("%s: MMC clock is zero!", __func__);
|
printf("DWMMC%d: MMC clock is zero!", idx);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calloc for zero init */
|
/* Get the register address from the device node */
|
||||||
host = calloc(1, sizeof(struct dwmci_host));
|
reg_base = fdtdec_get_addr(blob, node, "reg");
|
||||||
if (!host) {
|
if (!reg_base) {
|
||||||
printf("%s: calloc() failed!\n", __func__);
|
printf("DWMMC%d: Can't get base address\n", idx);
|
||||||
return -ENOMEM;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the bus width from the device node */
|
||||||
|
bus_width = fdtdec_get_int(blob, node, "bus-width", 0);
|
||||||
|
if (bus_width <= 0) {
|
||||||
|
printf("DWMMC%d: Can't get bus-width\n", idx);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fifo_depth = fdtdec_get_int(blob, node, "fifo-depth", 0);
|
||||||
|
if (fifo_depth < 0) {
|
||||||
|
printf("DWMMC%d: Can't get FIFO depth\n", idx);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the host */
|
||||||
|
host = calloc(1, sizeof(*host));
|
||||||
|
if (!host)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
host->name = "SOCFPGA DWMMC";
|
host->name = "SOCFPGA DWMMC";
|
||||||
host->ioaddr = (void *)regbase;
|
host->ioaddr = (void *)reg_base;
|
||||||
host->buswidth = bus_width;
|
host->buswidth = bus_width;
|
||||||
host->clksel = socfpga_dwmci_clksel;
|
host->clksel = socfpga_dwmci_clksel;
|
||||||
host->dev_index = index;
|
host->dev_index = idx;
|
||||||
/* fixed clock divide by 4 which due to the SDMMC wrapper */
|
/* Fixed clock divide by 4 which due to the SDMMC wrapper */
|
||||||
host->bus_hz = clk;
|
host->bus_hz = clk;
|
||||||
host->fifoth_val = MSIZE(0x2) |
|
host->fifoth_val = MSIZE(0x2) |
|
||||||
RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) |
|
RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2);
|
||||||
TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2);
|
|
||||||
|
|
||||||
return add_dwmci(host, host->bus_hz, 400000);
|
return add_dwmci(host, host->bus_hz, 400000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int socfpga_dwmci_process_node(const void *blob, int nodes[],
|
||||||
|
int count)
|
||||||
|
{
|
||||||
|
int i, node, ret;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
node = nodes[i];
|
||||||
|
if (node <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = socfpga_dwmci_of_probe(blob, node, i);
|
||||||
|
if (ret) {
|
||||||
|
printf("%s: failed to decode dev %d\n", __func__, i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socfpga_dwmmc_init(const void *blob)
|
||||||
|
{
|
||||||
|
int nodes[2]; /* Max. two controllers. */
|
||||||
|
int ret, count;
|
||||||
|
|
||||||
|
count = fdtdec_find_aliases_for_id(blob, "mmc",
|
||||||
|
COMPAT_ALTERA_SOCFPGA_DWMMC,
|
||||||
|
nodes, ARRAY_SIZE(nodes));
|
||||||
|
|
||||||
|
ret = socfpga_dwmci_process_node(blob, nodes, count);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -170,6 +170,7 @@ enum fdt_compat_id {
|
||||||
COMPAT_INTEL_PCH, /* Intel PCH */
|
COMPAT_INTEL_PCH, /* Intel PCH */
|
||||||
COMPAT_INTEL_IRQ_ROUTER, /* Intel Interrupt Router */
|
COMPAT_INTEL_IRQ_ROUTER, /* Intel Interrupt Router */
|
||||||
COMPAT_ALTERA_SOCFPGA_DWMAC, /* SoCFPGA Ethernet controller */
|
COMPAT_ALTERA_SOCFPGA_DWMAC, /* SoCFPGA Ethernet controller */
|
||||||
|
COMPAT_ALTERA_SOCFPGA_DWMMC, /* SoCFPGA DWMMC controller */
|
||||||
COMPAT_INTEL_BAYTRAIL_FSP, /* Intel Bay Trail FSP */
|
COMPAT_INTEL_BAYTRAIL_FSP, /* Intel Bay Trail FSP */
|
||||||
COMPAT_INTEL_BAYTRAIL_FSP_MDP, /* Intel FSP memory-down params */
|
COMPAT_INTEL_BAYTRAIL_FSP_MDP, /* Intel FSP memory-down params */
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
|
||||||
COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"),
|
COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"),
|
||||||
COMPAT(COMPAT_INTEL_IRQ_ROUTER, "intel,irq-router"),
|
COMPAT(COMPAT_INTEL_IRQ_ROUTER, "intel,irq-router"),
|
||||||
COMPAT(ALTERA_SOCFPGA_DWMAC, "altr,socfpga-stmmac"),
|
COMPAT(ALTERA_SOCFPGA_DWMAC, "altr,socfpga-stmmac"),
|
||||||
|
COMPAT(ALTERA_SOCFPGA_DWMMC, "altr,socfpga-dw-mshc"),
|
||||||
COMPAT(COMPAT_INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"),
|
COMPAT(COMPAT_INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"),
|
||||||
COMPAT(COMPAT_INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"),
|
COMPAT(COMPAT_INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue