Skip to content

Commit

Permalink
Merge tag 'mmc-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/ulfh/mmc

Pull MMC updates from Ulf Hansson:
 "MMC core:
   - Don't force a retune before eMMC RPMB switch
   - Add optional HS400 tuning in HS400es initialization
   - Add a sysfs node to for write-protect-group-size
   - Add re-tuning test to the mmc-test module
   - Use mrq.sbc to support close-ended ioctl requests

  MMC host:
   - mmci: Add support for SDIO in-band irqs for the stm32 variant
   - mmc_spi: Remove broken support custom DMA mapped buffers
   - mtk-sd: Improve and extend the support for tunings
   - renesas_sdhi: Document support for the RZ/Five variant
   - sdhci_am654: Drop support for the ti,otap-del-sel DT property
   - sdhci-brcmstb: Add support for the brcm 74165b0 variant
   - sdhci-msm: Add compatibles for IPQ4019 and IPQ8074
   - sdhci-of-dwcmshc: Add support for the T-Head TH1520 variant
   - sdhci-xenon: Add support for the Marvell ac5 variant"

* tag 'mmc-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (27 commits)
  mmc: xenon: Add ac5 support via bounce buffer
  dt-bindings: mmc: add Marvell ac5
  mmc: sdhci-brcmstb: add new sdhci reset sequence for brcm 74165b0
  dt-bindings: mmc: brcm,sdhci-brcmstb: Add support for 74165b0
  mmc: core: Do not force a retune before RPMB switch
  mmc: core: Add HS400 tuning in HS400es initialization
  mmc: sdhci_omap: Fix TI SoC dependencies
  mmc: sdhci_am654: Fix TI SoC dependencies
  mmc: core: Add wp_grp_size sysfs node
  mmc: mmc_test: Add re-tuning test
  mmc: mmc_spi: remove custom DMA mapped buffers
  dt-bindings: mmc: sdhci-msm: document dedicated IPQ4019 and IPQ8074
  dt-bindings: mmc: synopsys-dw-mshc: add iommus for Intel SocFPGA
  mmc: mtk-sd: Extend number of tuning steps
  dt-bindings: mmc: mtk-sd: add tuning steps related property
  mmc: sdhci-omap: don't misuse kernel-doc marker
  mmc: mtk-sd: Increase the verbosity of msdc_track_cmd_data
  mmc: core: Use mrq.sbc in close-ended ffu
  mmc: sdhci_am654: Drop lookup for deprecated ti,otap-del-sel
  mmc: sdhci-of-dwcmshc: Use logical OR instead of bitwise OR in dwcmshc_probe()
  ...
  • Loading branch information
Linus Torvalds committed Jan 12, 2024
2 parents 0c4b09c + 5d40213 commit 2007758
Show file tree
Hide file tree
Showing 28 changed files with 771 additions and 319 deletions.
8 changes: 4 additions & 4 deletions Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ examples:
interrupt-parent = <&gic>;
interrupts = <0 48 4>;
reg = <0xff160000 0x1000>;
clocks = <&clk200>, <&clk200>;
clock-names = "clk_xin", "clk_ahb";
clocks = <&clk200>, <&clk200>, <&clk1200>;
clock-names = "clk_xin", "clk_ahb", "gate";
clock-output-names = "clk_out_sd0", "clk_in_sd0";
#clock-cells = <1>;
clk-phase-sd-hs = <63>, <72>;
Expand All @@ -239,8 +239,8 @@ examples:
interrupt-parent = <&gic>;
interrupts = <0 126 4>;
reg = <0xf1040000 0x10000>;
clocks = <&clk200>, <&clk200>;
clock-names = "clk_xin", "clk_ahb";
clocks = <&clk200>, <&clk200>, <&clk1200>;
clock-names = "clk_xin", "clk_ahb", "gate";
clock-output-names = "clk_out_sd0", "clk_in_sd0";
#clock-cells = <1>;
clk-phase-sd-hs = <132>, <60>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ properties:
- const: brcm,sdhci-brcmstb
- items:
- enum:
- brcm,bcm74165b0-sdhci
- brcm,bcm7445-sdhci
- const: brcm,sdhci-brcmstb
- items:
- enum:
- brcm,bcm7425-sdhci
- const: brcm,sdhci-brcmstb

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ properties:
- marvell,armada-ap806-sdhci

