u-boot.lists.denx.de archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration
@ 2022-02-23 14:36 Michal Simek
  2022-02-23 14:36 ` [PATCH 1/4] firmware: zynqmp: Add and update firmware enums Michal Simek
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Michal Simek @ 2022-02-23 14:36 UTC (permalink / raw)
  To: u-boot, git; +Cc: Adrian Fiergolski, Ashok Reddy Soma, Jaehoon Chung, Peng Fan

Hi,

with SOM boards low level sdhci setting is not fully done. There are
additional registers which are normally programmed via psu_init() but in
this case they are not initialized. Information can be taken from DT and
via firmware interface that values can be setup and that's exactly what
this series is doing.

Thanks,
Michal


Ashok Reddy Soma (4):
  firmware: zynqmp: Add and update firmware enums
  firmware: zynqmp: Add support for set sd config and is function
    supported
  lib: div64: Add support for round up of div64_u64
  mmc: zynq_sdhci: Add support for dynamic configuration

 drivers/firmware/firmware-zynqmp.c |  51 +++++++++++++++
 drivers/mmc/zynq_sdhci.c           | 101 ++++++++++++++++++++++++++++-
 include/linux/math64.h             |   3 +
 include/zynqmp_firmware.h          |  29 +++++++++
 4 files changed, 182 insertions(+), 2 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] firmware: zynqmp: Add and update firmware enums
  2022-02-23 14:36 [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration Michal Simek
@ 2022-02-23 14:36 ` Michal Simek
  2022-02-23 14:36 ` [PATCH 2/4] firmware: zynqmp: Add support for set sd config and is function supported Michal Simek
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Michal Simek @ 2022-02-23 14:36 UTC (permalink / raw)
  To: u-boot, git; +Cc: Ashok Reddy Soma

From: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>

Update enum pm_ioctl_id with more IOCTLs.
Add enum pm_sd_config_type to support dynamic sd configuration.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 include/zynqmp_firmware.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h
index 41abc2eee951..6d7614f4af00 100644
--- a/include/zynqmp_firmware.h
+++ b/include/zynqmp_firmware.h
@@ -383,6 +383,29 @@ enum pm_ioctl_id {
 	IOCTL_GET_LAST_RESET_REASON = 23,
 	/* AIE ISR Clear */
 	IOCTL_AIE_ISR_CLEAR = 24,
+	/* Register SGI to ATF */
+	IOCTL_REGISTER_SGI = 25,
+	/* Runtime feature configuration */
+	IOCTL_SET_FEATURE_CONFIG = 26,
+	IOCTL_GET_FEATURE_CONFIG = 27,
+	/* IOCTL for Secure Read/Write Interface */
+	IOCTL_READ_REG = 28,
+	IOCTL_MASK_WRITE_REG = 29,
+	/* Dynamic SD/GEM/USB configuration */
+	IOCTL_SET_SD_CONFIG = 30,
+	IOCTL_SET_GEM_CONFIG = 31,
+	IOCTL_SET_USB_CONFIG = 32,
+	/* AIE/AIEML Operations */
+	IOCTL_AIE_OPS = 33,
+	/* IOCTL to get default/current QoS */
+	IOCTL_GET_QOS = 34,
+};
+
+enum pm_sd_config_type {
+	SD_CONFIG_EMMC_SEL = 1,	/* To set SD_EMMC_SEL in CTRL_REG_SD */
+	SD_CONFIG_BASECLK = 2,	/* To set SD_BASECLK in SD_CONFIG_REG1 */
+	SD_CONFIG_8BIT = 3,	/* To set SD_8BIT in SD_CONFIG_REG2 */
+	SD_CONFIG_FIXED = 4,	/* To set fixed config registers */
 };
 
 #define PM_SIP_SVC	0xc2000000
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] firmware: zynqmp: Add support for set sd config and is function supported
  2022-02-23 14:36 [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration Michal Simek
  2022-02-23 14:36 ` [PATCH 1/4] firmware: zynqmp: Add and update firmware enums Michal Simek
@ 2022-02-23 14:36 ` Michal Simek
  2022-02-23 14:36 ` [PATCH 3/4] lib: div64: Add support for round up of div64_u64 Michal Simek
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Michal Simek @ 2022-02-23 14:36 UTC (permalink / raw)
  To: u-boot, git; +Cc: Ashok Reddy Soma, Adrian Fiergolski, Jaehoon Chung

From: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>

Add firmware API's to set SD configuration and to check if a purticular
function is supported.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/firmware/firmware-zynqmp.c | 51 ++++++++++++++++++++++++++++++
 include/zynqmp_firmware.h          |  6 ++++
 2 files changed, 57 insertions(+)

diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 8d8492d99f7e..8916c5589635 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -140,6 +140,57 @@ unsigned int zynqmp_firmware_version(void)
 	return pm_api_version;
 };
 
+int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value)
+{
+	int ret;
+
+	ret = xilinx_pm_request(PM_IOCTL, node, IOCTL_SET_SD_CONFIG,
+				config, value, NULL);
+	if (ret)
+		printf("%s: node %d: set_sd_config %d failed\n",
+		       __func__, node, config);
+
+	return ret;
+}
+
+int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id)
+{
+	int ret;
+	u32 *bit_mask;
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+
+	/* Input arguments validation */
+	if (id >= 64 || (api_id != PM_IOCTL && api_id != PM_QUERY_DATA))
+		return -EINVAL;
+
+	/* Check feature check API version */
+	ret = xilinx_pm_request(PM_FEATURE_CHECK, PM_FEATURE_CHECK, 0, 0, 0,
+				ret_payload);
+	if (ret)
+		return ret;
+
+	/* Check if feature check version 2 is supported or not */
+	if ((ret_payload[1] & FIRMWARE_VERSION_MASK) == PM_API_VERSION_2) {
+		/*
+		 * Call feature check for IOCTL/QUERY API to get IOCTL ID or
+		 * QUERY ID feature status.
+		 */
+
+		ret = xilinx_pm_request(PM_FEATURE_CHECK, api_id, 0, 0, 0,
+					ret_payload);
+		if (ret)
+			return ret;
+
+		bit_mask = &ret_payload[2];
+		if ((bit_mask[(id / 32)] & BIT((id % 32))) == 0)
+			return -EOPNOTSUPP;
+	} else {
+		return -ENODATA;
+	}
+
+	return 0;
+}
+
 /**
  * Send a configuration object to the PMU firmware.
  *
diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h
index 6d7614f4af00..f577008736d9 100644
--- a/include/zynqmp_firmware.h
+++ b/include/zynqmp_firmware.h
@@ -438,6 +438,8 @@ int zynqmp_pmufw_config_close(void);
 void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size);
 int xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
 		      u32 arg3, u32 *ret_payload);
+int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value);
+int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id);
 
 /* Type of Config Object */
 #define PM_CONFIG_OBJECT_TYPE_BASE	0x1U
