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:
Marek Vasut 2015-07-25 10:48:14 +02:00
parent 6015f8f1b6
commit 129adf5bf4
5 changed files with 72 additions and 22 deletions

View File

@ -7,6 +7,6 @@
#ifndef _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_ */

View File

@ -125,14 +125,7 @@ int cpu_eth_init(bd_t *bis)
*/
int cpu_mmc_init(bd_t *bis)
{
/*
* 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);
return socfpga_dwmmc_init(gd->fdt_blob);
}
#endif

View File

@ -6,6 +6,8 @@
#include <common.h>
#include <malloc.h>
#include <fdtdec.h>
#include <libfdt.h>
#include <dwmmc.h>
#include <errno.h>
#include <asm/arch/dwmmc.h>
@ -42,34 +44,87 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host)
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;
unsigned long clk = cm_get_mmc_controller_clk_hz();
fdt_addr_t reg_base;
int bus_width, fifo_depth;
if (clk == 0) {
printf("%s: MMC clock is zero!", __func__);
printf("DWMMC%d: MMC clock is zero!", idx);
return -EINVAL;
}
/* calloc for zero init */
host = calloc(1, sizeof(struct dwmci_host));
if (!host) {
printf("%s: calloc() failed!\n", __func__);
return -ENOMEM;
/* Get the register address from the device node */
reg_base = fdtdec_get_addr(blob, node, "reg");
if (!reg_base) {
printf("DWMMC%d: Can't get base address\n", idx);
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->ioaddr = (void *)regbase;
host->ioaddr = (void *)reg_base;
host->buswidth = bus_width;
host->clksel = socfpga_dwmci_clksel;
host->dev_index = index;
/* fixed clock divide by 4 which due to the SDMMC wrapper */
host->dev_index = idx;
/* Fixed clock divide by 4 which due to the SDMMC wrapper */
host->bus_hz = clk;
host->fifoth_val = MSIZE(0x2) |
RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) |
TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2);
RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2);
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;
}

View File

@ -170,6 +170,7 @@ enum fdt_compat_id {
COMPAT_INTEL_PCH, /* Intel PCH */
COMPAT_INTEL_IRQ_ROUTER, /* Intel Interrupt Router */
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_MDP, /* Intel FSP memory-down params */

View File

@ -74,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"),
COMPAT(COMPAT_INTEL_IRQ_ROUTER, "intel,irq-router"),
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_MDP, "intel,baytrail-fsp-mdp"),
};