- items:
- const: marvell,armada-ap807-sdhci
- enum:
- marvell,armada-ap807-sdhci
- marvell,ac5-sdhci
- const: marvell,armada-ap806-sdhci

- items:
Expand Down
9 changes: 9 additions & 0 deletions Documentation/devicetree/bindings/mmc/mtk-sd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ properties:
minimum: 0
maximum: 7

mediatek,tuning-step:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Some SoCs need extend tuning step for better delay value to avoid CRC issue.
If not present, default tuning step is 32. For eMMC and SD, this can yield
satisfactory calibration results in most cases.
enum: [32, 64]
default: 32

resets:
maxItems: 1

Expand Down
2 changes: 1 addition & 1 deletion Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ properties:
- renesas,sdhi-r8a77980 # R-Car V3H
- renesas,sdhi-r8a77990 # R-Car E3
- renesas,sdhi-r8a77995 # R-Car D3
- renesas,sdhi-r9a07g043 # RZ/G2UL
- renesas,sdhi-r9a07g043 # RZ/G2UL and RZ/Five
- renesas,sdhi-r9a07g044 # RZ/G2{L,LC}
- renesas,sdhi-r9a07g054 # RZ/V2L
- renesas,sdhi-r9a08g045 # RZ/G3S
Expand Down
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/mmc/sdhci-msm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ properties:
- items:
- enum:
- qcom,apq8084-sdhci
- qcom,ipq4019-sdhci
- qcom,ipq8074-sdhci
- qcom,msm8226-sdhci
- qcom,msm8953-sdhci
- qcom,msm8974-sdhci
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ properties:
- rockchip,rk3568-dwcmshc
- rockchip,rk3588-dwcmshc
- snps,dwcmshc-sdhci
- thead,th1520-dwcmshc

reg:
maxItems: 1
Expand Down
4 changes: 4 additions & 0 deletions Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ properties:
- const: biu
- const: ciu

iommus:
maxItems: 1

altr,sysmgr-syscon:
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
Expand Down Expand Up @@ -62,6 +65,7 @@ allOf:
altr,sysmgr-syscon: true
else:
properties:
iommus: false
altr,sysmgr-syscon: false

required:
Expand Down
46 changes: 43 additions & 3 deletions drivers/mmc/core/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ struct mmc_blk_ioc_data {
struct mmc_ioc_cmd ic;
unsigned char *buf;
u64 buf_bytes;
unsigned int flags;
#define MMC_BLK_IOC_DROP BIT(0) /* drop this mrq */
#define MMC_BLK_IOC_SBC BIT(1) /* use mrq.sbc */

struct mmc_rpmb_data *rpmb;
};

Expand Down Expand Up @@ -465,7 +469,7 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr,
}

static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
struct mmc_blk_ioc_data *idata)
struct mmc_blk_ioc_data **idatas, int i)
{
struct mmc_command cmd = {}, sbc = {};
struct mmc_data data = {};
Expand All @@ -475,10 +479,18 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
unsigned int busy_timeout_ms;
int err;
unsigned int target_part;
struct mmc_blk_ioc_data *idata = idatas[i];
struct mmc_blk_ioc_data *prev_idata = NULL;

if (!card || !md || !idata)
return -EINVAL;

if (idata->flags & MMC_BLK_IOC_DROP)
return 0;

if (idata->flags & MMC_BLK_IOC_SBC)
prev_idata = idatas[i - 1];

/*
* The RPMB accesses comes in from the character device, so we
* need to target these explicitly. Else we just target the
Expand Down Expand Up @@ -532,14 +544,16 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
return err;
}

if (idata->rpmb) {
if (idata->rpmb || prev_idata) {
sbc.opcode = MMC_SET_BLOCK_COUNT;
/*
* We don't do any blockcount validation because the max size
* may be increased by a future standard. We just copy the
* 'Reliable Write' bit here.
*/
sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31));
if (prev_idata)
sbc.arg = prev_idata->ic.arg;
sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
mrq.sbc = &sbc;
}
Expand All @@ -557,6 +571,15 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
mmc_wait_for_req(card->host, &mrq);
memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));

