sdio: slove sdio & emmc dealocks on m8b

PD#141217: slove sdio & emmc dealocks on m8b.
1) Add a semaphore to avoid emmc deadlocks occur and sdio
when they shared the same controller.
2) remove sd ro of dts.
3) add m400 dts support.

Change-Id: I5fe0a76517a341313513e5abdbc16366724cbbe9
Signed-off-by: Nan Li <nan.li@amlogic.com>
This commit is contained in:
Nan Li
2017-05-23 15:03:35 +08:00
committed by Jianxin Pan
parent 2342337e4a
commit b559679884
5 changed files with 137 additions and 92 deletions

View File

@@ -499,26 +499,17 @@
};
sdhc_emmc_clk_cmd_pins:sdhc_emmc_clk_cmd_pins {
mux1 {
mux {
groups = "sdxc_clk_c",
"sdxc_cmd_c";
function = "sdxc_c";
input-enable;
bias-pull-up;
};
mux2 {
groups = "GPIOX_0",
"GPIOX_1",
"GPIOX_2",
"GPIOX_3",
"GPIOX_8",
"GPIOX_9";
function = "gpio";
};
};
sdhc_emmc_all_pins:sdhc_emmc_all_pins {
mux1 {
mux {
groups = "sdxc_d0_c",
"sdxc_d13_c",
"sdxc_d47_c",
@@ -528,15 +519,6 @@
input-enable;
bias-pull-up;
};
mux2 {
groups = "GPIOX_0",
"GPIOX_1",
"GPIOX_2",
"GPIOX_3",
"GPIOX_8",
"GPIOX_9";
function = "gpio";
};
};
sdhc_sd_clk_cmd_pins:sdhc_sd_clk_cmd_pins {
@@ -562,31 +544,17 @@
};
sdhc_sdio_clk_cmd_pins:sdhc_sdio_clk_cmd_pins {
mux1 {
mux {
groups = "sdxc_clk_a",
"sdxc_cmd_a";
function = "sdxc_a";
input-enable;
bias-pull-up;
};
mux2 {
groups = "BOOT_0",
"BOOT_1",
"BOOT_2",
"BOOT_3",
"BOOT_4",
"BOOT_5",
"BOOT_6",
"BOOT_7",
"BOOT_8",
"BOOT_10";
function = "gpio";
};
};
sdhc_sdio_all_pins:sdhc_sdio_all_pins {
mux1 {
mux {
groups = "sdxc_d0_1_a",
"sdxc_d13_1_a",
"sdxc_clk_a",
@@ -595,19 +563,6 @@
input-enable;
bias-pull-up;
};
mux2 {
groups = "BOOT_0",
"BOOT_1",
"BOOT_2",
"BOOT_3",
"BOOT_4",
"BOOT_5",
"BOOT_6",
"BOOT_7",
"BOOT_8",
"BOOT_10";
function = "gpio";
};
};
uart_a_pins: uart_a_pins {

View File

@@ -112,7 +112,7 @@
gpio_dat3 = <&gpio CARD_4 GPIO_ACTIVE_HIGH>;
jtag_pin = <&gpio CARD_0 GPIO_ACTIVE_HIGH>;
gpio_cd = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
gpio_ro = <&gpio GPIODV_25 GPIO_ACTIVE_HIGH>;
/*gpio_ro = <&gpio GPIODV_25 GPIO_ACTIVE_HIGH>;*/
card_type = <5>;
/* 0:unknown,
* 1:mmc card(include eMMC),
@@ -559,4 +559,95 @@
&i2c_ao {
status = "ok";
};
&pinctrl_cbus {
sdhc_emmc_clk_cmd_pins:sdhc_emmc_clk_cmd_pins {
mux {
groups = "sdxc_clk_c",
"sdxc_cmd_c";
function = "sdxc_c";
input-enable;
bias-pull-up;
};
mux1 {
groups = "GPIOX_0",
"GPIOX_1",
"GPIOX_2",
"GPIOX_3",
"GPIOX_8",
"GPIOX_9";
function = "gpio";
};
};
sdhc_emmc_all_pins:sdhc_emmc_all_pins {
mux {
groups = "sdxc_d0_c",
"sdxc_d13_c",
"sdxc_d47_c",
"sdxc_clk_c",
"sdxc_cmd_c";
function = "sdxc_c";
input-enable;
bias-pull-up;
};
mux1 {
groups = "GPIOX_0",
"GPIOX_1",
"GPIOX_2",
"GPIOX_3",
"GPIOX_8",
"GPIOX_9";
function = "gpio";
};
};
sdhc_sdio_clk_cmd_pins:sdhc_sdio_clk_cmd_pins {
mux {
groups = "sdxc_clk_a",
"sdxc_cmd_a";
function = "sdxc_a";
input-enable;
bias-pull-up;
};
mux1 {
groups = "BOOT_0",
"BOOT_1",
"BOOT_2",
"BOOT_3",
"BOOT_4",
"BOOT_5",
"BOOT_6",
"BOOT_7",
"BOOT_8",
"BOOT_10";
function = "gpio";
};
};
sdhc_sdio_all_pins:sdhc_sdio_all_pins {
mux {
groups = "sdxc_d0_1_a",
"sdxc_d13_1_a",
"sdxc_clk_a",
"sdxc_cmd_a";
function = "sdxc_a";
input-enable;
bias-pull-up;
};
mux1 {
groups = "BOOT_0",
"BOOT_1",
"BOOT_2",
"BOOT_3",
"BOOT_4",
"BOOT_5",
"BOOT_6",
"BOOT_7",
"BOOT_8",
"BOOT_10";
function = "gpio";
};
};
};

View File

@@ -94,7 +94,7 @@
gpio_dat3 = <&gpio CARD_4 GPIO_ACTIVE_HIGH>;
jtag_pin = <&gpio CARD_0 GPIO_ACTIVE_HIGH>;
gpio_cd = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
gpio_ro = <&gpio GPIODV_25 GPIO_ACTIVE_HIGH>;
/*gpio_ro = <&gpio GPIODV_25 GPIO_ACTIVE_HIGH>;*/
card_type = <5>;
/* 0:unknown,
* 1:mmc card(include eMMC),
@@ -110,7 +110,7 @@
sdhc {
compatible = "amlogic, aml_sdhc";
dev_name = "aml_sdhc.0";
status = "disable";
status = "okay";
interrupts = <0 78 1>;
reg = <0xc1108e00 0x3c>;
pinctrl-names = "sdhc_sd_clk_cmd_pins",
@@ -129,42 +129,6 @@
<&clkc CLKID_FCLK_DIV3>;
clock-names = "core", "div3";
emmc {
status = "okay";
port = <5>;
/* 0:sdio_a,
* 1:sdio_b,
* 2:sdio_c,
* 3:sdhc_a,
* 4:sdhc_b,
* 5:sdhc_c
*/
pinname = "emmc";
ocr_avail = <0x00200080>;
/* 3.3:0x200000, 1.8+3.3:0x00200080 */
caps = "MMC_CAP_8_BIT_DATA",
"MMC_CAP_MMC_HIGHSPEED",
"MMC_CAP_SD_HIGHSPEED",
"MMC_CAP_NONREMOVABLE",
"MMC_CAP_ERASE",
"MMC_CAP_HW_RESET";
caps2 = "MMC_CAP2_HS200_1_8V_SDR";
f_min = <300000>;
f_max = <100000000>;
max_req_size = <0x20000>; /* 128KB */
gpio_dat3 = <&gpio BOOT_3 GPIO_ACTIVE_HIGH>;
hw_reset = <&gpio BOOT_9 GPIO_ACTIVE_HIGH>;
card_type = <1>;
/* 0:unknown,
* 1:mmc card(include eMMC),
* 2:sd card(include tSD),
* 3:sdio device(ie:sdio-wifi),
* 4:SD combo (IO+mem) card,
* 5:NON sdio device(means sd/mmc card),
* other:reserved
*/
};
sdio {
status = "okay";
port = <3>;
@@ -581,4 +545,3 @@
&i2c_ao {
status = "ok";
};

View File

@@ -54,7 +54,8 @@ unsigned int timeout_cnt;
static unsigned int sdhc_error_flag;
static unsigned int sdhc_debug_flag;
static int sdhc_err_bak;
static struct semaphore sdhc_sema;
wait_queue_head_t mmc_req_wait_q;
static int wait_req_flag;
static void aml_sdhc_send_stop(struct amlsd_host *host);
static void aml_sdhc_emmc_clock_switch_on(struct amlsd_platform *pdata);
@@ -875,6 +876,8 @@ void aml_sdhc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
}
aml_sdhc_clk_switch_off(host);
mmc_request_done(host->mmc, mrq);
wake_up_interruptible(&mmc_req_wait_q);
wait_req_flag = 0;
}
char *msg_err[] = {
@@ -1031,6 +1034,8 @@ static void aml_sdhc_timeout(struct work_struct *work)
if (host->xfer_step == XFER_FINISHED) {
spin_unlock_irqrestore(&host->mrq_lock, flags);
sdhc_err("timeout after xfer finished\n");
wake_up_interruptible(&mmc_req_wait_q);
wait_req_flag = 0;
return;
}
@@ -1049,7 +1054,8 @@ static void aml_sdhc_timeout(struct work_struct *work)
mmc_hostname(host->mmc),
host->mrq->cmd->opcode, host->xfer_step,
time_start_cnt, timeout_cnt);
up(&sdhc_sema);
wake_up_interruptible(&mmc_req_wait_q);
wait_req_flag = 0;
return;
}
timeout_handle:
@@ -1125,6 +1131,7 @@ void aml_sdhc_request(struct mmc_host *mmc, struct mmc_request *mrq)
unsigned long flags;
unsigned int timeout;
u32 tuning_opcode;
long status;
WARN_ON(!mmc);
WARN_ON(!mrq);
@@ -1132,8 +1139,21 @@ void aml_sdhc_request(struct mmc_host *mmc, struct mmc_request *mrq)
pdata = mmc_priv(mmc);
host = (void *)pdata->host;
if (aml_check_unsupport_cmd(mmc, mrq))
status = wait_event_interruptible_timeout(mmc_req_wait_q,
wait_req_flag == 0, WAIT_UNTIL_REQ_DONE);
if (status == 0) {
mmc_request_done(mmc, mrq);
sdhc_err("SDHC CMD conflict!\n");
return;
} else if (status < 0)
return;
wait_req_flag = 1;
if (aml_check_unsupport_cmd(mmc, mrq)) {
wake_up_interruptible(&mmc_req_wait_q);
wait_req_flag = 0;
return;
}
aml_sdhc_emmc_clock_switch_on(pdata);
/* only for SDCARD */
if (!pdata->is_in || (!host->init_flag && aml_card_type_sd(pdata))) {
@@ -1142,14 +1162,27 @@ void aml_sdhc_request(struct mmc_host *mmc, struct mmc_request *mrq)
mrq->cmd->retries = 0;
spin_unlock_irqrestore(&host->mrq_lock, flags);
mmc_request_done(mmc, mrq);
wake_up_interruptible(&mmc_req_wait_q);
wait_req_flag = 0;
return;
}
if (pdata->need_retuning && mmc->card) {
wake_up_interruptible(&mmc_req_wait_q);
wait_req_flag = 0;
/* eMMC uses cmd21 but sd and sdio use cmd19 */
tuning_opcode = (mmc->card->type == MMC_TYPE_MMC) ?
MMC_SEND_TUNING_BLOCK_HS200 : MMC_SEND_TUNING_BLOCK;
aml_sdhc_execute_tuning(mmc, tuning_opcode);
status = wait_event_interruptible_timeout(mmc_req_wait_q,
wait_req_flag == 0, WAIT_UNTIL_REQ_DONE);
if (status == 0) {
mmc_request_done(mmc, mrq);
sdhc_err(" SDHC CMD conflict in tuning\n");
return;
} else if (status < 0)
return;
wait_req_flag = 1;
}
aml_sdhc_disable_imask(host, SDHC_ICTL_ALL);
@@ -2230,6 +2263,7 @@ static int aml_sdhc_probe(struct platform_device *pdev)
host->dev = &pdev->dev;
platform_set_drvdata(pdev, host);
aml_sdhc_reg_init(host);
init_waitqueue_head(&mmc_req_wait_q);
/* for (i = 0; i < MMC_MAX_DEVICE; i++) {*/
for (i = 0; i < 2; i++) {

View File

@@ -160,6 +160,8 @@ extern const u8 tuning_blk_pattern_8bit[128];
#define SD_CAPS(a, b) { .caps = a, .name = b }
#define WAIT_UNTIL_REQ_DONE msecs_to_jiffies(10000)
struct sd_caps {
unsigned int caps;
const char *name;