summaryrefslogtreecommitdiff
authorNan Li <nan.li@amlogic.com>2018-04-03 11:16:06 (GMT)
committer Xindong Xu <xindong.xu@amlogic.com>2018-04-19 06:00:03 (GMT)
commit1bce00a10327fcbd71281addcd71d12fb2c11fef (patch)
treec1e258d8fae54c6cf76801681af7bb2c31e243ce
parentaafdd4bd3fef0a00ca72093c13ea2cc4eff3b4af (diff)
downloadcommon-1bce00a10327fcbd71281addcd71d12fb2c11fef.zip
common-1bce00a10327fcbd71281addcd71d12fb2c11fef.tar.gz
common-1bce00a10327fcbd71281addcd71d12fb2c11fef.tar.bz2
sd: add sd & sdio wifi TDMA on portB.
PD#163048: add sd & sdio wifi time division multiple access on portB. Change-Id: Ie38a56daf03d5066af160575a322812ab5ffe5be Signed-off-by: Nan Li <nan.li@amlogic.com>
Diffstat
-rw-r--r--arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts19
-rw-r--r--arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts18
-rw-r--r--arch/arm64/boot/dts/amlogic/mesong12a.dtsi126
-rw-r--r--drivers/amlogic/mmc/aml_sd_emmc.c403
-rw-r--r--drivers/amlogic/mmc/aml_sd_emmc_v3.c144
-rw-r--r--drivers/amlogic/mmc/aml_sdhc_m8.c4
-rw-r--r--drivers/amlogic/mmc/aml_sdio.c4
-rw-r--r--drivers/amlogic/mmc/amlsd.c132
-rw-r--r--drivers/amlogic/mmc/amlsd_of.c29
-rw-r--r--include/linux/amlogic/aml_sd_emmc_internal.h5
-rw-r--r--include/linux/amlogic/amlsd.h64
-rw-r--r--include/linux/amlogic/sd.h21
12 files changed, 615 insertions, 354 deletions
diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts
index 374c0c5..54e9eb4 100644
--- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts
+++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts
@@ -1185,13 +1185,30 @@
caps = "MMC_CAP_4_BIT_DATA",
"MMC_CAP_MMC_HIGHSPEED",
"MMC_CAP_SD_HIGHSPEED";
+
f_min = <400000>;
f_max = <50000000>;
};
+
+ sdio {
+ caps = "MMC_CAP_4_BIT_DATA",
+ "MMC_CAP_MMC_HIGHSPEED",
+ "MMC_CAP_SD_HIGHSPEED",
+ "MMC_CAP_NONREMOVABLE",
+ "MMC_CAP_UHS_SDR12",
+ "MMC_CAP_UHS_SDR25",
+ "MMC_CAP_UHS_SDR50",
+ "MMC_CAP_UHS_SDR104",
+ "MMC_PM_KEEP_POWER",
+ "MMC_CAP_SDIO_IRQ";
+
+ f_min = <400000>;
+ f_max = <200000000>;
+ };
};
&sd_emmc_a {
- status = "okay";
+ status = "disabled";
sdio {
caps = "MMC_CAP_4_BIT_DATA",
"MMC_CAP_MMC_HIGHSPEED",
diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts
index 3a36b8d..3778132 100644
--- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts
+++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts
@@ -1175,10 +1175,26 @@
f_min = <400000>;
f_max = <50000000>;
};
+
+ sdio {
+ caps = "MMC_CAP_4_BIT_DATA",
+ "MMC_CAP_MMC_HIGHSPEED",
+ "MMC_CAP_SD_HIGHSPEED",
+ "MMC_CAP_NONREMOVABLE",
+ "MMC_CAP_UHS_SDR12",
+ "MMC_CAP_UHS_SDR25",
+ "MMC_CAP_UHS_SDR50",
+ "MMC_CAP_UHS_SDR104",
+ "MMC_PM_KEEP_POWER",
+ "MMC_CAP_SDIO_IRQ";
+
+ f_min = <400000>;
+ f_max = <200000000>;
+ };
};
&sd_emmc_a {
- status = "okay";
+ status = "disabled";
sdio {
caps = "MMC_CAP_4_BIT_DATA",
"MMC_CAP_MMC_HIGHSPEED",
diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi
index 0f4239e..d43d1a7 100644
--- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi
+++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi
@@ -1314,9 +1314,15 @@
interrupts = <0 190 1>;
pinctrl-names = "sd_all_pins",
- "sd_clk_cmd_pins";
- pinctrl-0 = <&sd_all_pins>;
- pinctrl-1 = <&sd_clk_cmd_pins>;
+ "sd_clk_cmd_pins",
+ "sdio_all_pins",
+ "sdio_clk_cmd_pins";
+ pinctrl-0 = <&sdio_x_clr_pins &sd_all_pins>;
+ pinctrl-1 = <&sdio_x_clr_pins &sd_clk_cmd_pins>;
+ pinctrl-2 = <&sd_clr_all_pins
+ &sdio_x_en_pins &sdio_x_all_pins>;
+ pinctrl-3 = <&sd_clr_all_pins
+ &sdio_x_en_pins &sdio_x_clk_cmd_pins>;
clocks = <&clkc CLKID_SD_EMMC_B>,
<&clkc CLKID_SD_EMMC_B_P0_COMP>,
@@ -1339,7 +1345,17 @@
gpio_cd = <&gpio GPIOC_6 GPIO_ACTIVE_HIGH>;
card_type = <5>;
/* 3:sdio device(ie:sdio-wifi),
- * 4:SD combo (IO+mem) card
+ * 5:NON sdio device(means sd/mmc card)
+ */
+ };
+
+ sdio {
+ pinname = "sdio";
+ ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
+ max_req_size = <0x20000>; /**128KB*/
+ card_type = <3>;
+ /* 3:sdio device(ie:sdio-wifi),
+ * 5:NON sdio device(means sd/mmc card)
*/
};
};
@@ -1776,23 +1792,21 @@
};
};
+ /* sdemmc portB */
sd_clk_cmd_pins:sd_clk_cmd_pins {
mux {
- groups = "sdcard_cmd_c",
- "sdcard_clk_c";
+ groups = "sdcard_cmd_c";
function = "sdcard";
input-enable;
bias-pull-up;
+ drive-strength = <3>;
};
- };
- /* sdemmc portB */
- sd_clk_cmd_pins:sd_clk_cmd_pins {
- mux {
- groups = "sdcard_cmd_c",
- "sdcard_clk_c";
+ mux1 {
+ groups = "sdcard_clk_c";
function = "sdcard";
- input-enable;
bias-pull-up;
+ output-high;
+ drive-strength = <3>;
};
};
@@ -1802,13 +1816,34 @@
"sdcard_d1_c",
"sdcard_d2_c",
"sdcard_d3_c",
- "sdcard_cmd_c",
- "sdcard_clk_c";
+ "sdcard_cmd_c";
function = "sdcard";
input-enable;
bias-pull-up;
+ drive-strength = <3>;
+ };
+ mux1 {
+ groups = "sdcard_clk_c";
+ function = "sdcard";
+ bias-pull-up;
+ output-high;
+ drive-strength = <3>;
};
};
+
+ sd_clr_all_pins:sd_clr_all_pins {
+ mux {
+ groups = "GPIOC_0",
+ "GPIOC_1",
+ "GPIOC_2",
+ "GPIOC_3",
+ "GPIOC_4",
+ "GPIOC_5";
+ function = "gpio_periphs";
+ output-high;
+ };
+ };
+
sd_1bit_pins:sd_1bit_pins {
mux {
groups = "sdcard_d0_c",
@@ -1837,7 +1872,7 @@
function = "sdio";
input-enable;
bias-pull-up;
- drive-strength = <2 1>;
+ drive-strength = <3>;
};
};
@@ -1852,9 +1887,66 @@
function = "sdio";
input-enable;
bias-pull-up;
- drive-strength = <1 1 1 1 2 1>;
+ drive-strength = <3>;
};
};
+
+ sdio_x_clk_cmd_pins:sdio_x_clk_cmd_pins {
+ mux {
+ groups = "GPIOX_5";
+ function = "gpio_periphs";
+ input-enable;
+ bias-pull-up;
+ drive-strength = <3>;
+ };
+ mux1 {
+ groups = "GPIOX_4";
+ function = "gpio_periphs";
+ bias-pull-up;
+ output-high;
+ drive-strength = <3>;
+ };
+ };
+
+ sdio_x_all_pins:sdio_x_all_pins {
+ mux {
+ groups = "GPIOX_0",
+ "GPIOX_1",
+ "GPIOX_2",
+ "GPIOX_3",
+ "GPIOX_5";
+ function = "gpio_periphs";
+ input-enable;
+ bias-pull-up;
+ drive-strength = <3>;
+ };
+ mux1 {
+ groups = "GPIOX_4";
+ function = "gpio_periphs";
+ bias-pull-up;
+ output-high;
+ drive-strength = <3>;
+ };
+ };
+
+ sdio_x_en_pins:sdio_x_en_pins {
+ mux {
+ groups = "sdio_dummy";
+ function = "sdio";
+ bias-pull-up;
+ output-high;
+ };
+ };
+
+ sdio_x_clr_pins:sdio_x_clr_pins {
+ mux {
+ groups = "GPIOV_0";
+ function = "gpio_periphs";
+ bias-pull-up;
+ output-high;
+ };
+ };
+
all_nand_pins: all_nand_pins {
mux {
groups = "emmc_nand_d0",
diff --git a/drivers/amlogic/mmc/aml_sd_emmc.c b/drivers/amlogic/mmc/aml_sd_emmc.c
index b7d4447..56d298d 100644
--- a/drivers/amlogic/mmc/aml_sd_emmc.c
+++ b/drivers/amlogic/mmc/aml_sd_emmc.c
@@ -120,7 +120,8 @@ static void find_base(struct amlsd_platform *pdata, u8 *is_base_index,
static int aml_sd_emmc_cali_transfer(struct mmc_host *mmc,
u8 opcode, u8 *blk_test, u32 blksz)
{
- struct amlsd_host *host = mmc_priv(mmc);
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
struct mmc_request mrq = {NULL};
struct mmc_command cmd = {0};
struct mmc_command stop = {0};
@@ -157,8 +158,8 @@ static int aml_sd_emmc_cali_transfer(struct mmc_host *mmc,
static int aml_cali_auto(struct mmc_host *mmc, struct cali_data *c_data)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u8 i, max_cali_i = 0;
u32 max_cali_count = 0;
u32 cali_tmp[4] = {0};
@@ -192,6 +193,7 @@ static int aml_cali_auto(struct mmc_host *mmc, struct cali_data *c_data)
line_delay = 0;
line_delay = dly_tmp << (4 * line_x);
writel(line_delay, host->base + SD_EMMC_DELAY);
+ pdata->dly1 = line_delay;
pdata->caling = 1;
aml_sd_emmc_cali_transfer(mmc,
MMC_READ_MULTIPLE_BLOCK,
@@ -254,8 +256,8 @@ static int aml_cali_auto(struct mmc_host *mmc, struct cali_data *c_data)
static int aml_cali_index(struct mmc_host *mmc, struct cali_data *c_data)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 line_delay = 0;
u8 calout_cmp_num = 0;
u32 base_index_val = 0;
@@ -292,6 +294,7 @@ static int aml_cali_index(struct mmc_host *mmc, struct cali_data *c_data)
line_delay = 0;
line_delay = dly_tmp << (4 * line_x);
writel(line_delay, host->base + SD_EMMC_DELAY);
+ pdata->dly1 = line_delay;
calout_cmp_num = 0;
pdata->c_ctrl.dly_tmp = dly_tmp;
/* cal_time */
@@ -365,8 +368,8 @@ static int aml_cali_index(struct mmc_host *mmc, struct cali_data *c_data)
static int aml_cali_find(struct mmc_host *mmc, struct cali_data *c_data)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 line_delay;
struct sd_emmc_delay *line_dly = (struct sd_emmc_delay *)&line_delay;
u32 max_cal_result = 0;
@@ -459,14 +462,15 @@ static int aml_cali_find(struct mmc_host *mmc, struct cali_data *c_data)
mmc_hostname(mmc), line_delay, max_cal_result);
/* set delay count into reg*/
writel(line_delay, host->base + SD_EMMC_DELAY);
+ pdata->dly1 = line_delay;
return 0;
}
static int aml_sd_emmc_execute_calibration(struct mmc_host *mmc,
u32 *adj_win_start, u32 type)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 adjust;
struct sd_emmc_adjust *gadjust = (struct sd_emmc_adjust *)&adjust;
u32 vclk, cali_retry = 0;
@@ -570,7 +574,8 @@ _cali_retry:
u32 aml_sd_emmc_tuning_transfer(struct mmc_host *mmc,
u32 opcode, const u8 *blk_pattern, u8 *blk_test, u32 blksz)
{
- struct amlsd_host *host = mmc_priv(mmc);
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 vctrl = readl(host->base + SD_EMMC_CFG);
struct sd_emmc_config *ctrl = (struct sd_emmc_config *)&vctrl;
u32 tuning_err = 0;
@@ -601,7 +606,8 @@ static int aml_tuning_adj(struct mmc_host *mmc, u32 opcode,
struct aml_tuning_data *tuning_data,
int *best_start, int *best_size)
{
- struct amlsd_host *host = mmc_priv(mmc);
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 adjust;
struct sd_emmc_adjust *gadjust = (struct sd_emmc_adjust *)&adjust;
u32 vclk;
@@ -696,8 +702,8 @@ int aml_sd_emmc_execute_tuning_(struct mmc_host *mmc, u32 opcode,
struct aml_tuning_data *tuning_data,
u32 adj_win_start)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 vclk;
struct sd_emmc_clock *clkc = (struct sd_emmc_clock *)&(vclk);
u32 adjust;
@@ -787,7 +793,8 @@ static int aml_sd_emmc_rxclk_find(struct mmc_host *mmc,
u8 *rx_tuning_result, u8 total_point,
int *best_win_start, int *best_win_size)
{
- struct amlsd_host *host = mmc_priv(mmc);
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
int wrap_win_start = -1, wrap_win_size = 0;
int curr_win_start = -1, curr_win_size = 0;
u8 n;
@@ -861,8 +868,8 @@ static int aml_sd_emmc_execute_tuning_rxclk(struct mmc_host *mmc, u32 opcode,
struct aml_tuning_data *tuning_data)
{
/* need finish later */
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 vclk;
struct sd_emmc_clock *clkc = (struct sd_emmc_clock *)&(vclk);
u32 vctrl;
@@ -952,8 +959,8 @@ static int aml_sd_emmc_execute_tuning_rxclk(struct mmc_host *mmc, u32 opcode,
static int aml_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
int err = 0;
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 adjust;
struct sd_emmc_adjust *gadjust = (struct sd_emmc_adjust *)&adjust;
u32 vclk = readl(host->base + SD_EMMC_CLOCK);
@@ -1037,10 +1044,11 @@ static int aml_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
}
-static void aml_mmc_clk_switch_off(struct amlsd_host *host)
+static void aml_mmc_clk_switch_off(struct amlsd_platform *pdata)
{
u32 vcfg = 0;
struct sd_emmc_config *conf = (struct sd_emmc_config *)&vcfg;
+ struct amlsd_host *host = pdata->host;
if (host->is_gated) {
pr_debug("direct return\n");
@@ -1056,13 +1064,13 @@ static void aml_mmc_clk_switch_off(struct amlsd_host *host)
}
void aml_mmc_clk_switch_on(
- struct amlsd_host *host, int clk_div, int clk_src_sel)
+ struct amlsd_platform *pdata, int clk_div, int clk_src_sel)
{
u32 vclkc = 0;
struct sd_emmc_clock *clkc = (struct sd_emmc_clock *)&vclkc;
u32 vcfg = 0;
struct sd_emmc_config *conf = (struct sd_emmc_config *)&vcfg;
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_host *host = pdata->host;
WARN_ON(!clk_div);
@@ -1081,50 +1089,96 @@ void aml_mmc_clk_switch_on(
host->is_gated = false;
}
-static void aml_mmc_clk_switch(struct amlsd_host *host,
+static void aml_mmc_clk_switch(struct amlsd_platform *pdata,
int clk_div, int clk_src_sel)
{
u32 vclkc = 0;
+ struct amlsd_host *host = pdata->host;
struct sd_emmc_clock *clkc = (struct sd_emmc_clock *)&vclkc;
vclkc = readl(host->base + SD_EMMC_CLOCK);
if (!host->is_gated && (clkc->div == clk_div)
- && (clkc->src == clk_src_sel)) {
+ && (clkc->src == clk_src_sel))
return; /* if the same, return directly */
- }
- aml_mmc_clk_switch_off(host);
+ aml_mmc_clk_switch_off(pdata);
/* mdelay(1); */
WARN_ON(!clk_div);
- aml_mmc_clk_switch_on(host, clk_div, clk_src_sel);
+ aml_mmc_clk_switch_on(pdata, clk_div, clk_src_sel);
}
-void aml_sd_emmc_set_clkc(struct amlsd_host *host)
+void aml_sd_emmc_set_clkc(struct amlsd_platform *pdata)
{
u32 vclkc = 0;
struct sd_emmc_clock *clkc = (struct sd_emmc_clock *)&vclkc;
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_host *host = pdata->host;
vclkc = readl(host->base + SD_EMMC_CLOCK);
- if (!host->is_gated && (pdata->clkc == vclkc))
- return;
if (host->is_gated)
- aml_mmc_clk_switch(host, clkc->div, clkc->src);
+ aml_mmc_clk_switch(pdata, clkc->div, clkc->src);
else
writel(pdata->clkc, host->base + SD_EMMC_CLOCK);
}
-static int meson_mmc_clk_set_rate(struct amlsd_host *host,
+#ifdef AML_MMC_TDMA
+void aml_sd_emmc_save_host_val(struct mmc_host *mmc)
+{
+ u32 adj, dly1, dly2, intf3;
+ u32 vconf = 0;
+ struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
+ unsigned long clk_ios;
+
+ strcpy(host->cur_dev, pdata->pinname);
+ host->val_f = 0;
+
+ clk_ios = clk_get_rate(host->cfg_div_clk);
+ vconf = readl(host->base + SD_EMMC_CFG);
+ adj = readl(host->base + SD_EMMC_ADJUST_V3);
+ dly1 = readl(host->base + SD_EMMC_DELAY1_V3);
+ dly2 = readl(host->base + SD_EMMC_DELAY2_V3);
+ intf3 = readl(host->base + SD_EMMC_INTF3);
+
+ if ((pconf->bus_width == pdata->bus_width)
+ && (pconf->bl_len == pdata->bl_len)
+ && (mmc->actual_clock == clk_ios)
+ && (adj == pdata->adj)
+ && (dly1 == pdata->dly1)
+ && (dly2 == pdata->dly2)
+ && (intf3 == pdata->intf3))
+ return;
+
+ clk_ios = mmc->actual_clock;
+ pconf->bus_width = pdata->bus_width;
+ pconf->bl_len = pdata->bl_len;
+ adj = pdata->adj;
+ dly1 = pdata->dly1;
+ dly2 = pdata->dly2;
+ intf3 = pdata->intf3;
+ if (aml_card_type_non_sdio(pdata))
+ pconf->stop_clk = 0;
+
+ clk_set_rate(host->cfg_div_clk, clk_ios);
+ writel(vconf, host->base + SD_EMMC_CFG);
+ writel(adj, host->base + SD_EMMC_ADJUST_V3);
+ writel(dly1, host->base + SD_EMMC_DELAY1_V3);
+ writel(dly2, host->base + SD_EMMC_DELAY2_V3);
+ writel(intf3, host->base + SD_EMMC_INTF3);
+}
+#endif
+
+static int meson_mmc_clk_set_rate(struct mmc_host *mmc,
unsigned long clk_ios)
{
- struct mmc_host *mmc = host->mmc;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
int ret = 0;
#ifdef SD_EMMC_CLK_CTRL
u32 clk_rate, clk_div, clk_src_sel;
- struct amlsd_platform *pdata = host->pdata;
#else
u32 vcfg = 0;
struct sd_emmc_config *conf = (struct sd_emmc_config *)&vcfg;
@@ -1132,7 +1186,7 @@ static int meson_mmc_clk_set_rate(struct amlsd_host *host,
#ifdef SD_EMMC_CLK_CTRL
if (clk_ios == 0) {
- aml_mmc_clk_switch_off(host);
+ aml_mmc_clk_switch_off(pdata);
return ret;
}
@@ -1166,7 +1220,7 @@ static int meson_mmc_clk_set_rate(struct amlsd_host *host,
}
clk_div = (clk_rate / clk_ios) + (!!(clk_rate % clk_ios));
- aml_mmc_clk_switch(host, clk_div, clk_src_sel);
+ aml_mmc_clk_switch(pdata, clk_div, clk_src_sel);
pdata->clkc = readl(host->base + SD_EMMC_CLOCK);
mmc->actual_clock = clk_rate / clk_div;
@@ -1195,6 +1249,7 @@ static int meson_mmc_clk_set_rate(struct amlsd_host *host,
vcfg = readl(host->base + SD_EMMC_CFG);
conf->stop_clk = 0;
writel(vcfg, host->base + SD_EMMC_CFG);
+ pdata->clkc = readl(host->base + SD_EMMC_CLOCK);
}
#endif
@@ -1204,7 +1259,7 @@ static int meson_mmc_clk_set_rate(struct amlsd_host *host,
int aml_emmc_clktree_init(struct amlsd_host *host)
{
int i, ret = 0;
- unsigned int f_min = UINT_MAX, mux_parent_count = 0;
+ unsigned int mux_parent_count = 0;
const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
struct clk_init_data init;
char clk_name[32], name[16];
@@ -1237,18 +1292,9 @@ int aml_emmc_clktree_init(struct amlsd_host *host)
pr_debug("rate: %lu, name: %s\n",
host->mux_parent_rate[i], mux_parent_names[i]);
mux_parent_count++;
- if (host->mux_parent_rate[i] < f_min)
- f_min = host->mux_parent_rate[i];
ret = clk_prepare_enable(host->mux_parent[i]);
}
- /* cacluate f_min based on input clocks, and max divider value */
- if (f_min != UINT_MAX)
- f_min = DIV_ROUND_UP(CLK_SRC_XTAL_RATE, CLK_DIV_MAX);
- else
- f_min = 400000; /* default min: 400 KHz */
- host->mmc->f_min = f_min;
-
/* create the mux */
snprintf(clk_name, sizeof(clk_name), "%s#mux", dev_name(host->dev));
pr_debug("clk_name: %s\n", clk_name);
@@ -1303,7 +1349,6 @@ static int meson_mmc_clk_init(struct amlsd_host *host)
struct sd_emmc_clock *pclkc = (struct sd_emmc_clock *)&vclkc;
u32 vconf = 0;
struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
- struct amlsd_platform *pdata = host->pdata;
writel(0, host->base + SD_EMMC_CLOCK);
ret = aml_emmc_clktree_init(host);
@@ -1319,7 +1364,6 @@ static int meson_mmc_clk_init(struct amlsd_host *host)
pclkc->tx_phase = 0;
pclkc->always_on = 1; /* Keep clock always on */
writel(vclkc, host->base + SD_EMMC_CLOCK);
- pdata->clkc = vclkc;
vconf = 0;
/* 1bit mode */
@@ -1340,9 +1384,9 @@ static int meson_mmc_clk_init(struct amlsd_host *host)
return ret;
}
-static void aml_sd_emmc_tx_phase_set(struct amlsd_host *host)
+static void aml_sd_emmc_tx_phase_set(struct amlsd_platform *pdata)
{
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_host *host = pdata->host;
u32 vclkc = 0;
struct sd_emmc_clock *pclkc = (struct sd_emmc_clock *)&vclkc;
@@ -1355,9 +1399,9 @@ static void aml_sd_emmc_tx_phase_set(struct amlsd_host *host)
}
static void aml_sd_emmc_set_timing(
- struct amlsd_host *host, u32 timing)
+ struct amlsd_platform *pdata, u32 timing)
{
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_host *host = pdata->host;
u32 vctrl;
struct sd_emmc_config *ctrl = (struct sd_emmc_config *)&vctrl;
u32 vclkc;
@@ -1400,11 +1444,11 @@ static void aml_sd_emmc_set_timing(
/*setup bus width, 1bit, 4bits, 8bits*/
void aml_sd_emmc_set_buswidth(
- struct amlsd_host *host, u32 busw_ios)
+ struct amlsd_platform *pdata, u32 busw_ios)
{
- u32 vconf;
+ u32 vconf, width = 0;
+ struct amlsd_host *host = pdata->host;
struct sd_emmc_config *conf = (struct sd_emmc_config *)&vconf;
- u32 width = 0;
switch (busw_ios) {
case MMC_BUS_WIDTH_1:
@@ -1422,19 +1466,19 @@ void aml_sd_emmc_set_buswidth(
break;
}
- if (width != host->bus_width) {
+ if (width != pdata->bus_width) {
vconf = readl(host->base + SD_EMMC_CFG);
conf->bus_width = width;
writel(vconf, host->base + SD_EMMC_CFG);
- host->bus_width = width;
+ pdata->bus_width = width;
pr_debug("Bus Width Ios %d\n", busw_ios);
}
}
/*call by mmc, power on, power off ...*/
-static void aml_sd_emmc_set_power(struct amlsd_host *host, u32 power_mode)
+static void aml_sd_emmc_set_power(struct amlsd_platform *pdata, u32 power_mode)
{
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_host *host = pdata->host;
switch (power_mode) {
case MMC_POWER_ON:
@@ -1460,23 +1504,22 @@ static void aml_sd_emmc_set_power(struct amlsd_host *host, u32 power_mode)
static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
if (!pdata->is_in)
return;
/*Set Power*/
- aml_sd_emmc_set_power(host, ios->power_mode);
+ aml_sd_emmc_set_power(pdata, ios->power_mode);
/* Set Clock */
- meson_mmc_clk_set_rate(host, ios->clock);
+ meson_mmc_clk_set_rate(mmc, ios->clock);
/* Set Bus Width */
- aml_sd_emmc_set_buswidth(host, ios->bus_width);
+ aml_sd_emmc_set_buswidth(pdata, ios->bus_width);
/* Set Date Mode */
- aml_sd_emmc_set_timing(host, ios->timing);
+ aml_sd_emmc_set_timing(pdata, ios->timing);
if (ios->chip_select == MMC_CS_HIGH)
aml_cs_high(mmc);
@@ -1505,6 +1548,7 @@ static void aml_sd_emmc_kunmap_atomic(
* a linear buffer and an SG list for amlogic,
* We don't disable irq in this function
*/
+#ifndef AML_MMC_TDMA
#ifdef CFG_SDEMMC_PIO
static u32 aml_sd_emmc_pre_pio(struct amlsd_host *host,
struct mmc_request *mrq, struct sd_emmc_desc_info *desc)
@@ -1577,6 +1621,7 @@ err_exit:
return ret;
}
#endif /* CFG_SDEMMC_PIO */
+#endif
static unsigned int aml_sd_emmc_pre_dma(struct amlsd_host *host,
struct mmc_request *mrq, struct sd_emmc_desc_info *desc)
@@ -1755,7 +1800,6 @@ int aml_sd_emmc_post_dma(struct amlsd_host *host,
unsigned long flags;
int i, ret = 0;
-
data = mrq->cmd->data;
if (data == NULL) {
WARN_ON(1);
@@ -1804,11 +1848,15 @@ static void aml_sd_emmc_check_sdio_irq(struct amlsd_host *host)
}
int meson_mmc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = NULL;
+ struct amlsd_host *host = NULL;
unsigned long flags;
+ pdata = mmc_priv(mmc);
+ host = pdata->host;
+#ifndef AML_MMC_TDMA
WARN_ON(host->mrq != mrq);
+#endif
spin_lock_irqsave(&host->mrq_lock, flags);
host->xfer_step = XFER_FINISHED;
@@ -1816,10 +1864,14 @@ int meson_mmc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
host->status = HOST_INVALID;
spin_unlock_irqrestore(&host->mrq_lock, flags);
if (pdata->xfer_post)
- pdata->xfer_post(mmc);
+ pdata->xfer_post(pdata);
aml_sd_emmc_check_sdio_irq(host);
mmc_request_done(host->mmc, mrq);
+#ifdef AML_MMC_TDMA
+ if (aml_card_type_sdio(pdata) || aml_card_type_non_sdio(pdata))
+ complete(&host->drv_completion);
+#endif
return 0;
}
@@ -1864,8 +1916,8 @@ static void __attribute__((unused))
static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_request *mrq)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
struct sd_emmc_desc_info *desc_cur;
struct cmd_cfg *des_cmd_cur = NULL;
u32 conf_flag = 0;
@@ -1927,6 +1979,7 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_request *mrq)
if (pconf->bl_len != log2i(mrq->data->blksz)) {
conf_flag |= 1 << 3;
pconf->bl_len = log2i(mrq->data->blksz);
+ pdata->bl_len = pconf->bl_len;
}
}
if (conf_flag)
@@ -2145,15 +2198,27 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_request *mrq)
static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = NULL;
+ struct amlsd_host *host = NULL;
unsigned long flags;
WARN_ON(!mmc);
WARN_ON(!mrq);
- if (aml_check_unsupport_cmd(mmc, mrq))
+ pdata = mmc_priv(mmc);
+ host = pdata->host;
+#ifdef AML_MMC_TDMA
+ if (aml_card_type_sdio(pdata) || aml_card_type_non_sdio(pdata))
+ wait_for_completion(&host->drv_completion);
+#endif
+
+ if (aml_check_unsupport_cmd(mmc, mrq)) {
+#ifdef AML_MMC_TDMA
+ if (aml_card_type_sdio(pdata) || aml_card_type_non_sdio(pdata))
+ complete(&host->drv_completion);
+#endif
return;
+ }
pr_debug("%s: starting CMD%u arg %08x flags %08x\n",
mmc_hostname(mmc), mrq->cmd->opcode,
@@ -2168,20 +2233,31 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
/*clear pinmux & set pinmux*/
if (pdata->xfer_pre)
- pdata->xfer_pre(mmc);
+ pdata->xfer_pre(pdata);
+
+#ifdef AML_MMC_TDMA
+ if ((aml_card_type_sdio(pdata)
+ || aml_card_type_non_sdio(pdata))
+ && (host->data->chip_type == MMC_CHIP_G12A)) {
+ if (strcmp(host->cur_dev, pdata->pinname) || host->val_f)
+ aml_sd_emmc_save_host_val(mmc);
+ }
+#endif
spin_lock_irqsave(&host->mrq_lock, flags);
host->mrq = mrq;
+ host->mmc = mmc;
+ host->xfer_step = XFER_START;
host->opcode = mrq->cmd->opcode;
meson_mmc_start_cmd(mmc, mrq);
- host->xfer_step = XFER_START;
spin_unlock_irqrestore(&host->mrq_lock, flags);
}
int meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
{
- struct amlsd_host *host = mmc_priv(mmc);
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
struct sd_emmc_desc_info *desc_info =
(struct sd_emmc_desc_info *)host->desc_buf;
struct cmd_cfg *des_cmd_cur = NULL;
@@ -2283,10 +2359,10 @@ void mmc_cmd_LBA_show(struct mmc_host *mmc, struct mmc_request *mrq)
static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
{
struct amlsd_host *host = dev_id;
+ struct mmc_host *mmc;
+ struct amlsd_platform *pdata;
struct mmc_request *mrq;
unsigned long flags;
- struct amlsd_platform *pdata = host->pdata;
- struct mmc_host *mmc;
u32 vstat = 0;
u32 virqc = 0;
u32 vstart = 0;
@@ -2319,6 +2395,7 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
spin_lock_irqsave(&host->mrq_lock, flags);
mrq = host->mrq;
mmc = host->mmc;
+ pdata = mmc_priv(mmc);
vstart = readl(host->base + SD_EMMC_START);
if ((desc_start->busy == 1)
&& (aml_card_type_mmc(pdata) ||
@@ -2481,7 +2558,7 @@ void aml_sd_emmc_send_stop(struct amlsd_host *host)
static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
{
struct amlsd_host *host = dev_id;
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata;
unsigned long flags;
struct mmc_request *mrq;
@@ -2495,6 +2572,7 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
struct sd_emmc_clock *clkc = (struct sd_emmc_clock *)&(vclk);
spin_lock_irqsave(&host->mrq_lock, flags);
+ pdata = mmc_priv(host->mmc);
mrq = host->mrq;
xfer_step = host->xfer_step;
status = host->status;
@@ -2724,8 +2802,8 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
static void aml_sd_emmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
unsigned long flags;
/* u32 vstat = 0; */
u32 vclkc = 0;
@@ -2765,8 +2843,7 @@ static void aml_sd_emmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
/*get readonly: 0 for rw, 1 for ro*/
static int aml_sd_emmc_get_ro(struct mmc_host *mmc)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
u32 ro = 0;
if (pdata->ro)
@@ -2780,8 +2857,7 @@ static int aml_sd_emmc_get_ro(struct mmc_host *mmc)
*/
static int meson_mmc_get_cd(struct mmc_host *mmc)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
return pdata->is_in;
}
@@ -2794,8 +2870,8 @@ int aml_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
/* Check if the card is pulling dat[0:3] low */
static int aml_sd_emmc_card_busy(struct mmc_host *mmc)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
unsigned int status = 0;
/* only check data3_0 gpio level?? */
u32 vstat;
@@ -2852,9 +2928,9 @@ static const struct mmc_host_ops meson_mmc_ops_v3 = {
.post_hs400_timming = aml_post_hs400_timming,
};
-static void aml_reg_print(struct amlsd_host *host)
+static void aml_reg_print(struct amlsd_platform *pdata)
{
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_host *host = pdata->host;
pr_debug("%s reg val:\n", pdata->pinname);
pr_debug("SD_EMMC_CLOCK = 0x%x\n", readl(host->base + SD_EMMC_CLOCK));
@@ -2869,20 +2945,17 @@ static int meson_mmc_probe(struct platform_device *pdev)
struct amlsd_host *host;
struct amlsd_platform *pdata = NULL;
struct mmc_host *mmc;
- int ret;
+ int ret = 0, clk = 0, cfg = 0;
+#ifdef AML_MMC_TDMA
+ int i = 0, k = 1;
+#endif
aml_mmc_ver_msg_show();
- pdata = kzalloc(sizeof(struct amlsd_platform), GFP_KERNEL);
- if (!pdata)
- ret = -ENOMEM;
-
- mmc = mmc_alloc_host(sizeof(struct amlsd_host), &pdev->dev);
- if (!mmc)
- return -ENOMEM;
+ host = kzalloc(sizeof(struct amlsd_host), GFP_KERNEL);
+ if (!host)
+ ret = -ENODEV;
- host = mmc_priv(mmc);
- host->mmc = mmc;
host->pdev = pdev;
host->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, host);
@@ -2891,19 +2964,19 @@ static int meson_mmc_probe(struct platform_device *pdev)
of_device_get_match_data(&pdev->dev);
if (!host->data) {
ret = -EINVAL;
- goto free_host;
+ goto fail_init_host;
}
if (host->data->chip_type >= MMC_CHIP_TXLX)
host->ctrl_ver = 3;
- host->pinmux_base = ioremap(host->data->pinmux_base, 0x200);
+ host->pinmux_base = ioremap(host->data->pinmux_base, 0x400);
if (IS_ERR(host->pinmux_base)) {
ret = PTR_ERR(host->pinmux_base);
- goto free_host;
+ goto fail_init_host;
}
host->clksrc_base = ioremap(host->data->clksrc_base, 0x300);
if (IS_ERR(host->clksrc_base)) {
ret = PTR_ERR(host->clksrc_base);
- goto free_host;
+ goto fail_init_host;
}
host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
res_mem = host->mem;
@@ -2911,15 +2984,16 @@ static int meson_mmc_probe(struct platform_device *pdev)
host->base = devm_ioremap_resource(&pdev->dev, res_mem);
if (IS_ERR(host->base)) {
ret = PTR_ERR(host->base);
- goto free_host;
+ goto fail_init_host;
}
host->irq = platform_get_irq(pdev, 0);
if (host->irq == 0) {
dev_err(&pdev->dev, "failed to get interrupt resource.\n");
ret = -EINVAL;
- goto free_host;
+ goto fail_init_host;
}
+
if (host->ctrl_ver >= 3)
ret = devm_request_threaded_irq(&pdev->dev, host->irq,
meson_mmc_irq, meson_mmc_irq_thread_v3,
@@ -2929,20 +3003,25 @@ static int meson_mmc_probe(struct platform_device *pdev)
meson_mmc_irq, meson_mmc_irq_thread,
IRQF_SHARED, "meson-aml-mmc", host);
if (ret)
- goto free_host;
+ goto fail_init_host;
host->blk_test = kzalloc((512 * CALI_BLK_CNT), GFP_KERNEL);
if (host->blk_test == NULL) {
ret = -ENOMEM;
- goto free_host;
+ goto fail_init_host;
}
- host->pdata = pdata;
spin_lock_init(&host->mrq_lock);
mutex_init(&host->pinmux_lock);
host->xfer_step = XFER_INIT;
host->init_flag = 1;
host->is_gated = false;
+ host->init_flag = 1;
+ host->version = AML_MMC_VERSION;
+ host->pinctrl = NULL;
+ host->status = HOST_INVALID;
+ host->is_tunning = 0;
+ host->is_timming = 0;
if (host->ctrl_ver >= 3)
ret = meson_mmc_clk_init_v3(host);
@@ -2951,16 +3030,54 @@ static int meson_mmc_probe(struct platform_device *pdev)
if (ret)
goto free_cali;
+ if (host->ctrl_ver >= 3)
+ clk = readl(host->base + SD_EMMC_CLOCK_V3);
+ else
+ clk = readl(host->base + SD_EMMC_CLOCK);
+ cfg = readl(host->base + SD_EMMC_CFG);
+
+ /* data bounce buffer */
+ host->bn_buf =
+ dma_alloc_coherent(host->dev, SD_EMMC_BOUNCE_REQ_SIZE,
+ &host->bn_dma_buf, GFP_KERNEL);
+ if (host->bn_buf == NULL) {
+ dev_err(host->dev, "Unable to map allocate DMA bounce buffer.\n");
+ ret = -ENOMEM;
+ goto free_cali;
+ }
+
+#ifdef AML_MMC_TDMA
+ if ((host->irq == 49) && (host->data->chip_type == MMC_CHIP_G12A)) {
+ init_completion(&host->drv_completion);
+ host->drv_completion.done = 1;
+ k = 2;
+ }
+ for (i = 0; i < k; i++) {
+#endif
+ mmc = mmc_alloc_host(sizeof(struct amlsd_platform), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto free_cali;
+ }
+
ret = mmc_of_parse(mmc);
if (ret) {
dev_warn(&pdev->dev, "error parsing DT: %d\n", ret);
- goto free_cali;
+ goto free_host;
}
- if (amlsd_get_platform_data(pdev, pdata, mmc, 0))
+ pdata = mmc_priv(mmc);
+ memset(pdata, 0, sizeof(struct amlsd_platform));
+#ifdef AML_MMC_TDMA
+ ret = amlsd_get_platform_data(pdev, pdata, mmc, i);
+#else
+ ret = amlsd_get_platform_data(pdev, pdata, mmc, 0);
+#endif
+ if (ret)
mmc_free_host(mmc);
/* data desc buffer */
+#ifndef AML_MMC_TDMA
#ifdef CFG_SDEMMC_PIO
pr_err(">>>>>>>>>>hostbase %p, dmode %s\n", host->base, pdata->dmode);
if (!strcmp(pdata->dmode, "pio")) {
@@ -2978,6 +3095,7 @@ static int meson_mmc_probe(struct platform_device *pdev)
}
} else {
#endif
+#endif
host->pre_cmd_op = aml_sd_emmc_pre_dma;
host->post_cmd_op = aml_sd_emmc_post_dma;
host->desc_buf =
@@ -2991,33 +3109,31 @@ static int meson_mmc_probe(struct platform_device *pdev)
ret = -ENOMEM;
goto free_cali;
}
+#ifndef AML_MMC_TDMA
#ifdef CFG_SDEMMC_PIO
}
#endif
- /* data bounce buffer */
- host->bn_buf =
- dma_alloc_coherent(host->dev, SD_EMMC_BOUNCE_REQ_SIZE,
- &host->bn_dma_buf, GFP_KERNEL);
- if (host->bn_buf == NULL) {
- dev_err(host->dev, "Unable to map allocate DMA bounce buffer.\n");
- ret = -ENOMEM;
- goto free_cali;
- }
+#endif
if (aml_card_type_mmc(pdata)
&& (host->ctrl_ver < 3))
/**set emmc tx_phase regs here base on dts**/
- aml_sd_emmc_tx_phase_set(host);
+ aml_sd_emmc_tx_phase_set(pdata);
dev_set_name(&mmc->class_dev, "%s", pdata->pinname);
+ /* save def clk & cfg */
+ pdata->clkc = clk;
+ pdata->ctrl = cfg;
+
+ if (pdata->caps & MMC_CAP_NONREMOVABLE)
+ pdata->is_in = 1;
+
if (pdata->caps & MMC_PM_KEEP_POWER)
mmc->pm_caps |= MMC_PM_KEEP_POWER;
- host->init_flag = 1;
- host->version = AML_MMC_VERSION;
- host->pinctrl = NULL;
- host->status = HOST_INVALID;
- host->is_tunning = 0;
+
+ pdata->host = host;
+ pdata->mmc = mmc;
mmc->ios.clock = 400000;
mmc->ios.bus_width = MMC_BUS_WIDTH_1;
#ifdef CFG_SDEMMC_PIO
@@ -3042,9 +3158,6 @@ static int meson_mmc_probe(struct platform_device *pdev)
mmc->max_current_180 = 300; /* 300 mA in 1.8V */
mmc->max_current_330 = 300; /* 300 mA in 3.3V */
- if (mmc->caps & MMC_CAP_NONREMOVABLE)
- pdata->is_in = 1;
-
if (aml_card_type_sdio(pdata)) { /* if sdio_wifi */
/* mmc->host_rescan_disable = true;*/
/* do NOT run mmc_rescan for the first time */
@@ -3076,11 +3189,11 @@ static int meson_mmc_probe(struct platform_device *pdev)
mmc->ops = &meson_mmc_ops_v3;
else
mmc->ops = &meson_mmc_ops;
- aml_reg_print(host);
+ aml_reg_print(pdata);
ret = mmc_add_host(mmc);
if (ret) { /* error */
pr_err("Failed to add mmc host.\n");
- goto free_cali;
+ goto free_host;
}
if (aml_card_type_sdio(pdata)) /* if sdio_wifi */
sdio_host = mmc;
@@ -3100,25 +3213,31 @@ static int meson_mmc_probe(struct platform_device *pdev)
"amlsd_cd", host);
if (ret) {
pr_err("Failed to request SD IN detect\n");
- goto free_cali;
+ goto free_host;
}
#else
- INIT_DELAYED_WORK(&host->cd_work, meson_mmc_cd_detect);
- schedule_delayed_work(&host->cd_work, 50);
+ INIT_DELAYED_WORK(&pdata->cd_detect, meson_mmc_cd_detect);
+ schedule_delayed_work(&pdata->cd_detect, 50);
#endif
}
#endif /* CONFIG_MESON_CPU_EMULATOR */
+#ifdef AML_MMC_TDMA
+ mdelay(800);
+ }
+#endif
pr_info("%s() : success!\n", __func__);
return 0;
+free_host:
+ mmc_free_host(mmc);
+ kfree(pdata);
free_cali:
#ifdef CFG_SDEMMC_PIO
kfree(host->desc_bn);
#endif
kfree(host->blk_test);
-free_host:
- mmc_free_host(mmc);
- kfree(pdata);
+fail_init_host:
+ kfree(host);
pr_err("%s() fail!\n", __func__);
return ret;
}
@@ -3150,6 +3269,7 @@ static int meson_mmc_remove(struct platform_device *pdev)
kfree(host->blk_test);
mmc_free_host(host->mmc);
kfree(pdata);
+ kfree(host);
return 0;
}
@@ -3251,6 +3371,15 @@ static struct meson_mmc_data mmc_data_g12a = {
.ds_pin_poll = 0x3a,
.ds_pin_poll_en = 0x48,
.ds_pin_poll_bit = 13,
+ .sdmmc.init.core_phase = 3,
+ .sdmmc.init.tx_phase = 0,
+ .sdmmc.init.rx_phase = 0,
+ .sdmmc.hs.core_phase = 3,
+ .sdmmc.ddr.core_phase = 2,
+ .sdmmc.hs2.core_phase = 3,
+ .sdmmc.hs4.tx_delay = 0,
+ .sdmmc.sd_hs.core_phase = 2,
+ .sdmmc.sdr104.core_phase = 2,
};
static const struct of_device_id meson_mmc_of_match[] = {
diff --git a/drivers/amlogic/mmc/aml_sd_emmc_v3.c b/drivers/amlogic/mmc/aml_sd_emmc_v3.c
index 3152a76..6d7db83 100644
--- a/drivers/amlogic/mmc/aml_sd_emmc_v3.c
+++ b/drivers/amlogic/mmc/aml_sd_emmc_v3.c
@@ -49,7 +49,6 @@ int meson_mmc_clk_init_v3(struct amlsd_host *host)
struct sd_emmc_clock_v3 *pclkc = (struct sd_emmc_clock_v3 *)&vclkc;
u32 vconf = 0;
struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
- struct amlsd_platform *pdata = host->pdata;
struct mmc_phase *init = &(host->data->sdmmc.init);
writel(0, host->base + SD_EMMC_CLOCK_V3);
@@ -67,7 +66,6 @@ int meson_mmc_clk_init_v3(struct amlsd_host *host)
pclkc->tx_phase = init->tx_phase;
pclkc->always_on = 1; /* Keep clock always on */
writel(vclkc, host->base + SD_EMMC_CLOCK_V3);
- pdata->clkc = vclkc;
vconf = 0;
/* 1bit mode */
@@ -88,16 +86,15 @@ int meson_mmc_clk_init_v3(struct amlsd_host *host)
return ret;
}
-static int meson_mmc_clk_set_rate_v3(struct amlsd_host *host,
+static int meson_mmc_clk_set_rate_v3(struct mmc_host *mmc,
unsigned long clk_ios)
{
- struct mmc_host *mmc = host->mmc;
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
int ret = 0;
#ifdef SD_EMMC_CLK_CTRL
u32 clk_rate, clk_div, clk_src_sel;
- struct amlsd_platform *pdata = host->pdata;
#else
struct clk *src0_clk = NULL;
u32 vcfg = 0;
@@ -194,6 +191,7 @@ static int meson_mmc_clk_set_rate_v3(struct amlsd_host *host,
vcfg = readl(host->base + SD_EMMC_CFG);
conf->stop_clk = 0;
writel(vcfg, host->base + SD_EMMC_CFG);
+ pdata->clkc = readl(host->base + SD_EMMC_CLOCK_V3);
}
#endif
pr_debug("actual_clock :%u, HHI_nand: 0x%x\n",
@@ -206,10 +204,10 @@ static int meson_mmc_clk_set_rate_v3(struct amlsd_host *host,
return ret;
}
-static void aml_sd_emmc_set_timing_v3(struct amlsd_host *host,
+static void aml_sd_emmc_set_timing_v3(struct amlsd_platform *pdata,
u32 timing)
{
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_host *host = pdata->host;
u32 vctrl;
struct sd_emmc_config *ctrl = (struct sd_emmc_config *)&vctrl;
u32 vclkc = readl(host->base + SD_EMMC_CLOCK_V3);
@@ -230,6 +228,12 @@ static void aml_sd_emmc_set_timing_v3(struct amlsd_host *host,
gadjust->ds_enable = 1;
writel(adjust, host->base + SD_EMMC_ADJUST_V3);
clkc->tx_delay = para->hs4.tx_delay;
+ pdata->adj = adjust;
+ /*TODO: double check!
+ * overide tx-delay by dts configs
+ */
+ if (pdata->tx_delay != 0)
+ clkc->tx_delay = pdata->tx_delay;
}
pr_info("%s: try set sd/emmc to HS400 mode\n",
mmc_hostname(host->mmc));
@@ -267,10 +271,10 @@ static void aml_sd_emmc_set_timing_v3(struct amlsd_host *host,
}
/*call by mmc, power on, power off ...*/
-static void aml_sd_emmc_set_power_v3(struct amlsd_host *host,
+static void aml_sd_emmc_set_power_v3(struct amlsd_platform *pdata,
u32 power_mode)
{
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_host *host = pdata->host;
switch (power_mode) {
case MMC_POWER_ON:
@@ -299,40 +303,60 @@ static void aml_sd_emmc_set_power_v3(struct amlsd_host *host,
void meson_mmc_set_ios_v3(struct mmc_host *mmc,
struct mmc_ios *ios)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
- if (!pdata->is_in)
+#ifdef AML_MMC_TDMA
+ if (aml_card_type_sdio(pdata) || aml_card_type_non_sdio(pdata))
+ wait_for_completion(&host->drv_completion);
+#endif
+ if (!pdata->is_in) {
+#ifdef AML_MMC_TDMA
+ if (aml_card_type_sdio(pdata) || aml_card_type_non_sdio(pdata))
+ complete(&host->drv_completion);
+#endif
return;
+ }
+
+ if ((aml_card_type_sdio(pdata)
+ || aml_card_type_non_sdio(pdata))
+ && (host->data->chip_type == MMC_CHIP_G12A))
+ host->val_f = 1;
+
/*Set Power*/
- aml_sd_emmc_set_power_v3(host, ios->power_mode);
+ aml_sd_emmc_set_power_v3(pdata, ios->power_mode);
/*Set Clock*/
- meson_mmc_clk_set_rate_v3(host, ios->clock);
+ meson_mmc_clk_set_rate_v3(mmc, ios->clock);
/*Set Bus Width*/
- aml_sd_emmc_set_buswidth(host, ios->bus_width);
+ aml_sd_emmc_set_buswidth(pdata, ios->bus_width);
/* Set Date Mode */
- aml_sd_emmc_set_timing_v3(host, ios->timing);
+ aml_sd_emmc_set_timing_v3(pdata, ios->timing);
if (ios->chip_select == MMC_CS_HIGH)
aml_cs_high(mmc);
else if (ios->chip_select == MMC_CS_DONTCARE)
aml_cs_dont_care(mmc);
+#ifdef AML_MMC_TDMA
+ if (aml_card_type_sdio(pdata) || aml_card_type_non_sdio(pdata))
+ complete(&host->drv_completion);
+#endif
}
irqreturn_t meson_mmc_irq_thread_v3(int irq, void *dev_id)
{
struct amlsd_host *host = dev_id;
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata;
struct mmc_request *mrq;
unsigned long flags;
enum aml_mmc_waitfor xfer_step;
u32 status, xfer_bytes = 0;
spin_lock_irqsave(&host->mrq_lock, flags);
+ pdata = mmc_priv(host->mmc);
mrq = host->mrq;
xfer_step = host->xfer_step;
status = host->status;
@@ -472,7 +496,8 @@ irqreturn_t meson_mmc_irq_thread_v3(int irq, void *dev_id)
static int aml_sd_emmc_cali_v3(struct mmc_host *mmc,
u8 opcode, u8 *blk_test, u32 blksz, u32 blocks)
{
- struct amlsd_host *host = mmc_priv(mmc);
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
struct mmc_request mrq = {NULL};
struct mmc_command cmd = {0};
struct mmc_command stop = {0};
@@ -541,8 +566,8 @@ static int aml_sd_emmc_cmd_v3(struct mmc_host *mmc)
static int emmc_eyetest_log(struct mmc_host *mmc, u32 line_x)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 adjust = readl(host->base + SD_EMMC_ADJUST_V3);
struct sd_emmc_adjust_v3 *gadjust =
(struct sd_emmc_adjust_v3 *)&adjust;
@@ -563,6 +588,7 @@ static int emmc_eyetest_log(struct mmc_host *mmc, u32 line_x)
gadjust->cali_enable = 1;
gadjust->cali_sel = line_x;
writel(adjust, host->base + SD_EMMC_ADJUST_V3);
+ pdata->adj = adjust;
if (line_x < 9)
gintf3->eyetest_exp = 7;
else
@@ -571,6 +597,7 @@ RETRY:
gintf3->eyetest_on = 1;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
/*****test start*************/
udelay(5);
@@ -589,6 +616,7 @@ RETRY:
eyetest_out0, eyetest_out1);
gintf3->eyetest_on = 0;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
retry--;
if (retry == 0) {
pr_warn("[%s][%d] retry eyetest failed\n",
@@ -601,6 +629,7 @@ RETRY:
eyetest_out1 = readl(host->base + SD_EMMC_EYETEST_OUT1);
gintf3->eyetest_on = 0;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
if (vcfg & 0x4) {
if (pdata->count > 32) {
eyetest_out1 <<= (32 - (pdata->count - 32));
@@ -645,8 +674,8 @@ static int emmc_detect_base_line(u64 *arr)
/**************** start all data align ********************/
static int emmc_all_data_line_alignment(struct mmc_host *mmc)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 delay1 = 0, delay2 = 0;
int result;
int temp = 0, base_line = 0, line_x = 0;
@@ -673,6 +702,8 @@ static int emmc_all_data_line_alignment(struct mmc_host *mmc)
delay2 += readl(host->base + SD_EMMC_DELAY2_V3);
writel(delay1, host->base + SD_EMMC_DELAY1_V3);
writel(delay2, host->base + SD_EMMC_DELAY2_V3);
+ pdata->dly1 = delay1;
+ pdata->dly2 = delay2;
pr_debug("gdelay1: 0x%x, gdelay2: 0x%x\n",
readl(host->base + SD_EMMC_DELAY1_V3),
readl(host->base + SD_EMMC_DELAY2_V3));
@@ -682,8 +713,8 @@ static int emmc_all_data_line_alignment(struct mmc_host *mmc)
static int emmc_ds_data_alignment(struct mmc_host *mmc)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 delay1 = readl(host->base + SD_EMMC_DELAY1_V3);
u32 delay2 = readl(host->base + SD_EMMC_DELAY2_V3);
int i, line_x, temp = 0;
@@ -703,6 +734,8 @@ static int emmc_ds_data_alignment(struct mmc_host *mmc)
delay2 += 1 << (6 * (line_x - 5));
writel(delay1, host->base + SD_EMMC_DELAY1_V3);
writel(delay2, host->base + SD_EMMC_DELAY2_V3);
+ pdata->dly1 = delay1;
+ pdata->dly2 = delay2;
emmc_eyetest_log(mmc, line_x);
if (pdata->align[line_x] & 0xf0)
break;
@@ -719,8 +752,7 @@ static int emmc_ds_data_alignment(struct mmc_host *mmc)
static void update_all_line_eyetest(struct mmc_host *mmc)
{
int line_x;
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
for (line_x = 0; line_x < 10; line_x++) {
if ((line_x == 8) && !(pdata->caps2 & MMC_CAP2_HS400))
@@ -731,8 +763,8 @@ static void update_all_line_eyetest(struct mmc_host *mmc)
/* first step*/
static int emmc_ds_core_align(struct mmc_host *mmc)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 delay1 = readl(host->base + SD_EMMC_DELAY1_V3);
u32 delay2 = readl(host->base + SD_EMMC_DELAY2_V3);
u32 delay2_bak = delay2;
@@ -778,6 +810,8 @@ static int emmc_ds_core_align(struct mmc_host *mmc)
delay2 += (cmd_count<<24);
writel(delay1, host->base + SD_EMMC_DELAY1_V3);
writel(delay2, host->base + SD_EMMC_DELAY2_V3);
+ pdata->dly1 = delay1;
+ pdata->dly2 = delay2;
pr_debug("cmd_count:%d,delay1:0x%x,delay2:0x%x,count: %u\n",
cmd_count, readl(host->base + SD_EMMC_DELAY1_V3),
readl(host->base + SD_EMMC_DELAY2_V3), count);
@@ -787,8 +821,8 @@ static int emmc_ds_core_align(struct mmc_host *mmc)
#if 1
static int emmc_ds_manual_sht(struct mmc_host *mmc)
{
- struct amlsd_host *host = mmc_priv(mmc);
- /* struct amlsd_platform *pdata = host->pdata; */
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 intf3 = readl(host->base + SD_EMMC_INTF3);
struct intf3 *gintf3 = (struct intf3 *)&(intf3);
u32 blksz = 512;
@@ -809,6 +843,7 @@ static int emmc_ds_manual_sht(struct mmc_host *mmc)
for (i = 0; i < 32; i++) {
gintf3->ds_sht_m += 1;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
err = aml_sd_emmc_cali_v3(mmc,
MMC_READ_MULTIPLE_BLOCK,
host->blk_test, blksz, 20);
@@ -854,6 +889,7 @@ static int emmc_ds_manual_sht(struct mmc_host *mmc)
gintf3->ds_sht_m = (best_start + best_size) / 2;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
pr_info("ds_sht:%u, window:%d, intf3:0x%x",
gintf3->ds_sht_m, best_size,
readl(host->base + SD_EMMC_INTF3));
@@ -867,8 +903,8 @@ static int emmc_ds_manual_sht(struct mmc_host *mmc)
*/
static unsigned int aml_sd_emmc_clktest(struct mmc_host *mmc)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 intf3 = readl(host->base + SD_EMMC_INTF3);
struct intf3 *gintf3 = (struct intf3 *)&(intf3);
u32 clktest = 0, delay_cell = 0, clktest_log = 0, count = 0;
@@ -882,9 +918,12 @@ static unsigned int aml_sd_emmc_clktest(struct mmc_host *mmc)
writel(vcfg, host->base + SD_EMMC_CFG);
writel(0, host->base + SD_EMMC_DELAY1_V3);
writel(0, host->base + SD_EMMC_DELAY2_V3);
+ pdata->dly1 = 0;
+ pdata->dly2 = 0;
gintf3->clktest_exp = 8;
gintf3->clktest_on_m = 1;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
clktest_log = readl(host->base + SD_EMMC_CLKTEST_LOG);
clktest = readl(host->base + SD_EMMC_CLKTEST_OUT);
@@ -912,6 +951,7 @@ static unsigned int aml_sd_emmc_clktest(struct mmc_host *mmc)
intf3 = readl(host->base + SD_EMMC_INTF3);
gintf3->clktest_on_m = 0;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
vcfg = readl(host->base + SD_EMMC_CFG);
vcfg |= (1 << 23);
writel(vcfg, host->base + SD_EMMC_CFG);
@@ -925,8 +965,8 @@ static int _aml_sd_emmc_execute_tuning(struct mmc_host *mmc, u32 opcode,
u32 adj_win_start)
{
#if 1 /* need finish later */
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 vclk;
struct sd_emmc_clock_v3 *clkc = (struct sd_emmc_clock_v3 *)&(vclk);
u32 adjust = readl(host->base + SD_EMMC_ADJUST_V3);
@@ -963,6 +1003,7 @@ tunning:
gadjust->cali_enable = 0;
gadjust->cali_rise = 0;
writel(adjust, host->base + SD_EMMC_ADJUST_V3);
+ pdata->adj = adjust;
nmatch = aml_sd_emmc_tuning_transfer(mmc, opcode,
blk_pattern, host->blk_test, blksz);
/*get a ok adjust point!*/
@@ -1044,6 +1085,7 @@ tunning:
gadjust->cali_enable = 0;
gadjust->cali_rise = 0;
writel(adjust, host->base + SD_EMMC_ADJUST_V3);
+ pdata->adj = adjust;
host->is_tunning = 0;
pr_info("%s: sd_emmc_regs->gclock=0x%x,sd_emmc_regs->gadjust=0x%x\n",
@@ -1057,8 +1099,8 @@ tunning:
int aml_emmc_hs200_timming(struct mmc_host *mmc)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 count = 0, delay1 = 0, delay2 = 0, line_x;
host->is_timming = 1;
@@ -1082,6 +1124,8 @@ int aml_emmc_hs200_timming(struct mmc_host *mmc)
}
writel(delay1, host->base + SD_EMMC_DELAY1_V3);
writel(delay2, host->base + SD_EMMC_DELAY2_V3);
+ pdata->dly1 = delay1;
+ pdata->dly2 = delay2;
pr_debug("gdelay1: 0x%x, gdelay2: 0x%x\n",
readl(host->base + SD_EMMC_DELAY1_V3),
readl(host->base + SD_EMMC_DELAY2_V3));
@@ -1093,8 +1137,8 @@ int aml_emmc_hs200_timming(struct mmc_host *mmc)
static int sdio_eyetest_log(struct mmc_host *mmc, u32 line_x, u32 opcode,
struct aml_tuning_data *tuning_data)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 adjust = readl(host->base + SD_EMMC_ADJUST_V3);
struct sd_emmc_adjust_v3 *gadjust =
(struct sd_emmc_adjust_v3 *)&adjust;
@@ -1117,11 +1161,13 @@ static int sdio_eyetest_log(struct mmc_host *mmc, u32 line_x, u32 opcode,
gadjust->cali_enable = 1;
gadjust->cali_sel = line_x;
writel(adjust, host->base + SD_EMMC_ADJUST_V3);
+ pdata->adj = adjust;
gintf3->eyetest_exp = 4;
RETRY:
gintf3->eyetest_on = 1;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
udelay(5);
for (i = 0; i < 40; i++)
@@ -1138,6 +1184,7 @@ RETRY:
eyetest_out0, eyetest_out1);
gintf3->eyetest_on = 0;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
retry--;
if (retry == 0) {
pr_warn("[%s][%d] retry eyetest failed\n",
@@ -1151,6 +1198,7 @@ RETRY:
eyetest_out0, eyetest_out1);
gintf3->eyetest_on = 0;
writel(intf3, host->base + SD_EMMC_INTF3);
+ pdata->intf3 = intf3;
pdata->align[line_x] = ((tmp | eyetest_out1) << 32) | eyetest_out0;
pr_debug("u64 eyetestout 0x%llx\n", pdata->align[line_x]);
host->is_tunning = 0;
@@ -1161,8 +1209,8 @@ static int aml_sdio_timing(struct mmc_host *mmc, u32 opcode,
struct aml_tuning_data *tuning_data,
u32 adj_win_start)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
u32 line_x = 0, delay1 = 0, retry = 1, temp;
int ret;
@@ -1170,6 +1218,7 @@ static int aml_sdio_timing(struct mmc_host *mmc, u32 opcode,
delay1 = 0;
for (line_x = 0; line_x < 4; line_x++) {
writel(0, host->base + SD_EMMC_DELAY1_V3);
+ pdata->dly1 = 0;
retry = 1;
RETRY:
ret = sdio_eyetest_log(mmc, line_x, opcode, tuning_data);
@@ -1178,6 +1227,7 @@ RETRY:
__func__, __LINE__);
writel(5 << (6 * line_x),
host->base + SD_EMMC_DELAY1_V3);
+ pdata->dly1 = readl(host->base + SD_EMMC_DELAY1_V3);
delay1 |= (5 << (6 * line_x));
retry--;
goto RETRY;
@@ -1189,6 +1239,7 @@ RETRY:
}
writel(delay1, host->base + SD_EMMC_DELAY1_V3);
+ pdata->dly1 = delay1;
delay1 = 0;
for (line_x = 0; line_x < 4; line_x++) {
temp = fbinary(pdata->align[line_x]);
@@ -1202,6 +1253,7 @@ RETRY:
}
delay1 += readl(host->base + SD_EMMC_DELAY1_V3);
writel(delay1, host->base + SD_EMMC_DELAY1_V3);
+ pdata->dly1 = delay1;
host->is_tunning = 0;
pr_info("%s: gadjust=0x%x, gdelay1=0x%x, gclock=0x%x\n",
@@ -1214,8 +1266,8 @@ RETRY:
int aml_mmc_execute_tuning_v3(struct mmc_host *mmc, u32 opcode)
{
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
struct aml_tuning_data tuning_data;
int err = -EINVAL;
u32 adj_win_start = 100;
@@ -1240,13 +1292,15 @@ int aml_mmc_execute_tuning_v3(struct mmc_host *mmc, u32 opcode)
}
if (aml_card_type_sdio(pdata)) {
- if (host->data->chip_type == MMC_CHIP_GXLX)
+ if ((host->data->chip_type == MMC_CHIP_GXLX)
+ || (host->data->chip_type == MMC_CHIP_G12A))
err = _aml_sd_emmc_execute_tuning(mmc, opcode,
&tuning_data, adj_win_start);
else {
intf3 = readl(host->base + SD_EMMC_INTF3);
intf3 |= (1<<22);
writel(intf3, (host->base + SD_EMMC_INTF3));
+ pdata->intf3 = intf3;
aml_sd_emmc_clktest(mmc);
err = aml_sdio_timing(mmc, opcode,
&tuning_data, adj_win_start);
@@ -1256,6 +1310,7 @@ int aml_mmc_execute_tuning_v3(struct mmc_host *mmc, u32 opcode)
intf3 = readl(host->base + SD_EMMC_INTF3);
intf3 |= (1<<22);
writel(intf3, (host->base + SD_EMMC_INTF3));
+ pdata->intf3 = intf3;
err = aml_emmc_hs200_timming(mmc);
} else
err = _aml_sd_emmc_execute_tuning(mmc, opcode,
@@ -1264,6 +1319,7 @@ int aml_mmc_execute_tuning_v3(struct mmc_host *mmc, u32 opcode)
intf3 = readl(host->base + SD_EMMC_INTF3);
intf3 |= (1<<22);
writel(intf3, (host->base + SD_EMMC_INTF3));
+ pdata->intf3 = intf3;
err = 0;
}
diff --git a/drivers/amlogic/mmc/aml_sdhc_m8.c b/drivers/amlogic/mmc/aml_sdhc_m8.c
index d92b2ca..7932b42 100644
--- a/drivers/amlogic/mmc/aml_sdhc_m8.c
+++ b/drivers/amlogic/mmc/aml_sdhc_m8.c
@@ -858,7 +858,7 @@ void aml_sdhc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
#endif
if (pdata->xfer_post)
- pdata->xfer_post(mmc);
+ pdata->xfer_post(pdata);
aml_sdhc_disable_imask(host, SDHC_ICTL_ALL);
/*Set irq status: write 1 clear*/
@@ -1218,7 +1218,7 @@ void aml_sdhc_request(struct mmc_host *mmc, struct mmc_request *mrq)
/*clear pinmux & set pinmux*/
if (pdata->xfer_pre)
- pdata->xfer_pre(mmc);
+ pdata->xfer_pre(pdata);
#ifdef CONFIG_MMC_AML_DEBUG
aml_dbg_verify_pull_up(pdata);
diff --git a/drivers/amlogic/mmc/aml_sdio.c b/drivers/amlogic/mmc/aml_sdio.c
index 7369177..7b9469d 100644
--- a/drivers/amlogic/mmc/aml_sdio.c
+++ b/drivers/amlogic/mmc/aml_sdio.c
@@ -421,7 +421,7 @@ void aml_sdio_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
#endif
if (pdata->xfer_post)
- pdata->xfer_post(mmc);
+ pdata->xfer_post(pdata);
mmc_request_done(host->mmc, mrq);
}
@@ -636,7 +636,7 @@ void aml_sdio_request(struct mmc_host *mmc, struct mmc_request *mrq)
/*clear pinmux & set pinmux*/
if (pdata->xfer_pre)
- pdata->xfer_pre(mmc);
+ pdata->xfer_pre(pdata);
#ifdef CONFIG_MMC_AML_DEBUG
aml_dbg_verify_pull_up(pdata);
diff --git a/drivers/amlogic/mmc/amlsd.c b/drivers/amlogic/mmc/amlsd.c
index aa51349..d4cae08 100644
--- a/drivers/amlogic/mmc/amlsd.c
+++ b/drivers/amlogic/mmc/amlsd.c
@@ -88,12 +88,8 @@ void aml_mmc_ver_msg_show(void)
static int aml_cmd_invalid(struct mmc_host *mmc, struct mmc_request *mrq)
{
-#ifdef CONFIG_AMLOGIC_M8B_MMC
struct amlsd_platform *pdata = mmc_priv(mmc);
struct amlsd_host *host = pdata->host;
-#else
- struct amlsd_host *host = mmc_priv(mmc);
-#endif
unsigned long flags;
spin_lock_irqsave(&host->mrq_lock, flags);
@@ -107,12 +103,8 @@ static int aml_cmd_invalid(struct mmc_host *mmc, struct mmc_request *mrq)
#if 0
static int aml_rpmb_cmd_invalid(struct mmc_host *mmc, struct mmc_request *mrq)
{
-#ifdef CONFIG_AMLOGIC_M8B_MMC
struct amlsd_platform *pdata = mmc_priv(mmc);
struct amlsd_host *host = pdata->host;
-#else
- struct amlsd_host *host = mmc_priv(mmc);
-#endif
unsigned long flags;
spin_lock_irqsave(&host->mrq_lock, flags);
@@ -128,12 +120,7 @@ static int aml_rpmb_cmd_invalid(struct mmc_host *mmc, struct mmc_request *mrq)
int aml_check_unsupport_cmd(struct mmc_host *mmc, struct mmc_request *mrq)
{
-#ifdef CONFIG_AMLOGIC_M8B_MMC
struct amlsd_platform *pdata = mmc_priv(mmc);
-#else
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
-#endif
u32 opcode, arg;
opcode = mrq->cmd->opcode;
@@ -183,8 +170,8 @@ int aml_check_unsupport_cmd(struct mmc_host *mmc, struct mmc_request *mrq)
int aml_sd_voltage_switch(struct mmc_host *mmc, char signal_voltage)
{
#ifndef CONFIG_AMLOGIC_M8B_MMC
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
+ struct amlsd_host *host = pdata->host;
int ret = 0;
/* voltage is the same, return directly */
@@ -253,8 +240,7 @@ void aml_emmc_hw_reset(struct mmc_host *mmc)
aml_set_reg32_mask((hw_ctrl + (0x1 << 2)), (1<<9));
mdelay(1);
#else
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_platform *pdata = mmc_priv(mmc);
u32 ret;
if (!aml_card_type_mmc(pdata) || !pdata->hw_reset)
@@ -459,19 +445,17 @@ static struct pinctrl * __must_check aml_devm_pinctrl_get_select(
}
#endif /* SD_EMMC_PIN_CTRL */
-void of_amlsd_xfer_pre(struct mmc_host *mmc)
+void of_amlsd_xfer_pre(struct amlsd_platform *pdata)
{
-#ifdef CONFIG_AMLOGIC_M8B_MMC
- struct amlsd_platform *pdata = mmc_priv(mmc);
struct amlsd_host *host = pdata->host;
-#else
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
-#endif
+ struct mmc_host *mmc = pdata->mmc;
char pinctrl[30];
char *p = pinctrl;
int i, size = 0;
struct pinctrl *ppin;
+#if 0
+ int val = 0;
+#endif
size = sizeof(pinctrl);
#ifdef CONFIG_AMLOGIC_M8B_MMC
@@ -534,13 +518,30 @@ void of_amlsd_xfer_pre(struct mmc_host *mmc)
*/
mdelay(1);
}
+#if 0
+ if (!strcmp(host->pinctrl_name,
+ "sdio_all_pins")
+ || !strcmp(host->pinctrl_name,
+ "sdio_clk_cmd_pins")) {
+ val = readl(host->pinmux_base + (0x16 << 2));
+ val &= ~(1 << 4);
+ writel(val, host->pinmux_base + (0x16 << 2));
+ } else if (!strcmp(host->pinctrl_name,
+ "sd_all_pins")
+ || !strcmp(host->pinctrl_name,
+ "sd_clk_cmd_pins")) {
+ val = readl(host->pinmux_base + (0x13 << 2));
+ val &= ~(1 << 4);
+ writel(val, host->pinmux_base + (0x13 << 2));
+ }
+#endif
if (i == 100)
pr_err("CMD%d: get pinctrl %s fail.\n",
host->opcode, pinctrl);
}
}
-void of_amlsd_xfer_post(struct mmc_host *mmc)
+void of_amlsd_xfer_post(struct amlsd_platform *pdata)
{
}
@@ -575,13 +576,8 @@ void aml_snprint (char **pp, int *left_size, const char *fmt, ...)
void aml_cs_high(struct mmc_host *mmc) /* chip select high */
{
int ret;
-#ifdef CONFIG_AMLOGIC_M8B_MMC
struct amlsd_platform *pdata = mmc_priv(mmc);
struct amlsd_host *host = pdata->host;
-#else
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
-#endif
if ((mmc->ios.chip_select == MMC_CS_HIGH)
&& (pdata->gpio_dat3 != 0)) {
@@ -600,12 +596,7 @@ void aml_cs_high(struct mmc_host *mmc) /* chip select high */
void aml_cs_dont_care(struct mmc_host *mmc)
{
#if 0
-#ifdef CONFIG_AMLOGIC_M8B_MMC
struct amlsd_platform *pdata = mmc_priv(mmc);
-#else
- struct amlsd_host *host = mmc_priv(mmc);
- struct amlsd_platform *pdata = host->pdata;
-#endif
if ((mmc->ios.chip_select == MMC_CS_DONTCARE)
&& (pdata->gpio_dat3 != 0)
@@ -641,11 +632,12 @@ static int aml_is_card_insert(struct amlsd_platform *pdata)
}
#ifndef CONFIG_AMLOGIC_M8B_MMC
-static int aml_is_sdjtag(struct amlsd_host *host)
+static int aml_is_sdjtag(struct amlsd_platform *pdata)
{
int in = 0, i;
int high_cnt = 0, low_cnt = 0;
u32 vstat = 0;
+ struct amlsd_host *host = pdata->host;
struct sd_emmc_status *ista = (struct sd_emmc_status *)&vstat;
for (i = 0; ; i++) {
@@ -667,7 +659,7 @@ static int aml_is_sdjtag(struct amlsd_host *host)
return !in;
}
-static int aml_is_sduart(struct amlsd_host *host)
+static int aml_is_sduart(struct amlsd_platform *pdata)
{
#ifndef SD_EMMC_DEBUG_BOARD
return 0;
@@ -676,6 +668,7 @@ static int aml_is_sduart(struct amlsd_host *host)
int high_cnt = 0, low_cnt = 0;
struct pinctrl *pc;
u32 vstat = 0;
+ struct amlsd_host *host = pdata->host;
struct sd_emmc_status *ista = (struct sd_emmc_status *)&vstat;
mutex_lock(&host->pinmux_lock);
@@ -703,7 +696,7 @@ static int aml_is_sduart(struct amlsd_host *host)
}
/* int n=0; */
-static int aml_uart_switch(struct amlsd_host *host, bool on)
+static int aml_uart_switch(struct amlsd_platform *pdata, bool on)
{
#ifndef SD_EMMC_DEBUG_BOARD
return on;
@@ -713,7 +706,7 @@ static int aml_uart_switch(struct amlsd_host *host, bool on)
"sd_to_ao_uart_pins",
"ao_to_sd_uart_pins",
};
- struct amlsd_platform *pdata = host->pdata;
+ struct amlsd_host *host = pdata->host;
pdata->is_sduart = on;
mutex_lock(&host->pinmux_lock);
@@ -766,10 +759,11 @@ void jtag_select_sd(void)
}
#endif
-static void aml_jtag_switch_sd(struct amlsd_host *host)
+static void aml_jtag_switch_sd(struct amlsd_platform *pdata)
{
struct pinctrl *pc;
int i;
+ struct amlsd_host *host = pdata->host;
for (i = 0; i < 100; i++) {
mutex_lock(&host->pinmux_lock);
@@ -788,13 +782,14 @@ static void aml_jtag_switch_sd(struct amlsd_host *host)
}
}
-static void aml_jtag_switch_ao(struct amlsd_host *host)
+static void aml_jtag_switch_ao(struct amlsd_platform *pdata)
{
#ifndef SD_EMMC_DEBUG_BOARD
#else
struct pinctrl *pc;
int i;
+ struct amlsd_host *host = pdata->host;
for (i = 0; i < 100; i++) {
mutex_lock(&host->pinmux_lock);
@@ -842,22 +837,21 @@ int aml_sd_uart_detect(struct amlsd_platform *pdata)
return 0;
}
#else
-int aml_sd_uart_detect(struct amlsd_host *host)
+int aml_sd_uart_detect(struct amlsd_platform *pdata)
{
static bool is_jtag;
- struct amlsd_platform *pdata = host->pdata;
- struct mmc_host *mmc = host->mmc;
+ struct mmc_host *mmc = pdata->mmc;
if (aml_is_card_insert(pdata)) {
if (pdata->is_in)
return 1;
pdata->is_in = true;
pdata->gpio_cd_sta = true;
- if (aml_is_sduart(host)) {
- aml_uart_switch(host, 1);
+ if (aml_is_sduart(pdata)) {
+ aml_uart_switch(pdata, 1);
pr_info("Uart in\n");
mmc->caps &= ~MMC_CAP_4_BIT_DATA;
- if (aml_is_sdjtag(host)) {
- aml_jtag_switch_sd(host);
+ if (aml_is_sdjtag(pdata)) {
+ aml_jtag_switch_sd(pdata);
is_jtag = true;
pdata->is_in = false;
pr_info("JTAG in\n");
@@ -865,8 +859,8 @@ int aml_sd_uart_detect(struct amlsd_host *host)
}
} else {
pr_info("normal card in\n");
- aml_uart_switch(host, 0);
- aml_jtag_switch_ao(host);
+ aml_uart_switch(pdata, 0);
+ aml_jtag_switch_ao(pdata);
if (pdata->caps & MMC_CAP_4_BIT_DATA)
mmc->caps |= MMC_CAP_4_BIT_DATA;
}
@@ -884,8 +878,8 @@ int aml_sd_uart_detect(struct amlsd_host *host)
pdata->is_tuned = false;
if (mmc && mmc->card)
mmc_card_set_removed(mmc->card);
- aml_uart_switch(host, 0);
- aml_jtag_switch_ao(host);
+ aml_uart_switch(pdata, 0);
+ aml_jtag_switch_ao(pdata);
/* switch to 3.3V */
aml_sd_voltage_switch(mmc,
MMC_SIGNAL_VOLTAGE_330);
@@ -901,15 +895,9 @@ static int card_dealed;
#ifdef CARD_DETECT_IRQ
irqreturn_t aml_irq_cd_thread(int irq, void *data)
{
-#ifdef CONFIG_AMLOGIC_M8B_MMC
struct amlsd_platform *pdata = (struct amlsd_platform *)data;
struct mmc_host *mmc = pdata->mmc;
struct amlsd_host *host = pdata->host;
-#else
- struct amlsd_host *host = (struct amlsd_host *)data;
- struct amlsd_platform *pdata = host->pdata;
- struct mmc_host *mmc = host->mmc;
-#endif
int ret = 0;
mutex_lock(&pdata->in_out_lock);
@@ -918,11 +906,7 @@ irqreturn_t aml_irq_cd_thread(int irq, void *data)
mutex_unlock(&pdata->in_out_lock);
return IRQ_HANDLED;
}
-#ifdef CONFIG_AMLOGIC_M8B_MMC
ret = aml_sd_uart_detect(pdata);
-#else
- ret = aml_sd_uart_detect(host);
-#endif
if (ret == 1) {/* the same as the last*/
mutex_unlock(&pdata->in_out_lock);
return IRQ_HANDLED;
@@ -949,15 +933,9 @@ irqreturn_t aml_sd_irq_cd(int irq, void *dev_id)
#else
static int meson_cd_op(void *data)
{
-#ifdef CONFIG_AMLOGIC_M8B_MMC
struct amlsd_platform *pdata = (struct amlsd_platform *)data;
struct mmc_host *mmc = pdata->mmc;
struct amlsd_host *host = pdata->host;
-#else
- struct amlsd_host *host = (struct amlsd_host *)data;
- struct amlsd_platform *pdata = host->pdata;
- struct mmc_host *mmc = host->mmc;
-#endif
int ret = 0;
mutex_lock(&pdata->in_out_lock);
@@ -966,11 +944,7 @@ static int meson_cd_op(void *data)
mutex_unlock(&pdata->in_out_lock);
return 0;
}
-#ifdef CONFIG_AMLOGIC_M8B_MMC
ret = aml_sd_uart_detect(pdata);
-#else
- ret = aml_sd_uart_detect(host);
-#endif
if (ret == 1) {/* the same as the last*/
mutex_unlock(&pdata->in_out_lock);
return 0;
@@ -991,32 +965,18 @@ static int meson_cd_op(void *data)
void meson_mmc_cd_detect(struct work_struct *work)
{
-#ifdef CONFIG_AMLOGIC_M8B_MMC
struct amlsd_platform *pdata = container_of(
work, struct amlsd_platform, cd_detect.work);
-#else
- struct amlsd_host *host = container_of(
- work, struct amlsd_host, cd_work.work);
- struct amlsd_platform *pdata = host->pdata;
-#endif
int i = 0, ret = 0;
for (i = 0; i < 5; i++) {
ret = gpio_get_value(pdata->gpio_cd);
if (pdata->gpio_cd_sta != ret)
continue;
-#ifdef CONFIG_AMLOGIC_M8B_MMC
meson_cd_op(pdata);
-#else
- meson_cd_op(host);
-#endif
mdelay(1);
}
-#ifdef CONFIG_AMLOGIC_M8B_MMC
schedule_delayed_work(&pdata->cd_detect, 50);
-#else
- schedule_delayed_work(&host->cd_work, 50);
-#endif
}
#endif
diff --git a/drivers/amlogic/mmc/amlsd_of.c b/drivers/amlogic/mmc/amlsd_of.c
index ecc1632..fd836b7 100644
--- a/drivers/amlogic/mmc/amlsd_of.c
+++ b/drivers/amlogic/mmc/amlsd_of.c
@@ -126,16 +126,13 @@ int amlsd_get_platform_data(struct platform_device *pdev,
struct device_node *child;
u32 i, prop;
const char *str = "none";
- struct amlsd_host *host = NULL;
#ifdef CONFIG_AMLOGIC_M8B_MMC
of_node = pdev->dev.of_node;
- host = platform_get_drvdata(pdev);
#else
if (!mmc->parent)
return 0;
of_node = mmc->parent->of_node;
- host = mmc_priv(mmc);
#endif
if (of_node) {
child = of_node->child;
@@ -187,22 +184,16 @@ int amlsd_get_platform_data(struct platform_device *pdev,
prop, pdata->card_type);
SD_PARSE_U32_PROP_DEC(child, "tx_delay",
prop, pdata->tx_delay);
- if (host->data->chip_type > MMC_CHIP_M8B) {
- if (aml_card_type_mmc(pdata)) {
- /*tx_phase set default value first*/
- if (host->data->chip_type == MMC_CHIP_GXTVBB)
- pdata->tx_phase = 1;
- if (host->data->chip_type == MMC_CHIP_TXL)
- pdata->tx_delay = 3;
- SD_PARSE_U32_PROP_DEC(child, "tx_phase",
- prop, pdata->tx_phase);
- }
- if (aml_card_type_non_sdio(pdata)) {
- /*card in default value*/
- pdata->card_in_delay = 0;
- SD_PARSE_U32_PROP_DEC(child, "card_in_delay",
- prop, pdata->card_in_delay);
- }
+ if (aml_card_type_mmc(pdata)) {
+ /*tx_phase set default value first*/
+ SD_PARSE_U32_PROP_DEC(child, "tx_phase",
+ prop, pdata->tx_phase);
+ }
+ if (aml_card_type_non_sdio(pdata)) {
+ /*card in default value*/
+ pdata->card_in_delay = 0;
+ SD_PARSE_U32_PROP_DEC(child, "card_in_delay",
+ prop, pdata->card_in_delay);
}
SD_PARSE_GPIO_NUM_PROP(child, "hw_reset",
str, pdata->hw_reset);
diff --git a/include/linux/amlogic/aml_sd_emmc_internal.h b/include/linux/amlogic/aml_sd_emmc_internal.h
index 9d0d863..a63caf11 100644
--- a/include/linux/amlogic/aml_sd_emmc_internal.h
+++ b/include/linux/amlogic/aml_sd_emmc_internal.h
@@ -24,7 +24,8 @@ extern int meson_mmc_clk_init_v3(struct amlsd_host *host);
extern void meson_mmc_set_ios_v3(struct mmc_host *mmc, struct mmc_ios *ios);
-extern void aml_sd_emmc_set_buswidth(struct amlsd_host *host, u32 busw_ios);
+extern void aml_sd_emmc_set_buswidth(struct amlsd_platform *pdata,
+ u32 busw_ios);
extern int meson_mmc_request_done(struct mmc_host *mmc,
struct mmc_request *mrq);
@@ -40,7 +41,7 @@ extern int aml_sd_emmc_post_dma(struct amlsd_host *host,
extern u32 aml_sd_emmc_tuning_transfer(struct mmc_host *mmc,
u32 opcode, const u8 *blk_pattern, u8 *blk_test, u32 blksz);
-void aml_mmc_clk_switch_off(struct amlsd_host *host);
+void aml_mmc_clk_switch_off(struct amlsd_platform *pdata);
void aml_mmc_clk_switch(struct amlsd_host *host,
int clk_div, int clk_src_sel);
diff --git a/include/linux/amlogic/amlsd.h b/include/linux/amlogic/amlsd.h
index 96675f3..9e2e76a 100644
--- a/include/linux/amlogic/amlsd.h
+++ b/include/linux/amlogic/amlsd.h
@@ -42,6 +42,7 @@ extern const u8 tuning_blk_pattern_8bit[128];
#define DEBUG_SD_OF 0
#define MODULE_NAME "amlsd"
/* #define CARD_DETECT_IRQ 1 */
+#define AML_MMC_TDMA 1
#if 0
#define A0_GP_CFG0 (0xc8100240)
@@ -135,7 +136,6 @@ void aml_mmc_ver_msg_show(void);
extern int sdio_reset_comm(struct mmc_card *card);
#if 0
extern int storage_flag;
-
extern void aml_debug_print_buf(char *buf, int size);
extern int aml_buf_verify(int *buf, int blocks, int lba);
extern void aml_sdhc_init_debugfs(struct mmc_host *mmc);
@@ -143,24 +143,8 @@ extern void aml_sdio_init_debugfs(struct mmc_host *mmc);
extern void aml_sd_emmc_init_debugfs(struct mmc_host *mmc);
extern void aml_sdio_print_reg(struct amlsd_host *host);
extern void aml_sd_emmc_print_reg(struct amlsd_host *host);
-
extern int add_part_table(struct mtd_partition *part, unsigned int nr_part);
extern int add_emmc_partition(struct gendisk *disk);
-#endif
-#ifdef CONFIG_AMLOGIC_M8B_MMC
-void aml_sdhc_print_reg_(u32 *buf);
-extern void aml_sdhc_print_reg(struct amlsd_host *host);
-void aml_dbg_print_pinmux(void);
-
-extern size_t aml_sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
- void *buf, size_t buflen, int to_buffer);
-#endif
-int amlsd_get_platform_data(struct platform_device *pdev,
- struct amlsd_platform *pdata,
- struct mmc_host *mmc, u32 index);
-
-int of_amlsd_init(struct amlsd_platform *pdata);
-#if 0
int amlsd_get_reg_base(struct platform_device *pdev,
struct amlsd_host *host);
@@ -168,22 +152,6 @@ int amlsd_get_reg_base(struct platform_device *pdev,
int aml_sd_uart_detect(struct amlsd_platform *pdata);
void aml_sd_uart_detect_clr(struct amlsd_platform *pdata);
-#endif
-void of_amlsd_pwr_prepare(struct amlsd_platform *pdata);
-void of_amlsd_pwr_on(struct amlsd_platform *pdata);
-void of_amlsd_pwr_off(struct amlsd_platform *pdata);
-
-void of_amlsd_xfer_pre(struct mmc_host *mmc);
-void of_amlsd_xfer_post(struct mmc_host *mmc);
-
-#ifdef CARD_DETECT_IRQ
-void of_amlsd_irq_init(struct amlsd_platform *pdata);
-irqreturn_t aml_sd_irq_cd(int irq, void *dev_id);
-irqreturn_t aml_irq_cd_thread(int irq, void *data);
-#else
-void meson_mmc_cd_detect(struct work_struct *work);
-#endif
-#if 0
void aml_sduart_pre(struct amlsd_platform *pdata);
/* is eMMC/tSD exist */
@@ -196,18 +164,40 @@ void aml_dbg_verify_pull_up(struct amlsd_platform *pdata);
int aml_dbg_verify_pinmux(struct amlsd_platform *pdata);
#endif
#endif
+
+#ifdef CONFIG_AMLOGIC_M8B_MMC
+void aml_sdhc_print_reg_(u32 *buf);
+extern void aml_sdhc_print_reg(struct amlsd_host *host);
+void aml_dbg_print_pinmux(void);
+extern size_t aml_sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
+ void *buf, size_t buflen, int to_buffer);
+#endif
+
+#ifdef CARD_DETECT_IRQ
+void of_amlsd_irq_init(struct amlsd_platform *pdata);
+irqreturn_t aml_sd_irq_cd(int irq, void *dev_id);
+irqreturn_t aml_irq_cd_thread(int irq, void *data);
+#else
+void meson_mmc_cd_detect(struct work_struct *work);
+#endif
+
+int amlsd_get_platform_data(struct platform_device *pdev,
+ struct amlsd_platform *pdata,
+ struct mmc_host *mmc, u32 index);
+int of_amlsd_init(struct amlsd_platform *pdata);
+void of_amlsd_pwr_prepare(struct amlsd_platform *pdata);
+void of_amlsd_pwr_on(struct amlsd_platform *pdata);
+void of_amlsd_pwr_off(struct amlsd_platform *pdata);
+void of_amlsd_xfer_pre(struct amlsd_platform *pdata);
+void of_amlsd_xfer_post(struct amlsd_platform *pdata);
/* chip select high */
void aml_cs_high(struct mmc_host *mmc);
-
/* chip select don't care */
void aml_cs_dont_care(struct mmc_host *mmc);
-
void aml_snprint (char **pp, int *left_size, const char *fmt, ...);
-
int of_amlsd_ro(struct amlsd_platform *pdata);
int aml_sd_voltage_switch(struct mmc_host *mmc, char signal_voltage);
int aml_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios);
-
int aml_check_unsupport_cmd(struct mmc_host *mmc, struct mmc_request *mrq);
extern void aml_emmc_hw_reset(struct mmc_host *mmc);
#endif
diff --git a/include/linux/amlogic/sd.h b/include/linux/amlogic/sd.h
index c5002a7..b2410c9 100644
--- a/include/linux/amlogic/sd.h
+++ b/include/linux/amlogic/sd.h
@@ -39,7 +39,7 @@
#define CALI_PATTERN_OFFSET ((SZ_1M * (36 + 3)) / 512)
/* #define AML_RESP_WR_EXT */
/* pio to transfer data */
-#define CFG_SDEMMC_PIO (1)
+#define CFG_SDEMMC_PIO (0)
#ifdef AML_CALIBRATION
#define MAX_CALI_RETRY 3
@@ -236,8 +236,8 @@ struct amlsd_platform {
#ifdef CONFIG_AMLOGIC_M8B_MMC
unsigned int width;
unsigned int tune_phase; /* store tuning result */
- struct delayed_work cd_detect;
#endif
+ struct delayed_work cd_detect;
unsigned int caps;
unsigned int caps2;
unsigned int card_capacity;
@@ -249,9 +249,15 @@ struct amlsd_platform {
unsigned int clk2;
unsigned int clkc_w;
unsigned int ctrl;
+ unsigned int adj;
+ unsigned int dly1;
+ unsigned int dly2;
+ unsigned int intf3;
unsigned int clock;
/* signalling voltage (1.8V or 3.3V) */
unsigned char signal_voltage;
+ int bus_width;
+ int bl_len;
unsigned int low_burst;
struct mutex in_out_lock;
@@ -261,6 +267,7 @@ struct amlsd_platform {
unsigned int gpio_cd_sta;
unsigned int gpio_power;
unsigned int power_level;
+
unsigned int auto_clk_close;
unsigned int vol_switch;
unsigned int vol_switch_18;
@@ -332,8 +339,8 @@ struct amlsd_platform {
unsigned int nr_parts;
struct resource *resource;
- void (*xfer_pre)(struct mmc_host *mmc);
- void (*xfer_post)(struct mmc_host *mmc);
+ void (*xfer_pre)(struct amlsd_platform *pdata);
+ void (*xfer_post)(struct amlsd_platform *pdata);
int (*port_init)(struct amlsd_platform *pdata);
int (*cd)(struct amlsd_platform *pdata);
@@ -401,6 +408,8 @@ struct amlsd_host {
char is_tunning;
char is_timming;
char tuning_mode;
+ char cur_dev[32];
+ unsigned int val_f;
unsigned int irq;
unsigned int irq_in;
unsigned int irq_out;
@@ -410,7 +419,6 @@ struct amlsd_host {
int sdio_irqen;
unsigned int error_bak;
struct delayed_work timeout;
- struct delayed_work cd_work;
struct class debug;
unsigned int send;
@@ -443,11 +451,12 @@ struct amlsd_host {
struct mmc_request *mrq2;
spinlock_t mrq_lock;
struct mutex pinmux_lock;
+ struct mutex pdata_lock;
+ struct completion drv_completion;
int cmd_is_stop;
enum aml_mmc_waitfor xfer_step;
enum aml_mmc_waitfor xfer_step_prev;
- int bus_width;
int port;
int locked;
bool is_gated;