From 7808c86161acbb42f7e23767c4d7b7b40b8b13c7 Mon Sep 17 00:00:00 2001 From: Nan Li Date: Tue, 3 Apr 2018 19:16:06 +0800 Subject: [PATCH] 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 --- arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts | 19 +- arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts | 18 +- arch/arm64/boot/dts/amlogic/mesong12a.dtsi | 126 ++++++- drivers/amlogic/mmc/aml_sd_emmc.c | 403 +++++++++++++++-------- drivers/amlogic/mmc/aml_sd_emmc_v3.c | 144 +++++--- drivers/amlogic/mmc/aml_sdhc_m8.c | 4 +- drivers/amlogic/mmc/aml_sdio.c | 4 +- drivers/amlogic/mmc/amlsd.c | 132 +++----- drivers/amlogic/mmc/amlsd_of.c | 29 +- include/linux/amlogic/aml_sd_emmc_internal.h | 5 +- include/linux/amlogic/amlsd.h | 64 ++-- include/linux/amlogic/sd.h | 21 +- 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; -- 2.7.4