1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2015 Atmel Corporation
4 * Wenyou.Yang <wenyou.yang@atmel.com>
12 #include <asm/arch/clk.h>
14 #define ATMEL_SDHC_MIN_FREQ 400000
15 #define ATMEL_SDHC_GCK_RATE 240000000
18 int atmel_sdhci_init(void *regbase
, u32 id
)
20 struct sdhci_host
*host
;
21 u32 max_clk
, min_clk
= ATMEL_SDHC_MIN_FREQ
;
23 host
= (struct sdhci_host
*)calloc(1, sizeof(struct sdhci_host
));
25 printf("%s: sdhci_host calloc failed\n", __func__
);
29 host
->name
= "atmel_sdhci";
30 host
->ioaddr
= regbase
;
31 host
->quirks
= SDHCI_QUIRK_WAIT_SEND_CMD
;
32 max_clk
= at91_get_periph_generated_clk(id
);
34 printf("%s: Failed to get the proper clock\n", __func__
);
38 host
->max_clk
= max_clk
;
40 add_sdhci(host
, 0, min_clk
);
47 DECLARE_GLOBAL_DATA_PTR
;
49 struct atmel_sdhci_plat
{
50 struct mmc_config cfg
;
54 static int atmel_sdhci_probe(struct udevice
*dev
)
56 struct mmc_uclass_priv
*upriv
= dev_get_uclass_priv(dev
);
57 struct atmel_sdhci_plat
*plat
= dev_get_platdata(dev
);
58 struct sdhci_host
*host
= dev_get_priv(dev
);
63 ret
= clk_get_by_index(dev
, 0, &clk
);
67 ret
= clk_enable(&clk
);
71 host
->name
= dev
->name
;
72 host
->ioaddr
= (void *)devfdt_get_addr(dev
);
74 host
->quirks
= SDHCI_QUIRK_WAIT_SEND_CMD
;
75 host
->bus_width
= fdtdec_get_int(gd
->fdt_blob
, dev_of_offset(dev
),
78 ret
= clk_get_by_index(dev
, 1, &clk
);
82 ret
= clk_set_rate(&clk
, ATMEL_SDHC_GCK_RATE
);
86 max_clk
= clk_get_rate(&clk
);
90 host
->max_clk
= max_clk
;
92 ret
= sdhci_setup_cfg(&plat
->cfg
, host
, 0, ATMEL_SDHC_MIN_FREQ
);
96 host
->mmc
= &plat
->mmc
;
98 host
->mmc
->priv
= host
;
99 upriv
->mmc
= host
->mmc
;
103 return sdhci_probe(dev
);
106 static int atmel_sdhci_bind(struct udevice
*dev
)
108 struct atmel_sdhci_plat
*plat
= dev_get_platdata(dev
);
110 return sdhci_bind(dev
, &plat
->mmc
, &plat
->cfg
);
113 static const struct udevice_id atmel_sdhci_ids
[] = {
114 { .compatible
= "atmel,sama5d2-sdhci" },
118 U_BOOT_DRIVER(atmel_sdhci_drv
) = {
119 .name
= "atmel_sdhci",
121 .of_match
= atmel_sdhci_ids
,
123 .bind
= atmel_sdhci_bind
,
124 .probe
= atmel_sdhci_probe
,
125 .priv_auto_alloc_size
= sizeof(struct sdhci_host
),
126 .platdata_auto_alloc_size
= sizeof(struct atmel_sdhci_plat
),