Files
Archive/lede/target/linux/bcm27xx/patches-6.12/950-0432-drivers-mmc-export-SD-extension-register-read-write-.patch
T
2025-06-30 20:37:48 +02:00

305 lines
9.3 KiB
Diff

From f35ffcd4c348aaf3bae173d888a5a84848db326a Mon Sep 17 00:00:00 2001
From: Jonathan Bell <jonathan@raspberrypi.com>
Date: Tue, 26 Mar 2024 13:25:01 +0000
Subject: [PATCH] drivers: mmc: export SD extension register read/write
functions
Certain status bits in these registers may need polling outside of
SD-specific code. Export in sd_ops.h
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
---
drivers/mmc/core/sd.c | 97 ++++-----------------------------------
drivers/mmc/core/sd_ops.c | 83 +++++++++++++++++++++++++++++++--
drivers/mmc/core/sd_ops.h | 4 ++
3 files changed, 93 insertions(+), 91 deletions(-)
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1027,83 +1027,6 @@ static bool mmc_sd_card_using_v18(struct
(SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50);
}
-int sd_write_ext_reg(struct mmc_card *card, u8 fno, u8 page, u16 offset,
- u8 reg_data)
-{
- struct mmc_host *host = card->host;
- struct mmc_request mrq = {};
- struct mmc_command cmd = {};
- struct mmc_data data = {};
- struct scatterlist sg;
- u8 *reg_buf;
-
- reg_buf = card->ext_reg_buf;
- memset(reg_buf, 0, 512);
-
- mrq.cmd = &cmd;
- mrq.data = &data;
-
- /*
- * Arguments of CMD49:
- * [31:31] MIO (0 = memory).
- * [30:27] FNO (function number).
- * [26:26] MW - mask write mode (0 = disable).
- * [25:18] page number.
- * [17:9] offset address.
- * [8:0] length (0 = 1 byte).
- */
- cmd.arg = fno << 27 | page << 18 | offset << 9;
-
- /* The first byte in the buffer is the data to be written. */
- reg_buf[0] = reg_data;
-
- data.flags = MMC_DATA_WRITE;
- data.blksz = 512;
- data.blocks = 1;
- data.sg = &sg;
- data.sg_len = 1;
- sg_init_one(&sg, reg_buf, 512);
-
- cmd.opcode = SD_WRITE_EXTR_SINGLE;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
-
- mmc_set_data_timeout(&data, card);
- mmc_wait_for_req(host, &mrq);
-
- /*
- * Note that, the SD card is allowed to signal busy on DAT0 up to 1s
- * after the CMD49. Although, let's leave this to be managed by the
- * caller.
- */
-
- if (cmd.error)
- return cmd.error;
- if (data.error)
- return data.error;
-
- return 0;
-}
-
-static int sd_read_ext_reg(struct mmc_card *card, u8 fno, u8 page,
- u16 offset, u16 len, u8 *reg_buf)
-{
- u32 cmd_args;
-
- /*
- * Command arguments of CMD48:
- * [31:31] MIO (0 = memory).
- * [30:27] FNO (function number).
- * [26:26] reserved (0).
- * [25:18] page number.
- * [17:9] offset address.
- * [8:0] length (0 = 1 byte, 1ff = 512 bytes).
- */
- cmd_args = fno << 27 | page << 18 | offset << 9 | (len -1);
-
- return mmc_send_adtc_data(card, card->host, SD_READ_EXTR_SINGLE,
- cmd_args, reg_buf, 512);
-}
-
static int sd_parse_ext_reg_power(struct mmc_card *card, u8 fno, u8 page,
u16 offset)
{
@@ -1113,7 +1036,7 @@ static int sd_parse_ext_reg_power(struct
reg_buf = card->ext_reg_buf;
/* Read the extension register for power management function. */
- err = sd_read_ext_reg(card, fno, page, offset, 512, reg_buf);
+ err = mmc_sd_read_ext_reg(card, fno, page, offset, 512, reg_buf);
if (err) {
pr_warn("%s: error %d reading PM func of ext reg\n",
mmc_hostname(card->host), err);
@@ -1151,7 +1074,7 @@ static int sd_parse_ext_reg_perf(struct
reg_buf = card->ext_reg_buf;
- err = sd_read_ext_reg(card, fno, page, offset, 512, reg_buf);
+ err = mmc_sd_read_ext_reg(card, fno, page, offset, 512, reg_buf);
if (err) {
pr_warn("%s: error %d reading PERF func of ext reg\n",
mmc_hostname(card->host), err);
@@ -1246,7 +1169,7 @@ static int sd_parse_ext_reg(struct mmc_c
return 0;
}
-static int sd_read_ext_regs(struct mmc_card *card)
+static int mmc_sd_read_ext_regs(struct mmc_card *card)
{
int err, i;
u8 num_ext, *gen_info_buf;
@@ -1272,7 +1195,7 @@ static int sd_read_ext_regs(struct mmc_c
* Read 512 bytes of general info, which is found at function number 0,
* at page 0 and with no offset.
*/
- err = sd_read_ext_reg(card, 0, 0, 0, 512, gen_info_buf);
+ err = mmc_sd_read_ext_reg(card, 0, 0, 0, 512, gen_info_buf);
if (err) {
pr_err("%s: error %d reading general info of SD ext reg\n",
mmc_hostname(card->host), err);
@@ -1344,7 +1267,7 @@ static int sd_flush_cache(struct mmc_hos
page = card->ext_perf.page;
offset = card->ext_perf.offset + 261;
- err = sd_write_ext_reg(card, fno, page, offset, BIT(0));
+ err = mmc_sd_write_ext_reg(card, fno, page, offset, BIT(0));
if (err) {
pr_warn("%s: error %d writing Cache Flush bit\n",
mmc_hostname(host), err);
@@ -1360,7 +1283,7 @@ static int sd_flush_cache(struct mmc_hos
* Read the Flush Cache bit. The card shall reset it, to confirm that
* it's has completed the flushing of the cache.
*/
- err = sd_read_ext_reg(card, fno, page, offset, 1, reg_buf);
+ err = mmc_sd_read_ext_reg(card, fno, page, offset, 1, reg_buf);
if (err) {
pr_warn("%s: error %d reading Cache Flush bit\n",
mmc_hostname(host), err);
@@ -1383,7 +1306,7 @@ static int sd_enable_cache(struct mmc_ca
* Set Cache Enable at bit 0 in the performance enhancement register at
* 260 bytes offset.
*/
- err = sd_write_ext_reg(card, card->ext_perf.fno, card->ext_perf.page,
+ err = mmc_sd_write_ext_reg(card, card->ext_perf.fno, card->ext_perf.page,
card->ext_perf.offset + 260, BIT(0));
if (err) {
pr_warn("%s: error %d writing Cache Enable bit\n",
@@ -1556,7 +1479,7 @@ retry:
cont:
if (!oldcard) {
/* Read/parse the extension registers. */
- err = sd_read_ext_regs(card);
+ err = mmc_sd_read_ext_regs(card);
if (err)
goto free_card;
}
@@ -1683,7 +1606,7 @@ static int sd_busy_poweroff_notify_cb(vo
* one byte offset and is one byte long. The Power Off Notification
* Ready is bit 0.
*/
- err = sd_read_ext_reg(card, card->ext_power.fno, card->ext_power.page,
+ err = mmc_sd_read_ext_reg(card, card->ext_power.fno, card->ext_power.page,
card->ext_power.offset + 1, 1, data->reg_buf);
if (err) {
pr_warn("%s: error %d reading status reg of PM func\n",
@@ -1709,7 +1632,7 @@ static int sd_poweroff_notify(struct mmc
* Set the Power Off Notification bit in the power management settings
* register at 2 bytes offset.
*/
- err = sd_write_ext_reg(card, card->ext_power.fno, card->ext_power.page,
+ err = mmc_sd_write_ext_reg(card, card->ext_power.fno, card->ext_power.page,
card->ext_power.offset + 2, BIT(0));
if (err) {
pr_warn("%s: error %d writing Power Off Notify bit\n",
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -394,8 +394,83 @@ int mmc_app_sd_status(struct mmc_card *c
return 0;
}
-int sd_write_ext_reg(struct mmc_card *card, u8 fno, u8 page, u16 offset,
- u8 reg_data);
+
+int mmc_sd_write_ext_reg(struct mmc_card *card, u8 fno, u8 page, u16 offset,
+ u8 reg_data)
+{
+ struct mmc_host *host = card->host;
+ struct mmc_request mrq = {};
+ struct mmc_command cmd = {};
+ struct mmc_data data = {};
+ struct scatterlist sg;
+ u8 *reg_buf;
+
+ reg_buf = card->ext_reg_buf;
+ memset(reg_buf, 0, 512);
+
+ mrq.cmd = &cmd;
+ mrq.data = &data;
+
+ /*
+ * Arguments of CMD49:
+ * [31:31] MIO (0 = memory).
+ * [30:27] FNO (function number).
+ * [26:26] MW - mask write mode (0 = disable).
+ * [25:18] page number.
+ * [17:9] offset address.
+ * [8:0] length (0 = 1 byte).
+ */
+ cmd.arg = fno << 27 | page << 18 | offset << 9;
+
+ /* The first byte in the buffer is the data to be written. */
+ reg_buf[0] = reg_data;
+
+ data.flags = MMC_DATA_WRITE;
+ data.blksz = 512;
+ data.blocks = 1;
+ data.sg = &sg;
+ data.sg_len = 1;
+ sg_init_one(&sg, reg_buf, 512);
+
+ cmd.opcode = SD_WRITE_EXTR_SINGLE;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+
+ mmc_set_data_timeout(&data, card);
+ mmc_wait_for_req(host, &mrq);
+
+ /*
+ * Note that, the SD card is allowed to signal busy on DAT0 up to 1s
+ * after the CMD49. Although, let's leave this to be managed by the
+ * caller.
+ */
+
+ if (cmd.error)
+ return cmd.error;
+ if (data.error)
+ return data.error;
+
+ return 0;
+}
+
+int mmc_sd_read_ext_reg(struct mmc_card *card, u8 fno, u8 page,
+ u16 offset, u16 len, u8 *reg_buf)
+{
+ u32 cmd_args;
+
+ /*
+ * Command arguments of CMD48:
+ * [31:31] MIO (0 = memory).
+ * [30:27] FNO (function number).
+ * [26:26] reserved (0).
+ * [25:18] page number.
+ * [17:9] offset address.
+ * [8:0] length (0 = 1 byte, 1ff = 512 bytes).
+ */
+ cmd_args = fno << 27 | page << 18 | offset << 9 | (len - 1);
+
+ return mmc_send_adtc_data(card, card->host, SD_READ_EXTR_SINGLE,
+ cmd_args, reg_buf, 512);
+}
static int mmc_sd_cmdq_switch(struct mmc_card *card, bool enable)
{
@@ -411,8 +486,8 @@ static int mmc_sd_cmdq_switch(struct mmc
reg = BIT(0);
/* Performance enhancement register byte 262 controls command queueing */
- err = sd_write_ext_reg(card, card->ext_perf.fno, card->ext_perf.page,
- card->ext_perf.offset + 262, reg);
+ err = mmc_sd_write_ext_reg(card, card->ext_perf.fno, card->ext_perf.page,
+ card->ext_perf.offset + 262, reg);
if (!err)
card->ext_csd.cmdq_en = enable;
--- a/drivers/mmc/core/sd_ops.h
+++ b/drivers/mmc/core/sd_ops.h
@@ -23,6 +23,10 @@ int mmc_app_sd_status(struct mmc_card *c
int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card);
int mmc_sd_cmdq_enable(struct mmc_card *card);
int mmc_sd_cmdq_disable(struct mmc_card *card);
+int mmc_sd_write_ext_reg(struct mmc_card *card, u8 fno, u8 page, u16 offset,
+ u8 reg_data);
+int mmc_sd_read_ext_reg(struct mmc_card *card, u8 fno, u8 page,
+ u16 offset, u16 len, u8 *reg_buf);
#endif