if (prev_idata) {
memcpy(&prev_idata->ic.response, sbc.resp, sizeof(sbc.resp));
if (sbc.error) {
dev_err(mmc_dev(card->host), "%s: sbc error %d\n",
__func__, sbc.error);
return sbc.error;
}
}

if (cmd.error) {
dev_err(mmc_dev(card->host), "%s: cmd error %d\n",
__func__, cmd.error);
Expand Down Expand Up @@ -1034,6 +1057,20 @@ static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type)
md->reset_done &= ~type;
}

static void mmc_blk_check_sbc(struct mmc_queue_req *mq_rq)
{
struct mmc_blk_ioc_data **idata = mq_rq->drv_op_data;
int i;

for (i = 1; i < mq_rq->ioc_count; i++) {
if (idata[i - 1]->ic.opcode == MMC_SET_BLOCK_COUNT &&
mmc_op_multi(idata[i]->ic.opcode)) {
idata[i - 1]->flags |= MMC_BLK_IOC_DROP;
idata[i]->flags |= MMC_BLK_IOC_SBC;
}
}
}

/*
* The non-block commands come back from the block layer after it queued it and
* processed it with all other requests and then they get issued in this
Expand Down Expand Up @@ -1061,11 +1098,14 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
if (ret)
break;
}

mmc_blk_check_sbc(mq_rq);

fallthrough;
case MMC_DRV_OP_IOCTL_RPMB:
idata = mq_rq->drv_op_data;
for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) {
ret = __mmc_blk_ioctl_cmd(card, md, idata[i]);
ret = __mmc_blk_ioctl_cmd(card, md, idata, i);
if (ret)
break;
}
Expand Down
3 changes: 1 addition & 2 deletions drivers/mmc/core/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,12 @@ void mmc_retune_enable(struct mmc_host *host)

/*
* Pause re-tuning for a small set of operations. The pause begins after the
* next command and after first doing re-tuning.
* next command.
*/
void mmc_retune_pause(struct mmc_host *host)
{
if (!host->retune_paused) {
host->retune_paused = 1;
mmc_retune_needed(host);
mmc_retune_hold(host);
}
}
Expand Down
30 changes: 22 additions & 8 deletions drivers/mmc/core/mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,17 @@ static void mmc_set_erase_size(struct mmc_card *card)
mmc_init_erase(card);
}


static void mmc_set_wp_grp_size(struct mmc_card *card)
{
if (card->ext_csd.erase_group_def & 1)
card->wp_grp_size = card->ext_csd.hc_erase_size *
card->ext_csd.raw_hc_erase_gap_size;
else
card->wp_grp_size = card->csd.erase_size *
(card->csd.wp_grp_size + 1);
}

/*
* Given a 128-bit response, decode to our card CSD structure.
*/
Expand Down Expand Up @@ -186,6 +197,7 @@ static int mmc_decode_csd(struct mmc_card *card)
b = UNSTUFF_BITS(resp, 37, 5);
csd->erase_size = (a + 1) * (b + 1);
csd->erase_size <<= csd->write_blkbits - 9;
csd->wp_grp_size = UNSTUFF_BITS(resp, 32, 5);
}

return 0;
Expand Down Expand Up @@ -613,11 +625,6 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
} else {
card->ext_csd.data_tag_unit_size = 0;
}

card->ext_csd.max_packed_writes =
ext_csd[EXT_CSD_MAX_PACKED_WRITES];
card->ext_csd.max_packed_reads =
ext_csd[EXT_CSD_MAX_PACKED_READS];
} else {
card->ext_csd.data_sector_size = 512;
}
Expand Down Expand Up @@ -790,6 +797,7 @@ MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9);
MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9);
MMC_DEV_ATTR(wp_grp_size, "%u\n", card->wp_grp_size << 9);
MMC_DEV_ATTR(ffu_capable, "%d\n", card->ext_csd.ffu_capable);
MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
Expand Down Expand Up @@ -850,6 +858,7 @@ static struct attribute *mmc_std_attrs[] = {
&dev_attr_date.attr,
&dev_attr_erase_size.attr,
&dev_attr_preferred_erase_size.attr,
&dev_attr_wp_grp_size.attr,
&dev_attr_fwrev.attr,
&dev_attr_ffu_capable.attr,
&dev_attr_hwrev.attr,
Expand Down Expand Up @@ -1764,7 +1773,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
mmc_set_erase_size(card);
}
}

