2 * Copyright (C) 2015 Atmel Corporation
3 * Wenyou.Yang <wenyou.yang@atmel.com>
5 * SPDX-License-Identifier: GPL-2.0+
13 #include <asm/arch/clk.h>
15 #define ATMEL_SDHC_MIN_FREQ 400000
16 #define ATMEL_SDHC_GCK_RATE 240000000
19 int atmel_sdhci_init(void *regbase
, u32 id
)
21 struct sdhci_host
*host
;
22 u32 max_clk
, min_clk
= ATMEL_SDHC_MIN_FREQ
;
24 host
= (struct sdhci_host
*)calloc(1, sizeof(struct sdhci_host
));
26 printf("%s: sdhci_host calloc failed\n", __func__
);
30 host
->name
= "atmel_sdhci";
31 host
->ioaddr
= regbase
;
32 host
->quirks
= SDHCI_QUIRK_WAIT_SEND_CMD
;
33 max_clk
= at91_get_periph_generated_clk(id
);
35 printf("%s: Failed to get the proper clock\n", __func__
);
39 host
->max_clk
= max_clk
;
41 add_sdhci(host
, 0, min_clk
);
48 DECLARE_GLOBAL_DATA_PTR
;
50 struct atmel_sdhci_plat
{
51 struct mmc_config cfg
;
55 static int atmel_sdhci_probe(struct udevice
*dev
)
57 struct mmc_uclass_priv
*upriv
= dev_get_uclass_priv(dev
);
58 struct atmel_sdhci_plat
*plat
= dev_get_platdata(dev
);
59 struct sdhci_host
*host
= dev_get_priv(dev
);
64 ret
= clk_get_by_index(dev
, 0, &clk
);
68 ret
= clk_enable(&clk
);
72 host
->name
= dev
->name
;
73 host
->ioaddr
= (void *)devfdt_get_addr(dev
);
75 host
->quirks
= SDHCI_QUIRK_WAIT_SEND_CMD
;
76 host
->bus_width
= fdtdec_get_int(gd
->fdt_blob
, dev_of_offset(dev
),
79 ret
= clk_get_by_index(dev
, 1, &clk
);
83 ret
= clk_set_rate(&clk
, ATMEL_SDHC_GCK_RATE
);
87 max_clk
= clk_get_rate(&clk
);
91 host
->max_clk
= max_clk
;
93 ret
= sdhci_setup_cfg(&plat
->cfg
, host
, 0, ATMEL_SDHC_MIN_FREQ
);
97 host
->mmc
= &plat
->mmc
;
99 host
->mmc
->priv
= host
;
100 upriv
->mmc
= host
->mmc
;
104 return sdhci_probe(dev
);
107 static int atmel_sdhci_bind(struct udevice
*dev
)
109 struct atmel_sdhci_plat
*plat
= dev_get_platdata(dev
);
111 return sdhci_bind(dev
, &plat
->mmc
, &plat
->cfg
);
114 static const struct udevice_id atmel_sdhci_ids
[] = {
115 { .compatible
= "atmel,sama5d2-sdhci" },
119 U_BOOT_DRIVER(atmel_sdhci_drv
) = {
120 .name
= "atmel_sdhci",
122 .of_match
= atmel_sdhci_ids
,
124 .bind
= atmel_sdhci_bind
,
125 .probe
= atmel_sdhci_probe
,
126 .priv_auto_alloc_size
= sizeof(struct sdhci_host
),
127 .platdata_auto_alloc_size
= sizeof(struct atmel_sdhci_plat
),