2018-05-06 21:58:06 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
2016-02-18 10:52:48 +00:00
|
|
|
/*
|
2016-07-19 12:56:13 +00:00
|
|
|
* Copyright (C) 2016 Socionext Inc.
|
|
|
|
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
|
2016-02-18 10:52:48 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <common.h>
|
|
|
|
#include <clk.h>
|
|
|
|
#include <fdtdec.h>
|
2020-02-03 14:36:16 +00:00
|
|
|
#include <malloc.h>
|
2016-02-18 10:52:48 +00:00
|
|
|
#include <mmc.h>
|
2017-05-17 23:18:03 +00:00
|
|
|
#include <dm.h>
|
2020-02-03 14:36:16 +00:00
|
|
|
#include <dm/device_compat.h>
|
2016-02-18 10:52:48 +00:00
|
|
|
#include <linux/compat.h>
|
2017-08-25 15:50:17 +00:00
|
|
|
#include <linux/dma-direction.h>
|
2016-02-18 10:52:48 +00:00
|
|
|
#include <linux/io.h>
|
2016-03-24 13:32:42 +00:00
|
|
|
#include <linux/sizes.h>
|
2017-09-15 19:10:54 +00:00
|
|
|
#include <power/regulator.h>
|
2016-02-18 10:52:48 +00:00
|
|
|
#include <asm/unaligned.h>
|
|
|
|
|
2018-04-13 21:51:33 +00:00
|
|
|
#include "tmio-common.h"
|
2016-08-25 05:52:36 +00:00
|
|
|
|
|
|
|
static const struct dm_mmc_ops uniphier_sd_ops = {
|
2018-04-13 21:51:33 +00:00
|
|
|
.send_cmd = tmio_sd_send_cmd,
|
|
|
|
.set_ios = tmio_sd_set_ios,
|
|
|
|
.get_cd = tmio_sd_get_cd,
|
2016-08-25 05:52:36 +00:00
|
|
|
};
|
|
|
|
|
2016-02-18 10:52:48 +00:00
|
|
|
static const struct udevice_id uniphier_sd_match[] = {
|
2018-09-10 03:58:35 +00:00
|
|
|
{ .compatible = "socionext,uniphier-sd-v2.91" },
|
|
|
|
{ .compatible = "socionext,uniphier-sd-v3.1" },
|
|
|
|
{ .compatible = "socionext,uniphier-sd-v3.1.1" },
|
2016-02-18 10:52:48 +00:00
|
|
|
{ /* sentinel */ }
|
|
|
|
};
|
|
|
|
|
2018-06-13 06:02:55 +00:00
|
|
|
static ulong uniphier_sd_clk_get_rate(struct tmio_sd_priv *priv)
|
|
|
|
{
|
|
|
|
#if CONFIG_IS_ENABLED(CLK)
|
|
|
|
return clk_get_rate(&priv->clk);
|
|
|
|
#elif CONFIG_SPL_BUILD
|
|
|
|
return 100000000;
|
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-04-08 15:45:23 +00:00
|
|
|
static int uniphier_sd_probe(struct udevice *dev)
|
|
|
|
{
|
2018-04-20 09:14:24 +00:00
|
|
|
struct tmio_sd_priv *priv = dev_get_priv(dev);
|
2018-06-13 06:02:55 +00:00
|
|
|
|
|
|
|
priv->clk_get_rate = uniphier_sd_clk_get_rate;
|
2019-01-11 22:45:54 +00:00
|
|
|
priv->read_poll_flag = TMIO_SD_DMA_INFO1_END_RD2;
|
2018-06-13 06:02:55 +00:00
|
|
|
|
2018-04-20 09:14:25 +00:00
|
|
|
#ifndef CONFIG_SPL_BUILD
|
2018-04-20 09:14:24 +00:00
|
|
|
int ret;
|
|
|
|
|
2018-06-13 06:02:55 +00:00
|
|
|
ret = clk_get_by_index(dev, 0, &priv->clk);
|
2018-04-20 09:14:24 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(dev, "failed to get host clock\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set to max rate */
|
2018-06-13 06:02:55 +00:00
|
|
|
ret = clk_set_rate(&priv->clk, ULONG_MAX);
|
|
|
|
if (ret < 0) {
|
2018-04-20 09:14:24 +00:00
|
|
|
dev_err(dev, "failed to set rate for host clock\n");
|
2018-06-13 06:02:55 +00:00
|
|
|
clk_free(&priv->clk);
|
|
|
|
return ret;
|
2018-04-20 09:14:24 +00:00
|
|
|
}
|
|
|
|
|
2018-06-13 06:02:55 +00:00
|
|
|
ret = clk_enable(&priv->clk);
|
2018-04-20 09:14:24 +00:00
|
|
|
if (ret) {
|
|
|
|
dev_err(dev, "failed to enable host clock\n");
|
|
|
|
return ret;
|
|
|
|
}
|
2018-04-20 09:14:25 +00:00
|
|
|
#endif
|
2018-04-20 09:14:24 +00:00
|
|
|
|
2018-04-13 21:51:33 +00:00
|
|
|
return tmio_sd_probe(dev, 0);
|
2018-04-08 15:45:23 +00:00
|
|
|
}
|
|
|
|
|
2016-02-18 10:52:48 +00:00
|
|
|
U_BOOT_DRIVER(uniphier_mmc) = {
|
|
|
|
.name = "uniphier-mmc",
|
|
|
|
.id = UCLASS_MMC,
|
|
|
|
.of_match = uniphier_sd_match,
|
2018-04-13 21:51:33 +00:00
|
|
|
.bind = tmio_sd_bind,
|
2018-04-08 15:45:23 +00:00
|
|
|
.probe = uniphier_sd_probe,
|
2018-04-13 21:51:33 +00:00
|
|
|
.priv_auto_alloc_size = sizeof(struct tmio_sd_priv),
|
|
|
|
.platdata_auto_alloc_size = sizeof(struct tmio_sd_plat),
|
2016-08-25 05:52:35 +00:00
|
|
|
.ops = &uniphier_sd_ops,
|
2016-02-18 10:52:48 +00:00
|
|
|
};
|