mmc_set_wp_grp_size(card);
/*
* Ensure eMMC user default partition is enabled
*/
Expand Down Expand Up @@ -1822,8 +1831,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,

if (err)
goto free_card;

} else if (!mmc_card_hs400es(card)) {
} else if (mmc_card_hs400es(card)) {
if (host->ops->execute_hs400_tuning) {
err = host->ops->execute_hs400_tuning(host, card);
if (err)
goto free_card;
}
} else {
/* Select the desired bus width optionally */
err = mmc_select_bus_width(card);
if (err > 0 && mmc_card_hs(card)) {
Expand Down
33 changes: 27 additions & 6 deletions drivers/mmc/core/mmc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1904,7 +1904,7 @@ static unsigned int mmc_test_rnd_num(unsigned int rnd_cnt)
}

static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print,
unsigned long sz)
unsigned long sz, int secs, int force_retuning)
{
unsigned int dev_addr, cnt, rnd_addr, range1, range2, last_ea = 0, ea;
unsigned int ssz;
Expand All @@ -1921,14 +1921,16 @@ static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print,
for (cnt = 0; cnt < UINT_MAX; cnt++) {
ktime_get_ts64(&ts2);
ts = timespec64_sub(ts2, ts1);
if (ts.tv_sec >= 10)
if (ts.tv_sec >= secs)
break;
ea = mmc_test_rnd_num(range1);
if (ea == last_ea)
ea -= 1;
last_ea = ea;
dev_addr = rnd_addr + test->card->pref_erase * ea +
ssz * mmc_test_rnd_num(range2);
if (force_retuning)
mmc_retune_needed(test->card->host);
ret = mmc_test_area_io(test, sz, dev_addr, write, 0, 0);
if (ret)
return ret;
Expand All @@ -1953,24 +1955,35 @@ static int mmc_test_random_perf(struct mmc_test_card *test, int write)
*/
if (write) {
next = rnd_next;
ret = mmc_test_rnd_perf(test, write, 0, sz);
ret = mmc_test_rnd_perf(test, write, 0, sz, 10, 0);
if (ret)
return ret;
rnd_next = next;
}
ret = mmc_test_rnd_perf(test, write, 1, sz);
ret = mmc_test_rnd_perf(test, write, 1, sz, 10, 0);
if (ret)
return ret;
}
sz = t->max_tfr;
if (write) {
next = rnd_next;
ret = mmc_test_rnd_perf(test, write, 0, sz);
ret = mmc_test_rnd_perf(test, write, 0, sz, 10, 0);
if (ret)
return ret;
rnd_next = next;
}
return mmc_test_rnd_perf(test, write, 1, sz);
return mmc_test_rnd_perf(test, write, 1, sz, 10, 0);
}

static int mmc_test_retuning(struct mmc_test_card *test)
{
if (!mmc_can_retune(test->card->host)) {
pr_info("%s: No retuning - test skipped\n",
mmc_hostname(test->card->host));
return RESULT_UNSUP_HOST;
}

return mmc_test_rnd_perf(test, 0, 0, 8192, 30, 1);
}

/*
Expand Down Expand Up @@ -2921,6 +2934,14 @@ static const struct mmc_test_case mmc_test_cases[] = {
.run = mmc_test_cmds_during_write_cmd23_nonblock,
.cleanup = mmc_test_area_cleanup,
},

{
.name = "Re-tuning reliability",
.prepare = mmc_test_area_prepare,
.run = mmc_test_retuning,
.cleanup = mmc_test_area_cleanup,
},

};

static DEFINE_MUTEX(mmc_test_lock);
Expand Down
Loading

0 comments on commit 2007758

Please sign in to comment.