Re: [PATCH v2 8/8] board: add support for Qualcomm SA8155P-ADP board

2024-03-19 Thread Volodymyr Babchuk


Hi,

Volodymyr Babchuk  writes:

> Caleb Connolly  writes:
>
>> On 11/03/2024 18:23, Volodymyr Babchuk wrote:
>>> Hi Caleb,
>>> Caleb Connolly  writes:
>>> 
>>>> On 06/03/2024 21:24, Volodymyr Babchuk wrote:
>>>>>
>>>>> Hi Caleb,
>>>>>
>>>>> Caleb Connolly  writes:
>>>>>
>>>>> [...]
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>> + {
>>>>>>>>> +   /* U-Boot pinctrl driver does not understand multiple tiles */
>>>>>>>>> +   reg = <0x0 0x0300 0x0 0x100>;
>>>>>>>>> +   /delete-property/ reg-names;
>>>>>>>>
>>>>>>>> This won't be needed if we can make the tiles offset in the pinctrl
>>>>>>>> driver compatible:
>>>>>>>>
>>>>>>>> #define WEST   0x
>>>>>>>> #define EAST   0x0040
>>>>>>>> #define NORTH  0x0080
>>>>>>>> #define SOUTH  0x00C0
>>>>>>>
>>>>>>> Hmm, I assume that in this case pinctrl driver should map all the four
>>>>>>> tiles independently? Are there guarantees in U-Boot that four separate
>>>>>>> memory regions will be mapped into virtual memory with the same relative
>>>>>>> positions? Linux clearly don't make such guarantees.
>>>>>>
>>>>>> U-Boot doesn't use virtual addresses on arm platforms, it only goes as
>>>>>> far as reading the address from DT, nothing else, so this is totally
>>>>>> fine and is how the other SoCs do it.
>>>>>
>>>>> For me it looks like we are depending on implementation details
>>>>> knowledge. I.e MMU API does not provide such guarantees, but drivers
>>>>> know how ARM MMU code is working internally and drivers depend on
>>>>> exactly this behavior. But if you are saying that it is totally fine,
>>>>> I'll rework the patch. No big deal. Actually, I already tried this and
>>>>> it is working fine.
>>>>>
>>>>>>>>> +
>>>>>>>>> +   /* U-Boot ethernet driver wants to drive reset as GPIO */
>>>>>>>>> +   /delete-node/ phy-reset-pins;
>>>>>>>>
>>>>>>>> I suppose this is not needed as phy-reset-pins also configures the pin
>>>>>>>> as GPIO only.
>>>>>>>>
>>>>>>> Well, yes. This also puzzles me up, but for some reason it stops working
>>>>>>> if I leave this node intact. Looks like I need to look at this deeper
>>>>>>> before posting the next version.
>>>>>>
>>>>>> Possibly the pinconf defined in the phy-reset-pins node causes U-Boot to
>>>>>> misbehave, can you check if this patch fixes it (there is a bug in the
>>>>>> line "return msm_gpio_direction_input(dev, gpio);", it should become
>>>>>> just "msm_gpio_direction_input(dev, gpio);").
>>>>>>
>>>>>> I had the exact same issue with the gpio-regulator driver and this was
>>>>>> the solution I ended up going with.
>>>>>>
>>>>>> https://urldefense.com/v3/__https://lore.kernel.org/u-boot/20240131-b4-qcom-livetree-v1-7-4071c0787...@linaro.org/__;!!GF_29dbcQIUBPA!xFhZe7DKgRbr63sirEJLuH-B0AnGs7jvx8tdJPKLTgFuZ3I3_zpVml7l23G-_vJO_JiUR-wUO4GMPJFcE-8p50H3pf7nbxit$
>>>>>> [lore[.]kernel[.]org]
>>>>>
>>>>> It is exactly this. With your patch I don't need to /delete-node/
>>>>> anymore. I'll add a comment in the cover message that this series are
>>>>> depended on your patch.
>>>>
>>>> Please can you split the power domain and clock patches into a separate
>>>> series? As I'd like to depend on them for the next revision of my
>>>> series, and we'd otherwise have a cyclical dependency.
>>> Of course.
>>> As I understood, you are interested in "clk: qcom: clear div mask
>>> before
>>> assigning a new divider" and "clk: qcom: add support for power domains
>>> uclass", correct?
>>
>> Yes.
>
> Okay, I'll send it today.
>
>> I tried the power domain stuff out on SMD845 t

Re: [PATCH v3 2/4] clk: qcom: clear div mask before assigning a new divider

2024-03-12 Thread Volodymyr Babchuk


Hi Sumit,

Thank you for the review.

Sumit Garg  writes:

> On Tue, 12 Mar 2024 at 03:03, Volodymyr Babchuk
>  wrote:
>>
>> The current behaviour does a bitwise OR of the previous and new
>> divider values, this is wrong as some bits maybe be set already. We
>
> nit: s/maybe be/maybe/
>

Oops, right. Can this be applied by the committer during the merge
process? I know that committers in other open source project do this
sometimes. Or should I post a new version?

[...]

-- 
WBR, Volodymyr

[PATCH v3 3/4] clk: qcom: add support for power domains uclass

2024-03-11 Thread Volodymyr Babchuk
Now sub-drivers for particular SoCs can register them as power domain
drivers. This is needed for upcoming SM8150 support, because it needs
to power up the Ethernet module.

Signed-off-by: Volodymyr Babchuk 

---
Caleb suggested to use "imply POWER_DOMAIN", not "depends
POWER_DOMAIN" in the Kconfig, but this does not work:
$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm
scripts/kconfig/conf  --syncconfig Kconfig
drivers/clk/Kconfig:3:error: recursive dependency detected!
drivers/clk/Kconfig:3:  symbol CLK is selected by IMX8M_POWER_DOMAIN
drivers/power/domain/Kconfig:35:symbol IMX8M_POWER_DOMAIN depends on 
POWER_DOMAIN
drivers/power/domain/Kconfig:3: symbol POWER_DOMAIN is implied by CLK_QCOM
drivers/clk/qcom/Kconfig:3: symbol CLK_QCOM depends on CLK
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"


Changes in v3:
 - Added "depends POWER_DOMAIN" to Kconfig (see note)
 - Use readl_poll_timeout() instead of open coded wait loop
 - Print warning if power domain can't be enabled/disabled

Changes in v2:
 - Reworked qcom_cc_bind() function
 - Added timeout to qcom_power_set()
 - Minor fixes in register names and formatting

 drivers/clk/qcom/Kconfig  |   2 +-
 drivers/clk/qcom/clock-qcom.c | 132 ++
 drivers/clk/qcom/clock-qcom.h |   6 ++
 3 files changed, 126 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 0df0d1881a..8dae635ac2 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -2,7 +2,7 @@ if ARCH_SNAPDRAGON || ARCH_IPQ40XX
 
 config CLK_QCOM
bool
-   depends on CLK && DM_RESET
+   depends on CLK && DM_RESET && POWER_DOMAIN
def_bool n
 
 menu "Qualcomm clock drivers"
diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 729d190c54..7a5938a06a 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -22,7 +22,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 #include "clock-qcom.h"
 
@@ -30,6 +32,13 @@
 #define CBCR_BRANCH_ENABLE_BIT  BIT(0)
 #define CBCR_BRANCH_OFF_BIT BIT(31)
 
+#define GDSC_SW_COLLAPSE_MASK  BIT(0)
+#define GDSC_POWER_DOWN_COMPLETE   BIT(15)
+#define GDSC_POWER_UP_COMPLETE BIT(16)
+#define GDSC_PWR_ON_MASK   BIT(31)
+#define CFG_GDSCR_OFFSET   0x4
+#define GDSC_STATUS_POLL_TIMEOUT_US1500
+
 /* Enable clock controlled by CBC soft macro */
 void clk_enable_cbc(phys_addr_t cbcr)
 {
@@ -223,7 +232,7 @@ U_BOOT_DRIVER(qcom_clk) = {
 int qcom_cc_bind(struct udevice *parent)
 {
struct msm_clk_data *data = (struct msm_clk_data 
*)dev_get_driver_data(parent);
-   struct udevice *clkdev, *rstdev;
+   struct udevice *clkdev = NULL, *rstdev = NULL, *pwrdev;
struct driver *drv;
int ret;
 
@@ -238,20 +247,41 @@ int qcom_cc_bind(struct udevice *parent)
if (ret)
return ret;
 
-   /* Bail out early if resets are not specified for this platform */
-   if (!data->resets)
-   return ret;
+   if (data->resets) {
+   /* Get a handle to the common reset handler */
+   drv = lists_driver_lookup_name("qcom_reset");
+   if (!drv) {
+   ret = -ENOENT;
+   goto unbind_clkdev;
+   }
+
+   /* Register the reset controller */
+   ret = device_bind_with_driver_data(parent, drv, "qcom_reset", 
(ulong)data,
+  dev_ofnode(parent), );
+   if (ret)
+   goto unbind_clkdev;
+   }
 
-   /* Get a handle to the common reset handler */
-   drv = lists_driver_lookup_name("qcom_reset");
-   if (!drv)
-   return -ENOENT;
+   if (data->power_domains) {
+   /* Get a handle to the common power domain handler */
+   drv = lists_driver_lookup_name("qcom_power");
+   if (!drv) {
+   ret = -ENOENT;
+   goto unbind_rstdev;
+   }
+   /* Register the power domain controller */
+   ret = device_bind_with_driver_data(parent, drv, "qcom_power", 
(ulong)data,
+  dev_ofnode(parent), );
+   if (ret)
+   goto unbind_rstdev;
+   }
 
-   /* Register the reset controller */
-   ret = device_bind_with_driver_data(parent, drv, "qcom_reset", 
(ulong)data,
-  dev_ofnode(parent), );
-   if (ret)
-   device_unbind(clkdev);
+   return 0;
+
+unbind_rstdev:
+   device_unbind(rstdev);
+unbind_clk

[PATCH v3 2/4] clk: qcom: clear div mask before assigning a new divider

2024-03-11 Thread Volodymyr Babchuk
The current behaviour does a bitwise OR of the previous and new
divider values, this is wrong as some bits maybe be set already. We
need to clear all the divider bits before applying new ones.

This fixes potential issue with 1Gbit ethernet on SA8155P-ADP boards.

Signed-off-by: Volodymyr Babchuk 
Reviewed-by: Caleb Connolly 

---

(no changes since v2)

Changes in v2:
 - Reworded the commit message
 - Added Caleb's R-b tag

 drivers/clk/qcom/clock-qcom.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 7c683e5192..729d190c54 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -117,7 +117,8 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct 
bcr_regs *regs,
 
/* setup src select and divider */
cfg  = readl(base + regs->cfg_rcgr);
-   cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK);
+   cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK |
+CFG_SRC_DIV_MASK);
cfg |= source & CFG_SRC_SEL_MASK; /* Select clock source */
 
if (div)
-- 
2.43.0


[PATCH v3 4/4] pinctrl: qcom: pass pin number to get_function_mux callback

2024-03-11 Thread Volodymyr Babchuk
This patch is the preparation for SM8150 support. This new SoC
depending on the particular pin can have different numbers for the
same function. For example "rgmii" function for GPIO4 has id=2 while
for GPIO59 it has id=1. So, to support this type of SoCs,
get_function_mux() callback needs to know for which pin the function
is requested.

Signed-off-by: Volodymyr Babchuk 
Reviewed-by: Caleb Connolly 
Reviewed-by: Sumit Garg 

---

Changes in v3:
 - Added Sumit's R-b tag

Changes in v2:
 - Added Caleb's R-b tag

 drivers/pinctrl/qcom/pinctrl-apq8016.c | 3 ++-
 drivers/pinctrl/qcom/pinctrl-apq8096.c | 3 ++-
 drivers/pinctrl/qcom/pinctrl-ipq4019.c | 3 ++-
 drivers/pinctrl/qcom/pinctrl-qcom.c| 4 ++--
 drivers/pinctrl/qcom/pinctrl-qcom.h| 3 ++-
 drivers/pinctrl/qcom/pinctrl-qcs404.c  | 3 ++-
 drivers/pinctrl/qcom/pinctrl-sdm845.c  | 3 ++-
 7 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/pinctrl/qcom/pinctrl-apq8016.c 
b/drivers/pinctrl/qcom/pinctrl-apq8016.c
index db0e212468..a9a00f4b08 100644
--- a/drivers/pinctrl/qcom/pinctrl-apq8016.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8016.c
@@ -49,7 +49,8 @@ static const char *apq8016_get_pin_name(struct udevice *dev,
}
 }
 
-static unsigned int apq8016_get_function_mux(unsigned int selector)
+static unsigned int apq8016_get_function_mux(__maybe_unused unsigned int pin,
+unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-apq8096.c 
b/drivers/pinctrl/qcom/pinctrl-apq8096.c
index 880df8fe3c..9697cb5beb 100644
--- a/drivers/pinctrl/qcom/pinctrl-apq8096.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8096.c
@@ -44,7 +44,8 @@ static const char *apq8096_get_pin_name(struct udevice *dev,
}
 }
 
-static unsigned int apq8096_get_function_mux(unsigned int selector)
+static unsigned int apq8096_get_function_mux(__maybe_unused unsigned int pin,
+unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq4019.c 
b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
index 74c04ab87c..4479230313 100644
--- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c
+++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
@@ -40,7 +40,8 @@ static const char *ipq4019_get_pin_name(struct udevice *dev,
return pin_name;
 }
 
-static unsigned int ipq4019_get_function_mux(unsigned int selector)
+static unsigned int ipq4019_get_function_mux(__maybe_unused unsigned int pin,
+unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.c 
b/drivers/pinctrl/qcom/pinctrl-qcom.c
index ee0624df29..909e566acf 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcom.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.c
@@ -83,14 +83,14 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int 
pin_selector,
  unsigned int func_selector)
 {
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+   u32 func = priv->data->get_function_mux(pin_selector, func_selector);
 
/* Always NOP for special pins, assume they're in the correct state */
if (qcom_is_special_pin(>data->pin_data, pin_selector))
return 0;
 
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
-   TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
-   priv->data->get_function_mux(func_selector) << 2);
+   TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE, func << 2);
return 0;
 }
 
diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.h 
b/drivers/pinctrl/qcom/pinctrl-qcom.h
index 07f2eae9ba..49b7bfbc00 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcom.h
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.h
@@ -18,7 +18,8 @@ struct msm_pinctrl_data {
int functions_count;
const char *(*get_function_name)(struct udevice *dev,
 unsigned int selector);
-   unsigned int (*get_function_mux)(unsigned int selector);
+   unsigned int (*get_function_mux)(unsigned int pin,
+unsigned int selector);
const char *(*get_pin_name)(struct udevice *dev,
unsigned int selector);
 };
diff --git a/drivers/pinctrl/qcom/pinctrl-qcs404.c 
b/drivers/pinctrl/qcom/pinctrl-qcs404.c
index 3a2d468599..4b7c670c90 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcs404.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcs404.c
@@ -94,7 +94,8 @@ static const char *qcs404_get_pin_name(struct udevice *dev,
}
 }
 