@@ -469,5 +471,9 @@ enum zynqmp_pm_request_ack {
 #define ZYNQMP_PM_CAPABILITY_UNUSABLE	0x8U
 
 #define ZYNQMP_PM_MAX_QOS		100U
+/* Firmware feature check version mask */
+#define FIRMWARE_VERSION_MASK		GENMASK(15, 0)
+/* PM API versions */
+#define PM_API_VERSION_2		2
 
 #endif /* _ZYNQMP_FIRMWARE_H_ */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] lib: div64: Add support for round up of div64_u64
  2022-02-23 14:36 [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration Michal Simek
  2022-02-23 14:36 ` [PATCH 1/4] firmware: zynqmp: Add and update firmware enums Michal Simek
  2022-02-23 14:36 ` [PATCH 2/4] firmware: zynqmp: Add support for set sd config and is function supported Michal Simek
@ 2022-02-23 14:36 ` Michal Simek
  2022-02-23 14:36 ` [PATCH 4/4] mmc: zynq_sdhci: Add support for dynamic configuration Michal Simek
  2022-03-09 11:35 ` [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration Michal Simek
  4 siblings, 0 replies; 6+ messages in thread
From: Michal Simek @ 2022-02-23 14:36 UTC (permalink / raw)
  To: u-boot, git; +Cc: Ashok Reddy Soma

From: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>

Most of the frequencies are not rounded up to a proper number.
When we need to devide these frequencies to get a number for example
frequency in Mhz, we see it as one less than the actual intended value.
Ex: If we want to get Mhz from frequency 199999994hz, we will calculate
it using div64_u64(199999994, 1000000) and we will get 199Mhz in place
of 200Mhz.

Add a macro DIV64_U64_ROUND_UP for rounding up div64_u64. This is taken
from linux 'commit 68600f623d69("mm: don't miss the last page because of
round-off error")'.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 include/linux/math64.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/math64.h b/include/linux/math64.h
index 08584c8f237f..eaa9fd5b9685 100644
--- a/include/linux/math64.h
+++ b/include/linux/math64.h
@@ -48,6 +48,9 @@ static inline u64 div64_u64(u64 dividend, u64 divisor)
 	return dividend / divisor;
 }
 
+#define DIV64_U64_ROUND_UP(ll, d)	\
+	({ u64 _tmp = (d); div64_u64((ll) + _tmp - 1, _tmp); })
+
 /**
  * div64_s64 - signed 64bit divide with 64bit divisor
  */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] mmc: zynq_sdhci: Add support for dynamic configuration
  2022-02-23 14:36 [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration Michal Simek
                   ` (2 preceding siblings ...)
  2022-02-23 14:36 ` [PATCH 3/4] lib: div64: Add support for round up of div64_u64 Michal Simek
@ 2022-02-23 14:36 ` Michal Simek
  2022-03-09 11:35 ` [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration Michal Simek
  4 siblings, 0 replies; 6+ messages in thread
From: Michal Simek @ 2022-02-23 14:36 UTC (permalink / raw)
  To: u-boot, git; +Cc: Ashok Reddy Soma, Jaehoon Chung, Peng Fan

From: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>

Add support for dynamic configuration which will takes care of
configuring the SD secure space configuration registers using firmware
APIs, performing SD reset assert and deassert.

High level sequence:
  - Check for the PM dynamic configuration support, if no error proceed
    with SD dynamic configurations(next steps) otherwise skip the dynamic
    configuration.
  - Put the SD Controller in reset.
  - Configure SD Fixed configurations.
  - Configure the SD Slot Type.
  - Configure the BASE_CLOCK.
  - Configure the 8-bit support.
  - Bring the SD Controller out of reset.

In the above steps, apart from the Fixed configurations, remaining all
configurations are dynamic and they will be read from devicetree.

And also remove hardcoded secure register writes, as dynamic sd config
support is added.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/mmc/zynq_sdhci.c | 101 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 99 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 33d00b06c777..d96f5d543f54 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -12,9 +12,12 @@
 #include <linux/delay.h>
 #include "mmc_private.h"
 #include <log.h>
+#include <reset.h>
 #include <dm/device_compat.h>
 #include <linux/err.h>
 #include <linux/libfdt.h>
+#include <asm/types.h>
+#include <linux/math64.h>
 #include <asm/cache.h>
 #include <malloc.h>
 #include <sdhci.h>
@@ -61,6 +64,7 @@ struct arasan_sdhci_priv {
 	u8 deviceid;
 	u8 bank;
 	u8 no_1p8;
+	struct reset_ctl_bulk resets;
 };
 
 /* For Versal platforms zynqmp_mmio_write() won't be available */
@@ -243,7 +247,7 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
 	char tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
 	u8 node_id = priv->deviceid ? NODE_SD_1 : NODE_SD_0;
 
-	debug("%s\n", __func__);
+	dev_dbg(mmc->dev, "%s\n", __func__);
 
 	host = priv->host;
 
@@ -703,6 +707,87 @@ static const struct sdhci_ops arasan_ops = {
 };
 #endif
 
+#if defined(CONFIG_ARCH_ZYNQMP)
+static int sdhci_zynqmp_set_dynamic_config(struct arasan_sdhci_priv *priv,
+					   struct udevice *dev)
+{
+	int ret;
+	u32 node_id = priv->deviceid ? NODE_SD_1 : NODE_SD_0;
+	struct clk clk;
+	unsigned long clock, mhz;
+
+	ret = xilinx_pm_request(PM_REQUEST_NODE, node_id, ZYNQMP_PM_CAPABILITY_ACCESS,
+				ZYNQMP_PM_MAX_QOS, ZYNQMP_PM_REQUEST_ACK_NO, NULL);
+	if (ret) {
+		dev_err(dev, "Request node failed for %d\n", node_id);
+		return ret;
+	}
+
+	ret = reset_get_bulk(dev, &priv->resets);
+	if (ret == -ENOTSUPP || ret == -ENOENT) {
+		dev_err(dev, "Reset not found\n");
+		return 0;
+	} else if (ret) {
+		dev_err(dev, "Reset failed\n");
+		return ret;
+	}
+
+	ret = reset_assert_bulk(&priv->resets);
+	if (ret) {
+		dev_err(dev, "Reset assert failed\n");
+		return ret;
+	}
+
+	ret = zynqmp_pm_set_sd_config(node_id, SD_CONFIG_FIXED, 0);
+	if (ret) {
+		dev_err(dev, "SD_CONFIG_FIXED failed\n");
+		return ret;
+	}
+
+	ret = zynqmp_pm_set_sd_config(node_id, SD_CONFIG_EMMC_SEL,
+				      dev_read_bool(dev, "non-removable"));
+	if (ret) {
+		dev_err(dev, "SD_CONFIG_EMMC_SEL failed\n");
+		return ret;
+	}
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to get clock\n");
+		return ret;
+	}
+
+	clock = clk_get_rate(&clk);
+	if (IS_ERR_VALUE(clock)) {
+		dev_err(dev, "failed to get rate\n");
+		return clock;
+	}
+
+	mhz = DIV64_U64_ROUND_UP(clock, 1000000);
+
+	ret = zynqmp_pm_set_sd_config(node_id, SD_CONFIG_BASECLK, mhz);
+	if (ret) {
+		dev_err(dev, "SD_CONFIG_BASECLK failed\n");
+		return ret;
+	}
+
+	ret = zynqmp_pm_set_sd_config(node_id, SD_CONFIG_8BIT,
+				      (dev_read_u32_default(dev, "bus-width", 1) == 8));
+	if (ret) {
+		dev_err(dev, "SD_CONFIG_8BIT failed\n");
+		return ret;
+	}
+
+	ret = reset_deassert_bulk(&priv->resets);
+	if (ret) {
+		dev_err(dev, "Reset release failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+#endif
+
 static int arasan_sdhci_probe(struct udevice *dev)
 {
 	struct arasan_sdhci_plat *plat = dev_get_plat(dev);
@@ -715,6 +800,18 @@ static int arasan_sdhci_probe(struct udevice *dev)
 
 	host = priv->host;
 
+#if defined(CONFIG_ARCH_ZYNQMP)
+	if (device_is_compatible(dev, "xlnx,zynqmp-8.9a")) {
+		ret = zynqmp_pm_is_function_supported(PM_IOCTL,
+						      IOCTL_SET_SD_CONFIG);
+		if (!ret) {
+			ret = sdhci_zynqmp_set_dynamic_config(priv, dev);
+			if (ret)
+				return ret;
+		}
+	}
+#endif
+
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (ret < 0) {
 		dev_err(dev, "failed to get clock\n");
@@ -727,7 +824,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
 		return clock;
 	}
 
-	debug("%s: CLK %ld\n", __func__, clock);
+	dev_dbg(dev, "%s: CLK %ld\n", __func__, clock);
 
 	ret = clk_enable(&clk);
 	if (ret) {
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration
  2022-02-23 14:36 [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration Michal Simek
                   ` (3 preceding siblings ...)
  2022-02-23 14:36 ` [PATCH 4/4] mmc: zynq_sdhci: Add support for dynamic configuration Michal Simek
@ 2022-03-09 11:35 ` Michal Simek
  4 siblings, 0 replies; 6+ messages in thread
From: Michal Simek @ 2022-03-09 11:35 UTC (permalink / raw)
  To: U-Boot, git; +Cc: Adrian Fiergolski, Ashok Reddy Soma, Jaehoon Chung, Peng Fan

st 23. 2. 2022 v 15:36 odesílatel Michal Simek <michal.simek@xilinx.com> napsal:
>
> Hi,
>
> with SOM boards low level sdhci setting is not fully done. There are
> additional registers which are normally programmed via psu_init() but in
> this case they are not initialized. Information can be taken from DT and
> via firmware interface that values can be setup and that's exactly what
> this series is doing.
>
> Thanks,
> Michal
>
>
> Ashok Reddy Soma (4):
>   firmware: zynqmp: Add and update firmware enums
>   firmware: zynqmp: Add support for set sd config and is function
>     supported
>   lib: div64: Add support for round up of div64_u64
>   mmc: zynq_sdhci: Add support for dynamic configuration
>
>  drivers/firmware/firmware-zynqmp.c |  51 +++++++++++++++
>  drivers/mmc/zynq_sdhci.c           | 101 ++++++++++++++++++++++++++++-
>  include/linux/math64.h             |   3 +
>  include/zynqmp_firmware.h          |  29 +++++++++
>  4 files changed, 182 insertions(+), 2 deletions(-)
>
> --
> 2.35.1
>

Applied.
M

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-03-09 11:35 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-23 14:36 [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration Michal Simek
2022-02-23 14:36 ` [PATCH 1/4] firmware: zynqmp: Add and update firmware enums Michal Simek
2022-02-23 14:36 ` [PATCH 2/4] firmware: zynqmp: Add support for set sd config and is function supported Michal Simek
2022-02-23 14:36 ` [PATCH 3/4] lib: div64: Add support for round up of div64_u64 Michal Simek
2022-02-23 14:36 ` [PATCH 4/4] mmc: zynq_sdhci: Add support for dynamic configuration Michal Simek
2022-03-09 11:35 ` [PATCH 0/4] mmc: zynq_sdhci: Add support for dynamic IP configuration Michal Simek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).