Skip to content

Commit b70721f

Browse files
AngeloGioacchino Del RegnoUlf Hansson
authored andcommitted
mmc: mtk-sd: Aggregate R/W for top_base iospace case where possible
In case the controller uses the top_base iospace, most register read/writes can be changed from multiple RWs to a single read and a single write. Where possible, and where it makes sense, aggregate the multiple reads and writes to just one. Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20250325110701.52623-5-angelogioacchino.delregno@collabora.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 1649904 commit b70721f

1 file changed

Lines changed: 28 additions & 24 deletions

File tree

drivers/mmc/host/mtk-sd.c

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,18 +1975,19 @@ static void msdc_init_hw(struct msdc_host *host)
19751975

19761976
if (host->dev_comp->data_tune) {
19771977
if (host->top_base) {
1978-
sdr_set_bits(host->top_base + EMMC_TOP_CONTROL,
1979-
PAD_DAT_RD_RXDLY_SEL);
1980-
sdr_clr_bits(host->top_base + EMMC_TOP_CONTROL,
1981-
DATA_K_VALUE_SEL);
1982-
sdr_set_bits(host->top_base + EMMC_TOP_CMD,
1983-
PAD_CMD_RD_RXDLY_SEL);
1978+
u32 top_ctl_val = readl(host->top_base + EMMC_TOP_CONTROL);
1979+
u32 top_cmd_val = readl(host->top_base + EMMC_TOP_CMD);
1980+
1981+
top_cmd_val |= PAD_CMD_RD_RXDLY_SEL;
1982+
top_ctl_val |= PAD_DAT_RD_RXDLY_SEL;
1983+
top_ctl_val &= ~DATA_K_VALUE_SEL;
19841984
if (host->tuning_step > PAD_DELAY_HALF) {
1985-
sdr_set_bits(host->top_base + EMMC_TOP_CONTROL,
1986-
PAD_DAT_RD_RXDLY2_SEL);
1987-
sdr_set_bits(host->top_base + EMMC_TOP_CMD,
1988-
PAD_CMD_RD_RXDLY2_SEL);
1985+
top_cmd_val |= PAD_CMD_RD_RXDLY2_SEL;
1986+
top_ctl_val |= PAD_DAT_RD_RXDLY2_SEL;
19891987
}
1988+
1989+
writel(top_ctl_val, host->top_base + EMMC_TOP_CONTROL);
1990+
writel(top_cmd_val, host->top_base + EMMC_TOP_CMD);
19901991
} else {
19911992
sdr_set_bits(host->base + tune_reg,
19921993
MSDC_PAD_TUNE_RD_SEL |
@@ -2196,15 +2197,17 @@ static inline void msdc_set_cmd_delay(struct msdc_host *host, u32 value)
21962197
u32 tune_reg = host->dev_comp->pad_tune_reg;
21972198

21982199
if (host->top_base) {
2200+
u32 regval = readl(host->top_base + EMMC_TOP_CMD);
2201+
2202+
regval &= ~(PAD_CMD_RXDLY | PAD_CMD_RXDLY2);
2203+
21992204
if (value < PAD_DELAY_HALF) {
2200-
sdr_set_field(host->top_base + EMMC_TOP_CMD, PAD_CMD_RXDLY, value);
2201-
sdr_set_field(host->top_base + EMMC_TOP_CMD, PAD_CMD_RXDLY2, 0);
2205+
regval |= FIELD_PREP(PAD_CMD_RXDLY, value);
22022206
} else {
2203-
sdr_set_field(host->top_base + EMMC_TOP_CMD, PAD_CMD_RXDLY,
2204-
PAD_DELAY_HALF - 1);
2205-
sdr_set_field(host->top_base + EMMC_TOP_CMD, PAD_CMD_RXDLY2,
2206-
value - PAD_DELAY_HALF);
2207+
regval |= FIELD_PREP(PAD_CMD_RXDLY, PAD_DELAY_HALF - 1);
2208+
regval |= FIELD_PREP(PAD_CMD_RXDLY2, value - PAD_DELAY_HALF);
22072209
}
2210+
writel(regval, host->top_base + EMMC_TOP_CMD);
22082211
} else {
22092212
if (value < PAD_DELAY_HALF) {
22102213
sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRDLY, value);
@@ -2224,17 +2227,18 @@ static inline void msdc_set_data_delay(struct msdc_host *host, u32 value)
22242227
u32 tune_reg = host->dev_comp->pad_tune_reg;
22252228

22262229
if (host->top_base) {
2230+
u32 regval = readl(host->top_base + EMMC_TOP_CONTROL);
2231+
2232+
regval &= ~(PAD_DAT_RD_RXDLY | PAD_DAT_RD_RXDLY2);
2233+
22272234
if (value < PAD_DELAY_HALF) {
2228-
sdr_set_field(host->top_base + EMMC_TOP_CONTROL,
2229-
PAD_DAT_RD_RXDLY, value);
2230-
sdr_set_field(host->top_base + EMMC_TOP_CONTROL,
2231-
PAD_DAT_RD_RXDLY2, 0);
2235+
regval |= FIELD_PREP(PAD_DAT_RD_RXDLY, value);
2236+
regval |= FIELD_PREP(PAD_DAT_RD_RXDLY2, value);
22322237
} else {
2233-
sdr_set_field(host->top_base + EMMC_TOP_CONTROL,
2234-
PAD_DAT_RD_RXDLY, PAD_DELAY_HALF - 1);
2235-
sdr_set_field(host->top_base + EMMC_TOP_CONTROL,
2236-
PAD_DAT_RD_RXDLY2, value - PAD_DELAY_HALF);
2238+
regval |= FIELD_PREP(PAD_DAT_RD_RXDLY, PAD_DELAY_HALF - 1);
2239+
regval |= FIELD_PREP(PAD_DAT_RD_RXDLY2, value - PAD_DELAY_HALF);
22372240
}
2241+
writel(regval, host->top_base + EMMC_TOP_CONTROL);
22382242
} else {
22392243
if (value < PAD_DELAY_HALF) {
22402244
sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_DATRRDLY, value);

0 commit comments

Comments
 (0)