-static unsigned int qcs404_get_function_mux(unsigned int selector)
+static unsigned int qcs404_get_function_mux(__maybe_unused unsigned int pin,
+   unsigned int selector)
 {
return msm_pinctrl_functions[selector

[PATCH v3 0/4]

2024-03-11 Thread Volodymyr Babchuk
Set of pre-req patches for Qualcomm SA8155P-ADP board support.

This path series consist of generic qcom changes that may benefit
different boards. It is the part of the bigger series that adds
SA8155P-ADP support, but I am posting this limited set because there
are other developers who depend on those changes and I am not ready to
post other patches of the bigger series.


Changes in v3:
 - Replaced fdt_valid() with fdt_check_header()
 - Added "depends POWER_DOMAIN" to Kconfig (see note)
 - Use readl_poll_timeout() instead of open coded wait loop
 - Print warning if power domain can't be enabled/disabled

Changes in v2:
 - New patch in v2
 - Reworked qcom_cc_bind() function
 - Added timeout to qcom_power_set()
 - Minor fixes in register names and formatting

Volodymyr Babchuk (4):
  qcom: board: validate fdt before trying to use it
  clk: qcom: clear div mask before assigning a new divider
  clk: qcom: add support for power domains uclass
  pinctrl: qcom: pass pin number to get_function_mux callback

 arch/arm/mach-snapdragon/board.c   |   5 +-
 drivers/clk/qcom/Kconfig   |   2 +-
 drivers/clk/qcom/clock-qcom.c  | 135 ++---
 drivers/clk/qcom/clock-qcom.h  |   6 ++
 drivers/pinctrl/qcom/pinctrl-apq8016.c |   3 +-
 drivers/pinctrl/qcom/pinctrl-apq8096.c |   3 +-
 drivers/pinctrl/qcom/pinctrl-ipq4019.c |   3 +-
 drivers/pinctrl/qcom/pinctrl-qcom.c|   4 +-
 drivers/pinctrl/qcom/pinctrl-qcom.h|   3 +-
 drivers/pinctrl/qcom/pinctrl-qcs404.c  |   3 +-
 drivers/pinctrl/qcom/pinctrl-sdm845.c  |   3 +-
 11 files changed, 146 insertions(+), 24 deletions(-)

-- 
2.43.0


[PATCH v3 1/4] qcom: board: validate fdt before trying to use it

2024-03-11 Thread Volodymyr Babchuk
There are cases when previous bootloader stage leaves some seemingly
valid value in r0, which in fact does not point to valid FDT
blob. This behavior was encountered when trying to boot U-Boot as
"hyp" loader on SA8155P-ADP.

To be sure that we really got the pointer to a device tree we need to
validate it with fdt_check_header() function.

Note: This approach is not 100% fool-proof, as get_prev_bl_fdt_addr()
theoretically can return a pointer to a region that is not physically
mapped and we will get data abort exception when fdt_check_header()
will try to access it. But at this early boot stage we don't know
where RAM is anyways so there is little we can do.

Signed-off-by: Volodymyr Babchuk 
Reviewed-by: Sumit Garg 

---

Changes in v3:
 - Replaced fdt_valid() with fdt_check_header()
 - Added Sumit's R-B tag

Changes in v2:
 - New patch in v2

 arch/arm/mach-snapdragon/board.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index f12f5791a1..6f762fc948 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -93,7 +94,9 @@ void *board_fdt_blob_setup(int *err)
 * try and use the FDT built into U-Boot if there is one...
 * This avoids having a hard dependency on the previous stage bootloader
 */
-   if (IS_ENABLED(CONFIG_OF_SEPARATE) && (!fdt || fdt != ALIGN(fdt, 
SZ_4K))) {
+
+   if (IS_ENABLED(CONFIG_OF_SEPARATE) && (!fdt || fdt != ALIGN(fdt, SZ_4K) 
||
+  fdt_check_header((void *)fdt))) {
debug("%s: Using built in FDT, bootloader gave us %#llx\n", 
__func__, fdt);
return (void *)gd->fdt_blob;
}
-- 
2.43.0


Re: [PATCH v2 8/8] board: add support for Qualcomm SA8155P-ADP board

2024-03-11 Thread Volodymyr Babchuk



Caleb Connolly  writes:

> On 11/03/2024 18:23, Volodymyr Babchuk wrote:
>> Hi Caleb,
>> Caleb Connolly  writes:
>> 
>>> On 06/03/2024 21:24, Volodymyr Babchuk wrote:
>>>>
>>>> Hi Caleb,
>>>>
>>>> Caleb Connolly  writes:
>>>>
>>>> [...]
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> + {
>>>>>>>> +   /* U-Boot pinctrl driver does not understand multiple tiles */
>>>>>>>> +   reg = <0x0 0x0300 0x0 0x100>;
>>>>>>>> +   /delete-property/ reg-names;
>>>>>>>
>>>>>>> This won't be needed if we can make the tiles offset in the pinctrl
>>>>>>> driver compatible:
>>>>>>>
>>>>>>> #define WEST   0x
>>>>>>> #define EAST   0x0040
>>>>>>> #define NORTH  0x0080
>>>>>>> #define SOUTH  0x00C0
>>>>>>
>>>>>> Hmm, I assume that in this case pinctrl driver should map all the four
>>>>>> tiles independently? Are there guarantees in U-Boot that four separate
>>>>>> memory regions will be mapped into virtual memory with the same relative
>>>>>> positions? Linux clearly don't make such guarantees.
>>>>>
>>>>> U-Boot doesn't use virtual addresses on arm platforms, it only goes as
>>>>> far as reading the address from DT, nothing else, so this is totally
>>>>> fine and is how the other SoCs do it.
>>>>
>>>> For me it looks like we are depending on implementation details
>>>> knowledge. I.e MMU API does not provide such guarantees, but drivers
>>>> know how ARM MMU code is working internally and drivers depend on
>>>> exactly this behavior. But if you are saying that it is totally fine,
>>>> I'll rework the patch. No big deal. Actually, I already tried this and
>>>> it is working fine.
>>>>
>>>>>>>> +
>>>>>>>> +   /* U-Boot ethernet driver wants to drive reset as GPIO */
>>>>>>>> +   /delete-node/ phy-reset-pins;
>>>>>>>
>>>>>>> I suppose this is not needed as phy-reset-pins also configures the pin
>>>>>>> as GPIO only.
>>>>>>>
>>>>>> Well, yes. This also puzzles me up, but for some reason it stops working
>>>>>> if I leave this node intact. Looks like I need to look at this deeper
>>>>>> before posting the next version.
>>>>>
>>>>> Possibly the pinconf defined in the phy-reset-pins node causes U-Boot to
>>>>> misbehave, can you check if this patch fixes it (there is a bug in the
>>>>> line "return msm_gpio_direction_input(dev, gpio);", it should become
>>>>> just "msm_gpio_direction_input(dev, gpio);").
>>>>>
>>>>> I had the exact same issue with the gpio-regulator driver and this was
>>>>> the solution I ended up going with.
>>>>>
>>>>> https://urldefense.com/v3/__https://lore.kernel.org/u-boot/20240131-b4-qcom-livetree-v1-7-4071c0787...@linaro.org/__;!!GF_29dbcQIUBPA!xFhZe7DKgRbr63sirEJLuH-B0AnGs7jvx8tdJPKLTgFuZ3I3_zpVml7l23G-_vJO_JiUR-wUO4GMPJFcE-8p50H3pf7nbxit$
>>>>> [lore[.]kernel[.]org]
>>>>
>>>> It is exactly this. With your patch I don't need to /delete-node/
>>>> anymore. I'll add a comment in the cover message that this series are
>>>> depended on your patch.
>>>
>>> Please can you split the power domain and clock patches into a separate
>>> series? As I'd like to depend on them for the next revision of my
>>> series, and we'd otherwise have a cyclical dependency.
>> Of course.
>> As I understood, you are interested in "clk: qcom: clear div mask
>> before
>> assigning a new divider" and "clk: qcom: add support for power domains
>> uclass", correct?
>
> Yes.

Okay, I'll send it today.

> I tried the power domain stuff out on SMD845 today and ran into
> quite a few issues. Specifically as a lot of the devices reference the
> rpmhpd power domain which we don't support (and don't *need* to
> support) in U-Boot. I'm not sure what the best way forward will be for
> this. Maybe a "nop" power domain driver?

Are you sure that they are not required?

"nop" power domain always is the option. Especially if it prints some
warning about an unknown device. I had quite a lot of issues with clock and
pin drivers that silently ignore unknown devices...

> Do you have the same issues on sm8150?

Yes and no. No, because I was lucky so far and devices I tried to use in
U-Boot does not require rpmhpd. Looking at DTS, I may only encounter
issues with sdhc_2, which requires rpmhpd for some reason. Also UFS
requires clock from rpmhcc.

And "yes", because I have found root cause for my troubles with UFS in
Linux kernel, when I am skipping hyp.mbn. This is not strictly related
to U-Boot, but you may be interested in this: apparently Qualcomm's
hypervisor enables access to RPM (maybe brings it out of reset?). cmd-db
shared memory region can't be accessed if I skip the hypervisor and try
to boot directly into Linux. So now I am looking for ways to enable it.

-- 
WBR, Volodymyr

Re: [PATCH v2 8/8] board: add support for Qualcomm SA8155P-ADP board

2024-03-11 Thread Volodymyr Babchuk


Hi Caleb,

Caleb Connolly  writes:

> On 06/03/2024 21:24, Volodymyr Babchuk wrote:
>> 
>> Hi Caleb,
>> 
>> Caleb Connolly  writes:
>> 
>> [...]
>>>>>> +};
>>>>>> +
>>>>>> + {
>>>>>> +   /* U-Boot pinctrl driver does not understand multiple tiles */
>>>>>> +   reg = <0x0 0x0300 0x0 0x100>;
>>>>>> +   /delete-property/ reg-names;
>>>>>
>>>>> This won't be needed if we can make the tiles offset in the pinctrl
>>>>> driver compatible:
>>>>>
>>>>> #define WEST   0x
>>>>> #define EAST   0x0040
>>>>> #define NORTH  0x0080
>>>>> #define SOUTH  0x00C0
>>>>
>>>> Hmm, I assume that in this case pinctrl driver should map all the four
>>>> tiles independently? Are there guarantees in U-Boot that four separate
>>>> memory regions will be mapped into virtual memory with the same relative
>>>> positions? Linux clearly don't make such guarantees.
>>>
>>> U-Boot doesn't use virtual addresses on arm platforms, it only goes as
>>> far as reading the address from DT, nothing else, so this is totally
>>> fine and is how the other SoCs do it.
>> 
>> For me it looks like we are depending on implementation details
>> knowledge. I.e MMU API does not provide such guarantees, but drivers
>> know how ARM MMU code is working internally and drivers depend on
>> exactly this behavior. But if you are saying that it is totally fine,
>> I'll rework the patch. No big deal. Actually, I already tried this and
>> it is working fine.
>> 
>>>>>> +
>>>>>> +   /* U-Boot ethernet driver wants to drive reset as GPIO */
>>>>>> +   /delete-node/ phy-reset-pins;
>>>>>
>>>>> I suppose this is not needed as phy-reset-pins also configures the pin
>>>>> as GPIO only.
>>>>>
>>>> Well, yes. This also puzzles me up, but for some reason it stops working
>>>> if I leave this node intact. Looks like I need to look at this deeper
>>>> before posting the next version.
>>>
>>> Possibly the pinconf defined in the phy-reset-pins node causes U-Boot to
>>> misbehave, can you check if this patch fixes it (there is a bug in the
>>> line "return msm_gpio_direction_input(dev, gpio);", it should become
>>> just "msm_gpio_direction_input(dev, gpio);").
>>>
>>> I had the exact same issue with the gpio-regulator driver and this was
>>> the solution I ended up going with.
>>>
>>> https://urldefense.com/v3/__https://lore.kernel.org/u-boot/20240131-b4-qcom-livetree-v1-7-4071c0787...@linaro.org/__;!!GF_29dbcQIUBPA!xFhZe7DKgRbr63sirEJLuH-B0AnGs7jvx8tdJPKLTgFuZ3I3_zpVml7l23G-_vJO_JiUR-wUO4GMPJFcE-8p50H3pf7nbxit$
>>> [lore[.]kernel[.]org]
>> 
>> It is exactly this. With your patch I don't need to /delete-node/
>> anymore. I'll add a comment in the cover message that this series are
>> depended on your patch.
>
> Please can you split the power domain and clock patches into a separate
> series? As I'd like to depend on them for the next revision of my
> series, and we'd otherwise have a cyclical dependency.

Of course.

As I understood, you are interested in "clk: qcom: clear div mask before
assigning a new divider" and "clk: qcom: add support for power domains
uclass", correct?


-- 
WBR, Volodymyr

Re: [PATCH v2 8/8] board: add support for Qualcomm SA8155P-ADP board

2024-03-06 Thread Volodymyr Babchuk


Hi Caleb,

Caleb Connolly  writes:

[...]
>>>> +};
>>>> +
>>>> + {
>>>> +   /* U-Boot pinctrl driver does not understand multiple tiles */
>>>> +   reg = <0x0 0x0300 0x0 0x100>;
>>>> +   /delete-property/ reg-names;
>>>
>>> This won't be needed if we can make the tiles offset in the pinctrl
>>> driver compatible:
>>>
>>> #define WEST   0x
>>> #define EAST   0x0040
>>> #define NORTH  0x0080
>>> #define SOUTH  0x00C0
>> 
>> Hmm, I assume that in this case pinctrl driver should map all the four
>> tiles independently? Are there guarantees in U-Boot that four separate
>> memory regions will be mapped into virtual memory with the same relative
>> positions? Linux clearly don't make such guarantees.
>
> U-Boot doesn't use virtual addresses on arm platforms, it only goes as
> far as reading the address from DT, nothing else, so this is totally
> fine and is how the other SoCs do it.

For me it looks like we are depending on implementation details
knowledge. I.e MMU API does not provide such guarantees, but drivers
know how ARM MMU code is working internally and drivers depend on
exactly this behavior. But if you are saying that it is totally fine,
I'll rework the patch. No big deal. Actually, I already tried this and
it is working fine.

>>>> +
>>>> +   /* U-Boot ethernet driver wants to drive reset as GPIO */
>>>> +   /delete-node/ phy-reset-pins;
>>>
>>> I suppose this is not needed as phy-reset-pins also configures the pin
>>> as GPIO only.
>>>
>> Well, yes. This also puzzles me up, but for some reason it stops working
>> if I leave this node intact. Looks like I need to look at this deeper
>> before posting the next version.
>
> Possibly the pinconf defined in the phy-reset-pins node causes U-Boot to
> misbehave, can you check if this patch fixes it (there is a bug in the
> line "return msm_gpio_direction_input(dev, gpio);", it should become
> just "msm_gpio_direction_input(dev, gpio);").
>
> I had the exact same issue with the gpio-regulator driver and this was
> the solution I ended up going with.
>
> https://urldefense.com/v3/__https://lore.kernel.org/u-boot/20240131-b4-qcom-livetree-v1-7-4071c0787...@linaro.org/__;!!GF_29dbcQIUBPA!xFhZe7DKgRbr63sirEJLuH-B0AnGs7jvx8tdJPKLTgFuZ3I3_zpVml7l23G-_vJO_JiUR-wUO4GMPJFcE-8p50H3pf7nbxit$
> [lore[.]kernel[.]org]

It is exactly this. With your patch I don't need to /delete-node/
anymore. I'll add a comment in the cover message that this series are
depended on your patch.

(and sorry for the mangled link. It is our corporate mail server doing)


>> 
>>>> +};
>>>> diff --git a/board/qualcomm/sa8155p-adp/MAINTAINERS 
>>>> b/board/qualcomm/sa8155p-adp/MAINTAINERS
>>>> new file mode 100644
>>>> index 00..03fac84f51
>>>> --- /dev/null
>>>> +++ b/board/qualcomm/sa8155p-adp/MAINTAINERS
>>>> @@ -0,0 +1,5 @@
>>>> +Qualcomm SA8155P Automotive Development Platform
>>>> +M: Volodymyr Babchuk 
>>>> +S: Maintained
>>>> +F: board/qualcomm/sa8155p-adp/
>>>> +F: configs/sa8155p-adp_defconfig
>>>> diff --git a/configs/sa8155p_adp_defconfig b/configs/sa8155p_adp_defconfig
>>>> new file mode 100644
>>>> index 00..b6969767f8
>>>> --- /dev/null
>>>> +++ b/configs/sa8155p_adp_defconfig
>>>> @@ -0,0 +1,35 @@
>>>> +CONFIG_ARM=y
>>>> +CONFIG_SKIP_LOWLEVEL_INIT=y
>>>> +CONFIG_COUNTER_FREQUENCY=1900
>>>> +CONFIG_POSITION_INDEPENDENT=y
>>>> +CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y
>>>> +CONFIG_ARCH_SNAPDRAGON=y
>>>> +CONFIG_TEXT_BASE=0x8571
>>>
>>> Being position independent shouldn't require a hardcoded U-Boot text
>>> base. Can you try if we can get rid of this?
>>>
>> 
>> Well, it is required if we want to load U-Boot instead of hyp.mbn. We
>> need correct addresses in the ELF file so Qualcomm loader will not
>> reject it right away.
>> 
>>>> +CONFIG_DEFAULT_DEVICE_TREE="qcom/sa8155p-adp"
>>>> +CONFIG_IDENT_STRING="\nQualcomm SA8155P-ADP"
>>>> +CONFIG_SYS_LOAD_ADDR=0x8571
>>>
>>> Ditto.
>>>
>>>> +CONFIG_REMAKE_ELF=y
>>>> +CONFIG_BOOTDELAY=3
>>>> +CONFIG_SYS_CBSIZE=512
>>>> +# CONFIG_DISPLAY_CPUINFO is not set
>>>> +CONFIG_HUSH_PARSER=y
>>>> +C

Re: [PATCH v2 8/8] board: add support for Qualcomm SA8155P-ADP board

2024-03-06 Thread Volodymyr Babchuk


Hi Sumit,

Sumit Garg  writes:

> Hi Volodymyr,
>
> On Wed, 6 Mar 2024 at 06:23, Volodymyr Babchuk
>  wrote:
>>
>> SA8155P Automotive Development Platform is Qualcomm SA8155-based board
>> for developers. The nice thing that it has unlocked loaders with test
>> keys support, which means that U-Boot for this platform can be
>> launched at earlier stages.
>>
>> This patch adds basic board support with only serial port and
>> networking operation. I am using U-Boot to ease up Xen porting onto
>> this board, so I am mostly interesting in booting U-Boot in EL2. But
>> more conventional setup with Android boot image is supported as well.
>>
>> Signed-off-by: Volodymyr Babchuk 
>>
>> ---
>>
>> Changes in v2:
>>  - Rebased onto qcom-next branch
>>  - Removed unnecessary files thanks to generic qualcomm board support
>>  - Enabled CONFIG_REMAKE_ELF (this removes one extra step in the
>>readme)
>
> Thanks for the rebase.

Thank you for the review.

>>
>>  arch/arm/dts/sa8155p-adp-u-boot.dtsi   | 30 +
>>  board/qualcomm/sa8155p-adp/MAINTAINERS |  5 ++
>>  configs/sa8155p_adp_defconfig  | 35 +++
>>  doc/board/qualcomm/index.rst   |  1 +
>>  doc/board/qualcomm/sa8155p-adp.rst | 87 ++
>>  5 files changed, 158 insertions(+)
>>  create mode 100644 arch/arm/dts/sa8155p-adp-u-boot.dtsi
>>  create mode 100644 board/qualcomm/sa8155p-adp/MAINTAINERS
>>  create mode 100644 configs/sa8155p_adp_defconfig
>>  create mode 100644 doc/board/qualcomm/sa8155p-adp.rst
>>
>> diff --git a/arch/arm/dts/sa8155p-adp-u-boot.dtsi 
>> b/arch/arm/dts/sa8155p-adp-u-boot.dtsi
>> new file mode 100644
>> index 00..ffbf0933c7
>> --- /dev/null
>> +++ b/arch/arm/dts/sa8155p-adp-u-boot.dtsi
>> @@ -0,0 +1,30 @@
>> +// SPDX-License-Identifier: BSD-3-Clause
>> +/*
>> + * Qualcomm SA8155P-ADP device tree fixups for U-BOot
>> + *
>> + * Volodymyr Babchuk 
>> + * Copyright (c) 2024 EPAM Systems.
>> + */
>> +
>> +/ {
>> +   /* Populate memory node with actual memory configuration */
>> +   memory@8000 {
>> +   reg = <0x00 0x8000 0x00 0x3990>,
>> +   <0x02 0x00x1  0x7fd0>,
>> +   <0x00 0xC000 0x1  0x4000>;
>> +   };
>> +};
>> +
>> + {
>> +   /* Ethernet driver tries to find reset by name */
>> +   reset-names = "emac";
>
> This deserves to be pushed upstream in Linux kernel DT. In the
> meantime we can carry it here.
>
>> +};
>> +
>> + {
>> +   /* U-Boot pinctrl driver does not understand multiple tiles */
>> +   reg = <0x0 0x0300 0x0 0x100>;
>> +   /delete-property/ reg-names;
>
> This won't be needed if we can make the tiles offset in the pinctrl
> driver compatible:
>
> #define WEST   0x
> #define EAST   0x0040
> #define NORTH  0x0080
> #define SOUTH  0x00C0

Hmm, I assume that in this case pinctrl driver should map all the four
tiles independently? Are there guarantees in U-Boot that four separate
memory regions will be mapped into virtual memory with the same relative
positions? Linux clearly don't make such guarantees.

>> +
>> +   /* U-Boot ethernet driver wants to drive reset as GPIO */
>> +   /delete-node/ phy-reset-pins;
>
> I suppose this is not needed as phy-reset-pins also configures the pin
> as GPIO only.
>
Well, yes. This also puzzles me up, but for some reason it stops working
if I leave this node intact. Looks like I need to look at this deeper
before posting the next version.

>> +};
>> diff --git a/board/qualcomm/sa8155p-adp/MAINTAINERS 
>> b/board/qualcomm/sa8155p-adp/MAINTAINERS
>> new file mode 100644
>> index 00..03fac84f51
>> --- /dev/null
>> +++ b/board/qualcomm/sa8155p-adp/MAINTAINERS
>> @@ -0,0 +1,5 @@
>> +Qualcomm SA8155P Automotive Development Platform
>> +M: Volodymyr Babchuk 
>> +S: Maintained
>> +F: board/qualcomm/sa8155p-adp/
>> +F: configs/sa8155p-adp_defconfig
>> diff --git a/configs/sa8155p_adp_defconfig b/configs/sa8155p_adp_defconfig
>> new file mode 100644
>> index 00..b6969767f8
>> --- /dev/null
>> +++ b/configs/sa8155p_adp_defconfig
>> @@ -0,0 +1,35 @@
>> +CONFIG_ARM=y
>> +CONFIG_SKIP_LOWLEVEL_INIT=y
>> +CONFIG_COUNTER_FREQUENCY=1900
>> +CONFIG_POSITION_INDEPENDENT=y
>> +CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y
&g

[PATCH v2 0/8] Add support for Qualcomm SA8155-ADP board

2024-03-05 Thread Volodymyr Babchuk


This patch series adds support for Qualcomm SA8155-ADP development
board. Main motivation for this series is to allow running
virtualization software on this board and U-Boot is a good way to
break Qualcomm's boot chain at EL2 with more convenient ways for
uploading and running the code. With this patches applied it is
possible to upload and run Xen on this board. KVM probably should work
too.

I added myself as a maintainer for this board, but my abilities to
maintain it are quite limited as I have no access to Qualcomm
documentation. I used mostly Linux drivers as the source for
device-specific information, like register addresses and offsets.
If anyone wants to maintain this, I will gladly agree.

This is the second version of the series. It is now rebased onto
qcom-next branch.


Changes in v2:
 - New patch in v2
 - Clear loopback bit explicitly
 - Reworked qcom_cc_bind() function
 - Added timeout to qcom_power_set()
 - Minor fixes in register names and formatting
 - Renamed GPLL7_MAIN to just GPLL7 (while I like idea to use Linux
   naming convention, such rework needs to be done in a separate
   commit)
 - Removed unnecessary include
 - Fixed GDSCR register values for couple of devices
 - Enable GPLL7 only when RGMII clock is enabled
 - Rebased onto qcom-next branch
 - Removed unnecessary files thanks to generic qualcomm board support
 - Enabled CONFIG_REMAKE_ELF (this removes one extra step in the
   readme)

Volodymyr Babchuk (8):
  qcom: board: validate fdt before trying to use it
  clk: qcom: clear div mask before assigning a new divider
  net: dw_eth_qos: add support for Qualcomm SM8150 SoC
  clk: qcom: add support for power domains uclass
  clk: qcom: add driver for SM8150 SoC
  pinctrl: qcom: pass pin number to get_function_mux callback
  pinctrl: qcom: add driver for SM8150 SoC
  board: add support for Qualcomm SA8155P-ADP board

 arch/arm/dts/sa8155p-adp-u-boot.dtsi   |  30 ++
 arch/arm/mach-snapdragon/board.c   |   5 +-
 board/qualcomm/sa8155p-adp/MAINTAINERS |   5 +
 configs/sa8155p_adp_defconfig  |  35 ++
 doc/board/qualcomm/index.rst   |   1 +
 doc/board/qualcomm/sa8155p-adp.rst |  87 
 drivers/clk/qcom/Kconfig   |   8 +
 drivers/clk/qcom/Makefile  |   1 +
 drivers/clk/qcom/clock-qcom.c  | 131 +-
 drivers/clk/qcom/clock-qcom.h  |   7 +
 drivers/clk/qcom/clock-sm8150.c| 237 ++
 drivers/net/dwc_eth_qos.c  |   4 +
 drivers/net/dwc_eth_qos.h  |   2 +
 drivers/net/dwc_eth_qos_qcom.c |  46 +-
 drivers/pinctrl/qcom/Kconfig   |   7 +
 drivers/pinctrl/qcom/Makefile  |   1 +
 drivers/pinctrl/qcom/pinctrl-apq8016.c |   3 +-
 drivers/pinctrl/qcom/pinctrl-apq8096.c |   3 +-
 drivers/pinctrl/qcom/pinctrl-ipq4019.c |   3 +-
 drivers/pinctrl/qcom/pinctrl-qcom.c|   4 +-
 drivers/pinctrl/qcom/pinctrl-qcom.h|   3 +-
 drivers/pinctrl/qcom/pinctrl-qcs404.c  |   3 +-
 drivers/pinctrl/qcom/pinctrl-sdm845.c  |   3 +-
 drivers/pinctrl/qcom/pinctrl-sm8150.c  | 589 +
 24 files changed, 1186 insertions(+), 32 deletions(-)
 create mode 100644 arch/arm/dts/sa8155p-adp-u-boot.dtsi
 create mode 100644 board/qualcomm/sa8155p-adp/MAINTAINERS
 create mode 100644 configs/sa8155p_adp_defconfig
 create mode 100644 doc/board/qualcomm/sa8155p-adp.rst
 create mode 100644 drivers/clk/qcom/clock-sm8150.c
 create mode 100644 drivers/pinctrl/qcom/pinctrl-sm8150.c

-- 
2.43.0


[PATCH v2 3/8] net: dw_eth_qos: add support for Qualcomm SM8150 SoC

2024-03-05 Thread Volodymyr Babchuk
Add support for Qualcomm SM8150 SoC to the EQOS driver. SM8150 has two
main differences from already supported QCS404: it has another RGMII
configuration registers set and it does require RGMII loopback to
be disabled.

To support different variants of QCOM SoC we had to add two new fields
to the eqos_priv struct: eqos_qcom_rgmii_regs and
qcom_enable_loopback.

Signed-off-by: Volodymyr Babchuk 

---

Changes in v2:
 - Clear loopback bit explicitly

 drivers/net/dwc_eth_qos.c  |  4 +++
 drivers/net/dwc_eth_qos.h  |  2 ++
 drivers/net/dwc_eth_qos_qcom.c | 46 +++---
 3 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 9b3bce1dc8..882b854697 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1700,6 +1700,10 @@ static const struct udevice_id eqos_ids[] = {
.compatible = "qcom,qcs404-ethqos",
.data = (ulong)_qcom_config
},
+   {
+   .compatible = "qcom,sm8150-ethqos",
+   .data = (ulong)_qcom_config
+   },
 #endif
 #if IS_ENABLED(CONFIG_DWC_ETH_QOS_STARFIVE)
{
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
index e3222e1e17..216e1afe53 100644
--- a/drivers/net/dwc_eth_qos.h
+++ b/drivers/net/dwc_eth_qos.h
@@ -255,6 +255,7 @@ struct eqos_priv {
struct eqos_dma_regs *dma_regs;
struct eqos_tegra186_regs *tegra186_regs;
void *eqos_qcom_rgmii_regs;
+   struct dwmac_rgmii_regs *eqos_qcom_por;
struct reset_ctl reset_ctl;
struct gpio_desc phy_reset_gpio;
struct clk clk_master_bus;
@@ -277,6 +278,7 @@ struct eqos_priv {
bool started;
bool reg_access_ok;
bool clk_ck_enabled;
+   bool qcom_enable_loopback;
unsigned int tx_fifo_sz, rx_fifo_sz;
u32 reset_delays[3];
 };
diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c
index 8178138fc6..ee8420c71d 100644
--- a/drivers/net/dwc_eth_qos_qcom.c
+++ b/drivers/net/dwc_eth_qos_qcom.c
@@ -95,6 +95,15 @@ static struct dwmac_rgmii_regs emac_v2_3_0_por = {
.io_macro_config2 = 0x2060
 };
 
+static struct dwmac_rgmii_regs emac_v2_1_0_por = {
+   .io_macro_config = 0x40C01343,
+   .sdcc_hc_dll_config = 0x2004642C,
+   .sdcc_hc_ddr_config = 0x,
+   .sdcc_hc_dll_config2 = 0x0020,
+   .sdcc_usr_ctl = 0x00010800,
+   .io_macro_config2 = 0x2060
+};
+
 static void ethqos_set_func_clk_en(struct dwmac_rgmii_regs *regs)
 {
setbits_le32(>io_macro_config, RGMII_CONFIG_FUNC_CLK_EN);
@@ -172,6 +181,10 @@ static int ethqos_rgmii_macro_init(struct udevice *dev,
   struct dwmac_rgmii_regs *regs,
   unsigned long speed)
 {
+   struct eqos_priv *eqos = dev_get_priv(dev);
+   uint32_t loopback =
+   eqos->qcom_enable_loopback ? RGMII_CONFIG_LOOPBACK_EN : 0;
+
/* Disable loopback mode */
clrbits_le32(>io_macro_config2,
 RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN);
@@ -202,7 +215,8 @@ static int ethqos_rgmii_macro_init(struct udevice *dev,
SDCC_DDR_CONFIG_PRG_RCLK_DLY, 57);
setbits_le32(>sdcc_hc_ddr_config, 
SDCC_DDR_CONFIG_PRG_DLY_EN);
 
-   setbits_le32(>io_macro_config, RGMII_CONFIG_LOOPBACK_EN);
+   clrsetbits_le32(>io_macro_config,
+   RGMII_CONFIG_LOOPBACK_EN, loopback);
break;
 
case SPEED_100:
@@ -233,7 +247,8 @@ static int ethqos_rgmii_macro_init(struct udevice *dev,
setbits_le32(>sdcc_hc_ddr_config,
 SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN);
 
-   setbits_le32(>io_macro_config, RGMII_CONFIG_LOOPBACK_EN);
+   clrsetbits_le32(>io_macro_config,
+   RGMII_CONFIG_LOOPBACK_EN, loopback);
break;
 
case SPEED_10:
@@ -265,7 +280,8 @@ static int ethqos_rgmii_macro_init(struct udevice *dev,
setbits_le32(>sdcc_hc_ddr_config,
 SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN);
 
-   setbits_le32(>io_macro_config, RGMII_CONFIG_LOOPBACK_EN);
+   clrsetbits_le32(>io_macro_config,
+   RGMII_CONFIG_LOOPBACK_EN, loopback);
break;
 
default:
@@ -281,14 +297,15 @@ static int ethqos_configure(struct udevice *dev,
unsigned long speed)
 {
unsigned int retry = 1000;
+   struct eqos_priv *eqos = dev_get_priv(dev);
 
/* Reset to POR values and enable clk */
-   writel(emac_v2_3_0_por.io_macro_config, >io_macro_config);
-   writel(emac_v2_3_0_por.sdcc_hc_dll_config, >sdcc_hc_dll_config);
-   writel(emac_v2_3_0_por.sdcc_hc_ddr_config, >sdcc_h

[PATCH v2 6/8] pinctrl: qcom: pass pin number to get_function_mux callback

2024-03-05 Thread Volodymyr Babchuk
This patch is the preparation for SM8150 support. This new SoC
depending on the particular pin can have different numbers for the
same function. For example "rgmii" function for GPIO4 has id=2 while
for GPIO59 it has id=1. So, to support this type of SoCs,
get_function_mux() callback needs to know for which pin the function
is requested.

Signed-off-by: Volodymyr Babchuk 
Reviewed-by: Caleb Connolly 

---

Changes in v2:
 - Added Caleb's R-b tag

 drivers/pinctrl/qcom/pinctrl-apq8016.c | 3 ++-
 drivers/pinctrl/qcom/pinctrl-apq8096.c | 3 ++-
 drivers/pinctrl/qcom/pinctrl-ipq4019.c | 3 ++-
 drivers/pinctrl/qcom/pinctrl-qcom.c| 4 ++--
 drivers/pinctrl/qcom/pinctrl-qcom.h| 3 ++-
 drivers/pinctrl/qcom/pinctrl-qcs404.c  | 3 ++-
 drivers/pinctrl/qcom/pinctrl-sdm845.c  | 3 ++-
 7 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/pinctrl/qcom/pinctrl-apq8016.c 
b/drivers/pinctrl/qcom/pinctrl-apq8016.c
index db0e212468..a9a00f4b08 100644
--- a/drivers/pinctrl/qcom/pinctrl-apq8016.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8016.c
@@ -49,7 +49,8 @@ static const char *apq8016_get_pin_name(struct udevice *dev,
}
 }
 
-static unsigned int apq8016_get_function_mux(unsigned int selector)
+static unsigned int apq8016_get_function_mux(__maybe_unused unsigned int pin,
+unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-apq8096.c 
b/drivers/pinctrl/qcom/pinctrl-apq8096.c
index 880df8fe3c..9697cb5beb 100644
--- a/drivers/pinctrl/qcom/pinctrl-apq8096.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8096.c
@@ -44,7 +44,8 @@ static const char *apq8096_get_pin_name(struct udevice *dev,
}
 }
 
-static unsigned int apq8096_get_function_mux(unsigned int selector)
+static unsigned int apq8096_get_function_mux(__maybe_unused unsigned int pin,
+unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq4019.c 
b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
index 74c04ab87c..4479230313 100644
--- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c
+++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
@@ -40,7 +40,8 @@ static const char *ipq4019_get_pin_name(struct udevice *dev,
return pin_name;
 }
 
-static unsigned int ipq4019_get_function_mux(unsigned int selector)
+static unsigned int ipq4019_get_function_mux(__maybe_unused unsigned int pin,
+unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.c 
b/drivers/pinctrl/qcom/pinctrl-qcom.c
index ee0624df29..909e566acf 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcom.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.c
@@ -83,14 +83,14 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int 
pin_selector,
  unsigned int func_selector)
 {
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+   u32 func = priv->data->get_function_mux(pin_selector, func_selector);
 
/* Always NOP for special pins, assume they're in the correct state */
if (qcom_is_special_pin(>data->pin_data, pin_selector))
return 0;
 
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
-   TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
-   priv->data->get_function_mux(func_selector) << 2);
+   TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE, func << 2);
return 0;
 }
 
diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.h 
b/drivers/pinctrl/qcom/pinctrl-qcom.h
index 07f2eae9ba..49b7bfbc00 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcom.h
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.h
@@ -18,7 +18,8 @@ struct msm_pinctrl_data {
int functions_count;
const char *(*get_function_name)(struct udevice *dev,
 unsigned int selector);
-   unsigned int (*get_function_mux)(unsigned int selector);
+   unsigned int (*get_function_mux)(unsigned int pin,
+unsigned int selector);
const char *(*get_pin_name)(struct udevice *dev,
unsigned int selector);
 };
diff --git a/drivers/pinctrl/qcom/pinctrl-qcs404.c 
b/drivers/pinctrl/qcom/pinctrl-qcs404.c
index 3a2d468599..4b7c670c90 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcs404.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcs404.c
@@ -94,7 +94,8 @@ static const char *qcs404_get_pin_name(struct udevice *dev,
}
 }
 
-static unsigned int qcs404_get_function_mux(unsigned int selector)
+static unsigned int qcs404_get_function_mux(__maybe_unused unsigned int pin,
+   unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845.c 
b/

[PATCH v2 8/8] board: add support for Qualcomm SA8155P-ADP board

2024-03-05 Thread Volodymyr Babchuk
SA8155P Automotive Development Platform is Qualcomm SA8155-based board
for developers. The nice thing that it has unlocked loaders with test
keys support, which means that U-Boot for this platform can be
launched at earlier stages.

This patch adds basic board support with only serial port and
networking operation. I am using U-Boot to ease up Xen porting onto
this board, so I am mostly interesting in booting U-Boot in EL2. But
more conventional setup with Android boot image is supported as well.

Signed-off-by: Volodymyr Babchuk 

---

Changes in v2:
 - Rebased onto qcom-next branch
 - Removed unnecessary files thanks to generic qualcomm board support
 - Enabled CONFIG_REMAKE_ELF (this removes one extra step in the
   readme)

 arch/arm/dts/sa8155p-adp-u-boot.dtsi   | 30 +
 board/qualcomm/sa8155p-adp/MAINTAINERS |  5 ++
 configs/sa8155p_adp_defconfig  | 35 +++
 doc/board/qualcomm/index.rst   |  1 +
 doc/board/qualcomm/sa8155p-adp.rst | 87 ++
 5 files changed, 158 insertions(+)
 create mode 100644 arch/arm/dts/sa8155p-adp-u-boot.dtsi
 create mode 100644 board/qualcomm/sa8155p-adp/MAINTAINERS
 create mode 100644 configs/sa8155p_adp_defconfig
 create mode 100644 doc/board/qualcomm/sa8155p-adp.rst

diff --git a/arch/arm/dts/sa8155p-adp-u-boot.dtsi 
b/arch/arm/dts/sa8155p-adp-u-boot.dtsi
new file mode 100644
index 00..ffbf0933c7
--- /dev/null
+++ b/arch/arm/dts/sa8155p-adp-u-boot.dtsi
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Qualcomm SA8155P-ADP device tree fixups for U-BOot
+ *
+ * Volodymyr Babchuk 
+ * Copyright (c) 2024 EPAM Systems.
+ */
+
+/ {
+   /* Populate memory node with actual memory configuration */
+   memory@8000 {
+   reg = <0x00 0x8000 0x00 0x3990>,
+   <0x02 0x00x1  0x7fd0>,
+   <0x00 0xC000 0x1  0x4000>;
+   };
+};
+
+ {
+   /* Ethernet driver tries to find reset by name */
+   reset-names = "emac";
+};
+
+ {
+   /* U-Boot pinctrl driver does not understand multiple tiles */
+   reg = <0x0 0x0300 0x0 0x100>;
+   /delete-property/ reg-names;
+
+   /* U-Boot ethernet driver wants to drive reset as GPIO */
+   /delete-node/ phy-reset-pins;
+};
diff --git a/board/qualcomm/sa8155p-adp/MAINTAINERS 
b/board/qualcomm/sa8155p-adp/MAINTAINERS
new file mode 100644
index 00..03fac84f51
--- /dev/null
+++ b/board/qualcomm/sa8155p-adp/MAINTAINERS
@@ -0,0 +1,5 @@
+Qualcomm SA8155P Automotive Development Platform
+M: Volodymyr Babchuk 
+S: Maintained
+F: board/qualcomm/sa8155p-adp/
+F: configs/sa8155p-adp_defconfig
diff --git a/configs/sa8155p_adp_defconfig b/configs/sa8155p_adp_defconfig
new file mode 100644
index 00..b6969767f8
--- /dev/null
+++ b/configs/sa8155p_adp_defconfig
@@ -0,0 +1,35 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=1900
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y
+CONFIG_ARCH_SNAPDRAGON=y
+CONFIG_TEXT_BASE=0x8571
+CONFIG_DEFAULT_DEVICE_TREE="qcom/sa8155p-adp"
+CONFIG_IDENT_STRING="\nQualcomm SA8155P-ADP"
+CONFIG_SYS_LOAD_ADDR=0x8571
+CONFIG_REMAKE_ELF=y
+CONFIG_BOOTDELAY=3
+CONFIG_SYS_CBSIZE=512
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_OF_UPSTREAM=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_CLK_QCOM_SM8150=y
+CONFIG_MSM_GPIO=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_ETH_PHY=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_QCOM=y
+CONFIG_PHY=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_QCOM_SM8150=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MSM_GENI_SERIAL=y
+CONFIG_SPMI_MSM=y
+CONFIG_LMB_MAX_REGIONS=64
diff --git a/doc/board/qualcomm/index.rst b/doc/board/qualcomm/index.rst
index 4955274a39..268218b05f 100644
--- a/doc/board/qualcomm/index.rst
+++ b/doc/board/qualcomm/index.rst
@@ -7,5 +7,6 @@ Qualcomm
:maxdepth: 2
 
dragonboard410c
+   sa8155p-adp
board
debugging
diff --git a/doc/board/qualcomm/sa8155p-adp.rst 
b/doc/board/qualcomm/sa8155p-adp.rst
new file mode 100644
index 00..66db512b52
--- /dev/null
+++ b/doc/board/qualcomm/sa8155p-adp.rst
@@ -0,0 +1,87 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+.. sectionauthor:: Volodymyr Babchuk 
+
+SA8155P Automotive Development Platform
+===
+
+About
+-
+This document describes the information about SA8155P Automotive
+Development Platform aka SA8155P-ADP.
+
+Currently U-Boot can be booted either as Android boot image, or in EL2
+mode, instead of hypervisor image. In the latter case it is possible
+to use U-Boot to either boot Linux with KVM support or to boot Xen
+Hypervisor on this board.
+
+Supported HW modules
+
+Port for this board is in early development state. Right now U-Boot
+supports serial console a

[PATCH v2 5/8] clk: qcom: add driver for SM8150 SoC

2024-03-05 Thread Volodymyr Babchuk
Add clock, reset and power domain driver for SM8150. Driver code is
based on the similar U-Boot drivers. All constants are taken from the
corresponding Linux driver.

This driver supports clock rate setting only for the debug UART and
RGMII/Ethernet modules, because this is all I can test right now.

Signed-off-by: Volodymyr Babchuk 

---

Changes in v2:
 - Renamed GPLL7_MAIN to just GPLL7 (while I like idea to use Linux
   naming convention, such rework needs to be done in a separate
   commit)
 - Removed unnecessary include
 - Fixed GDSCR register values for couple of devices
 - Enable GPLL7 only when RGMII clock is enabled

 drivers/clk/qcom/Kconfig|   8 ++
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/clock-qcom.h   |   1 +
 drivers/clk/qcom/clock-sm8150.c | 237 
 4 files changed, 247 insertions(+)
 create mode 100644 drivers/clk/qcom/clock-sm8150.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 0df0d1881a..18ccf6a45e 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -47,6 +47,14 @@ config CLK_QCOM_SDM845
  on the Snapdragon 845 SoC. This driver supports the clocks
  and resets exposed by the GCC hardware block.
 
+config CLK_QCOM_SM8150
+   bool "Qualcomm SM8150 GCC"
+   select CLK_QCOM
+   help
+ Say Y here to enable support for the Global Clock Controller
+ on the Snapdragon 8150 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
+
 endmenu
 
 endif
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index cb179fdac5..12c09ba19e 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o
 obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o
 obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
 obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
+obj-$(CONFIG_CLK_QCOM_SM8150) += clock-sm8150.o
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
index 12a1eaec2b..dd40487e94 100644
--- a/drivers/clk/qcom/clock-qcom.h
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -9,6 +9,7 @@
 
 #define CFG_CLK_SRC_CXO   (0 << 8)
 #define CFG_CLK_SRC_GPLL0 (1 << 8)
+#define CFG_CLK_SRC_GPLL7 (3 << 8)
 #define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
 #define CFG_CLK_SRC_MASK  (7 << 8)
 
diff --git a/drivers/clk/qcom/clock-sm8150.c b/drivers/clk/qcom/clock-sm8150.c
new file mode 100644
index 00..2592eef29b
--- /dev/null
+++ b/drivers/clk/qcom/clock-sm8150.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm SM8150
+ *
+ * Volodymyr Babchuk 
+ * Copyright (c) 2024 EPAM Systems.
+ *
+ * Based on U-Boot driver for SDM845. Constants are taken from the Linux 
driver.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clock-qcom.h"
+
+static struct pll_vote_clk gpll7_vote_clk = {
+   .status = 0x1a000,
+   .status_bit = BIT(31),
+   .ena_vote = 0x52000,
+   .vote_bit = BIT(7),
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+   F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
+   F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
+   F(1920, CFG_CLK_SRC_CXO, 1, 0, 0),
+   F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
+   F(3200, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
+   F(4800, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
+   F(6400, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
+   F(8000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
+   F(9600, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
+   F(1, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
+   F(10240, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375),
+   F(11200, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75),
+   F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625),
+   F(12000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
+   F(12800, CFG_CLK_SRC_GPLL0, 1, 16, 75),
+   { }
+};
+
+static const struct freq_tbl ftbl_gcc_emac_rgmii_clk_src[] = {
+   F(250, CFG_CLK_SRC_CXO, 1, 25, 192),
+   F(500, CFG_CLK_SRC_CXO, 1, 25, 96),
+   F(1920, CFG_CLK_SRC_CXO, 1, 0, 0),
+   F(2500, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+   F(5000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
+   F(12500, CFG_CLK_SRC_GPLL7, 4, 0, 0),
+   F(25000, CFG_CLK_SRC_GPLL7, 2, 0, 0),
+   { }
+};
+
+static const struct bcr_regs uart2_regs = {
+   .cfg_rcgr = 0x1814C,
+   .cmd_rcgr = 0x18148,
+   .M = 0x18150,
+   .N = 0x18154,
+   .D = 0x18158,
+};
+
+static const struct bcr_regs rgmii_regs = {
+   .cfg_rcgr = 0x6020,
+   .cmd_rcgr = 0x601C,
+   .M = 0x6024,
+   .N = 0x6028,
+   .D = 0x602C,
+};
+
+static ulong sm8150_clk_set_rate(struct clk *clk, ulong rate)
+{
+   struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+   c

[PATCH v2 4/8] clk: qcom: add support for power domains uclass

2024-03-05 Thread Volodymyr Babchuk
Now sub-drivers for particular SoCs can register them as power domain
drivers. This is needed for upcoming SM8150 support, because it needs
to power up the Ethernet module.

Signed-off-by: Volodymyr Babchuk 

---

Changes in v2:
 - Reworked qcom_cc_bind() function
 - Added timeout to qcom_power_set()
 - Minor fixes in register names and formatting

 drivers/clk/qcom/clock-qcom.c | 128 ++
 drivers/clk/qcom/clock-qcom.h |   6 ++
 2 files changed, 121 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 729d190c54..c3f8d96183 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "clock-qcom.h"
 
@@ -30,6 +31,13 @@
 #define CBCR_BRANCH_ENABLE_BIT  BIT(0)
 #define CBCR_BRANCH_OFF_BIT BIT(31)
 
+#define GDSC_SW_COLLAPSE_MASK  BIT(0)
+#define GDSC_POWER_DOWN_COMPLETE   BIT(15)
+#define GDSC_POWER_UP_COMPLETE BIT(16)
+#define GDSC_PWR_ON_MASK   BIT(31)
+#define CFG_GDSCR_OFFSET   0x4
+#define GDSC_STATUS_POLL_TIMEOUT_US1500
+
 /* Enable clock controlled by CBC soft macro */
 void clk_enable_cbc(phys_addr_t cbcr)
 {
@@ -223,7 +231,7 @@ U_BOOT_DRIVER(qcom_clk) = {
 int qcom_cc_bind(struct udevice *parent)
 {
struct msm_clk_data *data = (struct msm_clk_data 
*)dev_get_driver_data(parent);
-   struct udevice *clkdev, *rstdev;
+   struct udevice *clkdev = NULL, *rstdev = NULL, *pwrdev;
struct driver *drv;
int ret;
 
@@ -238,20 +246,41 @@ int qcom_cc_bind(struct udevice *parent)
if (ret)
return ret;
 
-   /* Bail out early if resets are not specified for this platform */
-   if (!data->resets)
-   return ret;
+   if (data->resets) {
+   /* Get a handle to the common reset handler */
+   drv = lists_driver_lookup_name("qcom_reset");
+   if (!drv) {
+   ret = -ENOENT;
+   goto unbind_clkdev;
+   }
+
+   /* Register the reset controller */
+   ret = device_bind_with_driver_data(parent, drv, "qcom_reset", 
(ulong)data,
+  dev_ofnode(parent), );
+   if (ret)
+   goto unbind_clkdev;
+   }
 
-   /* Get a handle to the common reset handler */
-   drv = lists_driver_lookup_name("qcom_reset");
-   if (!drv)
-   return -ENOENT;
+   if (data->power_domains) {
+   /* Get a handle to the common power domain handler */
+   drv = lists_driver_lookup_name("qcom_power");
+   if (!drv) {
+   ret = -ENOENT;
+   goto unbind_rstdev;
+   }
+   /* Register the power domain controller */
+   ret = device_bind_with_driver_data(parent, drv, "qcom_power", 
(ulong)data,
+  dev_ofnode(parent), );
+   if (ret)
+   goto unbind_rstdev;
+   }
 
-   /* Register the reset controller */
-   ret = device_bind_with_driver_data(parent, drv, "qcom_reset", 
(ulong)data,
-  dev_ofnode(parent), );
-   if (ret)
-   device_unbind(clkdev);
+   return 0;
+
+unbind_rstdev:
+   device_unbind(rstdev);
+unbind_clkdev:
+   device_unbind(clkdev);
 
return ret;
 }
@@ -306,3 +335,76 @@ U_BOOT_DRIVER(qcom_reset) = {
.ops = _reset_ops,
.probe = qcom_reset_probe,
 };
+
+static int qcom_power_set(struct power_domain *pwr, bool on)
+{
+   struct msm_clk_data *data = (struct msm_clk_data 
*)dev_get_driver_data(pwr->dev);
+   void __iomem *base = dev_get_priv(pwr->dev);
+   unsigned long timeout;
+   const struct qcom_power_map *map;
+   u32 value;
+
+   if (pwr->id >= data->num_power_domains)
+   return -ENODEV;
+
+   map = >power_domains[pwr->id];
+
+   if (!map->reg)
+   return -ENODEV;
+
+   value = readl(base + map->reg);
+
+   if (on)
+   value &= ~GDSC_SW_COLLAPSE_MASK;
+   else
+   value |= GDSC_SW_COLLAPSE_MASK;
+
+   writel(value, base + map->reg);
+
+   timeout = timer_get_us() + GDSC_STATUS_POLL_TIMEOUT_US;
+   /* Wait for power on */
+   while (timeout > timer_get_us()) {
+   value = readl(base + map->reg + CFG_GDSCR_OFFSET);
+   if (on) {
+   if ((value & GDSC_POWER_UP_COMPLETE) ||
+   (value & GDSC_PWR_ON_MASK))
+   return 0;
+   } else {
+   if (value 

[PATCH v2 2/8] clk: qcom: clear div mask before assigning a new divider

2024-03-05 Thread Volodymyr Babchuk
The current behaviour does a bitwise OR of the previous and new
divider values, this is wrong as some bits maybe be set already. We
need to clear all the divider bits before applying new ones.

This fixes potential issue with 1Gbit ethernet on SA8155P-ADP boards.

Signed-off-by: Volodymyr Babchuk 
Reviewed-by: Caleb Connolly 

---

Changes in v2:
 - Reworded the commit message
 - Added Caleb's R-b tag

 drivers/clk/qcom/clock-qcom.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 7c683e5192..729d190c54 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -117,7 +117,8 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct 
bcr_regs *regs,
 
/* setup src select and divider */
cfg  = readl(base + regs->cfg_rcgr);
-   cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK);
+   cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK |
+CFG_SRC_DIV_MASK);
cfg |= source & CFG_SRC_SEL_MASK; /* Select clock source */
 
if (div)
-- 
2.43.0


[PATCH v2 7/8] pinctrl: qcom: add driver for SM8150 SoC

2024-03-05 Thread Volodymyr Babchuk
Add pinctrl and GPIO driver for SM8150. Driver code is based on the
similar U-Boot drivers. All constants are taken from the corresponding
Linux driver. This drivers differs from the similar U-Boot drivers,
because SM8150 SoC have different function IDs for the same functions
on different pins.

Signed-off-by: Volodymyr Babchuk 
---

(no changes since v1)

 drivers/pinctrl/qcom/Kconfig  |   7 +
 drivers/pinctrl/qcom/Makefile |   1 +
 drivers/pinctrl/qcom/pinctrl-sm8150.c | 589 ++
 3 files changed, 597 insertions(+)
 create mode 100644 drivers/pinctrl/qcom/pinctrl-sm8150.c

diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 2fe6398147..290cefca47 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -41,6 +41,13 @@ config PINCTRL_QCOM_SDM845
  Say Y here to enable support for pinctrl on the Snapdragon 845 SoC,
  as well as the associated GPIO driver.
 
+config PINCTRL_QCOM_SM8150
+   bool "Qualcomm SM8150 GCC"
+   select PINCTRL_QCOM
+   help
+ Say Y here to enable support for pinctrl on the Snapdragon SM8150 SoC,
+ as well as the associated GPIO driver.
+
 endmenu
 
 endif
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 6d9aca6d7b..3c7be4a685 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o
 obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
 obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
 obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
+obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8150.c 
b/drivers/pinctrl/qcom/pinctrl-sm8150.c
new file mode 100644
index 00..a6c14d7254
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-sm8150.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Qualcomm SM8150 pinctrl and GPIO driver
+ *
+ * Volodymyr Babchuk 
+ * Copyright (c) 2024 EPAM Systems.
+ *
+ * Based on similar U-Boot drivers. Constants were taken from the Linux driver
+ */
+
+#include 
+
+#include "pinctrl-qcom.h"
+
+#define WEST   0x0010
+#define EAST   0x0050
+#define NORTH  0x0090
+#define SOUTH  0x00D0
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+enum sm8150_functions {
+   msm_mux_adsp_ext,
+   msm_mux_agera_pll,
+   msm_mux_aoss_cti,
+   msm_mux_atest_char,
+   msm_mux_atest_char0,
+   msm_mux_atest_char1,
+   msm_mux_atest_char2,
+   msm_mux_atest_char3,
+   msm_mux_atest_usb1,
+   msm_mux_atest_usb2,
+   msm_mux_atest_usb10,
+   msm_mux_atest_usb11,
+   msm_mux_atest_usb12,
+   msm_mux_atest_usb13,
+   msm_mux_atest_usb20,
+   msm_mux_atest_usb21,
+   msm_mux_atest_usb22,
+   msm_mux_atest_usb23,
+   msm_mux_audio_ref,
+   msm_mux_btfm_slimbus,
+   msm_mux_cam_mclk,
+   msm_mux_cci_async,
+   msm_mux_cci_i2c,
+   msm_mux_cci_timer0,
+   msm_mux_cci_timer1,
+   msm_mux_cci_timer2,
+   msm_mux_cci_timer3,
+   msm_mux_cci_timer4,
+   msm_mux_cri_trng,
+   msm_mux_cri_trng0,
+   msm_mux_cri_trng1,
+   msm_mux_dbg_out,
+   msm_mux_ddr_bist,
+   msm_mux_ddr_pxi0,
+   msm_mux_ddr_pxi1,
+   msm_mux_ddr_pxi2,
+   msm_mux_ddr_pxi3,
+   msm_mux_edp_hot,
+   msm_mux_edp_lcd,
+   msm_mux_emac_phy,
+   msm_mux_emac_pps,
+   msm_mux_gcc_gp1,
+   msm_mux_gcc_gp2,
+   msm_mux_gcc_gp3,
+   msm_mux_gpio,
+   msm_mux_jitter_bist,
+   msm_mux_hs1_mi2s,
+   msm_mux_hs2_mi2s,
+   msm_mux_hs3_mi2s,
+   msm_mux_lpass_slimbus,
+   msm_mux_mdp_vsync,
+   msm_mux_mdp_vsync0,
+   msm_mux_mdp_vsync1,
+   msm_mux_mdp_vsync2,
+   msm_mux_mdp_vsync3,
+   msm_mux_mss_lte,
+   msm_mux_m_voc,
+   msm_mux_nav_pps,
+   msm_mux_pa_indicator,
+   msm_mux_pci_e0,
+   msm_mux_pci_e1,
+   msm_mux_phase_flag,
+   msm_mux_pll_bist,
+   msm_mux_pll_bypassnl,
+   msm_mux_pll_reset,
+   msm_mux_pri_mi2s,
+   msm_mux_pri_mi2s_ws,
+   msm_mux_prng_rosc,
+   msm_mux_qdss,
+   msm_mux_qdss_cti,
+   msm_mux_qlink_enable,
+   msm_mux_qlink_request,
+   msm_mux_qspi0,
+   msm_mux_qspi1,
+   msm_mux_qspi2,
+   msm_mux_qspi3,
+   msm_mux_qspi_clk,
+   msm_mux_qspi_cs,
+   msm_mux_qua_mi2s,
+   msm_mux_qup0,
+   msm_mux_qup1,
+   msm_mux_qup2,
+   msm_mux_qup3,
+   msm_mux_qup4,
+   msm_mux_qup5,
+   msm_mux_qup6,
+   msm_mux_qup7,
+   msm_mux_qup8,
+   msm_mux_qup9,
+   msm_mux_qup10,
+   msm_mux_qup11,
+   msm_mux_qup12,
+   msm_mux_qup13,
+   msm_mux_qup14,
+   msm_mux_qup15,
+   msm_mux_qup16,
+   msm_mu

[PATCH v2 1/8] qcom: board: validate fdt before trying to use it

2024-03-05 Thread Volodymyr Babchuk
There are cases when previous bootloader stage leaves some seemingly
valid value in r0, which in fact does not point to valid FDT
blob. This behavior was encountered when trying to boot U-Boot as
"hyp" loader on SA8155P-ADP.

To be sure that we really got the pointer to a device tree we need to
validate it with fdt_valid() function.

Note: This approach is not 100% fool-proof, as get_prev_bl_fdt_addr()
theoretically can return a pointer to a region that is not physically
mapped and we will get data abort exception when "fdt_valid" will try
to access it. But at this early boot stage we don't know where RAM is
anyways so there is little we can do.

Signed-off-by: Volodymyr Babchuk 

---

Changes in v2:
 - New patch in v2

 arch/arm/mach-snapdragon/board.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index f12f5791a1..10eec47ada 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -93,7 +94,9 @@ void *board_fdt_blob_setup(int *err)
 * try and use the FDT built into U-Boot if there is one...
 * This avoids having a hard dependency on the previous stage bootloader
 */
-   if (IS_ENABLED(CONFIG_OF_SEPARATE) && (!fdt || fdt != ALIGN(fdt, 
SZ_4K))) {
+
+   if (IS_ENABLED(CONFIG_OF_SEPARATE) && (!fdt || fdt != ALIGN(fdt, SZ_4K) 
||
+  !fdt_valid((void * {
debug("%s: Using built in FDT, bootloader gave us %#llx\n", 
__func__, fdt);
return (void *)gd->fdt_blob;
}
-- 
2.43.0


Re: [PATCH 8/8] board: add support for Qualcomm SA8155P-ADP board

2024-03-04 Thread Volodymyr Babchuk


Hi Stephan,

Stephan Gerhold  writes:

[...]
>> +This approach ensures that U-Boot is booted in EL2 and it is possible
>> +to run virtualization software (like Xen or KVM) on the board. You
>> +must understand that this approach breaks Qualcomm's boot chain. You
>> +will not be able to call all subsequent loaders, so you will not be
>> +able to use fastboot for example. Use this approach only if you want
>> +to experiment with virtualization on SA8155P-ADP.
>> +
>> +We need to create ELF file from the u-boot binary. We can't use
>> +existing U-Boot ELF, because it does not include appended DTB
>> +file. Easiest way to do this is to use ``create_elf.py`` from the
>> +following repository: `qtestsign(lorc)
>> +> [github[.]com]>`_: ::
>> +
>> +$ python ../qtestsign/create_elf.py u-boot.bin 0x8571 u-boot.mbn
>> +
>
> Have you tried using CONFIG_REMAKE_ELF in U-Boot? That should
> effectively do the same (build a new ELF based on u-boot.bin with the
> appended device tree). The Qualcomm DragonBoard 410c port is using that
> option to solve the same problem.

I didn't knew that there is a such option. Looks like this is exactly
what I need, thank you. I'll include this in the V2.

> But I'm glad to see that the ELF abstractions in qtestsign worked well
> for your purpose. :-)

Well, I was surprised that pyelf can parse ELF files but can't modify
them. So your tool come in handy. I was going to make a PR that adds
this create_elf.py script, but looks like we don't need it.

-- 
WBR, Volodymyr

Re: [PATCH 0/8] Add support for Qualcomm SA8155-ADP board

2024-03-04 Thread Volodymyr Babchuk


Hi Stephan,

Stephan Gerhold  writes:

> On Fri, Mar 01, 2024 at 06:25:39PM +0000, Volodymyr Babchuk wrote:
>> Caleb Connolly  writes:
>> > On 29/02/2024 14:21, Volodymyr Babchuk wrote:
>> >> This patch series adds support for Qualcomm SA8155-ADP development
>> >> board. Main motivation for this series is to allow running
>> >> virtualization software on this board and U-Boot is a good way to
>> >> break Qualcomm's boot chain at EL2 with more convenient ways for
>> >> uploading and running the code. With this patches applied it is
>> >> possible to upload and run Xen on this board. KVM probably should work
>> >> too.
>> >
>> > This is really cool! I've experimented with this on SDM845 and SM8250
>> > but never really did anything with it... I'd love to take a look at your
>> > Xen branch?
>> 
>> Honestly, there is nothing to look at right now. I just implemented
>> early printk serial driver for the qcom, made hacks to the device tree
>> and trying to boot Dom0. I already expecting issues with the GPU,
>> because it has own SMMU without virtualization support and Xen already
>> complains about it. So I had to remove it from the DTS for a time being.
>> 
>
> Did you enable all the clocks/power domains/etc for the GPU SMMU? If I
> remember correctly it is off by default and all registers read as
> zeroes. The SMMU driver could easily get confused about the capabilities
> of the SMMU (e.g. the stage 2/virtualization support) if all the ID
> registers read as zeroes.

Ah, this is a great idea, thanks. I tried a quick test by enabling only
clocks that are provided by GCC, but looks like I need to enable GPUCC
clocks as well. So I need to write a driver for GPUCC or at least
figure which registers to write with a debugger. I'll try this later.

By the way, do you have any suggestion about my second issue? When Linux
in the Dom0 tries to access UFS, CPU gets a secure interrupt and hangs in
TZ. I had the same exactly behavior when I tried to access EMAC without enabling
clocks and power domains in U-Boot. But Linux should enable all
prerequisites for UFS... I suspect that there is an additional
initialization needs to be done, but I didn't figured it yet.

-- 
WBR, Volodymyr

Re: [PATCH 5/8] clk: qcom: add driver for SM8150 SoC

2024-03-01 Thread Volodymyr Babchuk


Hi Caleb,

Caleb Connolly  writes:

> On 29/02/2024 14:21, Volodymyr Babchuk wrote:
>> Add clock, reset and power domain driver for SM8150. Driver code is
>> based on the similar U-Boot drivers. All constants are taken from the
>> corresponding Linux driver.
>> 
>> This driver supports clock rate setting only for the debug UART and
>> RGMII/Ethernet modules, because this is all I can test right now.
>> 
>> Signed-off-by: Volodymyr Babchuk 
>> ---
>> 
>>  drivers/clk/qcom/Kconfig|   8 ++
>>  drivers/clk/qcom/Makefile   |   1 +
>>  drivers/clk/qcom/clock-qcom.h   |   1 +
>>  drivers/clk/qcom/clock-sm8150.c | 234 
>>  4 files changed, 244 insertions(+)
>>  create mode 100644 drivers/clk/qcom/clock-sm8150.c
>> 
>> diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
>> index 0df0d1881a..18ccf6a45e 100644
>> --- a/drivers/clk/qcom/Kconfig
>> +++ b/drivers/clk/qcom/Kconfig
>> @@ -47,6 +47,14 @@ config CLK_QCOM_SDM845
>>on the Snapdragon 845 SoC. This driver supports the clocks
>>and resets exposed by the GCC hardware block.
>>  
>> +config CLK_QCOM_SM8150
>> +bool "Qualcomm SM8150 GCC"
>> +select CLK_QCOM
>> +help
>> +  Say Y here to enable support for the Global Clock Controller
>> +  on the Snapdragon 8150 SoC. This driver supports the clocks
>> +  and resets exposed by the GCC hardware block.
>> +
>>  endmenu
>>  
>>  endif
>> diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
>> index cb179fdac5..12c09ba19e 100644
>> --- a/drivers/clk/qcom/Makefile
>> +++ b/drivers/clk/qcom/Makefile
>> @@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o
>>  obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o
>>  obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
>>  obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
>> +obj-$(CONFIG_CLK_QCOM_SM8150) += clock-sm8150.o
>> diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
>> index 12a1eaec2b..41107df216 100644
>> --- a/drivers/clk/qcom/clock-qcom.h
>> +++ b/drivers/clk/qcom/clock-qcom.h
>> @@ -9,6 +9,7 @@
>>  
>>  #define CFG_CLK_SRC_CXO   (0 << 8)
>>  #define CFG_CLK_SRC_GPLL0 (1 << 8)
>> +#define CFG_CLK_SRC_GPLL7_MAIN (3 << 8)
> Please follow the existing scheme and remove the _MAIN suffix.

Ah, yes, planned to do this, but looks like lost it when created a final
version of the patch.

> I'd also be fine with converting all of these definitions to follow how
> the Linux drivers name them.

This should be done in the separate patch, I think.

[...]


>> +static int sm8150_clk_enable(struct clk *clk)
>> +{
>> +struct msm_clk_priv *priv = dev_get_priv(clk->dev);
>> +
>> +clk_enable_gpll0(priv->base, _vote_clk);
> This will write to the GPLL for every single clock, I think you're
> missing a switch case block here.

Yes, you are right.

>> +qcom_gate_clk_en(priv, clk->id);
>> +
>> +return 0;
>> +}
>> +
>> +static const struct qcom_reset_map sm8150_gcc_resets[] = {
>> +[GCC_EMAC_BCR] = { 0x6000 },
>> +[GCC_GPU_BCR] = { 0x71000 },
>> +[GCC_MMSS_BCR] = { 0xb000 },
>> +[GCC_NPU_BCR] = { 0x4d000 },
>> +[GCC_PCIE_0_BCR] = { 0x6b000 },
>> +[GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
>> +[GCC_PCIE_1_BCR] = { 0x8d000 },
>> +[GCC_PCIE_1_PHY_BCR] = { 0x8e01c },
>> +[GCC_PCIE_PHY_BCR] = { 0x6f000 },
>> +[GCC_PDM_BCR] = { 0x33000 },
>> +[GCC_PRNG_BCR] = { 0x34000 },
>> +[GCC_QSPI_BCR] = { 0x24008 },
>> +[GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 },
>> +[GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
>> +[GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 },
>> +[GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
>> +[GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
>> +[GCC_USB3_PHY_PRIM_BCR] = { 0x5 },
>> +[GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
>> +[GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
>> +[GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
>> +[GCC_SDCC2_BCR] = { 0x14000 },
>> +[GCC_SDCC4_BCR] = { 0x16000 },
>> +[GCC_TSIF_BCR] = { 0x36000 },
>> +[GCC_UFS_CARD_BCR] = { 0x75000 },
>> +[GCC_UFS_PHY_BCR] = { 0x77000 },
>> +[GCC_USB30_PRIM_BCR] = { 0xf000 },
>> +[GCC_USB30_SEC_BCR] = { 0x1 },
>> +[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
>> +};
>> +
>> +static const struct qcom_power_map sm8150_gcc_power_domains[] = {
> This is really nice! Cert

Re: [PATCH 0/8] Add support for Qualcomm SA8155-ADP board

2024-03-01 Thread Volodymyr Babchuk


Hi Caleb,

Caleb Connolly  writes:

> On 29/02/2024 14:21, Volodymyr Babchuk wrote:
>> 
>> This patch series adds support for Qualcomm SA8155-ADP development
>> board. Main motivation for this series is to allow running
>> virtualization software on this board and U-Boot is a good way to
>> break Qualcomm's boot chain at EL2 with more convenient ways for
>> uploading and running the code. With this patches applied it is
>> possible to upload and run Xen on this board. KVM probably should work
>> too.
>
> This is really cool! I've experimented with this on SDM845 and SM8250
> but never really did anything with it... I'd love to take a look at your
> Xen branch?

Honestly, there is nothing to look at right now. I just implemented
early printk serial driver for the qcom, made hacks to the device tree
and trying to boot Dom0. I already expecting issues with the GPU,
because it has own SMMU without virtualization support and Xen already
complains about it. So I had to remove it from the DTS for a time being.

Anyways, right now my Dom0 does not want to boot due to some issues with
UFS. I suspect that some power domain or clock is disabled or some
other bit of initialization is missing in the mainline Linux. And
reason why bare Linux kernel have no issues with UFS is because
aboot/xbl does proper UFS initialization, while in my case I am skipping
the android bootloader completely...

I'll publish my work when I'll get Dom0 running.

-- 
WBR, Volodymyr

[PATCH 0/8] Add support for Qualcomm SA8155-ADP board

2024-02-29 Thread Volodymyr Babchuk


This patch series adds support for Qualcomm SA8155-ADP development
board. Main motivation for this series is to allow running
virtualization software on this board and U-Boot is a good way to
break Qualcomm's boot chain at EL2 with more convenient ways for
uploading and running the code. With this patches applied it is
possible to upload and run Xen on this board. KVM probably should work
too.

I added myself as a maintainer for this board, but my abilities to
maintain it are quite limited as I have no access to Qualcomm
documentation. I used mostly Linux drivers as the source for
device-specific information, like register addresses and offsets.
If anyone wants to maintain this, I will gladly agree.


Volodymyr Babchuk (8):
  clk: qcom: clear div mask before assigning new divider
  dts: qcom: import device trees and bindings for SA8155P-ADP
  net: dw_eth_qos: add support for Qualcomm SM8150 SoC
  clk: qcom: add support for power domains uclass
  clk: qcom: add driver for SM8150 SoC
  pinctr: qcom: pass pin number to get_function_mux callback
  pinctrl: qcom: add driver for SM8150 SoC
  board: add support for Qualcomm SA8155P-ADP board

 arch/arm/dts/pmm8155au_1.dtsi |  135 +
 arch/arm/dts/pmm8155au_2.dtsi |  108 +
 arch/arm/dts/sa8155p-adp-u-boot.dtsi  |   30 +
 arch/arm/dts/sa8155p-adp.dts  |  606 ++
 arch/arm/dts/sa8155p.dtsi |   40 +
 arch/arm/dts/sm8150.dtsi  | 5293 +
 arch/arm/mach-snapdragon/Kconfig  |   14 +
 arch/arm/mach-snapdragon/Makefile |2 +
 arch/arm/mach-snapdragon/init_sa8155p.c   |   30 +
 arch/arm/mach-snapdragon/sysmap-sm8150.c  |   31 +
 board/qualcomm/sa8155p-adp/Kconfig|   12 +
 board/qualcomm/sa8155p-adp/MAINTAINERS|6 +
 configs/sa8155p_adp_defconfig |   33 +
 doc/board/qualcomm/index.rst  |1 +
 doc/board/qualcomm/sa8155p-adp.rst|   94 +
 drivers/clk/qcom/Kconfig  |8 +
 drivers/clk/qcom/Makefile |1 +
 drivers/clk/qcom/clock-qcom.c |   96 +-
 drivers/clk/qcom/clock-qcom.h |7 +
 drivers/clk/qcom/clock-sm8150.c   |  234 +
 drivers/net/dwc_eth_qos.c |4 +
 drivers/net/dwc_eth_qos.h |2 +
 drivers/net/dwc_eth_qos_qcom.c|   47 +-
 drivers/pinctrl/qcom/Kconfig  |7 +
 drivers/pinctrl/qcom/Makefile |1 +
 drivers/pinctrl/qcom/pinctrl-apq8016.c|3 +-
 drivers/pinctrl/qcom/pinctrl-apq8096.c|3 +-
 drivers/pinctrl/qcom/pinctrl-ipq4019.c|3 +-
 drivers/pinctrl/qcom/pinctrl-qcom.c   |4 +-
 drivers/pinctrl/qcom/pinctrl-qcom.h   |3 +-
 drivers/pinctrl/qcom/pinctrl-qcs404.c |3 +-
 drivers/pinctrl/qcom/pinctrl-sdm845.c |3 +-
 drivers/pinctrl/qcom/pinctrl-sm8150.c |  589 ++
 include/configs/sa8155p_adp.h |   25 +
 .../dt-bindings/clock/qcom,dispcc-sm8150.h|   76 +
 include/dt-bindings/clock/qcom,gcc-sm8150.h   |  252 +
 include/dt-bindings/clock/qcom,gpucc-sm8150.h |   33 +
 include/dt-bindings/clock/qcom,rpmh.h |   37 +
 include/dt-bindings/dma/qcom-gpi.h|   11 +
 include/dt-bindings/firmware/qcom,scm.h   |   39 +
 include/dt-bindings/iio/qcom,spmi-vadc.h  |  303 +
 .../dt-bindings/interconnect/qcom,osm-l3.h|   15 +
 .../dt-bindings/interconnect/qcom,sm8150.h|  159 +
 include/dt-bindings/phy/phy-qcom-qmp.h|   20 +
 include/dt-bindings/power/qcom-rpmpd.h|  412 ++
 .../regulator/qcom,rpmh-regulator.h   |   36 +
 include/dt-bindings/soc/qcom,rpmh-rsc.h   |   14 +
 47 files changed, 8866 insertions(+), 19 deletions(-)
 create mode 100644 arch/arm/dts/pmm8155au_1.dtsi
 create mode 100644 arch/arm/dts/pmm8155au_2.dtsi
 create mode 100644 arch/arm/dts/sa8155p-adp-u-boot.dtsi
 create mode 100644 arch/arm/dts/sa8155p-adp.dts
 create mode 100644 arch/arm/dts/sa8155p.dtsi
 create mode 100644 arch/arm/dts/sm8150.dtsi
 create mode 100644 arch/arm/mach-snapdragon/init_sa8155p.c
 create mode 100644 arch/arm/mach-snapdragon/sysmap-sm8150.c
 create mode 100644 board/qualcomm/sa8155p-adp/Kconfig
 create mode 100644 board/qualcomm/sa8155p-adp/MAINTAINERS
 create mode 100644 configs/sa8155p_adp_defconfig
 create mode 100644 doc/board/qualcomm/sa8155p-adp.rst
 create mode 100644 drivers/clk/qcom/clock-sm8150.c
 create mode 100644 drivers/pinctrl/qcom/pinctrl-sm8150.c
 create mode 100644 include/configs/sa8155p_adp.h
 create mode 100644 include/dt-bindings/clock/qcom,dispcc-sm8150.h
 create mode 100644 include/dt-bindings/clock/qcom,gcc-sm8150.h
 create mode 100644 include/dt-bindings/clock/qcom,gpucc-sm8150.h
 create mode 100644 include/dt-bindings/clock/qcom,rpmh.h
 create mode 100644 include/dt-bindings/dma/qcom-gpi.h
 create mode 100644

[PATCH 8/8] board: add support for Qualcomm SA8155P-ADP board

2024-02-29 Thread Volodymyr Babchuk
SA8155P Automotive Development Platform is Qualcomm SA8155-based board
for developers. The nice thing that it has unlocked loaders with test
keys support, which means that U-Boot for this platform can be
launched at earlier stages.

This patch adds basic board support with only serial port and
networking operation. I am using U-Boot to ease up Xen porting onto
this board, so I am mostly interesting in booting U-Boot in EL2. But
more conventional setup with Android boot image is supported as well.

Signed-off-by: Volodymyr Babchuk 

---

 arch/arm/dts/sa8155p-adp-u-boot.dtsi | 30 
 arch/arm/mach-snapdragon/Kconfig | 14 
 arch/arm/mach-snapdragon/Makefile|  2 +
 arch/arm/mach-snapdragon/init_sa8155p.c  | 30 
 arch/arm/mach-snapdragon/sysmap-sm8150.c | 31 
 board/qualcomm/sa8155p-adp/Kconfig   | 12 +++
 board/qualcomm/sa8155p-adp/MAINTAINERS   |  6 ++
 configs/sa8155p_adp_defconfig| 33 +
 doc/board/qualcomm/index.rst |  1 +
 doc/board/qualcomm/sa8155p-adp.rst   | 94 
 include/configs/sa8155p_adp.h| 25 +++
 11 files changed, 278 insertions(+)
 create mode 100644 arch/arm/dts/sa8155p-adp-u-boot.dtsi
 create mode 100644 arch/arm/mach-snapdragon/init_sa8155p.c
 create mode 100644 arch/arm/mach-snapdragon/sysmap-sm8150.c
 create mode 100644 board/qualcomm/sa8155p-adp/Kconfig
 create mode 100644 board/qualcomm/sa8155p-adp/MAINTAINERS
 create mode 100644 configs/sa8155p_adp_defconfig
 create mode 100644 doc/board/qualcomm/sa8155p-adp.rst
 create mode 100644 include/configs/sa8155p_adp.h

diff --git a/arch/arm/dts/sa8155p-adp-u-boot.dtsi 
b/arch/arm/dts/sa8155p-adp-u-boot.dtsi
new file mode 100644
index 00..4484ea2734
--- /dev/null
+++ b/arch/arm/dts/sa8155p-adp-u-boot.dtsi
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Qualcomm SA8155P-ADP device tree fixups for U-BOot
+ *
+ * Volodymyr Babchuk 
+ * Copyright (c) 2024 EPAM Systems.
+ */
+
+/ {
+   /* Populate memory node with actual memory configuration */
+   memory@8000 {
+   reg = <0x00 0x8000 0x00 0x3990> ,
+ <0x02 0x00x1  0x7fd0>,
+ <0x00 0xC000 0x1  0x4000>;
+   };
+};
+
+ {
+   /* Ethernet driver tries to find reset by name */
+   reset-names = "emac";
+};
+
+ {
+   /* U-Boot pinctrl driver does not understand multiple tiles */
+   reg = <0x0 0x0300 0x0 0x100>;
+   /delete-property/ reg-names;
+
+   /* U-Boot ethernet driver wants to drive reset as GPIO */
+   /delete-node/ phy-reset-pins;
+};
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index ad66710819..6431b6eca0 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -19,6 +19,12 @@ config SDM845
imply PINCTRL_QCOM_SDM845
imply BUTTON_QCOM_PMIC
 
+config SM8150
+   bool "Qualcomm Snapdragon 855 SoC"
+   select LINUX_KERNEL_IMAGE_HEADER
+   imply CLK_QCOM_SM8150
+   imply PINCTRL_QCOM_SDM8150
+
 config LNX_KRNL_IMG_TEXT_OFFSET_BASE
default 0x8000
 
@@ -90,6 +96,13 @@ config TARGET_QCS404EVB
  - 1GiB RAM
  - 8GiB eMMC, uSD slot
 
+config TARGET_SA8155P_ADP
+   bool "SA8155 Automotive Development Platform"
+   help
+ Support for Lantronix/Qualcomm SA8155P Automotive Development Platform
+ based on Snapdragon SA8155P
+   select SM8150
+
 endchoice
 
 source "board/qualcomm/dragonboard410c/Kconfig"
@@ -97,5 +110,6 @@ source "board/qualcomm/dragonboard820c/Kconfig"
 source "board/qualcomm/dragonboard845c/Kconfig"
 source "board/samsung/starqltechn/Kconfig"
 source "board/qualcomm/qcs404-evb/Kconfig"
+source "board/qualcomm/sa8155p-adp/Kconfig"
 
 endif
diff --git a/arch/arm/mach-snapdragon/Makefile 
b/arch/arm/mach-snapdragon/Makefile
index 3a3a297c17..ff2887e384 100644
--- a/arch/arm/mach-snapdragon/Makefile
+++ b/arch/arm/mach-snapdragon/Makefile
@@ -4,8 +4,10 @@
 
 obj-$(CONFIG_SDM845) += sysmap-sdm845.o
 obj-$(CONFIG_SDM845) += init_sdm845.o
+obj-$(CONFIG_SM8150) += sysmap-sm8150.o
 obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o
 obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o
 obj-y += misc.o
 obj-y += dram.o
 obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o
+obj-$(CONFIG_TARGET_SA8155P_ADP) += init_sa8155p.o
diff --git a/arch/arm/mach-snapdragon/init_sa8155p.c 
b/arch/arm/mach-snapdragon/init_sa8155p.c
new file mode 100644
index 00..64dd07ae92
--- /dev/null
+++ b/arch/arm/mach-snapdragon/init_sa8155p.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Qualcomm SM8150 initialization procedures
+ *
+ * Volodymyr Babchuk 
+ * Copyright (c) 2024 EPAM Systems.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#incl

[PATCH 4/8] clk: qcom: add support for power domains uclass

2024-02-29 Thread Volodymyr Babchuk
Now sub-drivers for particular SoCs can register them as power domain
drivers. This is needed for upcoming SM8150 support, because it needs
to power up the Ethernet module.

Signed-off-by: Volodymyr Babchuk 
---

 drivers/clk/qcom/clock-qcom.c | 93 ++-
 drivers/clk/qcom/clock-qcom.h |  6 +++
 2 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 729d190c54..986b8e4da4 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "clock-qcom.h"
 
@@ -30,6 +31,11 @@
 #define CBCR_BRANCH_ENABLE_BIT  BIT(0)
 #define CBCR_BRANCH_OFF_BIT BIT(31)
 
+#define GDSC_POWER_UP_COMPLETE BIT(16)
+#define GDSC_POWER_DOWN_COMPLETE   BIT(15)
+#define CFG_GDSCR_OFFSET   0x4
+#define PWR_ON_MASKBIT(31)
+
 /* Enable clock controlled by CBC soft macro */
 void clk_enable_cbc(phys_addr_t cbcr)
 {
@@ -223,7 +229,7 @@ U_BOOT_DRIVER(qcom_clk) = {
 int qcom_cc_bind(struct udevice *parent)
 {
struct msm_clk_data *data = (struct msm_clk_data 
*)dev_get_driver_data(parent);
-   struct udevice *clkdev, *rstdev;
+   struct udevice *clkdev, *rstdev, *pwrdev;
struct driver *drv;
int ret;
 
@@ -253,6 +259,20 @@ int qcom_cc_bind(struct udevice *parent)
if (ret)
device_unbind(clkdev);
 
+   if (!data->power_domains)
+   return ret;
+
+   /* Get a handle to the common power domain handler */
+   drv = lists_driver_lookup_name("qcom_power");
+   if (!drv)
+   return -ENOENT;
+
+   /* Register the power domain controller */
+   ret = device_bind_with_driver_data(parent, drv, "qcom_power", 
(ulong)data,
+  dev_ofnode(parent), );
+   if (ret)
+   device_unbind(pwrdev);
+
return ret;
 }
 
@@ -306,3 +326,74 @@ U_BOOT_DRIVER(qcom_reset) = {
.ops = _reset_ops,
.probe = qcom_reset_probe,
 };
+
+static int qcom_power_set(struct power_domain *pwr, bool on)
+{
+   struct msm_clk_data *data = (struct msm_clk_data 
*)dev_get_driver_data(pwr->dev);
+   void __iomem *base = dev_get_priv(pwr->dev);
+   const struct qcom_power_map *map;
+   u32 value;
+
+   if (pwr->id >= data->num_power_domains)
+   return -ENODEV;
+
+   map = >power_domains[pwr->id];
+
+   if (!map->reg)
+   return -ENODEV;
+
+   value = readl(base + map->reg);
+
+   if (on)
+   value &= ~BIT(0);
+   else
+   value |= BIT(0);
+
+   writel(value, base + map->reg);
+
+   /* Wait for power on */
+   while (true) {
+   value = readl(base + map->reg + CFG_GDSCR_OFFSET);
+   if (on) {
+   if ((value & GDSC_POWER_UP_COMPLETE) ||
+   (value & PWR_ON_MASK))
+   return 0;
+   } else {
+   if (value & GDSC_POWER_DOWN_COMPLETE ||
+   !(value & PWR_ON_MASK))
+   return 0;
+   }
+   }
+
+   return 0;
+}
+
+static int qcom_power_on(struct power_domain *pwr)
+{
+   return qcom_power_set(pwr, true);
+}
+
+static int qcom_power_off(struct power_domain *pwr)
+{
+   return qcom_power_set(pwr, false);
+}
+
+static const struct power_domain_ops qcom_power_ops = {
+   .on = qcom_power_on,
+   .off = qcom_power_off,
+};
+
+static int qcom_power_probe(struct udevice *dev)
+{
+   /* Set our priv pointer to the base address */
+   dev_set_priv(dev, (void *)dev_read_addr(dev));
+
+   return 0;
+}
+
+U_BOOT_DRIVER(qcom_power) = {
+   .name = "qcom_power",
+   .id = UCLASS_POWER_DOMAIN,
+   .ops = _power_ops,
+   .probe = qcom_power_probe,
+};
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
index 01088c1901..12a1eaec2b 100644
--- a/drivers/clk/qcom/clock-qcom.h
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -59,9 +59,15 @@ struct qcom_reset_map {
u8 bit;
 };
 
+struct qcom_power_map {
+   unsigned int reg;
+};
+
 struct clk;
 
 struct msm_clk_data {
+   const struct qcom_power_map *power_domains;
+   unsigned long   num_power_domains;
const struct qcom_reset_map *resets;
unsigned long   num_resets;
const struct gate_clk   *clks;
-- 
2.43.0


[PATCH 3/8] net: dw_eth_qos: add support for Qualcomm SM8150 SoC

2024-02-29 Thread Volodymyr Babchuk
Add support for Qualcomm SM8150 SoC to the EQOS driver. SM8150 has two
main differences from already supported QCS404: it has another RGMII
configuration registers set and it does require RGMII loopback to
be disabled.

To support different variants of QCOM SoC we had to add two new fields
to the eqos_priv struct: eqos_qcom_rgmii_regs and
qcom_enable_loopback.

Signed-off-by: Volodymyr Babchuk 
---

 drivers/net/dwc_eth_qos.c  |  4 +++
 drivers/net/dwc_eth_qos.h  |  2 ++
 drivers/net/dwc_eth_qos_qcom.c | 47 +++---
 3 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 9b3bce1dc8..882b854697 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1700,6 +1700,10 @@ static const struct udevice_id eqos_ids[] = {
.compatible = "qcom,qcs404-ethqos",
.data = (ulong)_qcom_config
},
+   {
+   .compatible = "qcom,sm8150-ethqos",
+   .data = (ulong)_qcom_config
+   },
 #endif
 #if IS_ENABLED(CONFIG_DWC_ETH_QOS_STARFIVE)
{
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
index e3222e1e17..216e1afe53 100644
--- a/drivers/net/dwc_eth_qos.h
+++ b/drivers/net/dwc_eth_qos.h
@@ -255,6 +255,7 @@ struct eqos_priv {
struct eqos_dma_regs *dma_regs;
struct eqos_tegra186_regs *tegra186_regs;
void *eqos_qcom_rgmii_regs;
+   struct dwmac_rgmii_regs *eqos_qcom_por;
struct reset_ctl reset_ctl;
struct gpio_desc phy_reset_gpio;
struct clk clk_master_bus;
@@ -277,6 +278,7 @@ struct eqos_priv {
bool started;
bool reg_access_ok;
bool clk_ck_enabled;
+   bool qcom_enable_loopback;
unsigned int tx_fifo_sz, rx_fifo_sz;
u32 reset_delays[3];
 };
diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c
index 8178138fc6..e9592ff686 100644
--- a/drivers/net/dwc_eth_qos_qcom.c
+++ b/drivers/net/dwc_eth_qos_qcom.c
@@ -95,6 +95,15 @@ static struct dwmac_rgmii_regs emac_v2_3_0_por = {
.io_macro_config2 = 0x2060
 };
 
+static struct dwmac_rgmii_regs emac_v2_1_0_por = {
+   .io_macro_config = 0x40C01343,
+   .sdcc_hc_dll_config = 0x2004642C,
+   .sdcc_hc_ddr_config = 0x,
+   .sdcc_hc_dll_config2 = 0x0020,
+   .sdcc_usr_ctl = 0x00010800,
+   .io_macro_config2 = 0x2060
+};
+
 static void ethqos_set_func_clk_en(struct dwmac_rgmii_regs *regs)
 {
setbits_le32(>io_macro_config, RGMII_CONFIG_FUNC_CLK_EN);
@@ -172,6 +181,8 @@ static int ethqos_rgmii_macro_init(struct udevice *dev,
   struct dwmac_rgmii_regs *regs,
   unsigned long speed)
 {
+   struct eqos_priv *eqos = dev_get_priv(dev);
+
/* Disable loopback mode */
clrbits_le32(>io_macro_config2,
 RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN);
@@ -202,7 +213,9 @@ static int ethqos_rgmii_macro_init(struct udevice *dev,
SDCC_DDR_CONFIG_PRG_RCLK_DLY, 57);
setbits_le32(>sdcc_hc_ddr_config, 
SDCC_DDR_CONFIG_PRG_DLY_EN);
 
-   setbits_le32(>io_macro_config, RGMII_CONFIG_LOOPBACK_EN);
+   if (eqos->qcom_enable_loopback)
+   setbits_le32(>io_macro_config,
+RGMII_CONFIG_LOOPBACK_EN);
break;
 
case SPEED_100:
@@ -233,7 +246,9 @@ static int ethqos_rgmii_macro_init(struct udevice *dev,
setbits_le32(>sdcc_hc_ddr_config,
 SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN);
 
-   setbits_le32(>io_macro_config, RGMII_CONFIG_LOOPBACK_EN);
+   if (eqos->qcom_enable_loopback)
+   setbits_le32(>io_macro_config,
+RGMII_CONFIG_LOOPBACK_EN);
break;
 
case SPEED_10:
@@ -265,7 +280,9 @@ static int ethqos_rgmii_macro_init(struct udevice *dev,
setbits_le32(>sdcc_hc_ddr_config,
 SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN);
 
-   setbits_le32(>io_macro_config, RGMII_CONFIG_LOOPBACK_EN);
+   if (eqos->qcom_enable_loopback)
+   setbits_le32(>io_macro_config,
+RGMII_CONFIG_LOOPBACK_EN);
break;
 
default:
@@ -281,14 +298,15 @@ static int ethqos_configure(struct udevice *dev,
unsigned long speed)
 {
unsigned int retry = 1000;
+   struct eqos_priv *eqos = dev_get_priv(dev);
 
/* Reset to POR values and enable clk */
-   writel(emac_v2_3_0_por.io_macro_config, >io_macro_config);
-   writel(emac_v2_3_0_por.sdcc_hc_dll_config, >sdcc_hc_dll_config);
-   writel(emac_v2_3_0_por.sdcc_hc_ddr_config, >

[PATCH 5/8] clk: qcom: add driver for SM8150 SoC

2024-02-29 Thread Volodymyr Babchuk
Add clock, reset and power domain driver for SM8150. Driver code is
based on the similar U-Boot drivers. All constants are taken from the
corresponding Linux driver.

This driver supports clock rate setting only for the debug UART and
RGMII/Ethernet modules, because this is all I can test right now.

Signed-off-by: Volodymyr Babchuk 
---

 drivers/clk/qcom/Kconfig|   8 ++
 drivers/clk/qcom/Makefile   |   1 +
 drivers/clk/qcom/clock-qcom.h   |   1 +
 drivers/clk/qcom/clock-sm8150.c | 234 
 4 files changed, 244 insertions(+)
 create mode 100644 drivers/clk/qcom/clock-sm8150.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 0df0d1881a..18ccf6a45e 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -47,6 +47,14 @@ config CLK_QCOM_SDM845
  on the Snapdragon 845 SoC. This driver supports the clocks
  and resets exposed by the GCC hardware block.
 
+config CLK_QCOM_SM8150
+   bool "Qualcomm SM8150 GCC"
+   select CLK_QCOM
+   help
+ Say Y here to enable support for the Global Clock Controller
+ on the Snapdragon 8150 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
+
 endmenu
 
 endif
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index cb179fdac5..12c09ba19e 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o
 obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o
 obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
 obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
+obj-$(CONFIG_CLK_QCOM_SM8150) += clock-sm8150.o
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
index 12a1eaec2b..41107df216 100644
--- a/drivers/clk/qcom/clock-qcom.h
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -9,6 +9,7 @@
 
 #define CFG_CLK_SRC_CXO   (0 << 8)
 #define CFG_CLK_SRC_GPLL0 (1 << 8)
+#define CFG_CLK_SRC_GPLL7_MAIN (3 << 8)
 #define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
 #define CFG_CLK_SRC_MASK  (7 << 8)
 
diff --git a/drivers/clk/qcom/clock-sm8150.c b/drivers/clk/qcom/clock-sm8150.c
new file mode 100644
index 00..e23dbccdd3
--- /dev/null
+++ b/drivers/clk/qcom/clock-sm8150.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm SM8150
+ *
+ * Volodymyr Babchuk 
+ * Copyright (c) 2024 EPAM Systems.
+ *
+ * Based on U-Boot driver for SDM845. Constants are taken from the Linux 
driver.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clock-qcom.h"
+
+static struct pll_vote_clk gpll7_vote_clk = {
+   .status = 0x1a000,
+   .status_bit = BIT(31),
+   .ena_vote = 0x52000,
+   .vote_bit = BIT(7),
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+   F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
+   F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
+   F(1920, CFG_CLK_SRC_CXO, 1, 0, 0),
+   F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
+   F(3200, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
+   F(4800, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
+   F(6400, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
+   F(8000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
+   F(9600, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
+   F(1, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
+   F(10240, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375),
+   F(11200, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75),
+   F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625),
+   F(12000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
+   F(12800, CFG_CLK_SRC_GPLL0, 1, 16, 75),
+   { }
+};
+
+static const struct freq_tbl ftbl_gcc_emac_rgmii_clk_src[] = {
+   F(250, CFG_CLK_SRC_CXO, 1, 25, 192),
+   F(500, CFG_CLK_SRC_CXO, 1, 25, 96),
+   F(1920, CFG_CLK_SRC_CXO, 1, 0, 0),
+   F(2500, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+   F(5000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
+   F(12500, CFG_CLK_SRC_GPLL7_MAIN, 4, 0, 0),
+   F(25000, CFG_CLK_SRC_GPLL7_MAIN, 2, 0, 0),
+   { }
+};
+
+static const struct bcr_regs uart2_regs = {
+   .cfg_rcgr = 0x1814C,
+   .cmd_rcgr = 0x18148,
+   .M = 0x18150,
+   .N = 0x18154,
+   .D = 0x18158,
+};
+
+static const struct bcr_regs rgmii_regs = {
+   .cfg_rcgr = 0x6020,
+   .cmd_rcgr = 0x601C,
+   .M = 0x6024,
+   .N = 0x6028,
+   .D = 0x602C,
+};
+
+static ulong sm8150_clk_set_rate(struct clk *clk, ulong rate)
+{
+   struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+   const struct freq_tbl *freq;
+
+   switch (clk->id) {
+   case GCC_QUPV3_WRAP1_S4_CLK: /* UART2 aka debug-uart */
+   freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
+   clk_rcg_set_rate_mnd(priv->base, _regs,
+   

[PATCH 7/8] pinctrl: qcom: add driver for SM8150 SoC

2024-02-29 Thread Volodymyr Babchuk
Add pinctrl and GPIO driver for SM8150. Driver code is based on the
similar U-Boot drivers. All constants are taken from the corresponding
Linux driver. This drivers differs from the similar U-Boot drivers,
because SM8150 SoC have different function IDs for the same functions
on different pins.

Signed-off-by: Volodymyr Babchuk 
---

 drivers/pinctrl/qcom/Kconfig  |   7 +
 drivers/pinctrl/qcom/Makefile |   1 +
 drivers/pinctrl/qcom/pinctrl-sm8150.c | 589 ++
 3 files changed, 597 insertions(+)
 create mode 100644 drivers/pinctrl/qcom/pinctrl-sm8150.c

diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 2fe6398147..290cefca47 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -41,6 +41,13 @@ config PINCTRL_QCOM_SDM845
  Say Y here to enable support for pinctrl on the Snapdragon 845 SoC,
  as well as the associated GPIO driver.
 
+config PINCTRL_QCOM_SM8150
+   bool "Qualcomm SM8150 GCC"
+   select PINCTRL_QCOM
+   help
+ Say Y here to enable support for pinctrl on the Snapdragon SM8150 SoC,
+ as well as the associated GPIO driver.
+
 endmenu
 
 endif
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 6d9aca6d7b..3c7be4a685 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o
 obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
 obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
 obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
+obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8150.c 
b/drivers/pinctrl/qcom/pinctrl-sm8150.c
new file mode 100644
index 00..a6c14d7254
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-sm8150.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Qualcomm SM8150 pinctrl and GPIO driver
+ *
+ * Volodymyr Babchuk 
+ * Copyright (c) 2024 EPAM Systems.
+ *
+ * Based on similar U-Boot drivers. Constants were taken from the Linux driver
+ */
+
+#include 
+
+#include "pinctrl-qcom.h"
+
+#define WEST   0x0010
+#define EAST   0x0050
+#define NORTH  0x0090
+#define SOUTH  0x00D0
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+enum sm8150_functions {
+   msm_mux_adsp_ext,
+   msm_mux_agera_pll,
+   msm_mux_aoss_cti,
+   msm_mux_atest_char,
+   msm_mux_atest_char0,
+   msm_mux_atest_char1,
+   msm_mux_atest_char2,
+   msm_mux_atest_char3,
+   msm_mux_atest_usb1,
+   msm_mux_atest_usb2,
+   msm_mux_atest_usb10,
+   msm_mux_atest_usb11,
+   msm_mux_atest_usb12,
+   msm_mux_atest_usb13,
+   msm_mux_atest_usb20,
+   msm_mux_atest_usb21,
+   msm_mux_atest_usb22,
+   msm_mux_atest_usb23,
+   msm_mux_audio_ref,
+   msm_mux_btfm_slimbus,
+   msm_mux_cam_mclk,
+   msm_mux_cci_async,
+   msm_mux_cci_i2c,
+   msm_mux_cci_timer0,
+   msm_mux_cci_timer1,
+   msm_mux_cci_timer2,
+   msm_mux_cci_timer3,
+   msm_mux_cci_timer4,
+   msm_mux_cri_trng,
+   msm_mux_cri_trng0,
+   msm_mux_cri_trng1,
+   msm_mux_dbg_out,
+   msm_mux_ddr_bist,
+   msm_mux_ddr_pxi0,
+   msm_mux_ddr_pxi1,
+   msm_mux_ddr_pxi2,
+   msm_mux_ddr_pxi3,
+   msm_mux_edp_hot,
+   msm_mux_edp_lcd,
+   msm_mux_emac_phy,
+   msm_mux_emac_pps,
+   msm_mux_gcc_gp1,
+   msm_mux_gcc_gp2,
+   msm_mux_gcc_gp3,
+   msm_mux_gpio,
+   msm_mux_jitter_bist,
+   msm_mux_hs1_mi2s,
+   msm_mux_hs2_mi2s,
+   msm_mux_hs3_mi2s,
+   msm_mux_lpass_slimbus,
+   msm_mux_mdp_vsync,
+   msm_mux_mdp_vsync0,
+   msm_mux_mdp_vsync1,
+   msm_mux_mdp_vsync2,
+   msm_mux_mdp_vsync3,
+   msm_mux_mss_lte,
+   msm_mux_m_voc,
+   msm_mux_nav_pps,
+   msm_mux_pa_indicator,
+   msm_mux_pci_e0,
+   msm_mux_pci_e1,
+   msm_mux_phase_flag,
+   msm_mux_pll_bist,
+   msm_mux_pll_bypassnl,
+   msm_mux_pll_reset,
+   msm_mux_pri_mi2s,
+   msm_mux_pri_mi2s_ws,
+   msm_mux_prng_rosc,
+   msm_mux_qdss,
+   msm_mux_qdss_cti,
+   msm_mux_qlink_enable,
+   msm_mux_qlink_request,
+   msm_mux_qspi0,
+   msm_mux_qspi1,
+   msm_mux_qspi2,
+   msm_mux_qspi3,
+   msm_mux_qspi_clk,
+   msm_mux_qspi_cs,
+   msm_mux_qua_mi2s,
+   msm_mux_qup0,
+   msm_mux_qup1,
+   msm_mux_qup2,
+   msm_mux_qup3,
+   msm_mux_qup4,
+   msm_mux_qup5,
+   msm_mux_qup6,
+   msm_mux_qup7,
+   msm_mux_qup8,
+   msm_mux_qup9,
+   msm_mux_qup10,
+   msm_mux_qup11,
+   msm_mux_qup12,
+   msm_mux_qup13,
+   msm_mux_qup14,
+   msm_mux_qup15,
+   msm_mux_qup16,
+   msm_mux_qup17,
+   msm_mu

[PATCH 6/8] pinctr: qcom: pass pin number to get_function_mux callback

2024-02-29 Thread Volodymyr Babchuk
This patch is the preparation for SM8150 support. This new SoC
depending on the particular pin can have different numbers for the
same function. For example "rgmii" function for GPIO4 has id=2 while
for GPIO59 it has id=1. So, to support this type of SoCs,
get_function_mux() callback needs to know for which pin the function
is requested.

Signed-off-by: Volodymyr Babchuk 
---

 drivers/pinctrl/qcom/pinctrl-apq8016.c | 3 ++-
 drivers/pinctrl/qcom/pinctrl-apq8096.c | 3 ++-
 drivers/pinctrl/qcom/pinctrl-ipq4019.c | 3 ++-
 drivers/pinctrl/qcom/pinctrl-qcom.c| 4 ++--
 drivers/pinctrl/qcom/pinctrl-qcom.h| 3 ++-
 drivers/pinctrl/qcom/pinctrl-qcs404.c  | 3 ++-
 drivers/pinctrl/qcom/pinctrl-sdm845.c  | 3 ++-
 7 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/pinctrl/qcom/pinctrl-apq8016.c 
b/drivers/pinctrl/qcom/pinctrl-apq8016.c
index 8149ffd83c..53042b6e05 100644
--- a/drivers/pinctrl/qcom/pinctrl-apq8016.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8016.c
@@ -49,7 +49,8 @@ static const char *apq8016_get_pin_name(struct udevice *dev,
}
 }
 
-static unsigned int apq8016_get_function_mux(unsigned int selector)
+static unsigned int apq8016_get_function_mux(__maybe_unused unsigned int pin,
+unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-apq8096.c 
b/drivers/pinctrl/qcom/pinctrl-apq8096.c
index d64ab1ff7b..8dcd171259 100644
--- a/drivers/pinctrl/qcom/pinctrl-apq8096.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8096.c
@@ -44,7 +44,8 @@ static const char *apq8096_get_pin_name(struct udevice *dev,
}
 }
 
-static unsigned int apq8096_get_function_mux(unsigned int selector)
+static unsigned int apq8096_get_function_mux(__maybe_unused unsigned int pin,
+unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq4019.c 
b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
index 2d99f99e1e..c2c358f556 100644
--- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c
+++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
@@ -40,7 +40,8 @@ static const char *ipq4019_get_pin_name(struct udevice *dev,
return pin_name;
 }
 
-static unsigned int ipq4019_get_function_mux(unsigned int selector)
+static unsigned int ipq4019_get_function_mux(__maybe_unused unsigned int pin,
+unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.c 
b/drivers/pinctrl/qcom/pinctrl-qcom.c
index dc3d8c4d90..de0bb4de0a 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcom.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.c
@@ -82,10 +82,10 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int 
pin_selector,
  unsigned int func_selector)
 {
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+   u32 func = priv->data->get_function_mux(pin_selector, func_selector);
 
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
-   TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
-   priv->data->get_function_mux(func_selector) << 2);
+   TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE, func << 2);
return 0;
 }
 
diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.h 
b/drivers/pinctrl/qcom/pinctrl-qcom.h
index 07f2eae9ba..49b7bfbc00 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcom.h
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.h
@@ -18,7 +18,8 @@ struct msm_pinctrl_data {
int functions_count;
const char *(*get_function_name)(struct udevice *dev,
 unsigned int selector);
-   unsigned int (*get_function_mux)(unsigned int selector);
+   unsigned int (*get_function_mux)(unsigned int pin,
+unsigned int selector);
const char *(*get_pin_name)(struct udevice *dev,
unsigned int selector);
 };
diff --git a/drivers/pinctrl/qcom/pinctrl-qcs404.c 
b/drivers/pinctrl/qcom/pinctrl-qcs404.c
index ac00afa2a1..977f7b2ac3 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcs404.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcs404.c
@@ -56,7 +56,8 @@ static const char *qcs404_get_pin_name(struct udevice *dev,
}
 }
 
-static unsigned int qcs404_get_function_mux(unsigned int selector)
+static unsigned int qcs404_get_function_mux(__maybe_unused unsigned int pin,
+   unsigned int selector)
 {
return msm_pinctrl_functions[selector].val;
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845.c 
b/drivers/pinctrl/qcom/pinctrl-sdm845.c
index 9f0f4085ce..64ce1bf15e 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdm845.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdm845.c
@@ -70,7 +70,8 @@ static const char *sdm845_get_pin_name(struct udevice *dev,
r

[PATCH 1/8] clk: qcom: clear div mask before assigning new divider

2024-02-29 Thread Volodymyr Babchuk
We need to do this to ensure that new divider is applied
correctly. This fixes potential issue with 1Gbit ethernet on
SA8155P-ADP boards.

Signed-off-by: Volodymyr Babchuk 
---

 drivers/clk/qcom/clock-qcom.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 7c683e5192..729d190c54 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -117,7 +117,8 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct 
bcr_regs *regs,
 
/* setup src select and divider */
cfg  = readl(base + regs->cfg_rcgr);
-   cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK);
+   cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK |
+CFG_SRC_DIV_MASK);
cfg |= source & CFG_SRC_SEL_MASK; /* Select clock source */
 
if (div)
-- 
2.43.0


[PATCH] smcc: fix sign bit expansion

2021-01-06 Thread Volodymyr Babchuk
Signed ARM_SMCCC_FAST_CALL value is shifted to 31'st bit. Then, it is expanded
to 64 bit value, which results in 1s in higher 32 bits.

This causes corrupted values in 64-bit SMC IDs and issues in buggy handlers of
32-bit calls.

We need to make ARM_SMCCC_FAST_CALL unsigned long, so it would work properly
on 32 bit architectures.

Signed-off-by: Volodymyr Babchuk 
---
 include/linux/arm-smccc.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 2d1e6cc156..7f2be23394 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -11,8 +11,8 @@
  * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
  */
 
-#define ARM_SMCCC_STD_CALL 0
-#define ARM_SMCCC_FAST_CALL1
+#define ARM_SMCCC_STD_CALL 0UL
+#define ARM_SMCCC_FAST_CALL1UL
 #define ARM_SMCCC_TYPE_SHIFT   31
 
 #define ARM_SMCCC_SMC_32   0
-- 
2.29.2


[PATCH v2] arm64: issue ISB after updating system registers

2020-06-23 Thread Volodymyr Babchuk
ARM Architecture reference manual clearly states that PE pipeline
should be flushed after any change to system registers. Refer to
paragraph "B2.3.5 Memory Barriers" at page B2-92 of "Arm Architecture
Reference Manual ARMv8 for ARMv8-A Architecture Profile" (ARM DDI
0487B.a).

Failing to issue instruction memory synchronization barrier can lead
to spurious errors, like synchronous exception when accessing FPU
registers. This is very prominent on CPUs with long instruction
pipeline, like ARM Cortex A72.

This change fixes the following U-Boot panic:

 "Synchronous Abort" handler, esr 0x1fe0
 elr: 800948cc lr : 80091e04
 x0 : 801ffdc8 x1 : 00c8
 x2 : 800979d4 x3 : 801ffc60
 x4 : 801ffd40 x5 : ff80ffd8
 x6 : 801ffd70 x7 : 801ffd70
 x8 : 000a x9 : 
 x10: 0044 x11: 
 x12:  x13: 
 x14:  x15: 
 x16: 8008b2e0 x17: 
 x18: 801ffec0 x19: 800957b0
 x20: 00c8 x21: 801ffdc8
 x22: 8009909e x23: 
 x24:  x25: 
 x26:  x27: 
 x28:  x29: 801ffc50

 Code: a94417e4 a90217e4 a9051fe6 a90617e4 (3d801fe0)

While executing instruction

 str q0, [sp, #112]

in vsnprintf() prologue. This panic was observed only on Cortex A72 so
far.

This patch places ISBs on other strategic places as well.

Also, this probably is the right fix for the issue workarounded in the
commit 45f41c13 ("ARM: uniphier: add weird workaround code for LD20")

Reported-by: Oleksandr Andrushchenko 
Suggested-by: Julien Grall 
Signed-off-by: Volodymyr Babchuk 
CC: Tom Rini 
CC: Masahiro Yamada 
CC: Stefano Stabellini 

--

Changes from v1:
 - Added ISBs under CONFIG_ARMV8_SET_SMPEN and erratas.
 - Added Stefano, Julien and Oleksandr
---
 arch/arm/cpu/armv8/start.S | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index 99d126660d..002698b501 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -120,6 +120,7 @@ pie_fixup_done:
mov x0, #3 << 20
msr cpacr_el1, x0   /* Enable FP/SIMD */
 0:
+   isb
 
/*
 * Enable SMPEN bit for coherency.
@@ -132,6 +133,7 @@ pie_fixup_done:
mrs x0, S3_1_c15_c2_1   /* cpuectlr_el1 */
orr x0, x0, #0x40
msr S3_1_c15_c2_1, x0
+   isb
 1:
 #endif
 
@@ -233,6 +235,7 @@ apply_a53_core_errata:
/* Enable data cache clean as data cache clean/invalidate */
orr x0, x0, #1 << 44
msr S3_1_c15_c2_0, x0   /* cpuactlr_el1 */
+   isb
 #endif
b 0b
 
@@ -247,6 +250,7 @@ apply_a57_core_errata:
/* Disable write streaming no-allocate threshold */
orr x0, x0, #3 << 27
msr S3_1_c15_c2_0, x0   /* cpuactlr_el1 */
+   isb
 #endif
 
 #ifdef CONFIG_ARM_ERRATA_826974
@@ -254,6 +258,7 @@ apply_a57_core_errata:
/* Disable speculative load execution ahead of a DMB */
orr x0, x0, #1 << 59
msr S3_1_c15_c2_0, x0   /* cpuactlr_el1 */
+   isb
 #endif
 
 #ifdef CONFIG_ARM_ERRATA_833471
@@ -263,6 +268,7 @@ apply_a57_core_errata:
could impact performance. */
orr x0, x0, #1 << 38
msr S3_1_c15_c2_0, x0   /* cpuactlr_el1 */
+   isb
 #endif
 
 #ifdef CONFIG_ARM_ERRATA_829520
@@ -273,6 +279,7 @@ apply_a57_core_errata:
could impact performance. */
orr x0, x0, #1 << 4
msr S3_1_c15_c2_0, x0   /* cpuactlr_el1 */
+   isb
 #endif
 
 #ifdef CONFIG_ARM_ERRATA_833069
@@ -280,6 +287,7 @@ apply_a57_core_errata:
/* Disable Enable Invalidates of BTB bit */
and x0, x0, #0xE
msr S3_1_c15_c2_0, x0   /* cpuactlr_el1 */
+   isb
 #endif
b 0b
 ENDPROC(apply_core_errata)
-- 
2.27.0


[PATCH] arm64: issue ISB after updating system registers

2020-06-17 Thread Volodymyr Babchuk
ARM Architecture reference manual clearly states that PE pipeline
should be flushed after any change to system registers. Failing to
do so can lead to spurious errors, like synchronous exception when
accessing FPU registers. This is very prominent on CPUs with long
instruction pipeline, like Cortex A72.

This change fixes the following U-Boot panic:

 "Synchronous Abort" handler, esr 0x1fe0
 elr: 800948cc lr : 80091e04
 x0 : 801ffdc8 x1 : 00c8
 x2 : 800979d4 x3 : 801ffc60
 x4 : 801ffd40 x5 : ff80ffd8
 x6 : 801ffd70 x7 : 801ffd70
 x8 : 000a x9 : 
 x10: 0044 x11: 
 x12:  x13: 
 x14:  x15: 
 x16: 8008b2e0 x17: 
 x18: 801ffec0 x19: 800957b0
 x20: 00c8 x21: 801ffdc8
 x22: 8009909e x23: 
 x24:  x25: 
 x26:  x27: 
 x28:  x29: 801ffc50

 Code: a94417e4 a90217e4 a9051fe6 a90617e4 (3d801fe0)

While executing instruction

 str q0, [sp, #112]

in vsnprintf() prologue. This panic was observed on Cortex A72 so far.

Also, this probably the right fix for the issue workarounded in the
commit 45f41c13 ("ARM: uniphier: add weird workaround code for LD20")

Signed-off-by: Volodymyr Babchuk 
CC: Tom Rini 
CC: Masahiro Yamada 
---
 arch/arm/cpu/armv8/start.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index 99d126660d..eb1290ad29 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -120,6 +120,7 @@ pie_fixup_done:
mov x0, #3 << 20
msr cpacr_el1, x0   /* Enable FP/SIMD */
 0:
+   isb
 
/*
 * Enable SMPEN bit for coherency.
-- 
2.26.2