* [PATCH v2 01/12] platform: andes/ae350: Remove enabling cache from an350_final_init
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:27 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 02/12] platform: andes/ae350: Use kconfig to set platform version and default name Yu Chien Peter Lin
` (10 subsequent siblings)
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
Boot-time cache operations have been handled by U-boot SPL, so we
can drop duplicate code.
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
platform/andes/ae350/platform.c | 19 -------------------
1 file changed, 19 deletions(-)
diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
index 6bd0a69..33f9c4c 100644
--- a/platform/andes/ae350/platform.c
+++ b/platform/andes/ae350/platform.c
@@ -34,25 +34,6 @@ static int ae350_final_init(bool cold_boot)
{
void *fdt;
- /* enable L1 cache */
- uintptr_t mcache_ctl_val = csr_read(CSR_MCACHECTL);
-
- if (!(mcache_ctl_val & V5_MCACHE_CTL_IC_EN))
- mcache_ctl_val |= V5_MCACHE_CTL_IC_EN;
- if (!(mcache_ctl_val & V5_MCACHE_CTL_DC_EN))
- mcache_ctl_val |= V5_MCACHE_CTL_DC_EN;
- if (!(mcache_ctl_val & V5_MCACHE_CTL_CCTL_SUEN))
- mcache_ctl_val |= V5_MCACHE_CTL_CCTL_SUEN;
- csr_write(CSR_MCACHECTL, mcache_ctl_val);
-
- /* enable L2 cache */
- uint32_t *l2c_ctl_base = (void *)AE350_L2C_ADDR + V5_L2C_CTL_OFFSET;
- uint32_t l2c_ctl_val = *l2c_ctl_base;
-
- if (!(l2c_ctl_val & V5_L2C_CTL_ENABLE_MASK))
- l2c_ctl_val |= V5_L2C_CTL_ENABLE_MASK;
- *l2c_ctl_base = l2c_ctl_val;
-
if (!cold_boot)
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 01/12] platform: andes/ae350: Remove enabling cache from an350_final_init
2022-10-03 11:52 ` [PATCH v2 01/12] platform: andes/ae350: Remove enabling cache from an350_final_init Yu Chien Peter Lin
@ 2022-10-11 16:27 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:27 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:22 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> Boot-time cache operations have been handled by U-boot SPL, so we
> can drop duplicate code.
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Looks good to me.
Reviewed-by: Anup Patel <anup@brainfault.org>
Regards,
Anup
> ---
> platform/andes/ae350/platform.c | 19 -------------------
> 1 file changed, 19 deletions(-)
>
> diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
> index 6bd0a69..33f9c4c 100644
> --- a/platform/andes/ae350/platform.c
> +++ b/platform/andes/ae350/platform.c
> @@ -34,25 +34,6 @@ static int ae350_final_init(bool cold_boot)
> {
> void *fdt;
>
> - /* enable L1 cache */
> - uintptr_t mcache_ctl_val = csr_read(CSR_MCACHECTL);
> -
> - if (!(mcache_ctl_val & V5_MCACHE_CTL_IC_EN))
> - mcache_ctl_val |= V5_MCACHE_CTL_IC_EN;
> - if (!(mcache_ctl_val & V5_MCACHE_CTL_DC_EN))
> - mcache_ctl_val |= V5_MCACHE_CTL_DC_EN;
> - if (!(mcache_ctl_val & V5_MCACHE_CTL_CCTL_SUEN))
> - mcache_ctl_val |= V5_MCACHE_CTL_CCTL_SUEN;
> - csr_write(CSR_MCACHECTL, mcache_ctl_val);
> -
> - /* enable L2 cache */
> - uint32_t *l2c_ctl_base = (void *)AE350_L2C_ADDR + V5_L2C_CTL_OFFSET;
> - uint32_t l2c_ctl_val = *l2c_ctl_base;
> -
> - if (!(l2c_ctl_val & V5_L2C_CTL_ENABLE_MASK))
> - l2c_ctl_val |= V5_L2C_CTL_ENABLE_MASK;
> - *l2c_ctl_base = l2c_ctl_val;
> -
> if (!cold_boot)
> return 0;
>
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 02/12] platform: andes/ae350: Use kconfig to set platform version and default name
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
2022-10-03 11:52 ` [PATCH v2 01/12] platform: andes/ae350: Remove enabling cache from an350_final_init Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:28 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 03/12] platform: andes/ae350: Use fdt serial driver Yu Chien Peter Lin
` (9 subsequent siblings)
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
This patch makes andes platform name and version can be set in
menuconfig interface.
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
platform/andes/ae350/Kconfig | 18 ++++++++++++++++++
platform/andes/ae350/platform.c | 6 ++++--
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
index d57f19f..3abad04 100644
--- a/platform/andes/ae350/Kconfig
+++ b/platform/andes/ae350/Kconfig
@@ -6,3 +6,21 @@ config PLATFORM_ANDES_AE350
select IRQCHIP_PLIC
select SERIAL_UART8250
default y
+
+if PLATFORM_ANDES_AE350
+
+config PLATFORM_ANDES_AE350_NAME
+ string "Platform default name"
+ default "Andes AE350"
+
+config PLATFORM_ANDES_AE350_MAJOR_VER
+ int "Platform major version"
+ range 0 65535
+ default 0
+
+config PLATFORM_ANDES_AE350_MINOR_VER
+ int "Platform minor version"
+ range 0 65535
+ default 1
+
+endif
diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
index 33f9c4c..c07f6be 100644
--- a/platform/andes/ae350/platform.c
+++ b/platform/andes/ae350/platform.c
@@ -168,8 +168,10 @@ const struct sbi_platform_operations platform_ops = {
const struct sbi_platform platform = {
.opensbi_version = OPENSBI_VERSION,
- .platform_version = SBI_PLATFORM_VERSION(0x0, 0x01),
- .name = "Andes AE350",
+ .platform_version =
+ SBI_PLATFORM_VERSION(CONFIG_PLATFORM_ANDES_AE350_MAJOR_VER,
+ CONFIG_PLATFORM_ANDES_AE350_MINOR_VER),
+ .name = CONFIG_PLATFORM_ANDES_AE350_NAME,
.features = SBI_PLATFORM_DEFAULT_FEATURES,
.hart_count = AE350_HART_COUNT,
.hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 02/12] platform: andes/ae350: Use kconfig to set platform version and default name
2022-10-03 11:52 ` [PATCH v2 02/12] platform: andes/ae350: Use kconfig to set platform version and default name Yu Chien Peter Lin
@ 2022-10-11 16:28 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:28 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:22 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> This patch makes andes platform name and version can be set in
> menuconfig interface.
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Looks good to me.
Reviewed-by: Anup Patel <anup@brainfault.org>
Regards,
Anup
> ---
> platform/andes/ae350/Kconfig | 18 ++++++++++++++++++
> platform/andes/ae350/platform.c | 6 ++++--
> 2 files changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
> index d57f19f..3abad04 100644
> --- a/platform/andes/ae350/Kconfig
> +++ b/platform/andes/ae350/Kconfig
> @@ -6,3 +6,21 @@ config PLATFORM_ANDES_AE350
> select IRQCHIP_PLIC
> select SERIAL_UART8250
> default y
> +
> +if PLATFORM_ANDES_AE350
> +
> +config PLATFORM_ANDES_AE350_NAME
> + string "Platform default name"
> + default "Andes AE350"
> +
> +config PLATFORM_ANDES_AE350_MAJOR_VER
> + int "Platform major version"
> + range 0 65535
> + default 0
> +
> +config PLATFORM_ANDES_AE350_MINOR_VER
> + int "Platform minor version"
> + range 0 65535
> + default 1
> +
> +endif
> diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
> index 33f9c4c..c07f6be 100644
> --- a/platform/andes/ae350/platform.c
> +++ b/platform/andes/ae350/platform.c
> @@ -168,8 +168,10 @@ const struct sbi_platform_operations platform_ops = {
>
> const struct sbi_platform platform = {
> .opensbi_version = OPENSBI_VERSION,
> - .platform_version = SBI_PLATFORM_VERSION(0x0, 0x01),
> - .name = "Andes AE350",
> + .platform_version =
> + SBI_PLATFORM_VERSION(CONFIG_PLATFORM_ANDES_AE350_MAJOR_VER,
> + CONFIG_PLATFORM_ANDES_AE350_MINOR_VER),
> + .name = CONFIG_PLATFORM_ANDES_AE350_NAME,
> .features = SBI_PLATFORM_DEFAULT_FEATURES,
> .hart_count = AE350_HART_COUNT,
> .hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 03/12] platform: andes/ae350: Use fdt serial driver
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
2022-10-03 11:52 ` [PATCH v2 01/12] platform: andes/ae350: Remove enabling cache from an350_final_init Yu Chien Peter Lin
2022-10-03 11:52 ` [PATCH v2 02/12] platform: andes/ae350: Use kconfig to set platform version and default name Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:29 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 04/12] lib: utils/timer: Add Andes fdt timer support Yu Chien Peter Lin
` (8 subsequent siblings)
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
Andes UART is compatible with uart8250 driver. We can use
fdt_serial_init() as platform console init hook.
dts example:
serial0: serial at f0300000 {
compatible = "andestech,uart16550", "ns16550a";
reg = <0x00000000 0xf0300000 0x00000000 0x00001000>;
interrupts = <9 4>;
interrupt-parent = <&plic0>;
clock-frequency = <19660800>;
current-speed = <38400>;
reg-shift = <2>;
reg-offset = <32>;
reg-io-width = <4>;
no-loopback-test = <1>;
};
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
---
platform/andes/ae350/Kconfig | 3 ++-
platform/andes/ae350/platform.c | 15 ++-------------
platform/andes/ae350/platform.h | 8 --------
3 files changed, 4 insertions(+), 22 deletions(-)
diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
index 3abad04..8dd8ebe 100644
--- a/platform/andes/ae350/Kconfig
+++ b/platform/andes/ae350/Kconfig
@@ -4,7 +4,8 @@ config PLATFORM_ANDES_AE350
bool
select FDT
select IRQCHIP_PLIC
- select SERIAL_UART8250
+ select FDT_SERIAL
+ select FDT_SERIAL_UART8250
default y
if PLATFORM_ANDES_AE350
diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
index c07f6be..04428d1 100644
--- a/platform/andes/ae350/platform.c
+++ b/platform/andes/ae350/platform.c
@@ -18,7 +18,7 @@
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/fdt/fdt_fixup.h>
#include <sbi_utils/irqchip/plic.h>
-#include <sbi_utils/serial/uart8250.h>
+#include <sbi_utils/serial/fdt_serial.h>
#include "platform.h"
#include "plicsw.h"
#include "plmt.h"
@@ -43,17 +43,6 @@ static int ae350_final_init(bool cold_boot)
return 0;
}
-/* Initialize the platform console. */
-static int ae350_console_init(void)
-{
- return uart8250_init(AE350_UART_ADDR,
- AE350_UART_FREQUENCY,
- AE350_UART_BAUDRATE,
- AE350_UART_REG_SHIFT,
- AE350_UART_REG_WIDTH,
- AE350_UART_REG_OFFSET);
-}
-
/* Initialize the platform interrupt controller for current HART. */
static int ae350_irqchip_init(bool cold_boot)
{
@@ -155,7 +144,7 @@ static int ae350_vendor_ext_provider(long extid, long funcid,
const struct sbi_platform_operations platform_ops = {
.final_init = ae350_final_init,
- .console_init = ae350_console_init,
+ .console_init = fdt_serial_init,
.irqchip_init = ae350_irqchip_init,
diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
index 9b54816..c699b7f 100644
--- a/platform/andes/ae350/platform.h
+++ b/platform/andes/ae350/platform.h
@@ -22,14 +22,6 @@
#define AE350_L2C_ADDR 0xe0500000
-#define AE350_UART_ADDR_OFFSET 0x20
-#define AE350_UART_ADDR (0xf0300000 + AE350_UART_ADDR_OFFSET)
-#define AE350_UART_FREQUENCY 19660800
-#define AE350_UART_BAUDRATE 38400
-#define AE350_UART_REG_SHIFT 2
-#define AE350_UART_REG_WIDTH 0
-#define AE350_UART_REG_OFFSET 0
-
/*Memory and Miscellaneous Registers*/
#define CSR_MILMB 0x7c0
#define CSR_MDLMB 0x7c1
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 03/12] platform: andes/ae350: Use fdt serial driver
2022-10-03 11:52 ` [PATCH v2 03/12] platform: andes/ae350: Use fdt serial driver Yu Chien Peter Lin
@ 2022-10-11 16:29 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:29 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:23 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> Andes UART is compatible with uart8250 driver. We can use
> fdt_serial_init() as platform console init hook.
>
> dts example:
>
> serial0: serial at f0300000 {
> compatible = "andestech,uart16550", "ns16550a";
> reg = <0x00000000 0xf0300000 0x00000000 0x00001000>;
> interrupts = <9 4>;
> interrupt-parent = <&plic0>;
> clock-frequency = <19660800>;
> current-speed = <38400>;
> reg-shift = <2>;
> reg-offset = <32>;
> reg-io-width = <4>;
> no-loopback-test = <1>;
> };
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Looks good to me.
Reviewed-by: Anup Patel <anup@brainfault.org>
Regards,
Anup
> ---
> platform/andes/ae350/Kconfig | 3 ++-
> platform/andes/ae350/platform.c | 15 ++-------------
> platform/andes/ae350/platform.h | 8 --------
> 3 files changed, 4 insertions(+), 22 deletions(-)
>
> diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
> index 3abad04..8dd8ebe 100644
> --- a/platform/andes/ae350/Kconfig
> +++ b/platform/andes/ae350/Kconfig
> @@ -4,7 +4,8 @@ config PLATFORM_ANDES_AE350
> bool
> select FDT
> select IRQCHIP_PLIC
> - select SERIAL_UART8250
> + select FDT_SERIAL
> + select FDT_SERIAL_UART8250
> default y
>
> if PLATFORM_ANDES_AE350
> diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
> index c07f6be..04428d1 100644
> --- a/platform/andes/ae350/platform.c
> +++ b/platform/andes/ae350/platform.c
> @@ -18,7 +18,7 @@
> #include <sbi_utils/fdt/fdt_helper.h>
> #include <sbi_utils/fdt/fdt_fixup.h>
> #include <sbi_utils/irqchip/plic.h>
> -#include <sbi_utils/serial/uart8250.h>
> +#include <sbi_utils/serial/fdt_serial.h>
> #include "platform.h"
> #include "plicsw.h"
> #include "plmt.h"
> @@ -43,17 +43,6 @@ static int ae350_final_init(bool cold_boot)
> return 0;
> }
>
> -/* Initialize the platform console. */
> -static int ae350_console_init(void)
> -{
> - return uart8250_init(AE350_UART_ADDR,
> - AE350_UART_FREQUENCY,
> - AE350_UART_BAUDRATE,
> - AE350_UART_REG_SHIFT,
> - AE350_UART_REG_WIDTH,
> - AE350_UART_REG_OFFSET);
> -}
> -
> /* Initialize the platform interrupt controller for current HART. */
> static int ae350_irqchip_init(bool cold_boot)
> {
> @@ -155,7 +144,7 @@ static int ae350_vendor_ext_provider(long extid, long funcid,
> const struct sbi_platform_operations platform_ops = {
> .final_init = ae350_final_init,
>
> - .console_init = ae350_console_init,
> + .console_init = fdt_serial_init,
>
> .irqchip_init = ae350_irqchip_init,
>
> diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
> index 9b54816..c699b7f 100644
> --- a/platform/andes/ae350/platform.h
> +++ b/platform/andes/ae350/platform.h
> @@ -22,14 +22,6 @@
>
> #define AE350_L2C_ADDR 0xe0500000
>
> -#define AE350_UART_ADDR_OFFSET 0x20
> -#define AE350_UART_ADDR (0xf0300000 + AE350_UART_ADDR_OFFSET)
> -#define AE350_UART_FREQUENCY 19660800
> -#define AE350_UART_BAUDRATE 38400
> -#define AE350_UART_REG_SHIFT 2
> -#define AE350_UART_REG_WIDTH 0
> -#define AE350_UART_REG_OFFSET 0
> -
> /*Memory and Miscellaneous Registers*/
> #define CSR_MILMB 0x7c0
> #define CSR_MDLMB 0x7c1
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 04/12] lib: utils/timer: Add Andes fdt timer support
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
` (2 preceding siblings ...)
2022-10-03 11:52 ` [PATCH v2 03/12] platform: andes/ae350: Use fdt serial driver Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:32 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 05/12] lib: utils/timer: Add PLMT mmio region to root domain Yu Chien Peter Lin
` (7 subsequent siblings)
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
Since we can get the PLMT base address and timer frequency from
device tree, move plmt timer device to fdt timer framework.
dts example (ax45mp 4 core):
cpus {
...
timebase-frequency = <0x3938700>;
...
}
soc {
...
plmt0 at e6000000 {
compatible = "andestech,plmt0";
reg = <0x00 0xe6000000 0x00 0x100000>;
interrupts-extended = <&cpu0_intc 0x07
&cpu1_intc 0x07
&cpu2_intc 0x07
&cpu3_intc 0x07>;
};
...
}
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
---
include/sbi_utils/fdt/fdt_helper.h | 3 +
include/sbi_utils/timer/andes_plmt.h | 32 ++++++++
lib/utils/fdt/fdt_helper.c | 54 ++++++++++++++
lib/utils/timer/Kconfig | 9 +++
lib/utils/timer/andes_plmt.c | 54 ++++++++++++++
lib/utils/timer/fdt_timer_plmt.c | 71 ++++++++++++++++++
lib/utils/timer/objects.mk | 4 +
platform/andes/ae350/Kconfig | 2 +
platform/andes/ae350/objects.mk | 2 +-
platform/andes/ae350/platform.c | 19 +----
platform/andes/ae350/platform.h | 2 -
platform/andes/ae350/plmt.c | 107 ---------------------------
platform/andes/ae350/plmt.h | 17 -----
13 files changed, 232 insertions(+), 144 deletions(-)
create mode 100644 include/sbi_utils/timer/andes_plmt.h
create mode 100644 lib/utils/timer/andes_plmt.c
create mode 100644 lib/utils/timer/fdt_timer_plmt.c
delete mode 100644 platform/andes/ae350/plmt.c
delete mode 100644 platform/andes/ae350/plmt.h
diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index bcd4996..7ef63c9 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -95,6 +95,9 @@ int fdt_parse_aclint_node(void *fdt, int nodeoffset, bool for_timer,
unsigned long *out_addr2, unsigned long *out_size2,
u32 *out_first_hartid, u32 *out_hart_count);
+int fdt_parse_plmt_node(void *fdt, int nodeoffset, unsigned long *plmt_base,
+ unsigned long *plmt_size, u32 *hart_count);
+
int fdt_parse_compat_addr(void *fdt, uint64_t *addr,
const char *compatible);
diff --git a/include/sbi_utils/timer/andes_plmt.h b/include/sbi_utils/timer/andes_plmt.h
new file mode 100644
index 0000000..ce3cfcf
--- /dev/null
+++ b/include/sbi_utils/timer/andes_plmt.h
@@ -0,0 +1,32 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Andes Technology Corporation
+ *
+ * Authors:
+ * Zong Li <zong@andestech.com>
+ * Nylon Chen <nylon7@andestech.com>
+ * Yu Chien Peter Lin <peterlin@andestech.com>
+ */
+
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_timer.h>
+
+#ifndef __TIMER_ANDES_PLMT_H__
+#define __TIMER_ANDES_PLMT_H__
+
+#define DEFAULT_AE350_PLMT_FREQ 60000000
+
+struct plmt_data {
+ u32 hart_count;
+ unsigned long size;
+ volatile u64 *time_val;
+ volatile u64 *time_cmp;
+};
+
+u64 plmt_timer_value(void);
+void plmt_timer_event_stop(void);
+void plmt_timer_event_start(u64 next_event);
+
+#endif /* __TIMER_ANDES_PLMT_H__ */
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index 6a75d6f..ce52fca 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -835,6 +835,60 @@ int fdt_parse_aclint_node(void *fdt, int nodeoffset, bool for_timer,
return 0;
}
+int fdt_parse_plmt_node(void *fdt, int nodeoffset, unsigned long *plmt_base,
+ unsigned long *plmt_size, u32 *hart_count)
+{
+ const fdt32_t *val;
+ int rc, i, count;
+ uint64_t reg_addr, reg_size, cpu_offset, cpu_intc_offset;
+ u32 phandle, hwirq, hartid, hcount;
+
+ if (nodeoffset < 0 || !fdt || !plmt_base ||
+ !hart_count || !plmt_size)
+ return SBI_EINVAL;
+
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
+ ®_addr, ®_size);
+ if (rc < 0 || !plmt_base || !plmt_size)
+ return SBI_ENODEV;
+ *plmt_base = reg_addr;
+ *plmt_size = reg_size;
+
+ val = fdt_getprop(fdt, nodeoffset, "interrupts-extended", &count);
+ if (!val || count < sizeof(fdt32_t))
+ return 0;
+ count = count / sizeof(fdt32_t);
+
+ hcount = 0;
+ for (i = 0; i < (count / 2); i++) {
+ phandle = fdt32_to_cpu(val[2 * i]);
+ hwirq = fdt32_to_cpu(val[2 * i + 1]);
+
+ cpu_intc_offset = fdt_node_offset_by_phandle(fdt, phandle);
+ if (cpu_intc_offset < 0)
+ continue;
+
+ cpu_offset = fdt_parent_offset(fdt, cpu_intc_offset);
+ if (cpu_intc_offset < 0)
+ continue;
+
+ rc = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
+
+ if (rc)
+ continue;
+
+ if (SBI_HARTMASK_MAX_BITS <= hartid)
+ continue;
+
+ if (hwirq == IRQ_M_TIMER)
+ hcount++;
+ }
+
+ *hart_count = hcount;
+
+ return 0;
+}
+
int fdt_parse_compat_addr(void *fdt, uint64_t *addr,
const char *compatible)
{
diff --git a/lib/utils/timer/Kconfig b/lib/utils/timer/Kconfig
index 23c48c5..ba211b6 100644
--- a/lib/utils/timer/Kconfig
+++ b/lib/utils/timer/Kconfig
@@ -14,10 +14,19 @@ config FDT_TIMER_MTIMER
select TIMER_MTIMER
default n
+config FDT_TIMER_PLMT
+ bool "Andes PLMT FDT driver"
+ select TIMER_PLMT
+ default n
+
endif
config TIMER_MTIMER
bool "ACLINT MTIMER support"
default n
+config TIMER_PLMT
+ bool "Andes PLMT support"
+ default n
+
endmenu
diff --git a/lib/utils/timer/andes_plmt.c b/lib/utils/timer/andes_plmt.c
new file mode 100644
index 0000000..ea4f311
--- /dev/null
+++ b/lib/utils/timer/andes_plmt.c
@@ -0,0 +1,54 @@
+#include <sbi_utils/timer/andes_plmt.h>
+
+struct plmt_data plmt;
+
+u64 plmt_timer_value(void)
+{
+#if __riscv_xlen == 64
+ return readq_relaxed(plmt.time_val);
+#else
+ u32 lo, hi;
+
+ do {
+ hi = readl_relaxed((void *)plmt.time_val + 0x04);
+ lo = readl_relaxed(plmt.time_val);
+ } while (hi != readl_relaxed((void *)plmt.time_val + 0x04));
+
+ return ((u64)hi << 32) | (u64)lo;
+#endif
+}
+
+void plmt_timer_event_stop(void)
+{
+ u32 target_hart = current_hartid();
+
+ if (plmt.hart_count <= target_hart)
+ ebreak();
+
+ /* Clear PLMT Time Compare */
+#if __riscv_xlen == 64
+ writeq_relaxed(-1ULL, &plmt.time_cmp[target_hart]);
+#else
+ writel_relaxed(-1UL, &plmt.time_cmp[target_hart]);
+ writel_relaxed(-1UL, (void *)(&plmt.time_cmp[target_hart]) + 0x04);
+#endif
+}
+
+void plmt_timer_event_start(u64 next_event)
+{
+ u32 target_hart = current_hartid();
+
+ if (plmt.hart_count <= target_hart)
+ ebreak();
+
+ /* Program PLMT Time Compare */
+#if __riscv_xlen == 64
+ writeq_relaxed(next_event, &plmt.time_cmp[target_hart]);
+#else
+ u32 mask = -1UL;
+
+ writel_relaxed(next_event & mask, &plmt.time_cmp[target_hart]);
+ writel_relaxed(next_event >> 32,
+ (void *)(&plmt.time_cmp[target_hart]) + 0x04);
+#endif
+}
diff --git a/lib/utils/timer/fdt_timer_plmt.c b/lib/utils/timer/fdt_timer_plmt.c
new file mode 100644
index 0000000..74d85b6
--- /dev/null
+++ b/lib/utils/timer/fdt_timer_plmt.c
@@ -0,0 +1,71 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Andes Technology Corporation
+ *
+ * Authors:
+ * Yu Chien Peter Lin <peterlin@andestech.com>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_error.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/timer/fdt_timer.h>
+#include <sbi_utils/timer/andes_plmt.h>
+
+extern struct plmt_data plmt;
+
+static struct sbi_timer_device plmt_timer = {
+ .name = "andes_plmt",
+ .timer_freq = DEFAULT_AE350_PLMT_FREQ,
+ .timer_value = plmt_timer_value,
+ .timer_event_start = plmt_timer_event_start,
+ .timer_event_stop = plmt_timer_event_stop
+};
+
+static int plmt_warm_timer_init(void)
+{
+ if (!plmt.time_val)
+ return SBI_ENODEV;
+
+ plmt_timer_event_stop();
+
+ return 0;
+}
+
+static int plmt_cold_timer_init(void *fdt, int nodeoff,
+ const struct fdt_match *match)
+{
+ int rc;
+ unsigned long freq, plmt_base;
+
+ rc = fdt_parse_plmt_node(fdt, nodeoff, &plmt_base, &plmt.size,
+ &plmt.hart_count);
+ if (rc)
+ return rc;
+
+ plmt.time_val = (u64 *)plmt_base;
+ plmt.time_cmp = (u64 *)(plmt_base + 0x8);
+
+ rc = fdt_parse_timebase_frequency(fdt, &freq);
+ if (rc)
+ return rc;
+
+ plmt_timer.timer_freq = freq;
+
+ sbi_timer_set_device(&plmt_timer);
+
+ return 0;
+}
+
+static const struct fdt_match timer_plmt_match[] = {
+ { .compatible = "andestech,plmt0" },
+ {},
+};
+
+struct fdt_timer fdt_timer_plmt = {
+ .match_table = timer_plmt_match,
+ .cold_init = plmt_cold_timer_init,
+ .warm_init = plmt_warm_timer_init,
+ .exit = NULL,
+};
diff --git a/lib/utils/timer/objects.mk b/lib/utils/timer/objects.mk
index 7f5f3ce..9360a76 100644
--- a/lib/utils/timer/objects.mk
+++ b/lib/utils/timer/objects.mk
@@ -8,9 +8,13 @@
#
libsbiutils-objs-$(CONFIG_TIMER_MTIMER) += timer/aclint_mtimer.o
+libsbiutils-objs-$(CONFIG_TIMER_PLMT) += timer/andes_plmt.o
libsbiutils-objs-$(CONFIG_FDT_TIMER) += timer/fdt_timer.o
libsbiutils-objs-$(CONFIG_FDT_TIMER) += timer/fdt_timer_drivers.o
carray-fdt_timer_drivers-$(CONFIG_FDT_TIMER_MTIMER) += fdt_timer_mtimer
libsbiutils-objs-$(CONFIG_FDT_TIMER_MTIMER) += timer/fdt_timer_mtimer.o
+
+carray-fdt_timer_drivers-$(CONFIG_FDT_TIMER_PLMT) += fdt_timer_plmt
+libsbiutils-objs-$(CONFIG_FDT_TIMER_PLMT) += timer/fdt_timer_plmt.o
diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
index 8dd8ebe..f6f50eb 100644
--- a/platform/andes/ae350/Kconfig
+++ b/platform/andes/ae350/Kconfig
@@ -6,6 +6,8 @@ config PLATFORM_ANDES_AE350
select IRQCHIP_PLIC
select FDT_SERIAL
select FDT_SERIAL_UART8250
+ select FDT_TIMER
+ select FDT_TIMER_PLMT
default y
if PLATFORM_ANDES_AE350
diff --git a/platform/andes/ae350/objects.mk b/platform/andes/ae350/objects.mk
index 80f0737..1ccb894 100644
--- a/platform/andes/ae350/objects.mk
+++ b/platform/andes/ae350/objects.mk
@@ -15,7 +15,7 @@ platform-asflags-y =
platform-ldflags-y =
# Objects to build
-platform-objs-y += cache.o platform.o plicsw.o plmt.o
+platform-objs-y += cache.o platform.o plicsw.o
# Blobs to build
FW_TEXT_START=0x00000000
diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
index 04428d1..79736c0 100644
--- a/platform/andes/ae350/platform.c
+++ b/platform/andes/ae350/platform.c
@@ -19,9 +19,9 @@
#include <sbi_utils/fdt/fdt_fixup.h>
#include <sbi_utils/irqchip/plic.h>
#include <sbi_utils/serial/fdt_serial.h>
+#include <sbi_utils/timer/fdt_timer.h>
#include "platform.h"
#include "plicsw.h"
-#include "plmt.h"
#include "cache.h"
static struct plic_data plic = {
@@ -81,21 +81,6 @@ static int ae350_ipi_init(bool cold_boot)
return plicsw_warm_ipi_init();
}
-/* Initialize platform timer for current HART. */
-static int ae350_timer_init(bool cold_boot)
-{
- int ret;
-
- if (cold_boot) {
- ret = plmt_cold_timer_init(AE350_PLMT_ADDR,
- AE350_HART_COUNT);
- if (ret)
- return ret;
- }
-
- return plmt_warm_timer_init();
-}
-
/* Vendor-Specific SBI handler */
static int ae350_vendor_ext_provider(long extid, long funcid,
const struct sbi_trap_regs *regs, unsigned long *out_value,
@@ -150,7 +135,7 @@ const struct sbi_platform_operations platform_ops = {
.ipi_init = ae350_ipi_init,
- .timer_init = ae350_timer_init,
+ .timer_init = fdt_timer_init,
.vendor_ext_provider = ae350_vendor_ext_provider
};
diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
index c699b7f..6a29fe5 100644
--- a/platform/andes/ae350/platform.h
+++ b/platform/andes/ae350/platform.h
@@ -18,8 +18,6 @@
#define AE350_PLICSW_ADDR 0xe6400000
-#define AE350_PLMT_ADDR 0xe6000000
-
#define AE350_L2C_ADDR 0xe0500000
/*Memory and Miscellaneous Registers*/
diff --git a/platform/andes/ae350/plmt.c b/platform/andes/ae350/plmt.c
deleted file mode 100644
index 54dcb94..0000000
--- a/platform/andes/ae350/plmt.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 Andes Technology Corporation
- *
- * Authors:
- * Zong Li <zong@andestech.com>
- * Nylon Chen <nylon7@andestech.com>
- */
-
-#include <sbi/riscv_asm.h>
-#include <sbi/riscv_io.h>
-#include <sbi/sbi_timer.h>
-
-static u32 plmt_time_hart_count;
-static volatile void *plmt_time_base;
-static volatile u64 *plmt_time_val;
-static volatile u64 *plmt_time_cmp;
-
-static u64 plmt_timer_value(void)
-{
-#if __riscv_xlen == 64
- return readq_relaxed(plmt_time_val);
-#else
- u32 lo, hi;
-
- do {
- hi = readl_relaxed((void *)plmt_time_val + 0x04);
- lo = readl_relaxed(plmt_time_val);
- } while (hi != readl_relaxed((void *)plmt_time_val + 0x04));
-
- return ((u64)hi << 32) | (u64)lo;
-#endif
-}
-
-static void plmt_timer_event_stop(void)
-{
- u32 target_hart = current_hartid();
-
- if (plmt_time_hart_count <= target_hart)
- return;
-
- /* Clear PLMT Time Compare */
-#if __riscv_xlen == 64
- writeq_relaxed(-1ULL, &plmt_time_cmp[target_hart]);
-#else
- writel_relaxed(-1UL, &plmt_time_cmp[target_hart]);
- writel_relaxed(-1UL, (void *)(&plmt_time_cmp[target_hart]) + 0x04);
-#endif
-}
-
-static void plmt_timer_event_start(u64 next_event)
-{
- u32 target_hart = current_hartid();
-
- if (plmt_time_hart_count <= target_hart)
- return;
-
- /* Program PLMT Time Compare */
-#if __riscv_xlen == 64
- writeq_relaxed(next_event, &plmt_time_cmp[target_hart]);
-#else
- u32 mask = -1UL;
-
- writel_relaxed(next_event & mask, &plmt_time_cmp[target_hart]);
- writel_relaxed(next_event >> 32,
- (void *)(&plmt_time_cmp[target_hart]) + 0x04);
-#endif
-
-}
-
-static struct sbi_timer_device plmt_timer = {
- .name = "ae350_plmt",
- .timer_value = plmt_timer_value,
- .timer_event_start = plmt_timer_event_start,
- .timer_event_stop = plmt_timer_event_stop
-};
-
-int plmt_warm_timer_init(void)
-{
- u32 target_hart = current_hartid();
-
- if (plmt_time_hart_count <= target_hart || !plmt_time_base)
- return -1;
-
- /* Clear PLMT Time Compare */
-#if __riscv_xlen == 64
- writeq_relaxed(-1ULL, &plmt_time_cmp[target_hart]);
-#else
- writel_relaxed(-1UL, &plmt_time_cmp[target_hart]);
- writel_relaxed(-1UL, (void *)(&plmt_time_cmp[target_hart]) + 0x04);
-#endif
-
- return 0;
-}
-
-int plmt_cold_timer_init(unsigned long base, u32 hart_count)
-{
- plmt_time_hart_count = hart_count;
- plmt_time_base = (void *)base;
- plmt_time_val = (u64 *)(plmt_time_base);
- plmt_time_cmp = (u64 *)(plmt_time_base + 0x8);
-
- sbi_timer_set_device(&plmt_timer);
-
- return 0;
-}
diff --git a/platform/andes/ae350/plmt.h b/platform/andes/ae350/plmt.h
deleted file mode 100644
index db093e0..0000000
--- a/platform/andes/ae350/plmt.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 Andes Technology Corporation
- *
- * Authors:
- * Zong Li <zong@andestech.com>
- */
-
-#ifndef _AE350_PLMT_H_
-#define _AE350_PLMT_H_
-
-int plmt_warm_timer_init(void);
-
-int plmt_cold_timer_init(unsigned long base, u32 hart_count);
-
-#endif /* _AE350_PLMT_H_ */
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 04/12] lib: utils/timer: Add Andes fdt timer support
2022-10-03 11:52 ` [PATCH v2 04/12] lib: utils/timer: Add Andes fdt timer support Yu Chien Peter Lin
@ 2022-10-11 16:32 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:32 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:23 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> Since we can get the PLMT base address and timer frequency from
> device tree, move plmt timer device to fdt timer framework.
>
> dts example (ax45mp 4 core):
>
> cpus {
> ...
> timebase-frequency = <0x3938700>;
> ...
> }
> soc {
> ...
> plmt0 at e6000000 {
> compatible = "andestech,plmt0";
> reg = <0x00 0xe6000000 0x00 0x100000>;
> interrupts-extended = <&cpu0_intc 0x07
> &cpu1_intc 0x07
> &cpu2_intc 0x07
> &cpu3_intc 0x07>;
> };
> ...
> }
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Looks good to me.
Reviewed-by: Anup Patel <anup@brainfault.org>
Regards,
Anup
> ---
> include/sbi_utils/fdt/fdt_helper.h | 3 +
> include/sbi_utils/timer/andes_plmt.h | 32 ++++++++
> lib/utils/fdt/fdt_helper.c | 54 ++++++++++++++
> lib/utils/timer/Kconfig | 9 +++
> lib/utils/timer/andes_plmt.c | 54 ++++++++++++++
> lib/utils/timer/fdt_timer_plmt.c | 71 ++++++++++++++++++
> lib/utils/timer/objects.mk | 4 +
> platform/andes/ae350/Kconfig | 2 +
> platform/andes/ae350/objects.mk | 2 +-
> platform/andes/ae350/platform.c | 19 +----
> platform/andes/ae350/platform.h | 2 -
> platform/andes/ae350/plmt.c | 107 ---------------------------
> platform/andes/ae350/plmt.h | 17 -----
> 13 files changed, 232 insertions(+), 144 deletions(-)
> create mode 100644 include/sbi_utils/timer/andes_plmt.h
> create mode 100644 lib/utils/timer/andes_plmt.c
> create mode 100644 lib/utils/timer/fdt_timer_plmt.c
> delete mode 100644 platform/andes/ae350/plmt.c
> delete mode 100644 platform/andes/ae350/plmt.h
>
> diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
> index bcd4996..7ef63c9 100644
> --- a/include/sbi_utils/fdt/fdt_helper.h
> +++ b/include/sbi_utils/fdt/fdt_helper.h
> @@ -95,6 +95,9 @@ int fdt_parse_aclint_node(void *fdt, int nodeoffset, bool for_timer,
> unsigned long *out_addr2, unsigned long *out_size2,
> u32 *out_first_hartid, u32 *out_hart_count);
>
> +int fdt_parse_plmt_node(void *fdt, int nodeoffset, unsigned long *plmt_base,
> + unsigned long *plmt_size, u32 *hart_count);
> +
> int fdt_parse_compat_addr(void *fdt, uint64_t *addr,
> const char *compatible);
>
> diff --git a/include/sbi_utils/timer/andes_plmt.h b/include/sbi_utils/timer/andes_plmt.h
> new file mode 100644
> index 0000000..ce3cfcf
> --- /dev/null
> +++ b/include/sbi_utils/timer/andes_plmt.h
> @@ -0,0 +1,32 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2022 Andes Technology Corporation
> + *
> + * Authors:
> + * Zong Li <zong@andestech.com>
> + * Nylon Chen <nylon7@andestech.com>
> + * Yu Chien Peter Lin <peterlin@andestech.com>
> + */
> +
> +#include <sbi/riscv_asm.h>
> +#include <sbi/riscv_io.h>
> +#include <sbi/sbi_timer.h>
> +
> +#ifndef __TIMER_ANDES_PLMT_H__
> +#define __TIMER_ANDES_PLMT_H__
> +
> +#define DEFAULT_AE350_PLMT_FREQ 60000000
> +
> +struct plmt_data {
> + u32 hart_count;
> + unsigned long size;
> + volatile u64 *time_val;
> + volatile u64 *time_cmp;
> +};
> +
> +u64 plmt_timer_value(void);
> +void plmt_timer_event_stop(void);
> +void plmt_timer_event_start(u64 next_event);
> +
> +#endif /* __TIMER_ANDES_PLMT_H__ */
> diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
> index 6a75d6f..ce52fca 100644
> --- a/lib/utils/fdt/fdt_helper.c
> +++ b/lib/utils/fdt/fdt_helper.c
> @@ -835,6 +835,60 @@ int fdt_parse_aclint_node(void *fdt, int nodeoffset, bool for_timer,
> return 0;
> }
>
> +int fdt_parse_plmt_node(void *fdt, int nodeoffset, unsigned long *plmt_base,
> + unsigned long *plmt_size, u32 *hart_count)
> +{
> + const fdt32_t *val;
> + int rc, i, count;
> + uint64_t reg_addr, reg_size, cpu_offset, cpu_intc_offset;
> + u32 phandle, hwirq, hartid, hcount;
> +
> + if (nodeoffset < 0 || !fdt || !plmt_base ||
> + !hart_count || !plmt_size)
> + return SBI_EINVAL;
> +
> + rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
> + ®_addr, ®_size);
> + if (rc < 0 || !plmt_base || !plmt_size)
> + return SBI_ENODEV;
> + *plmt_base = reg_addr;
> + *plmt_size = reg_size;
> +
> + val = fdt_getprop(fdt, nodeoffset, "interrupts-extended", &count);
> + if (!val || count < sizeof(fdt32_t))
> + return 0;
> + count = count / sizeof(fdt32_t);
> +
> + hcount = 0;
> + for (i = 0; i < (count / 2); i++) {
> + phandle = fdt32_to_cpu(val[2 * i]);
> + hwirq = fdt32_to_cpu(val[2 * i + 1]);
> +
> + cpu_intc_offset = fdt_node_offset_by_phandle(fdt, phandle);
> + if (cpu_intc_offset < 0)
> + continue;
> +
> + cpu_offset = fdt_parent_offset(fdt, cpu_intc_offset);
> + if (cpu_intc_offset < 0)
> + continue;
> +
> + rc = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
> +
> + if (rc)
> + continue;
> +
> + if (SBI_HARTMASK_MAX_BITS <= hartid)
> + continue;
> +
> + if (hwirq == IRQ_M_TIMER)
> + hcount++;
> + }
> +
> + *hart_count = hcount;
> +
> + return 0;
> +}
> +
> int fdt_parse_compat_addr(void *fdt, uint64_t *addr,
> const char *compatible)
> {
> diff --git a/lib/utils/timer/Kconfig b/lib/utils/timer/Kconfig
> index 23c48c5..ba211b6 100644
> --- a/lib/utils/timer/Kconfig
> +++ b/lib/utils/timer/Kconfig
> @@ -14,10 +14,19 @@ config FDT_TIMER_MTIMER
> select TIMER_MTIMER
> default n
>
> +config FDT_TIMER_PLMT
> + bool "Andes PLMT FDT driver"
> + select TIMER_PLMT
> + default n
> +
> endif
>
> config TIMER_MTIMER
> bool "ACLINT MTIMER support"
> default n
>
> +config TIMER_PLMT
> + bool "Andes PLMT support"
> + default n
> +
> endmenu
> diff --git a/lib/utils/timer/andes_plmt.c b/lib/utils/timer/andes_plmt.c
> new file mode 100644
> index 0000000..ea4f311
> --- /dev/null
> +++ b/lib/utils/timer/andes_plmt.c
> @@ -0,0 +1,54 @@
> +#include <sbi_utils/timer/andes_plmt.h>
> +
> +struct plmt_data plmt;
> +
> +u64 plmt_timer_value(void)
> +{
> +#if __riscv_xlen == 64
> + return readq_relaxed(plmt.time_val);
> +#else
> + u32 lo, hi;
> +
> + do {
> + hi = readl_relaxed((void *)plmt.time_val + 0x04);
> + lo = readl_relaxed(plmt.time_val);
> + } while (hi != readl_relaxed((void *)plmt.time_val + 0x04));
> +
> + return ((u64)hi << 32) | (u64)lo;
> +#endif
> +}
> +
> +void plmt_timer_event_stop(void)
> +{
> + u32 target_hart = current_hartid();
> +
> + if (plmt.hart_count <= target_hart)
> + ebreak();
> +
> + /* Clear PLMT Time Compare */
> +#if __riscv_xlen == 64
> + writeq_relaxed(-1ULL, &plmt.time_cmp[target_hart]);
> +#else
> + writel_relaxed(-1UL, &plmt.time_cmp[target_hart]);
> + writel_relaxed(-1UL, (void *)(&plmt.time_cmp[target_hart]) + 0x04);
> +#endif
> +}
> +
> +void plmt_timer_event_start(u64 next_event)
> +{
> + u32 target_hart = current_hartid();
> +
> + if (plmt.hart_count <= target_hart)
> + ebreak();
> +
> + /* Program PLMT Time Compare */
> +#if __riscv_xlen == 64
> + writeq_relaxed(next_event, &plmt.time_cmp[target_hart]);
> +#else
> + u32 mask = -1UL;
> +
> + writel_relaxed(next_event & mask, &plmt.time_cmp[target_hart]);
> + writel_relaxed(next_event >> 32,
> + (void *)(&plmt.time_cmp[target_hart]) + 0x04);
> +#endif
> +}
> diff --git a/lib/utils/timer/fdt_timer_plmt.c b/lib/utils/timer/fdt_timer_plmt.c
> new file mode 100644
> index 0000000..74d85b6
> --- /dev/null
> +++ b/lib/utils/timer/fdt_timer_plmt.c
> @@ -0,0 +1,71 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2022 Andes Technology Corporation
> + *
> + * Authors:
> + * Yu Chien Peter Lin <peterlin@andestech.com>
> + */
> +
> +#include <libfdt.h>
> +#include <sbi/sbi_error.h>
> +#include <sbi_utils/fdt/fdt_helper.h>
> +#include <sbi_utils/timer/fdt_timer.h>
> +#include <sbi_utils/timer/andes_plmt.h>
> +
> +extern struct plmt_data plmt;
> +
> +static struct sbi_timer_device plmt_timer = {
> + .name = "andes_plmt",
> + .timer_freq = DEFAULT_AE350_PLMT_FREQ,
> + .timer_value = plmt_timer_value,
> + .timer_event_start = plmt_timer_event_start,
> + .timer_event_stop = plmt_timer_event_stop
> +};
> +
> +static int plmt_warm_timer_init(void)
> +{
> + if (!plmt.time_val)
> + return SBI_ENODEV;
> +
> + plmt_timer_event_stop();
> +
> + return 0;
> +}
> +
> +static int plmt_cold_timer_init(void *fdt, int nodeoff,
> + const struct fdt_match *match)
> +{
> + int rc;
> + unsigned long freq, plmt_base;
> +
> + rc = fdt_parse_plmt_node(fdt, nodeoff, &plmt_base, &plmt.size,
> + &plmt.hart_count);
> + if (rc)
> + return rc;
> +
> + plmt.time_val = (u64 *)plmt_base;
> + plmt.time_cmp = (u64 *)(plmt_base + 0x8);
> +
> + rc = fdt_parse_timebase_frequency(fdt, &freq);
> + if (rc)
> + return rc;
> +
> + plmt_timer.timer_freq = freq;
> +
> + sbi_timer_set_device(&plmt_timer);
> +
> + return 0;
> +}
> +
> +static const struct fdt_match timer_plmt_match[] = {
> + { .compatible = "andestech,plmt0" },
> + {},
> +};
> +
> +struct fdt_timer fdt_timer_plmt = {
> + .match_table = timer_plmt_match,
> + .cold_init = plmt_cold_timer_init,
> + .warm_init = plmt_warm_timer_init,
> + .exit = NULL,
> +};
> diff --git a/lib/utils/timer/objects.mk b/lib/utils/timer/objects.mk
> index 7f5f3ce..9360a76 100644
> --- a/lib/utils/timer/objects.mk
> +++ b/lib/utils/timer/objects.mk
> @@ -8,9 +8,13 @@
> #
>
> libsbiutils-objs-$(CONFIG_TIMER_MTIMER) += timer/aclint_mtimer.o
> +libsbiutils-objs-$(CONFIG_TIMER_PLMT) += timer/andes_plmt.o
>
> libsbiutils-objs-$(CONFIG_FDT_TIMER) += timer/fdt_timer.o
> libsbiutils-objs-$(CONFIG_FDT_TIMER) += timer/fdt_timer_drivers.o
>
> carray-fdt_timer_drivers-$(CONFIG_FDT_TIMER_MTIMER) += fdt_timer_mtimer
> libsbiutils-objs-$(CONFIG_FDT_TIMER_MTIMER) += timer/fdt_timer_mtimer.o
> +
> +carray-fdt_timer_drivers-$(CONFIG_FDT_TIMER_PLMT) += fdt_timer_plmt
> +libsbiutils-objs-$(CONFIG_FDT_TIMER_PLMT) += timer/fdt_timer_plmt.o
> diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
> index 8dd8ebe..f6f50eb 100644
> --- a/platform/andes/ae350/Kconfig
> +++ b/platform/andes/ae350/Kconfig
> @@ -6,6 +6,8 @@ config PLATFORM_ANDES_AE350
> select IRQCHIP_PLIC
> select FDT_SERIAL
> select FDT_SERIAL_UART8250
> + select FDT_TIMER
> + select FDT_TIMER_PLMT
> default y
>
> if PLATFORM_ANDES_AE350
> diff --git a/platform/andes/ae350/objects.mk b/platform/andes/ae350/objects.mk
> index 80f0737..1ccb894 100644
> --- a/platform/andes/ae350/objects.mk
> +++ b/platform/andes/ae350/objects.mk
> @@ -15,7 +15,7 @@ platform-asflags-y =
> platform-ldflags-y =
>
> # Objects to build
> -platform-objs-y += cache.o platform.o plicsw.o plmt.o
> +platform-objs-y += cache.o platform.o plicsw.o
>
> # Blobs to build
> FW_TEXT_START=0x00000000
> diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
> index 04428d1..79736c0 100644
> --- a/platform/andes/ae350/platform.c
> +++ b/platform/andes/ae350/platform.c
> @@ -19,9 +19,9 @@
> #include <sbi_utils/fdt/fdt_fixup.h>
> #include <sbi_utils/irqchip/plic.h>
> #include <sbi_utils/serial/fdt_serial.h>
> +#include <sbi_utils/timer/fdt_timer.h>
> #include "platform.h"
> #include "plicsw.h"
> -#include "plmt.h"
> #include "cache.h"
>
> static struct plic_data plic = {
> @@ -81,21 +81,6 @@ static int ae350_ipi_init(bool cold_boot)
> return plicsw_warm_ipi_init();
> }
>
> -/* Initialize platform timer for current HART. */
> -static int ae350_timer_init(bool cold_boot)
> -{
> - int ret;
> -
> - if (cold_boot) {
> - ret = plmt_cold_timer_init(AE350_PLMT_ADDR,
> - AE350_HART_COUNT);
> - if (ret)
> - return ret;
> - }
> -
> - return plmt_warm_timer_init();
> -}
> -
> /* Vendor-Specific SBI handler */
> static int ae350_vendor_ext_provider(long extid, long funcid,
> const struct sbi_trap_regs *regs, unsigned long *out_value,
> @@ -150,7 +135,7 @@ const struct sbi_platform_operations platform_ops = {
>
> .ipi_init = ae350_ipi_init,
>
> - .timer_init = ae350_timer_init,
> + .timer_init = fdt_timer_init,
>
> .vendor_ext_provider = ae350_vendor_ext_provider
> };
> diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
> index c699b7f..6a29fe5 100644
> --- a/platform/andes/ae350/platform.h
> +++ b/platform/andes/ae350/platform.h
> @@ -18,8 +18,6 @@
>
> #define AE350_PLICSW_ADDR 0xe6400000
>
> -#define AE350_PLMT_ADDR 0xe6000000
> -
> #define AE350_L2C_ADDR 0xe0500000
>
> /*Memory and Miscellaneous Registers*/
> diff --git a/platform/andes/ae350/plmt.c b/platform/andes/ae350/plmt.c
> deleted file mode 100644
> index 54dcb94..0000000
> --- a/platform/andes/ae350/plmt.c
> +++ /dev/null
> @@ -1,107 +0,0 @@
> -/*
> - * SPDX-License-Identifier: BSD-2-Clause
> - *
> - * Copyright (c) 2019 Andes Technology Corporation
> - *
> - * Authors:
> - * Zong Li <zong@andestech.com>
> - * Nylon Chen <nylon7@andestech.com>
> - */
> -
> -#include <sbi/riscv_asm.h>
> -#include <sbi/riscv_io.h>
> -#include <sbi/sbi_timer.h>
> -
> -static u32 plmt_time_hart_count;
> -static volatile void *plmt_time_base;
> -static volatile u64 *plmt_time_val;
> -static volatile u64 *plmt_time_cmp;
> -
> -static u64 plmt_timer_value(void)
> -{
> -#if __riscv_xlen == 64
> - return readq_relaxed(plmt_time_val);
> -#else
> - u32 lo, hi;
> -
> - do {
> - hi = readl_relaxed((void *)plmt_time_val + 0x04);
> - lo = readl_relaxed(plmt_time_val);
> - } while (hi != readl_relaxed((void *)plmt_time_val + 0x04));
> -
> - return ((u64)hi << 32) | (u64)lo;
> -#endif
> -}
> -
> -static void plmt_timer_event_stop(void)
> -{
> - u32 target_hart = current_hartid();
> -
> - if (plmt_time_hart_count <= target_hart)
> - return;
> -
> - /* Clear PLMT Time Compare */
> -#if __riscv_xlen == 64
> - writeq_relaxed(-1ULL, &plmt_time_cmp[target_hart]);
> -#else
> - writel_relaxed(-1UL, &plmt_time_cmp[target_hart]);
> - writel_relaxed(-1UL, (void *)(&plmt_time_cmp[target_hart]) + 0x04);
> -#endif
> -}
> -
> -static void plmt_timer_event_start(u64 next_event)
> -{
> - u32 target_hart = current_hartid();
> -
> - if (plmt_time_hart_count <= target_hart)
> - return;
> -
> - /* Program PLMT Time Compare */
> -#if __riscv_xlen == 64
> - writeq_relaxed(next_event, &plmt_time_cmp[target_hart]);
> -#else
> - u32 mask = -1UL;
> -
> - writel_relaxed(next_event & mask, &plmt_time_cmp[target_hart]);
> - writel_relaxed(next_event >> 32,
> - (void *)(&plmt_time_cmp[target_hart]) + 0x04);
> -#endif
> -
> -}
> -
> -static struct sbi_timer_device plmt_timer = {
> - .name = "ae350_plmt",
> - .timer_value = plmt_timer_value,
> - .timer_event_start = plmt_timer_event_start,
> - .timer_event_stop = plmt_timer_event_stop
> -};
> -
> -int plmt_warm_timer_init(void)
> -{
> - u32 target_hart = current_hartid();
> -
> - if (plmt_time_hart_count <= target_hart || !plmt_time_base)
> - return -1;
> -
> - /* Clear PLMT Time Compare */
> -#if __riscv_xlen == 64
> - writeq_relaxed(-1ULL, &plmt_time_cmp[target_hart]);
> -#else
> - writel_relaxed(-1UL, &plmt_time_cmp[target_hart]);
> - writel_relaxed(-1UL, (void *)(&plmt_time_cmp[target_hart]) + 0x04);
> -#endif
> -
> - return 0;
> -}
> -
> -int plmt_cold_timer_init(unsigned long base, u32 hart_count)
> -{
> - plmt_time_hart_count = hart_count;
> - plmt_time_base = (void *)base;
> - plmt_time_val = (u64 *)(plmt_time_base);
> - plmt_time_cmp = (u64 *)(plmt_time_base + 0x8);
> -
> - sbi_timer_set_device(&plmt_timer);
> -
> - return 0;
> -}
> diff --git a/platform/andes/ae350/plmt.h b/platform/andes/ae350/plmt.h
> deleted file mode 100644
> index db093e0..0000000
> --- a/platform/andes/ae350/plmt.h
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -/*
> - * SPDX-License-Identifier: BSD-2-Clause
> - *
> - * Copyright (c) 2019 Andes Technology Corporation
> - *
> - * Authors:
> - * Zong Li <zong@andestech.com>
> - */
> -
> -#ifndef _AE350_PLMT_H_
> -#define _AE350_PLMT_H_
> -
> -int plmt_warm_timer_init(void);
> -
> -int plmt_cold_timer_init(unsigned long base, u32 hart_count);
> -
> -#endif /* _AE350_PLMT_H_ */
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 05/12] lib: utils/timer: Add PLMT mmio region to root domain
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
` (3 preceding siblings ...)
2022-10-03 11:52 ` [PATCH v2 04/12] lib: utils/timer: Add Andes fdt timer support Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-03 11:52 ` [PATCH v2 06/12] lib: utils/reset: Add Andes fdt reset driver support Yu Chien Peter Lin
` (6 subsequent siblings)
11 siblings, 0 replies; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
Add PLMT as mmio memregion in root domain at boot-time.
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
lib/utils/timer/fdt_timer_plmt.c | 36 ++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/lib/utils/timer/fdt_timer_plmt.c b/lib/utils/timer/fdt_timer_plmt.c
index 74d85b6..6c14f6a 100644
--- a/lib/utils/timer/fdt_timer_plmt.c
+++ b/lib/utils/timer/fdt_timer_plmt.c
@@ -9,6 +9,7 @@
#include <libfdt.h>
#include <sbi/sbi_error.h>
+#include <sbi/sbi_domain.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/timer/fdt_timer.h>
#include <sbi_utils/timer/andes_plmt.h>
@@ -33,6 +34,36 @@ static int plmt_warm_timer_init(void)
return 0;
}
+static int andes_plmt_add_regions(unsigned long addr, unsigned long size)
+{
+#define PLMT_ADD_REGION_ALIGN 0x1000
+ int rc;
+ unsigned long pos, end, region_size;
+ struct sbi_domain_memregion reg;
+
+ pos = addr;
+ end = addr + size;
+ while (pos < end) {
+ if (pos & (PLMT_ADD_REGION_ALIGN - 1))
+ region_size = 1UL << sbi_ffs(pos);
+ else
+ region_size = ((end - pos) < PLMT_ADD_REGION_ALIGN)
+ ? (end - pos)
+ : PLMT_ADD_REGION_ALIGN;
+
+ sbi_domain_memregion_init(pos, region_size,
+ SBI_DOMAIN_MEMREGION_MMIO |
+ SBI_DOMAIN_MEMREGION_READABLE,
+ ®);
+ rc = sbi_domain_root_add_memregion(®);
+ if (rc)
+ return rc;
+ pos += region_size;
+ }
+
+ return 0;
+}
+
static int plmt_cold_timer_init(void *fdt, int nodeoff,
const struct fdt_match *match)
{
@@ -53,6 +84,11 @@ static int plmt_cold_timer_init(void *fdt, int nodeoff,
plmt_timer.timer_freq = freq;
+ /* Add PLMT region to the root domain */
+ rc = andes_plmt_add_regions(plmt_base, plmt.size);
+ if (rc)
+ return rc;
+
sbi_timer_set_device(&plmt_timer);
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 06/12] lib: utils/reset: Add Andes fdt reset driver support
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
` (4 preceding siblings ...)
2022-10-03 11:52 ` [PATCH v2 05/12] lib: utils/timer: Add PLMT mmio region to root domain Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:35 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 07/12] platform: andes/ae350: Use fdt irqchip driver Yu Chien Peter Lin
` (5 subsequent siblings)
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
Add ATCWDT200 as reset device of ae350 platform, this driver requires
SMU to program the reset vector registers before triggering WDT software
restart signal.
dts example:
smu at f0100000 {
compatible = "andestech,atcsmu";
reg = <0x00000000 0xf0100000 0x00000000 0x00001000>;
};
wdt: wdt at f0500000 {
compatible = "andestech,atcwdt200";
reg = <0x00000000 0xf0500000 0x00000000 0x00001000>;
interrupts = <3 4>;
interrupt-parent = <&plic0>;
clock-frequency = <15000000>;
};
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
lib/utils/reset/Kconfig | 4 +
lib/utils/reset/fdt_reset_atcwdt200.c | 122 ++++++++++++++++++++++++++
lib/utils/reset/objects.mk | 3 +
platform/andes/ae350/Kconfig | 2 +
platform/andes/ae350/platform.c | 3 +
5 files changed, 134 insertions(+)
create mode 100644 lib/utils/reset/fdt_reset_atcwdt200.c
diff --git a/lib/utils/reset/Kconfig b/lib/utils/reset/Kconfig
index 2e83ff6..0e0c2c1 100644
--- a/lib/utils/reset/Kconfig
+++ b/lib/utils/reset/Kconfig
@@ -9,6 +9,10 @@ config FDT_RESET
if FDT_RESET
+config FDT_RESET_ATCWDT200
+ bool "Andes WDT FDT reset driver"
+ default n
+
config FDT_RESET_GPIO
bool "GPIO FDT reset driver"
depends on FDT_GPIO
diff --git a/lib/utils/reset/fdt_reset_atcwdt200.c b/lib/utils/reset/fdt_reset_atcwdt200.c
new file mode 100644
index 0000000..91acc9f
--- /dev/null
+++ b/lib/utils/reset/fdt_reset_atcwdt200.c
@@ -0,0 +1,122 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Andes Technology Corporation
+ *
+ * Authors:
+ * Yu Chien Peter Lin <peterlin@andestech.com>
+ */
+
+#include <libfdt.h>
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_ecall_interface.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_system.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/reset/fdt_reset.h>
+
+#define ATCWDT200_WP_NUM 0x5aa5
+#define WREN_REG 0x18
+#define CTRL_REG 0x10
+#define RST_TIME_OFF 8
+#define RST_TIME_MSK (0x3 << RST_TIME_OFF)
+#define RST_CLK_128 (0 << RST_TIME_OFF)
+#define RST_CLK_256 (1 << RST_TIME_OFF)
+#define RST_CLK_512 (2 << RST_TIME_OFF)
+#define RST_CLK_1024 (3 << RST_TIME_OFF)
+#define INT_TIME_OFF 4
+#define INT_TIME_MSK (0xf << INT_TIME_OFF)
+#define INT_CLK_64 (0 << INT_TIME_OFF)
+#define INT_CLK_256 (1 << INT_TIME_OFF)
+#define INT_CLK_1024 (2 << INT_TIME_OFF)
+#define INT_CLK_2048 (3 << INT_TIME_OFF)
+#define INT_CLK_4096 (4 << INT_TIME_OFF)
+#define INT_CLK_8192 (5 << INT_TIME_OFF)
+#define INT_CLK_16384 (6 << INT_TIME_OFF)
+#define INT_CLK_32768 (7 << INT_TIME_OFF)
+#define RST_EN (1 << 3)
+#define INT_EN (1 << 2)
+#define CLK_PCLK (1 << 1)
+#define WDT_EN (1 << 0)
+
+#define FLASH_BASE 0x80000000ULL
+#define SMU_RESET_VEC_LO_OFF 0x50
+#define SMU_RESET_VEC_HI_OFF 0x60
+#define SMU_HARTn_RESET_VEC_LO(n) (SMU_RESET_VEC_LO_OFF + (n * 0x4))
+#define SMU_HARTn_RESET_VEC_HI(n) (SMU_RESET_VEC_HI_OFF + (n * 0x4))
+
+static volatile char *wdt_addr;
+static volatile char *smu_addr;
+
+static int ae350_system_reset_check(u32 type, u32 reason)
+{
+ switch (type) {
+ case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+ return 1;
+ case SBI_SRST_RESET_TYPE_SHUTDOWN:
+ case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+ default:
+ return 0;
+ }
+}
+
+static void ae350_system_reset(u32 type, u32 reason)
+{
+ const struct sbi_platform *plat = sbi_platform_thishart_ptr();
+
+ for (int i = 0; i < sbi_platform_hart_count(plat); i++) {
+ writel(FLASH_BASE, smu_addr + SMU_HARTn_RESET_VEC_LO(i));
+ writel(FLASH_BASE >> 32, smu_addr + SMU_HARTn_RESET_VEC_HI(i));
+ }
+
+ /* Program WDT control register */
+ writew(ATCWDT200_WP_NUM, wdt_addr + WREN_REG);
+ writel(INT_CLK_32768 | INT_EN | RST_CLK_128 | RST_EN | WDT_EN,
+ wdt_addr + CTRL_REG);
+
+ sbi_hart_hang();
+}
+
+static struct sbi_system_reset_device atcwdt200_reset = {
+ .name = "atcwdt200",
+ .system_reset_check = ae350_system_reset_check,
+ .system_reset = ae350_system_reset,
+};
+
+static int atcwdt200_reset_init(void *fdt, int nodeoff,
+ const struct fdt_match *match)
+{
+ uint64_t reg_addr;
+ int rc;
+
+ rc = fdt_get_node_addr_size(fdt, nodeoff, 0, ®_addr, NULL);
+ if (rc < 0 || !reg_addr)
+ return SBI_ENODEV;
+
+ wdt_addr = (volatile char *)(unsigned long)reg_addr;
+
+ /*
+ * The reset device requires smu to program the reset
+ * vector for each hart.
+ */
+ if (fdt_parse_compat_addr(fdt, ®_addr, "andestech,atcsmu"))
+ return SBI_ENODEV;
+
+ smu_addr = (volatile char *)(unsigned long)reg_addr;
+
+ sbi_system_reset_add_device(&atcwdt200_reset);
+
+ return 0;
+}
+
+static const struct fdt_match atcwdt200_reset_match[] = {
+ { .compatible = "andestech,atcwdt200" },
+ {},
+};
+
+struct fdt_reset fdt_reset_atcwdt200 = {
+ .match_table = atcwdt200_reset_match,
+ .init = atcwdt200_reset_init,
+};
diff --git a/lib/utils/reset/objects.mk b/lib/utils/reset/objects.mk
index 8a50dd0..c9f851c 100644
--- a/lib/utils/reset/objects.mk
+++ b/lib/utils/reset/objects.mk
@@ -10,6 +10,9 @@
libsbiutils-objs-$(CONFIG_FDT_RESET) += reset/fdt_reset.o
libsbiutils-objs-$(CONFIG_FDT_RESET) += reset/fdt_reset_drivers.o
+carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_ATCWDT200) += fdt_reset_atcwdt200
+libsbiutils-objs-$(CONFIG_FDT_RESET_ATCWDT200) += reset/fdt_reset_atcwdt200.o
+
carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_GPIO) += fdt_poweroff_gpio
carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_GPIO) += fdt_reset_gpio
libsbiutils-objs-$(CONFIG_FDT_RESET_GPIO) += reset/fdt_reset_gpio.o
diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
index f6f50eb..8486f08 100644
--- a/platform/andes/ae350/Kconfig
+++ b/platform/andes/ae350/Kconfig
@@ -8,6 +8,8 @@ config PLATFORM_ANDES_AE350
select FDT_SERIAL_UART8250
select FDT_TIMER
select FDT_TIMER_PLMT
+ select FDT_RESET
+ select FDT_RESET_ATCWDT200
default y
if PLATFORM_ANDES_AE350
diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
index 79736c0..c6a8eeb 100644
--- a/platform/andes/ae350/platform.c
+++ b/platform/andes/ae350/platform.c
@@ -18,6 +18,7 @@
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/fdt/fdt_fixup.h>
#include <sbi_utils/irqchip/plic.h>
+#include <sbi_utils/reset/fdt_reset.h>
#include <sbi_utils/serial/fdt_serial.h>
#include <sbi_utils/timer/fdt_timer.h>
#include "platform.h"
@@ -37,6 +38,8 @@ static int ae350_final_init(bool cold_boot)
if (!cold_boot)
return 0;
+ fdt_reset_init();
+
fdt = fdt_get_address();
fdt_fixups(fdt);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 06/12] lib: utils/reset: Add Andes fdt reset driver support
2022-10-03 11:52 ` [PATCH v2 06/12] lib: utils/reset: Add Andes fdt reset driver support Yu Chien Peter Lin
@ 2022-10-11 16:35 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:35 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:23 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> Add ATCWDT200 as reset device of ae350 platform, this driver requires
> SMU to program the reset vector registers before triggering WDT software
> restart signal.
>
> dts example:
>
> smu at f0100000 {
> compatible = "andestech,atcsmu";
> reg = <0x00000000 0xf0100000 0x00000000 0x00001000>;
> };
>
> wdt: wdt at f0500000 {
> compatible = "andestech,atcwdt200";
> reg = <0x00000000 0xf0500000 0x00000000 0x00001000>;
> interrupts = <3 4>;
> interrupt-parent = <&plic0>;
> clock-frequency = <15000000>;
> };
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Looks good to me.
Reviewed-by: Anup Patel <anup@brainfault.org>
Regards,
Anup
> ---
> lib/utils/reset/Kconfig | 4 +
> lib/utils/reset/fdt_reset_atcwdt200.c | 122 ++++++++++++++++++++++++++
> lib/utils/reset/objects.mk | 3 +
> platform/andes/ae350/Kconfig | 2 +
> platform/andes/ae350/platform.c | 3 +
> 5 files changed, 134 insertions(+)
> create mode 100644 lib/utils/reset/fdt_reset_atcwdt200.c
>
> diff --git a/lib/utils/reset/Kconfig b/lib/utils/reset/Kconfig
> index 2e83ff6..0e0c2c1 100644
> --- a/lib/utils/reset/Kconfig
> +++ b/lib/utils/reset/Kconfig
> @@ -9,6 +9,10 @@ config FDT_RESET
>
> if FDT_RESET
>
> +config FDT_RESET_ATCWDT200
> + bool "Andes WDT FDT reset driver"
> + default n
> +
> config FDT_RESET_GPIO
> bool "GPIO FDT reset driver"
> depends on FDT_GPIO
> diff --git a/lib/utils/reset/fdt_reset_atcwdt200.c b/lib/utils/reset/fdt_reset_atcwdt200.c
> new file mode 100644
> index 0000000..91acc9f
> --- /dev/null
> +++ b/lib/utils/reset/fdt_reset_atcwdt200.c
> @@ -0,0 +1,122 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2022 Andes Technology Corporation
> + *
> + * Authors:
> + * Yu Chien Peter Lin <peterlin@andestech.com>
> + */
> +
> +#include <libfdt.h>
> +#include <sbi/riscv_io.h>
> +#include <sbi/sbi_ecall_interface.h>
> +#include <sbi/sbi_error.h>
> +#include <sbi/sbi_hart.h>
> +#include <sbi/sbi_platform.h>
> +#include <sbi/sbi_system.h>
> +#include <sbi_utils/fdt/fdt_helper.h>
> +#include <sbi_utils/reset/fdt_reset.h>
> +
> +#define ATCWDT200_WP_NUM 0x5aa5
> +#define WREN_REG 0x18
> +#define CTRL_REG 0x10
> +#define RST_TIME_OFF 8
> +#define RST_TIME_MSK (0x3 << RST_TIME_OFF)
> +#define RST_CLK_128 (0 << RST_TIME_OFF)
> +#define RST_CLK_256 (1 << RST_TIME_OFF)
> +#define RST_CLK_512 (2 << RST_TIME_OFF)
> +#define RST_CLK_1024 (3 << RST_TIME_OFF)
> +#define INT_TIME_OFF 4
> +#define INT_TIME_MSK (0xf << INT_TIME_OFF)
> +#define INT_CLK_64 (0 << INT_TIME_OFF)
> +#define INT_CLK_256 (1 << INT_TIME_OFF)
> +#define INT_CLK_1024 (2 << INT_TIME_OFF)
> +#define INT_CLK_2048 (3 << INT_TIME_OFF)
> +#define INT_CLK_4096 (4 << INT_TIME_OFF)
> +#define INT_CLK_8192 (5 << INT_TIME_OFF)
> +#define INT_CLK_16384 (6 << INT_TIME_OFF)
> +#define INT_CLK_32768 (7 << INT_TIME_OFF)
> +#define RST_EN (1 << 3)
> +#define INT_EN (1 << 2)
> +#define CLK_PCLK (1 << 1)
> +#define WDT_EN (1 << 0)
> +
> +#define FLASH_BASE 0x80000000ULL
> +#define SMU_RESET_VEC_LO_OFF 0x50
> +#define SMU_RESET_VEC_HI_OFF 0x60
> +#define SMU_HARTn_RESET_VEC_LO(n) (SMU_RESET_VEC_LO_OFF + (n * 0x4))
> +#define SMU_HARTn_RESET_VEC_HI(n) (SMU_RESET_VEC_HI_OFF + (n * 0x4))
> +
> +static volatile char *wdt_addr;
> +static volatile char *smu_addr;
> +
> +static int ae350_system_reset_check(u32 type, u32 reason)
> +{
> + switch (type) {
> + case SBI_SRST_RESET_TYPE_COLD_REBOOT:
> + return 1;
> + case SBI_SRST_RESET_TYPE_SHUTDOWN:
> + case SBI_SRST_RESET_TYPE_WARM_REBOOT:
> + default:
> + return 0;
> + }
> +}
> +
> +static void ae350_system_reset(u32 type, u32 reason)
> +{
> + const struct sbi_platform *plat = sbi_platform_thishart_ptr();
> +
> + for (int i = 0; i < sbi_platform_hart_count(plat); i++) {
> + writel(FLASH_BASE, smu_addr + SMU_HARTn_RESET_VEC_LO(i));
> + writel(FLASH_BASE >> 32, smu_addr + SMU_HARTn_RESET_VEC_HI(i));
> + }
> +
> + /* Program WDT control register */
> + writew(ATCWDT200_WP_NUM, wdt_addr + WREN_REG);
> + writel(INT_CLK_32768 | INT_EN | RST_CLK_128 | RST_EN | WDT_EN,
> + wdt_addr + CTRL_REG);
> +
> + sbi_hart_hang();
> +}
> +
> +static struct sbi_system_reset_device atcwdt200_reset = {
> + .name = "atcwdt200",
> + .system_reset_check = ae350_system_reset_check,
> + .system_reset = ae350_system_reset,
> +};
> +
> +static int atcwdt200_reset_init(void *fdt, int nodeoff,
> + const struct fdt_match *match)
> +{
> + uint64_t reg_addr;
> + int rc;
> +
> + rc = fdt_get_node_addr_size(fdt, nodeoff, 0, ®_addr, NULL);
> + if (rc < 0 || !reg_addr)
> + return SBI_ENODEV;
> +
> + wdt_addr = (volatile char *)(unsigned long)reg_addr;
> +
> + /*
> + * The reset device requires smu to program the reset
> + * vector for each hart.
> + */
> + if (fdt_parse_compat_addr(fdt, ®_addr, "andestech,atcsmu"))
> + return SBI_ENODEV;
> +
> + smu_addr = (volatile char *)(unsigned long)reg_addr;
> +
> + sbi_system_reset_add_device(&atcwdt200_reset);
> +
> + return 0;
> +}
> +
> +static const struct fdt_match atcwdt200_reset_match[] = {
> + { .compatible = "andestech,atcwdt200" },
> + {},
> +};
> +
> +struct fdt_reset fdt_reset_atcwdt200 = {
> + .match_table = atcwdt200_reset_match,
> + .init = atcwdt200_reset_init,
> +};
> diff --git a/lib/utils/reset/objects.mk b/lib/utils/reset/objects.mk
> index 8a50dd0..c9f851c 100644
> --- a/lib/utils/reset/objects.mk
> +++ b/lib/utils/reset/objects.mk
> @@ -10,6 +10,9 @@
> libsbiutils-objs-$(CONFIG_FDT_RESET) += reset/fdt_reset.o
> libsbiutils-objs-$(CONFIG_FDT_RESET) += reset/fdt_reset_drivers.o
>
> +carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_ATCWDT200) += fdt_reset_atcwdt200
> +libsbiutils-objs-$(CONFIG_FDT_RESET_ATCWDT200) += reset/fdt_reset_atcwdt200.o
> +
> carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_GPIO) += fdt_poweroff_gpio
> carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_GPIO) += fdt_reset_gpio
> libsbiutils-objs-$(CONFIG_FDT_RESET_GPIO) += reset/fdt_reset_gpio.o
> diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
> index f6f50eb..8486f08 100644
> --- a/platform/andes/ae350/Kconfig
> +++ b/platform/andes/ae350/Kconfig
> @@ -8,6 +8,8 @@ config PLATFORM_ANDES_AE350
> select FDT_SERIAL_UART8250
> select FDT_TIMER
> select FDT_TIMER_PLMT
> + select FDT_RESET
> + select FDT_RESET_ATCWDT200
> default y
>
> if PLATFORM_ANDES_AE350
> diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
> index 79736c0..c6a8eeb 100644
> --- a/platform/andes/ae350/platform.c
> +++ b/platform/andes/ae350/platform.c
> @@ -18,6 +18,7 @@
> #include <sbi_utils/fdt/fdt_helper.h>
> #include <sbi_utils/fdt/fdt_fixup.h>
> #include <sbi_utils/irqchip/plic.h>
> +#include <sbi_utils/reset/fdt_reset.h>
> #include <sbi_utils/serial/fdt_serial.h>
> #include <sbi_utils/timer/fdt_timer.h>
> #include "platform.h"
> @@ -37,6 +38,8 @@ static int ae350_final_init(bool cold_boot)
> if (!cold_boot)
> return 0;
>
> + fdt_reset_init();
> +
> fdt = fdt_get_address();
> fdt_fixups(fdt);
>
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 07/12] platform: andes/ae350: Use fdt irqchip driver
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
` (5 preceding siblings ...)
2022-10-03 11:52 ` [PATCH v2 06/12] lib: utils/reset: Add Andes fdt reset driver support Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:35 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 08/12] platform: andes/ae350: Add fw_platform_init for platform initialization Yu Chien Peter Lin
` (4 subsequent siblings)
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
Andes PLIC is compatible with plic driver. The PLIC base address and
number of source can be obtained by parsing the device tree.
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
platform/andes/ae350/Kconfig | 3 ++-
platform/andes/ae350/platform.c | 24 ++----------------------
platform/andes/ae350/platform.h | 3 ---
3 files changed, 4 insertions(+), 26 deletions(-)
diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
index 8486f08..084b27f 100644
--- a/platform/andes/ae350/Kconfig
+++ b/platform/andes/ae350/Kconfig
@@ -3,13 +3,14 @@
config PLATFORM_ANDES_AE350
bool
select FDT
- select IRQCHIP_PLIC
select FDT_SERIAL
select FDT_SERIAL_UART8250
select FDT_TIMER
select FDT_TIMER_PLMT
select FDT_RESET
select FDT_RESET_ATCWDT200
+ select FDT_IRQCHIP
+ select FDT_IRQCHIP_PLIC
default y
if PLATFORM_ANDES_AE350
diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
index c6a8eeb..98acaaa 100644
--- a/platform/andes/ae350/platform.c
+++ b/platform/andes/ae350/platform.c
@@ -17,7 +17,7 @@
#include <sbi/sbi_trap.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/fdt/fdt_fixup.h>
-#include <sbi_utils/irqchip/plic.h>
+#include <sbi_utils/irqchip/fdt_irqchip.h>
#include <sbi_utils/reset/fdt_reset.h>
#include <sbi_utils/serial/fdt_serial.h>
#include <sbi_utils/timer/fdt_timer.h>
@@ -25,11 +25,6 @@
#include "plicsw.h"
#include "cache.h"
-static struct plic_data plic = {
- .addr = AE350_PLIC_ADDR,
- .num_src = AE350_PLIC_NUM_SOURCES,
-};
-
/* Platform final initialization. */
static int ae350_final_init(bool cold_boot)
{
@@ -46,21 +41,6 @@ static int ae350_final_init(bool cold_boot)
return 0;
}
-/* Initialize the platform interrupt controller for current HART. */
-static int ae350_irqchip_init(bool cold_boot)
-{
- u32 hartid = current_hartid();
- int ret;
-
- if (cold_boot) {
- ret = plic_cold_irqchip_init(&plic);
- if (ret)
- return ret;
- }
-
- return plic_warm_irqchip_init(&plic, 2 * hartid, 2 * hartid + 1);
-}
-
static struct sbi_ipi_device plicsw_ipi = {
.name = "ae350_plicsw",
.ipi_send = plicsw_ipi_send,
@@ -134,7 +114,7 @@ const struct sbi_platform_operations platform_ops = {
.console_init = fdt_serial_init,
- .irqchip_init = ae350_irqchip_init,
+ .irqchip_init = fdt_irqchip_init,
.ipi_init = ae350_ipi_init,
diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
index 6a29fe5..3264b6f 100644
--- a/platform/andes/ae350/platform.h
+++ b/platform/andes/ae350/platform.h
@@ -13,9 +13,6 @@
#define AE350_HART_COUNT 4
-#define AE350_PLIC_ADDR 0xe4000000
-#define AE350_PLIC_NUM_SOURCES 71
-
#define AE350_PLICSW_ADDR 0xe6400000
#define AE350_L2C_ADDR 0xe0500000
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 07/12] platform: andes/ae350: Use fdt irqchip driver
2022-10-03 11:52 ` [PATCH v2 07/12] platform: andes/ae350: Use fdt irqchip driver Yu Chien Peter Lin
@ 2022-10-11 16:35 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:35 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:23 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> Andes PLIC is compatible with plic driver. The PLIC base address and
> number of source can be obtained by parsing the device tree.
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Looks good to me.
Reviewed-by: Anup Patel <anup@brainfault.org>
Regards,
Anup
> ---
> platform/andes/ae350/Kconfig | 3 ++-
> platform/andes/ae350/platform.c | 24 ++----------------------
> platform/andes/ae350/platform.h | 3 ---
> 3 files changed, 4 insertions(+), 26 deletions(-)
>
> diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
> index 8486f08..084b27f 100644
> --- a/platform/andes/ae350/Kconfig
> +++ b/platform/andes/ae350/Kconfig
> @@ -3,13 +3,14 @@
> config PLATFORM_ANDES_AE350
> bool
> select FDT
> - select IRQCHIP_PLIC
> select FDT_SERIAL
> select FDT_SERIAL_UART8250
> select FDT_TIMER
> select FDT_TIMER_PLMT
> select FDT_RESET
> select FDT_RESET_ATCWDT200
> + select FDT_IRQCHIP
> + select FDT_IRQCHIP_PLIC
> default y
>
> if PLATFORM_ANDES_AE350
> diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
> index c6a8eeb..98acaaa 100644
> --- a/platform/andes/ae350/platform.c
> +++ b/platform/andes/ae350/platform.c
> @@ -17,7 +17,7 @@
> #include <sbi/sbi_trap.h>
> #include <sbi_utils/fdt/fdt_helper.h>
> #include <sbi_utils/fdt/fdt_fixup.h>
> -#include <sbi_utils/irqchip/plic.h>
> +#include <sbi_utils/irqchip/fdt_irqchip.h>
> #include <sbi_utils/reset/fdt_reset.h>
> #include <sbi_utils/serial/fdt_serial.h>
> #include <sbi_utils/timer/fdt_timer.h>
> @@ -25,11 +25,6 @@
> #include "plicsw.h"
> #include "cache.h"
>
> -static struct plic_data plic = {
> - .addr = AE350_PLIC_ADDR,
> - .num_src = AE350_PLIC_NUM_SOURCES,
> -};
> -
> /* Platform final initialization. */
> static int ae350_final_init(bool cold_boot)
> {
> @@ -46,21 +41,6 @@ static int ae350_final_init(bool cold_boot)
> return 0;
> }
>
> -/* Initialize the platform interrupt controller for current HART. */
> -static int ae350_irqchip_init(bool cold_boot)
> -{
> - u32 hartid = current_hartid();
> - int ret;
> -
> - if (cold_boot) {
> - ret = plic_cold_irqchip_init(&plic);
> - if (ret)
> - return ret;
> - }
> -
> - return plic_warm_irqchip_init(&plic, 2 * hartid, 2 * hartid + 1);
> -}
> -
> static struct sbi_ipi_device plicsw_ipi = {
> .name = "ae350_plicsw",
> .ipi_send = plicsw_ipi_send,
> @@ -134,7 +114,7 @@ const struct sbi_platform_operations platform_ops = {
>
> .console_init = fdt_serial_init,
>
> - .irqchip_init = ae350_irqchip_init,
> + .irqchip_init = fdt_irqchip_init,
>
> .ipi_init = ae350_ipi_init,
>
> diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
> index 6a29fe5..3264b6f 100644
> --- a/platform/andes/ae350/platform.h
> +++ b/platform/andes/ae350/platform.h
> @@ -13,9 +13,6 @@
>
> #define AE350_HART_COUNT 4
>
> -#define AE350_PLIC_ADDR 0xe4000000
> -#define AE350_PLIC_NUM_SOURCES 71
> -
> #define AE350_PLICSW_ADDR 0xe6400000
>
> #define AE350_L2C_ADDR 0xe0500000
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 08/12] platform: andes/ae350: Add fw_platform_init for platform initialization
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
` (6 preceding siblings ...)
2022-10-03 11:52 ` [PATCH v2 07/12] platform: andes/ae350: Use fdt irqchip driver Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:37 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 09/12] lib: utils/ipi: Add Andes fdt ipi driver support Yu Chien Peter Lin
` (3 subsequent siblings)
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
This patch adds fw_platform_init() to initialize ae350 platform.name
and platform.hart_count by parsing device tree.
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
platform/andes/ae350/platform.c | 51 +++++++++++++++++++++++++++++++--
platform/andes/ae350/platform.h | 2 --
2 files changed, 49 insertions(+), 4 deletions(-)
diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
index 98acaaa..cf5417c 100644
--- a/platform/andes/ae350/platform.c
+++ b/platform/andes/ae350/platform.c
@@ -6,14 +6,18 @@
* Authors:
* Zong Li <zong@andestech.com>
* Nylon Chen <nylon7@andestech.com>
+ * Yu Chien Peter Lin <peterlin@andestech.com>
*/
+#include <libfdt.h>
#include <sbi/riscv_asm.h>
#include <sbi/riscv_encoding.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_const.h>
+#include <sbi/sbi_hartmask.h>
#include <sbi/sbi_ipi.h>
#include <sbi/sbi_platform.h>
+#include <sbi/sbi_string.h>
#include <sbi/sbi_trap.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/fdt/fdt_fixup.h>
@@ -25,6 +29,49 @@
#include "plicsw.h"
#include "cache.h"
+struct sbi_platform platform;
+unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4)
+{
+ const char *model;
+ void *fdt = (void *)arg1;
+ u32 hartid, hart_count = 0;
+ int rc, root_offset, cpus_offset, cpu_offset, len;
+
+ root_offset = fdt_path_offset(fdt, "/");
+ if (root_offset < 0)
+ goto fail;
+
+ model = fdt_getprop(fdt, root_offset, "model", &len);
+ if (model)
+ sbi_strncpy(platform.name, model, sizeof(platform.name) - 1);
+
+ cpus_offset = fdt_path_offset(fdt, "/cpus");
+ if (cpus_offset < 0)
+ goto fail;
+
+ fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
+ rc = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
+ if (rc)
+ continue;
+
+ if (SBI_HARTMASK_MAX_BITS <= hartid)
+ continue;
+
+ hart_count++;
+ }
+
+ platform.hart_count = hart_count;
+
+ /* Return original FDT pointer */
+ return arg1;
+
+fail:
+ while (1)
+ wfi();
+}
+
/* Platform final initialization. */
static int ae350_final_init(bool cold_boot)
{
@@ -123,14 +170,14 @@ const struct sbi_platform_operations platform_ops = {
.vendor_ext_provider = ae350_vendor_ext_provider
};
-const struct sbi_platform platform = {
+struct sbi_platform platform = {
.opensbi_version = OPENSBI_VERSION,
.platform_version =
SBI_PLATFORM_VERSION(CONFIG_PLATFORM_ANDES_AE350_MAJOR_VER,
CONFIG_PLATFORM_ANDES_AE350_MINOR_VER),
.name = CONFIG_PLATFORM_ANDES_AE350_NAME,
.features = SBI_PLATFORM_DEFAULT_FEATURES,
- .hart_count = AE350_HART_COUNT,
+ .hart_count = SBI_HARTMASK_MAX_BITS,
.hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
.platform_ops_addr = (unsigned long)&platform_ops
};
diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
index 3264b6f..3003bb4 100644
--- a/platform/andes/ae350/platform.h
+++ b/platform/andes/ae350/platform.h
@@ -11,8 +11,6 @@
#ifndef _AE350_PLATFORM_H_
#define _AE350_PLATFORM_H_
-#define AE350_HART_COUNT 4
-
#define AE350_PLICSW_ADDR 0xe6400000
#define AE350_L2C_ADDR 0xe0500000
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 08/12] platform: andes/ae350: Add fw_platform_init for platform initialization
2022-10-03 11:52 ` [PATCH v2 08/12] platform: andes/ae350: Add fw_platform_init for platform initialization Yu Chien Peter Lin
@ 2022-10-11 16:37 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:37 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:23 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> This patch adds fw_platform_init() to initialize ae350 platform.name
> and platform.hart_count by parsing device tree.
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Looks good to me.
Reviewed-by: Anup Patel <anup@brainfault.org>
Regards,
Anup
> ---
> platform/andes/ae350/platform.c | 51 +++++++++++++++++++++++++++++++--
> platform/andes/ae350/platform.h | 2 --
> 2 files changed, 49 insertions(+), 4 deletions(-)
>
> diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
> index 98acaaa..cf5417c 100644
> --- a/platform/andes/ae350/platform.c
> +++ b/platform/andes/ae350/platform.c
> @@ -6,14 +6,18 @@
> * Authors:
> * Zong Li <zong@andestech.com>
> * Nylon Chen <nylon7@andestech.com>
> + * Yu Chien Peter Lin <peterlin@andestech.com>
> */
>
> +#include <libfdt.h>
> #include <sbi/riscv_asm.h>
> #include <sbi/riscv_encoding.h>
> #include <sbi/sbi_console.h>
> #include <sbi/sbi_const.h>
> +#include <sbi/sbi_hartmask.h>
> #include <sbi/sbi_ipi.h>
> #include <sbi/sbi_platform.h>
> +#include <sbi/sbi_string.h>
> #include <sbi/sbi_trap.h>
> #include <sbi_utils/fdt/fdt_helper.h>
> #include <sbi_utils/fdt/fdt_fixup.h>
> @@ -25,6 +29,49 @@
> #include "plicsw.h"
> #include "cache.h"
>
> +struct sbi_platform platform;
> +unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,
> + unsigned long arg2, unsigned long arg3,
> + unsigned long arg4)
> +{
> + const char *model;
> + void *fdt = (void *)arg1;
> + u32 hartid, hart_count = 0;
> + int rc, root_offset, cpus_offset, cpu_offset, len;
> +
> + root_offset = fdt_path_offset(fdt, "/");
> + if (root_offset < 0)
> + goto fail;
> +
> + model = fdt_getprop(fdt, root_offset, "model", &len);
> + if (model)
> + sbi_strncpy(platform.name, model, sizeof(platform.name) - 1);
> +
> + cpus_offset = fdt_path_offset(fdt, "/cpus");
> + if (cpus_offset < 0)
> + goto fail;
> +
> + fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
> + rc = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
> + if (rc)
> + continue;
> +
> + if (SBI_HARTMASK_MAX_BITS <= hartid)
> + continue;
> +
> + hart_count++;
> + }
> +
> + platform.hart_count = hart_count;
> +
> + /* Return original FDT pointer */
> + return arg1;
> +
> +fail:
> + while (1)
> + wfi();
> +}
> +
> /* Platform final initialization. */
> static int ae350_final_init(bool cold_boot)
> {
> @@ -123,14 +170,14 @@ const struct sbi_platform_operations platform_ops = {
> .vendor_ext_provider = ae350_vendor_ext_provider
> };
>
> -const struct sbi_platform platform = {
> +struct sbi_platform platform = {
> .opensbi_version = OPENSBI_VERSION,
> .platform_version =
> SBI_PLATFORM_VERSION(CONFIG_PLATFORM_ANDES_AE350_MAJOR_VER,
> CONFIG_PLATFORM_ANDES_AE350_MINOR_VER),
> .name = CONFIG_PLATFORM_ANDES_AE350_NAME,
> .features = SBI_PLATFORM_DEFAULT_FEATURES,
> - .hart_count = AE350_HART_COUNT,
> + .hart_count = SBI_HARTMASK_MAX_BITS,
> .hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
> .platform_ops_addr = (unsigned long)&platform_ops
> };
> diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
> index 3264b6f..3003bb4 100644
> --- a/platform/andes/ae350/platform.h
> +++ b/platform/andes/ae350/platform.h
> @@ -11,8 +11,6 @@
> #ifndef _AE350_PLATFORM_H_
> #define _AE350_PLATFORM_H_
>
> -#define AE350_HART_COUNT 4
> -
> #define AE350_PLICSW_ADDR 0xe6400000
>
> #define AE350_L2C_ADDR 0xe0500000
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 09/12] lib: utils/ipi: Add Andes fdt ipi driver support
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
` (7 preceding siblings ...)
2022-10-03 11:52 ` [PATCH v2 08/12] platform: andes/ae350: Add fw_platform_init for platform initialization Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:42 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 10/12] lib: utils/ipi: Add PLICSW mmio region to root domain Yu Chien Peter Lin
` (2 subsequent siblings)
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
Move Andes PLICSW ipi device to fdt ipi framework, this patch is based
on Leo's modified IPI scheme on PLICSW.
Current IPI scheme uses bit 0 of pending reigster on PLICSW to send IPI
from hart 0 to hart 7, but bit 0 needs to be hardwired to 0 according
to spec. After some investigation, self-IPI seems to be seldom or never
used, so we re-order the IPI scheme to support 8 core bitmaps.
dts example (ax45mp 4 core):
plicsw: interrupt-controller at e6400000 {
compatible = "andestech,plicsw";
reg = <0x00000000 0xe6400000 0x00000000 0x00400000>;
interrupts-extended = < &CPU0_intc 3
&CPU1_intc 3
&CPU2_intc 3
&CPU3_intc 3>;
interrupt-controller;
#address-cells = <2>;
#interrupt-cells = <2>;
riscv,ndev = <4>;
};
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
---
include/sbi_utils/fdt/fdt_helper.h | 3 +
include/sbi_utils/ipi/andes_plicsw.h | 48 +++++++++
lib/utils/fdt/fdt_helper.c | 59 ++++++++++++
lib/utils/ipi/Kconfig | 9 ++
lib/utils/ipi/andes_plicsw.c | 85 ++++++++++++++++
lib/utils/ipi/fdt_ipi_plicsw.c | 79 +++++++++++++++
lib/utils/ipi/objects.mk | 4 +
platform/andes/ae350/Kconfig | 2 +
platform/andes/ae350/objects.mk | 2 +-
platform/andes/ae350/platform.c | 27 +-----
platform/andes/ae350/platform.h | 2 -
platform/andes/ae350/plicsw.c | 139 ---------------------------
platform/andes/ae350/plicsw.h | 44 ---------
13 files changed, 292 insertions(+), 211 deletions(-)
create mode 100644 include/sbi_utils/ipi/andes_plicsw.h
create mode 100644 lib/utils/ipi/andes_plicsw.c
create mode 100644 lib/utils/ipi/fdt_ipi_plicsw.c
delete mode 100644 platform/andes/ae350/plicsw.c
delete mode 100644 platform/andes/ae350/plicsw.h
diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 7ef63c9..7e0083a 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -98,6 +98,9 @@ int fdt_parse_aclint_node(void *fdt, int nodeoffset, bool for_timer,
int fdt_parse_plmt_node(void *fdt, int nodeoffset, unsigned long *plmt_base,
unsigned long *plmt_size, u32 *hart_count);
+int fdt_parse_plicsw_node(void *fdt, int nodeoffset, unsigned long *plicsw_base,
+ unsigned long *size, unsigned long *num_src, u32 *hart_count);
+
int fdt_parse_compat_addr(void *fdt, uint64_t *addr,
const char *compatible);
diff --git a/include/sbi_utils/ipi/andes_plicsw.h b/include/sbi_utils/ipi/andes_plicsw.h
new file mode 100644
index 0000000..47f79ad
--- /dev/null
+++ b/include/sbi_utils/ipi/andes_plicsw.h
@@ -0,0 +1,48 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Andes Technology Corporation
+ *
+ * Authors:
+ * Zong Li <zong@andestech.com>
+ * Nylon Chen <nylon7@andestech.com>
+ * Leo Yu-Chi Liang <ycliang@andestech.com>
+ * Yu Chien Peter Lin <peterlin@andestech.com>
+ */
+
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_types.h>
+
+#ifndef _IPI_ANDES_PLICSW_H_
+#define _IPI_ANDES_PLICSW_H_
+
+#define PLICSW_PRIORITY_BASE 0x4
+
+#define PLICSW_PENDING_BASE 0x1000
+#define PLICSW_PENDING_STRIDE 0x8
+
+#define PLICSW_ENABLE_BASE 0x2000
+#define PLICSW_ENABLE_STRIDE 0x80
+
+#define PLICSW_CONTEXT_BASE 0x200000
+#define PLICSW_CONTEXT_STRIDE 0x1000
+#define PLICSW_CONTEXT_CLAIM 0x4
+
+#define PLICSW_HART_MASK 0x01010101
+
+#define PLICSW_HART_MAX_NR 8
+
+struct plicsw_data {
+ unsigned long addr;
+ unsigned long size;
+ unsigned long num_src;
+ uint32_t hart_count;
+ /* hart id to source id table */
+ uint32_t source_id[PLICSW_HART_MAX_NR];
+};
+
+void plicsw_ipi_send(u32 target_hart);
+void plicsw_ipi_clear(u32 target_hart);
+
+#endif /* _IPI_ANDES_PLICSW_H_ */
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index ce52fca..bed8b0a 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -889,6 +889,65 @@ int fdt_parse_plmt_node(void *fdt, int nodeoffset, unsigned long *plmt_base,
return 0;
}
+int fdt_parse_plicsw_node(void *fdt, int nodeoffset, unsigned long *plicsw_base,
+ unsigned long *size, unsigned long *num_src, u32 *hart_count)
+{
+ const fdt32_t *val;
+ int rc, i, count, len;
+ uint64_t reg_addr, reg_size, cpu_offset, cpu_intc_offset;
+ u32 phandle, hwirq, hartid, hcount;
+
+ if (nodeoffset < 0 || !fdt || !plicsw_base ||
+ !hart_count || !size)
+ return SBI_EINVAL;
+
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
+ ®_addr, ®_size);
+ if (rc < 0 || !plicsw_base || !size)
+ return SBI_ENODEV;
+ *plicsw_base = reg_addr;
+ *size = reg_size;
+
+ val = fdt_getprop(fdt, nodeoffset, "riscv,ndev", &len);
+ if (len > 0)
+ *num_src = fdt32_to_cpu(*val);
+
+ val = fdt_getprop(fdt, nodeoffset, "interrupts-extended", &count);
+ if (!val || count < sizeof(fdt32_t))
+ return 0;
+ count = count / sizeof(fdt32_t);
+
+ hcount = 0;
+ for (i = 0; i < (count / 2); i++) {
+ phandle = fdt32_to_cpu(val[2 * i]);
+ hwirq = fdt32_to_cpu(val[2 * i + 1]);
+
+ cpu_intc_offset = fdt_node_offset_by_phandle(fdt, phandle);
+ if (cpu_intc_offset < 0)
+ continue;
+
+ cpu_offset = fdt_parent_offset(fdt, cpu_intc_offset);
+ if (cpu_intc_offset < 0)
+ continue;
+
+ rc = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
+
+ if (rc)
+ continue;
+
+ if (SBI_HARTMASK_MAX_BITS <= hartid)
+ continue;
+
+ if (hwirq == IRQ_M_SOFT)
+ hcount++;
+ }
+
+ *hart_count = hcount;
+
+ return 0;
+}
+
+
int fdt_parse_compat_addr(void *fdt, uint64_t *addr,
const char *compatible)
{
diff --git a/lib/utils/ipi/Kconfig b/lib/utils/ipi/Kconfig
index efc8960..3718852 100644
--- a/lib/utils/ipi/Kconfig
+++ b/lib/utils/ipi/Kconfig
@@ -14,10 +14,19 @@ config FDT_IPI_MSWI
select IPI_MSWI
default n
+config FDT_IPI_PLICSW
+ bool "Andes PLICSW FDT driver"
+ select IPI_PLICSW
+ default n
+
endif
config IPI_MSWI
bool "ACLINT MSWI support"
default n
+config IPI_PLICSW
+ bool "Andes PLICSW support"
+ default n
+
endmenu
diff --git a/lib/utils/ipi/andes_plicsw.c b/lib/utils/ipi/andes_plicsw.c
new file mode 100644
index 0000000..f353610
--- /dev/null
+++ b/lib/utils/ipi/andes_plicsw.c
@@ -0,0 +1,85 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Andes Technology Corporation
+ *
+ * Authors:
+ * Zong Li <zong@andestech.com>
+ * Nylon Chen <nylon7@andestech.com>
+ * Leo Yu-Chi Liang <ycliang@andestech.com>
+ * Yu Chien Peter Lin <peterlin@andestech.com>
+ */
+
+#include <sbi/sbi_types.h>
+#include <sbi_utils/ipi/andes_plicsw.h>
+
+extern struct plicsw_data plicsw;
+
+static inline void plicsw_claim(void)
+{
+ u32 hartid = current_hartid();
+
+ if (plicsw.hart_count <= hartid)
+ ebreak();
+
+ plicsw.source_id[hartid] =
+ readl((void *)plicsw.addr + PLICSW_CONTEXT_BASE +
+ PLICSW_CONTEXT_CLAIM + PLICSW_CONTEXT_STRIDE * hartid);
+}
+
+static inline void plicsw_complete(void)
+{
+ u32 hartid = current_hartid();
+ u32 source = plicsw.source_id[hartid];
+
+ writel(source, (void *)plicsw.addr + PLICSW_CONTEXT_BASE +
+ PLICSW_CONTEXT_CLAIM +
+ PLICSW_CONTEXT_STRIDE * hartid);
+}
+
+static inline void plic_sw_pending(u32 target_hart)
+{
+ /*
+ * The pending array registers are w1s type.
+ * IPI pending array mapping as following:
+ *
+ * Pending array start address: base + 0x1000
+ * ---------------------------------
+ * | hart3 | hart2 | hart1 | hart0 |
+ * ---------------------------------
+ * Each hartX can send IPI to another hart by setting the
+ * bitY to its own region (see the below).
+ *
+ * In each hartX region:
+ * <---------- PICSW_PENDING_STRIDE -------->
+ * | bit7 | ... | bit3 | bit2 | bit1 | bit0 |
+ * ------------------------------------------
+ * The bitY of hartX region indicates that hartX sends an
+ * IPI to hartY.
+ */
+ u32 hartid = current_hartid();
+ u32 word_index = hartid / 4;
+ u32 per_hart_offset = PLICSW_PENDING_STRIDE * hartid;
+ u32 val = 1 << target_hart << per_hart_offset;
+
+ writel(val, (void *)plicsw.addr + PLICSW_PENDING_BASE + word_index * 4);
+}
+
+void plicsw_ipi_send(u32 target_hart)
+{
+ if (plicsw.hart_count <= target_hart)
+ ebreak();
+
+ /* Set PLICSW IPI */
+ plic_sw_pending(target_hart);
+}
+
+void plicsw_ipi_clear(u32 target_hart)
+{
+ if (plicsw.hart_count <= target_hart)
+ ebreak();
+
+ /* Clear PLICSW IPI */
+ plicsw_claim();
+ plicsw_complete();
+}
diff --git a/lib/utils/ipi/fdt_ipi_plicsw.c b/lib/utils/ipi/fdt_ipi_plicsw.c
new file mode 100644
index 0000000..8788f74
--- /dev/null
+++ b/lib/utils/ipi/fdt_ipi_plicsw.c
@@ -0,0 +1,79 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Andes Technology Corporation
+ *
+ * Authors:
+ * Zong Li <zong@andestech.com>
+ * Nylon Chen <nylon7@andestech.com>
+ * Leo Yu-Chi Liang <ycliang@andestech.com>
+ * Yu Chien Peter Lin <peterlin@andestech.com>
+ */
+
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_ipi.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/ipi/fdt_ipi.h>
+#include <sbi_utils/ipi/andes_plicsw.h>
+
+struct plicsw_data plicsw;
+
+static struct sbi_ipi_device plicsw_ipi = {
+ .name = "andes_plicsw",
+ .ipi_send = plicsw_ipi_send,
+ .ipi_clear = plicsw_ipi_clear
+};
+
+static int plicsw_warm_ipi_init(void)
+{
+ u32 hartid = current_hartid();
+
+ /* Clear PLICSW IPI */
+ plicsw_ipi_clear(hartid);
+
+ return 0;
+}
+
+static int plicsw_cold_ipi_init(void *fdt, int nodeoff,
+ const struct fdt_match *match)
+{
+ int rc;
+
+ rc = fdt_parse_plicsw_node(fdt, nodeoff, &plicsw.addr, &plicsw.size,
+ &plicsw.num_src, &plicsw.hart_count);
+ if (rc)
+ return rc;
+
+ /* Setup source priority */
+ uint32_t *priority = (void *)plicsw.addr + PLICSW_PRIORITY_BASE;
+
+ for (int i = 0; i < plicsw.hart_count; i++)
+ writel(1, &priority[i]);
+
+ /* Setup target enable */
+ uint32_t enable_mask = PLICSW_HART_MASK;
+
+ for (int i = 0; i < plicsw.hart_count; i++) {
+ uint32_t *enable = (void *)plicsw.addr + PLICSW_ENABLE_BASE +
+ PLICSW_ENABLE_STRIDE * i;
+ writel(enable_mask, enable);
+ writel(enable_mask, enable + 1);
+ enable_mask <<= 1;
+ }
+
+ sbi_ipi_set_device(&plicsw_ipi);
+
+ return 0;
+}
+
+static const struct fdt_match ipi_plicsw_match[] = {
+ { .compatible = "andestech,plicsw" },
+ {},
+};
+
+struct fdt_ipi fdt_ipi_plicsw = {
+ .match_table = ipi_plicsw_match,
+ .cold_init = plicsw_cold_ipi_init,
+ .warm_init = plicsw_warm_ipi_init,
+ .exit = NULL,
+};
diff --git a/lib/utils/ipi/objects.mk b/lib/utils/ipi/objects.mk
index 0600cac..999e7bd 100644
--- a/lib/utils/ipi/objects.mk
+++ b/lib/utils/ipi/objects.mk
@@ -8,9 +8,13 @@
#
libsbiutils-objs-$(CONFIG_IPI_MSWI) += ipi/aclint_mswi.o
+libsbiutils-objs-$(CONFIG_IPI_PLICSW) += ipi/andes_plicsw.o
libsbiutils-objs-$(CONFIG_FDT_IPI) += ipi/fdt_ipi.o
libsbiutils-objs-$(CONFIG_FDT_IPI) += ipi/fdt_ipi_drivers.o
carray-fdt_ipi_drivers-$(CONFIG_FDT_IPI_MSWI) += fdt_ipi_mswi
libsbiutils-objs-$(CONFIG_FDT_IPI_MSWI) += ipi/fdt_ipi_mswi.o
+
+carray-fdt_ipi_drivers-$(CONFIG_FDT_IPI_PLICSW) += fdt_ipi_plicsw
+libsbiutils-objs-$(CONFIG_FDT_IPI_PLICSW) += ipi/fdt_ipi_plicsw.o
diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
index 084b27f..38e4001 100644
--- a/platform/andes/ae350/Kconfig
+++ b/platform/andes/ae350/Kconfig
@@ -11,6 +11,8 @@ config PLATFORM_ANDES_AE350
select FDT_RESET_ATCWDT200
select FDT_IRQCHIP
select FDT_IRQCHIP_PLIC
+ select FDT_IPI
+ select FDT_IPI_PLICSW
default y
if PLATFORM_ANDES_AE350
diff --git a/platform/andes/ae350/objects.mk b/platform/andes/ae350/objects.mk
index 1ccb894..a4a2332 100644
--- a/platform/andes/ae350/objects.mk
+++ b/platform/andes/ae350/objects.mk
@@ -15,7 +15,7 @@ platform-asflags-y =
platform-ldflags-y =
# Objects to build
-platform-objs-y += cache.o platform.o plicsw.o
+platform-objs-y += cache.o platform.o
# Blobs to build
FW_TEXT_START=0x00000000
diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
index cf5417c..30e4606 100644
--- a/platform/andes/ae350/platform.c
+++ b/platform/andes/ae350/platform.c
@@ -25,8 +25,8 @@
#include <sbi_utils/reset/fdt_reset.h>
#include <sbi_utils/serial/fdt_serial.h>
#include <sbi_utils/timer/fdt_timer.h>
+#include <sbi_utils/ipi/fdt_ipi.h>
#include "platform.h"
-#include "plicsw.h"
#include "cache.h"
struct sbi_platform platform;
@@ -88,29 +88,6 @@ static int ae350_final_init(bool cold_boot)
return 0;
}
-static struct sbi_ipi_device plicsw_ipi = {
- .name = "ae350_plicsw",
- .ipi_send = plicsw_ipi_send,
- .ipi_clear = plicsw_ipi_clear
-};
-
-/* Initialize IPI for current HART. */
-static int ae350_ipi_init(bool cold_boot)
-{
- int ret;
-
- if (cold_boot) {
- ret = plicsw_cold_ipi_init(AE350_PLICSW_ADDR,
- AE350_HART_COUNT);
- if (ret)
- return ret;
-
- sbi_ipi_set_device(&plicsw_ipi);
- }
-
- return plicsw_warm_ipi_init();
-}
-
/* Vendor-Specific SBI handler */
static int ae350_vendor_ext_provider(long extid, long funcid,
const struct sbi_trap_regs *regs, unsigned long *out_value,
@@ -163,7 +140,7 @@ const struct sbi_platform_operations platform_ops = {
.irqchip_init = fdt_irqchip_init,
- .ipi_init = ae350_ipi_init,
+ .ipi_init = fdt_ipi_init,
.timer_init = fdt_timer_init,
diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
index 3003bb4..903bef0 100644
--- a/platform/andes/ae350/platform.h
+++ b/platform/andes/ae350/platform.h
@@ -11,8 +11,6 @@
#ifndef _AE350_PLATFORM_H_
#define _AE350_PLATFORM_H_
-#define AE350_PLICSW_ADDR 0xe6400000
-
#define AE350_L2C_ADDR 0xe0500000
/*Memory and Miscellaneous Registers*/
diff --git a/platform/andes/ae350/plicsw.c b/platform/andes/ae350/plicsw.c
deleted file mode 100644
index edbbb11..0000000
--- a/platform/andes/ae350/plicsw.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 Andes Technology Corporation
- *
- * Authors:
- * Zong Li <zong@andestech.com>
- * Nylon Chen <nylon7@andestech.com>
- */
-
-#include <sbi/riscv_asm.h>
-#include <sbi/riscv_io.h>
-#include <sbi/sbi_types.h>
-#include "plicsw.h"
-#include "platform.h"
-
-static u32 plicsw_ipi_hart_count;
-static struct plicsw plicsw_dev[AE350_HART_COUNT];
-
-static inline void plicsw_claim(void)
-{
- u32 source_hart = current_hartid();
-
- plicsw_dev[source_hart].source_id =
- readl(plicsw_dev[source_hart].plicsw_claim);
-}
-
-static inline void plicsw_complete(void)
-{
- u32 source_hart = current_hartid();
- u32 source = plicsw_dev[source_hart].source_id;
-
- writel(source, plicsw_dev[source_hart].plicsw_claim);
-}
-
-static inline void plic_sw_pending(u32 target_hart)
-{
- /*
- * The pending array registers are w1s type.
- * IPI pending array mapping as following:
- *
- * Pending array start address: base + 0x1000
- * -------------------------------------
- * | hart 3 | hart 2 | hart 1 | hart 0 |
- * -------------------------------------
- * Each hart X can send IPI to another hart by setting the
- * corresponding bit in hart X own region(see the below).
- *
- * In each hart region:
- * -----------------------------------------------
- * | bit 7 | bit 6 | bit 5 | bit 4 | ... | bit 0 |
- * -----------------------------------------------
- * The bit 7 is used to send IPI to hart 0
- * The bit 6 is used to send IPI to hart 1
- * The bit 5 is used to send IPI to hart 2
- * The bit 4 is used to send IPI to hart 3
- */
- u32 source_hart = current_hartid();
- u32 target_offset = (PLICSW_PENDING_PER_HART - 1) - target_hart;
- u32 per_hart_offset = PLICSW_PENDING_PER_HART * source_hart;
- u32 val = 1 << target_offset << per_hart_offset;
-
- writel(val, plicsw_dev[source_hart].plicsw_pending);
-}
-
-void plicsw_ipi_send(u32 target_hart)
-{
- if (plicsw_ipi_hart_count <= target_hart)
- return;
-
- /* Set PLICSW IPI */
- plic_sw_pending(target_hart);
-}
-
-void plicsw_ipi_clear(u32 target_hart)
-{
- if (plicsw_ipi_hart_count <= target_hart)
- return;
-
- /* Clear PLICSW IPI */
- plicsw_claim();
- plicsw_complete();
-}
-
-int plicsw_warm_ipi_init(void)
-{
- u32 hartid = current_hartid();
-
- if (!plicsw_dev[hartid].plicsw_pending
- && !plicsw_dev[hartid].plicsw_enable
- && !plicsw_dev[hartid].plicsw_claim)
- return -1;
-
- /* Clear PLICSW IPI */
- plicsw_ipi_clear(hartid);
-
- return 0;
-}
-
-int plicsw_cold_ipi_init(unsigned long base, u32 hart_count)
-{
- /* Setup source priority */
- uint32_t *priority = (void *)base + PLICSW_PRIORITY_BASE;
-
- for (int i = 0; i < AE350_HART_COUNT * PLICSW_PENDING_PER_HART; i++)
- writel(1, &priority[i]);
-
- /* Setup target enable */
- uint32_t enable_mask = PLICSW_HART_MASK;
-
- for (int i = 0; i < AE350_HART_COUNT; i++) {
- uint32_t *enable = (void *)base + PLICSW_ENABLE_BASE
- + PLICSW_ENABLE_PER_HART * i;
- writel(enable_mask, &enable[0]);
- enable_mask >>= 1;
- }
-
- /* Figure-out PLICSW IPI register address */
- plicsw_ipi_hart_count = hart_count;
-
- for (u32 hartid = 0; hartid < AE350_HART_COUNT; hartid++) {
- plicsw_dev[hartid].source_id = 0;
- plicsw_dev[hartid].plicsw_pending =
- (void *)base
- + PLICSW_PENDING_BASE
- + ((hartid / 4) * 4);
- plicsw_dev[hartid].plicsw_enable =
- (void *)base
- + PLICSW_ENABLE_BASE
- + PLICSW_ENABLE_PER_HART * hartid;
- plicsw_dev[hartid].plicsw_claim =
- (void *)base
- + PLICSW_CONTEXT_BASE
- + PLICSW_CONTEXT_CLAIM
- + PLICSW_CONTEXT_PER_HART * hartid;
- }
-
- return 0;
-}
diff --git a/platform/andes/ae350/plicsw.h b/platform/andes/ae350/plicsw.h
deleted file mode 100644
index 58728f6..0000000
--- a/platform/andes/ae350/plicsw.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 Andes Technology Corporation
- *
- * Authors:
- * Zong Li <zong@andestech.com>
- * Nylon Chen <nylon7@andestech.com>
- */
-
-#ifndef _AE350_PLICSW_H_
-#define _AE350_PLICSW_H_
-
-#define PLICSW_PRIORITY_BASE 0x4
-
-#define PLICSW_PENDING_BASE 0x1000
-#define PLICSW_PENDING_PER_HART 0x8
-
-#define PLICSW_ENABLE_BASE 0x2000
-#define PLICSW_ENABLE_PER_HART 0x80
-
-#define PLICSW_CONTEXT_BASE 0x200000
-#define PLICSW_CONTEXT_PER_HART 0x1000
-#define PLICSW_CONTEXT_CLAIM 0x4
-
-#define PLICSW_HART_MASK 0x80808080
-
-struct plicsw {
- u32 source_id;
-
- volatile uint32_t *plicsw_pending;
- volatile uint32_t *plicsw_enable;
- volatile uint32_t *plicsw_claim;
-};
-
-void plicsw_ipi_send(u32 target_hart);
-
-void plicsw_ipi_clear(u32 target_hart);
-
-int plicsw_warm_ipi_init(void);
-
-int plicsw_cold_ipi_init(unsigned long base, u32 hart_count);
-
-#endif /* _AE350_PLICSW_H_ */
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 09/12] lib: utils/ipi: Add Andes fdt ipi driver support
2022-10-03 11:52 ` [PATCH v2 09/12] lib: utils/ipi: Add Andes fdt ipi driver support Yu Chien Peter Lin
@ 2022-10-11 16:42 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:42 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:24 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> Move Andes PLICSW ipi device to fdt ipi framework, this patch is based
> on Leo's modified IPI scheme on PLICSW.
>
> Current IPI scheme uses bit 0 of pending reigster on PLICSW to send IPI
> from hart 0 to hart 7, but bit 0 needs to be hardwired to 0 according
> to spec. After some investigation, self-IPI seems to be seldom or never
> used, so we re-order the IPI scheme to support 8 core bitmaps.
>
> dts example (ax45mp 4 core):
>
> plicsw: interrupt-controller at e6400000 {
> compatible = "andestech,plicsw";
> reg = <0x00000000 0xe6400000 0x00000000 0x00400000>;
> interrupts-extended = < &CPU0_intc 3
> &CPU1_intc 3
> &CPU2_intc 3
> &CPU3_intc 3>;
> interrupt-controller;
> #address-cells = <2>;
> #interrupt-cells = <2>;
> riscv,ndev = <4>;
The "num_src" and this DT property is not used anywhere so please
drop both things.
Regards,
Anup
> };
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> ---
> include/sbi_utils/fdt/fdt_helper.h | 3 +
> include/sbi_utils/ipi/andes_plicsw.h | 48 +++++++++
> lib/utils/fdt/fdt_helper.c | 59 ++++++++++++
> lib/utils/ipi/Kconfig | 9 ++
> lib/utils/ipi/andes_plicsw.c | 85 ++++++++++++++++
> lib/utils/ipi/fdt_ipi_plicsw.c | 79 +++++++++++++++
> lib/utils/ipi/objects.mk | 4 +
> platform/andes/ae350/Kconfig | 2 +
> platform/andes/ae350/objects.mk | 2 +-
> platform/andes/ae350/platform.c | 27 +-----
> platform/andes/ae350/platform.h | 2 -
> platform/andes/ae350/plicsw.c | 139 ---------------------------
> platform/andes/ae350/plicsw.h | 44 ---------
> 13 files changed, 292 insertions(+), 211 deletions(-)
> create mode 100644 include/sbi_utils/ipi/andes_plicsw.h
> create mode 100644 lib/utils/ipi/andes_plicsw.c
> create mode 100644 lib/utils/ipi/fdt_ipi_plicsw.c
> delete mode 100644 platform/andes/ae350/plicsw.c
> delete mode 100644 platform/andes/ae350/plicsw.h
>
> diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
> index 7ef63c9..7e0083a 100644
> --- a/include/sbi_utils/fdt/fdt_helper.h
> +++ b/include/sbi_utils/fdt/fdt_helper.h
> @@ -98,6 +98,9 @@ int fdt_parse_aclint_node(void *fdt, int nodeoffset, bool for_timer,
> int fdt_parse_plmt_node(void *fdt, int nodeoffset, unsigned long *plmt_base,
> unsigned long *plmt_size, u32 *hart_count);
>
> +int fdt_parse_plicsw_node(void *fdt, int nodeoffset, unsigned long *plicsw_base,
> + unsigned long *size, unsigned long *num_src, u32 *hart_count);
> +
> int fdt_parse_compat_addr(void *fdt, uint64_t *addr,
> const char *compatible);
>
> diff --git a/include/sbi_utils/ipi/andes_plicsw.h b/include/sbi_utils/ipi/andes_plicsw.h
> new file mode 100644
> index 0000000..47f79ad
> --- /dev/null
> +++ b/include/sbi_utils/ipi/andes_plicsw.h
> @@ -0,0 +1,48 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2022 Andes Technology Corporation
> + *
> + * Authors:
> + * Zong Li <zong@andestech.com>
> + * Nylon Chen <nylon7@andestech.com>
> + * Leo Yu-Chi Liang <ycliang@andestech.com>
> + * Yu Chien Peter Lin <peterlin@andestech.com>
> + */
> +
> +#include <sbi/riscv_asm.h>
> +#include <sbi/riscv_io.h>
> +#include <sbi/sbi_types.h>
> +
> +#ifndef _IPI_ANDES_PLICSW_H_
> +#define _IPI_ANDES_PLICSW_H_
> +
> +#define PLICSW_PRIORITY_BASE 0x4
> +
> +#define PLICSW_PENDING_BASE 0x1000
> +#define PLICSW_PENDING_STRIDE 0x8
> +
> +#define PLICSW_ENABLE_BASE 0x2000
> +#define PLICSW_ENABLE_STRIDE 0x80
> +
> +#define PLICSW_CONTEXT_BASE 0x200000
> +#define PLICSW_CONTEXT_STRIDE 0x1000
> +#define PLICSW_CONTEXT_CLAIM 0x4
> +
> +#define PLICSW_HART_MASK 0x01010101
> +
> +#define PLICSW_HART_MAX_NR 8
> +
> +struct plicsw_data {
> + unsigned long addr;
> + unsigned long size;
> + unsigned long num_src;
> + uint32_t hart_count;
> + /* hart id to source id table */
> + uint32_t source_id[PLICSW_HART_MAX_NR];
> +};
> +
> +void plicsw_ipi_send(u32 target_hart);
> +void plicsw_ipi_clear(u32 target_hart);
> +
> +#endif /* _IPI_ANDES_PLICSW_H_ */
> diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
> index ce52fca..bed8b0a 100644
> --- a/lib/utils/fdt/fdt_helper.c
> +++ b/lib/utils/fdt/fdt_helper.c
> @@ -889,6 +889,65 @@ int fdt_parse_plmt_node(void *fdt, int nodeoffset, unsigned long *plmt_base,
> return 0;
> }
>
> +int fdt_parse_plicsw_node(void *fdt, int nodeoffset, unsigned long *plicsw_base,
> + unsigned long *size, unsigned long *num_src, u32 *hart_count)
> +{
> + const fdt32_t *val;
> + int rc, i, count, len;
> + uint64_t reg_addr, reg_size, cpu_offset, cpu_intc_offset;
> + u32 phandle, hwirq, hartid, hcount;
> +
> + if (nodeoffset < 0 || !fdt || !plicsw_base ||
> + !hart_count || !size)
> + return SBI_EINVAL;
> +
> + rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
> + ®_addr, ®_size);
> + if (rc < 0 || !plicsw_base || !size)
> + return SBI_ENODEV;
> + *plicsw_base = reg_addr;
> + *size = reg_size;
> +
> + val = fdt_getprop(fdt, nodeoffset, "riscv,ndev", &len);
> + if (len > 0)
> + *num_src = fdt32_to_cpu(*val);
> +
> + val = fdt_getprop(fdt, nodeoffset, "interrupts-extended", &count);
> + if (!val || count < sizeof(fdt32_t))
> + return 0;
> + count = count / sizeof(fdt32_t);
> +
> + hcount = 0;
> + for (i = 0; i < (count / 2); i++) {
> + phandle = fdt32_to_cpu(val[2 * i]);
> + hwirq = fdt32_to_cpu(val[2 * i + 1]);
> +
> + cpu_intc_offset = fdt_node_offset_by_phandle(fdt, phandle);
> + if (cpu_intc_offset < 0)
> + continue;
> +
> + cpu_offset = fdt_parent_offset(fdt, cpu_intc_offset);
> + if (cpu_intc_offset < 0)
> + continue;
> +
> + rc = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
> +
> + if (rc)
> + continue;
> +
> + if (SBI_HARTMASK_MAX_BITS <= hartid)
> + continue;
> +
> + if (hwirq == IRQ_M_SOFT)
> + hcount++;
> + }
> +
> + *hart_count = hcount;
> +
> + return 0;
> +}
> +
> +
> int fdt_parse_compat_addr(void *fdt, uint64_t *addr,
> const char *compatible)
> {
> diff --git a/lib/utils/ipi/Kconfig b/lib/utils/ipi/Kconfig
> index efc8960..3718852 100644
> --- a/lib/utils/ipi/Kconfig
> +++ b/lib/utils/ipi/Kconfig
> @@ -14,10 +14,19 @@ config FDT_IPI_MSWI
> select IPI_MSWI
> default n
>
> +config FDT_IPI_PLICSW
> + bool "Andes PLICSW FDT driver"
> + select IPI_PLICSW
> + default n
> +
> endif
>
> config IPI_MSWI
> bool "ACLINT MSWI support"
> default n
>
> +config IPI_PLICSW
> + bool "Andes PLICSW support"
> + default n
> +
> endmenu
> diff --git a/lib/utils/ipi/andes_plicsw.c b/lib/utils/ipi/andes_plicsw.c
> new file mode 100644
> index 0000000..f353610
> --- /dev/null
> +++ b/lib/utils/ipi/andes_plicsw.c
> @@ -0,0 +1,85 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2022 Andes Technology Corporation
> + *
> + * Authors:
> + * Zong Li <zong@andestech.com>
> + * Nylon Chen <nylon7@andestech.com>
> + * Leo Yu-Chi Liang <ycliang@andestech.com>
> + * Yu Chien Peter Lin <peterlin@andestech.com>
> + */
> +
> +#include <sbi/sbi_types.h>
> +#include <sbi_utils/ipi/andes_plicsw.h>
> +
> +extern struct plicsw_data plicsw;
> +
> +static inline void plicsw_claim(void)
> +{
> + u32 hartid = current_hartid();
> +
> + if (plicsw.hart_count <= hartid)
> + ebreak();
> +
> + plicsw.source_id[hartid] =
> + readl((void *)plicsw.addr + PLICSW_CONTEXT_BASE +
> + PLICSW_CONTEXT_CLAIM + PLICSW_CONTEXT_STRIDE * hartid);
> +}
> +
> +static inline void plicsw_complete(void)
> +{
> + u32 hartid = current_hartid();
> + u32 source = plicsw.source_id[hartid];
> +
> + writel(source, (void *)plicsw.addr + PLICSW_CONTEXT_BASE +
> + PLICSW_CONTEXT_CLAIM +
> + PLICSW_CONTEXT_STRIDE * hartid);
> +}
> +
> +static inline void plic_sw_pending(u32 target_hart)
> +{
> + /*
> + * The pending array registers are w1s type.
> + * IPI pending array mapping as following:
> + *
> + * Pending array start address: base + 0x1000
> + * ---------------------------------
> + * | hart3 | hart2 | hart1 | hart0 |
> + * ---------------------------------
> + * Each hartX can send IPI to another hart by setting the
> + * bitY to its own region (see the below).
> + *
> + * In each hartX region:
> + * <---------- PICSW_PENDING_STRIDE -------->
> + * | bit7 | ... | bit3 | bit2 | bit1 | bit0 |
> + * ------------------------------------------
> + * The bitY of hartX region indicates that hartX sends an
> + * IPI to hartY.
> + */
> + u32 hartid = current_hartid();
> + u32 word_index = hartid / 4;
> + u32 per_hart_offset = PLICSW_PENDING_STRIDE * hartid;
> + u32 val = 1 << target_hart << per_hart_offset;
> +
> + writel(val, (void *)plicsw.addr + PLICSW_PENDING_BASE + word_index * 4);
> +}
> +
> +void plicsw_ipi_send(u32 target_hart)
> +{
> + if (plicsw.hart_count <= target_hart)
> + ebreak();
> +
> + /* Set PLICSW IPI */
> + plic_sw_pending(target_hart);
> +}
> +
> +void plicsw_ipi_clear(u32 target_hart)
> +{
> + if (plicsw.hart_count <= target_hart)
> + ebreak();
> +
> + /* Clear PLICSW IPI */
> + plicsw_claim();
> + plicsw_complete();
> +}
> diff --git a/lib/utils/ipi/fdt_ipi_plicsw.c b/lib/utils/ipi/fdt_ipi_plicsw.c
> new file mode 100644
> index 0000000..8788f74
> --- /dev/null
> +++ b/lib/utils/ipi/fdt_ipi_plicsw.c
> @@ -0,0 +1,79 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2022 Andes Technology Corporation
> + *
> + * Authors:
> + * Zong Li <zong@andestech.com>
> + * Nylon Chen <nylon7@andestech.com>
> + * Leo Yu-Chi Liang <ycliang@andestech.com>
> + * Yu Chien Peter Lin <peterlin@andestech.com>
> + */
> +
> +#include <sbi/sbi_error.h>
> +#include <sbi/sbi_ipi.h>
> +#include <sbi_utils/fdt/fdt_helper.h>
> +#include <sbi_utils/ipi/fdt_ipi.h>
> +#include <sbi_utils/ipi/andes_plicsw.h>
> +
> +struct plicsw_data plicsw;
> +
> +static struct sbi_ipi_device plicsw_ipi = {
> + .name = "andes_plicsw",
> + .ipi_send = plicsw_ipi_send,
> + .ipi_clear = plicsw_ipi_clear
> +};
> +
> +static int plicsw_warm_ipi_init(void)
> +{
> + u32 hartid = current_hartid();
> +
> + /* Clear PLICSW IPI */
> + plicsw_ipi_clear(hartid);
> +
> + return 0;
> +}
> +
> +static int plicsw_cold_ipi_init(void *fdt, int nodeoff,
> + const struct fdt_match *match)
> +{
> + int rc;
> +
> + rc = fdt_parse_plicsw_node(fdt, nodeoff, &plicsw.addr, &plicsw.size,
> + &plicsw.num_src, &plicsw.hart_count);
> + if (rc)
> + return rc;
> +
> + /* Setup source priority */
> + uint32_t *priority = (void *)plicsw.addr + PLICSW_PRIORITY_BASE;
> +
> + for (int i = 0; i < plicsw.hart_count; i++)
> + writel(1, &priority[i]);
> +
> + /* Setup target enable */
> + uint32_t enable_mask = PLICSW_HART_MASK;
> +
> + for (int i = 0; i < plicsw.hart_count; i++) {
> + uint32_t *enable = (void *)plicsw.addr + PLICSW_ENABLE_BASE +
> + PLICSW_ENABLE_STRIDE * i;
> + writel(enable_mask, enable);
> + writel(enable_mask, enable + 1);
> + enable_mask <<= 1;
> + }
> +
> + sbi_ipi_set_device(&plicsw_ipi);
> +
> + return 0;
> +}
> +
> +static const struct fdt_match ipi_plicsw_match[] = {
> + { .compatible = "andestech,plicsw" },
> + {},
> +};
> +
> +struct fdt_ipi fdt_ipi_plicsw = {
> + .match_table = ipi_plicsw_match,
> + .cold_init = plicsw_cold_ipi_init,
> + .warm_init = plicsw_warm_ipi_init,
> + .exit = NULL,
> +};
> diff --git a/lib/utils/ipi/objects.mk b/lib/utils/ipi/objects.mk
> index 0600cac..999e7bd 100644
> --- a/lib/utils/ipi/objects.mk
> +++ b/lib/utils/ipi/objects.mk
> @@ -8,9 +8,13 @@
> #
>
> libsbiutils-objs-$(CONFIG_IPI_MSWI) += ipi/aclint_mswi.o
> +libsbiutils-objs-$(CONFIG_IPI_PLICSW) += ipi/andes_plicsw.o
>
> libsbiutils-objs-$(CONFIG_FDT_IPI) += ipi/fdt_ipi.o
> libsbiutils-objs-$(CONFIG_FDT_IPI) += ipi/fdt_ipi_drivers.o
>
> carray-fdt_ipi_drivers-$(CONFIG_FDT_IPI_MSWI) += fdt_ipi_mswi
> libsbiutils-objs-$(CONFIG_FDT_IPI_MSWI) += ipi/fdt_ipi_mswi.o
> +
> +carray-fdt_ipi_drivers-$(CONFIG_FDT_IPI_PLICSW) += fdt_ipi_plicsw
> +libsbiutils-objs-$(CONFIG_FDT_IPI_PLICSW) += ipi/fdt_ipi_plicsw.o
> diff --git a/platform/andes/ae350/Kconfig b/platform/andes/ae350/Kconfig
> index 084b27f..38e4001 100644
> --- a/platform/andes/ae350/Kconfig
> +++ b/platform/andes/ae350/Kconfig
> @@ -11,6 +11,8 @@ config PLATFORM_ANDES_AE350
> select FDT_RESET_ATCWDT200
> select FDT_IRQCHIP
> select FDT_IRQCHIP_PLIC
> + select FDT_IPI
> + select FDT_IPI_PLICSW
> default y
>
> if PLATFORM_ANDES_AE350
> diff --git a/platform/andes/ae350/objects.mk b/platform/andes/ae350/objects.mk
> index 1ccb894..a4a2332 100644
> --- a/platform/andes/ae350/objects.mk
> +++ b/platform/andes/ae350/objects.mk
> @@ -15,7 +15,7 @@ platform-asflags-y =
> platform-ldflags-y =
>
> # Objects to build
> -platform-objs-y += cache.o platform.o plicsw.o
> +platform-objs-y += cache.o platform.o
>
> # Blobs to build
> FW_TEXT_START=0x00000000
> diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
> index cf5417c..30e4606 100644
> --- a/platform/andes/ae350/platform.c
> +++ b/platform/andes/ae350/platform.c
> @@ -25,8 +25,8 @@
> #include <sbi_utils/reset/fdt_reset.h>
> #include <sbi_utils/serial/fdt_serial.h>
> #include <sbi_utils/timer/fdt_timer.h>
> +#include <sbi_utils/ipi/fdt_ipi.h>
> #include "platform.h"
> -#include "plicsw.h"
> #include "cache.h"
>
> struct sbi_platform platform;
> @@ -88,29 +88,6 @@ static int ae350_final_init(bool cold_boot)
> return 0;
> }
>
> -static struct sbi_ipi_device plicsw_ipi = {
> - .name = "ae350_plicsw",
> - .ipi_send = plicsw_ipi_send,
> - .ipi_clear = plicsw_ipi_clear
> -};
> -
> -/* Initialize IPI for current HART. */
> -static int ae350_ipi_init(bool cold_boot)
> -{
> - int ret;
> -
> - if (cold_boot) {
> - ret = plicsw_cold_ipi_init(AE350_PLICSW_ADDR,
> - AE350_HART_COUNT);
> - if (ret)
> - return ret;
> -
> - sbi_ipi_set_device(&plicsw_ipi);
> - }
> -
> - return plicsw_warm_ipi_init();
> -}
> -
> /* Vendor-Specific SBI handler */
> static int ae350_vendor_ext_provider(long extid, long funcid,
> const struct sbi_trap_regs *regs, unsigned long *out_value,
> @@ -163,7 +140,7 @@ const struct sbi_platform_operations platform_ops = {
>
> .irqchip_init = fdt_irqchip_init,
>
> - .ipi_init = ae350_ipi_init,
> + .ipi_init = fdt_ipi_init,
>
> .timer_init = fdt_timer_init,
>
> diff --git a/platform/andes/ae350/platform.h b/platform/andes/ae350/platform.h
> index 3003bb4..903bef0 100644
> --- a/platform/andes/ae350/platform.h
> +++ b/platform/andes/ae350/platform.h
> @@ -11,8 +11,6 @@
> #ifndef _AE350_PLATFORM_H_
> #define _AE350_PLATFORM_H_
>
> -#define AE350_PLICSW_ADDR 0xe6400000
> -
> #define AE350_L2C_ADDR 0xe0500000
>
> /*Memory and Miscellaneous Registers*/
> diff --git a/platform/andes/ae350/plicsw.c b/platform/andes/ae350/plicsw.c
> deleted file mode 100644
> index edbbb11..0000000
> --- a/platform/andes/ae350/plicsw.c
> +++ /dev/null
> @@ -1,139 +0,0 @@
> -/*
> - * SPDX-License-Identifier: BSD-2-Clause
> - *
> - * Copyright (c) 2019 Andes Technology Corporation
> - *
> - * Authors:
> - * Zong Li <zong@andestech.com>
> - * Nylon Chen <nylon7@andestech.com>
> - */
> -
> -#include <sbi/riscv_asm.h>
> -#include <sbi/riscv_io.h>
> -#include <sbi/sbi_types.h>
> -#include "plicsw.h"
> -#include "platform.h"
> -
> -static u32 plicsw_ipi_hart_count;
> -static struct plicsw plicsw_dev[AE350_HART_COUNT];
> -
> -static inline void plicsw_claim(void)
> -{
> - u32 source_hart = current_hartid();
> -
> - plicsw_dev[source_hart].source_id =
> - readl(plicsw_dev[source_hart].plicsw_claim);
> -}
> -
> -static inline void plicsw_complete(void)
> -{
> - u32 source_hart = current_hartid();
> - u32 source = plicsw_dev[source_hart].source_id;
> -
> - writel(source, plicsw_dev[source_hart].plicsw_claim);
> -}
> -
> -static inline void plic_sw_pending(u32 target_hart)
> -{
> - /*
> - * The pending array registers are w1s type.
> - * IPI pending array mapping as following:
> - *
> - * Pending array start address: base + 0x1000
> - * -------------------------------------
> - * | hart 3 | hart 2 | hart 1 | hart 0 |
> - * -------------------------------------
> - * Each hart X can send IPI to another hart by setting the
> - * corresponding bit in hart X own region(see the below).
> - *
> - * In each hart region:
> - * -----------------------------------------------
> - * | bit 7 | bit 6 | bit 5 | bit 4 | ... | bit 0 |
> - * -----------------------------------------------
> - * The bit 7 is used to send IPI to hart 0
> - * The bit 6 is used to send IPI to hart 1
> - * The bit 5 is used to send IPI to hart 2
> - * The bit 4 is used to send IPI to hart 3
> - */
> - u32 source_hart = current_hartid();
> - u32 target_offset = (PLICSW_PENDING_PER_HART - 1) - target_hart;
> - u32 per_hart_offset = PLICSW_PENDING_PER_HART * source_hart;
> - u32 val = 1 << target_offset << per_hart_offset;
> -
> - writel(val, plicsw_dev[source_hart].plicsw_pending);
> -}
> -
> -void plicsw_ipi_send(u32 target_hart)
> -{
> - if (plicsw_ipi_hart_count <= target_hart)
> - return;
> -
> - /* Set PLICSW IPI */
> - plic_sw_pending(target_hart);
> -}
> -
> -void plicsw_ipi_clear(u32 target_hart)
> -{
> - if (plicsw_ipi_hart_count <= target_hart)
> - return;
> -
> - /* Clear PLICSW IPI */
> - plicsw_claim();
> - plicsw_complete();
> -}
> -
> -int plicsw_warm_ipi_init(void)
> -{
> - u32 hartid = current_hartid();
> -
> - if (!plicsw_dev[hartid].plicsw_pending
> - && !plicsw_dev[hartid].plicsw_enable
> - && !plicsw_dev[hartid].plicsw_claim)
> - return -1;
> -
> - /* Clear PLICSW IPI */
> - plicsw_ipi_clear(hartid);
> -
> - return 0;
> -}
> -
> -int plicsw_cold_ipi_init(unsigned long base, u32 hart_count)
> -{
> - /* Setup source priority */
> - uint32_t *priority = (void *)base + PLICSW_PRIORITY_BASE;
> -
> - for (int i = 0; i < AE350_HART_COUNT * PLICSW_PENDING_PER_HART; i++)
> - writel(1, &priority[i]);
> -
> - /* Setup target enable */
> - uint32_t enable_mask = PLICSW_HART_MASK;
> -
> - for (int i = 0; i < AE350_HART_COUNT; i++) {
> - uint32_t *enable = (void *)base + PLICSW_ENABLE_BASE
> - + PLICSW_ENABLE_PER_HART * i;
> - writel(enable_mask, &enable[0]);
> - enable_mask >>= 1;
> - }
> -
> - /* Figure-out PLICSW IPI register address */
> - plicsw_ipi_hart_count = hart_count;
> -
> - for (u32 hartid = 0; hartid < AE350_HART_COUNT; hartid++) {
> - plicsw_dev[hartid].source_id = 0;
> - plicsw_dev[hartid].plicsw_pending =
> - (void *)base
> - + PLICSW_PENDING_BASE
> - + ((hartid / 4) * 4);
> - plicsw_dev[hartid].plicsw_enable =
> - (void *)base
> - + PLICSW_ENABLE_BASE
> - + PLICSW_ENABLE_PER_HART * hartid;
> - plicsw_dev[hartid].plicsw_claim =
> - (void *)base
> - + PLICSW_CONTEXT_BASE
> - + PLICSW_CONTEXT_CLAIM
> - + PLICSW_CONTEXT_PER_HART * hartid;
> - }
> -
> - return 0;
> -}
> diff --git a/platform/andes/ae350/plicsw.h b/platform/andes/ae350/plicsw.h
> deleted file mode 100644
> index 58728f6..0000000
> --- a/platform/andes/ae350/plicsw.h
> +++ /dev/null
> @@ -1,44 +0,0 @@
> -/*
> - * SPDX-License-Identifier: BSD-2-Clause
> - *
> - * Copyright (c) 2019 Andes Technology Corporation
> - *
> - * Authors:
> - * Zong Li <zong@andestech.com>
> - * Nylon Chen <nylon7@andestech.com>
> - */
> -
> -#ifndef _AE350_PLICSW_H_
> -#define _AE350_PLICSW_H_
> -
> -#define PLICSW_PRIORITY_BASE 0x4
> -
> -#define PLICSW_PENDING_BASE 0x1000
> -#define PLICSW_PENDING_PER_HART 0x8
> -
> -#define PLICSW_ENABLE_BASE 0x2000
> -#define PLICSW_ENABLE_PER_HART 0x80
> -
> -#define PLICSW_CONTEXT_BASE 0x200000
> -#define PLICSW_CONTEXT_PER_HART 0x1000
> -#define PLICSW_CONTEXT_CLAIM 0x4
> -
> -#define PLICSW_HART_MASK 0x80808080
> -
> -struct plicsw {
> - u32 source_id;
> -
> - volatile uint32_t *plicsw_pending;
> - volatile uint32_t *plicsw_enable;
> - volatile uint32_t *plicsw_claim;
> -};
> -
> -void plicsw_ipi_send(u32 target_hart);
> -
> -void plicsw_ipi_clear(u32 target_hart);
> -
> -int plicsw_warm_ipi_init(void);
> -
> -int plicsw_cold_ipi_init(unsigned long base, u32 hart_count);
> -
> -#endif /* _AE350_PLICSW_H_ */
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 10/12] lib: utils/ipi: Add PLICSW mmio region to root domain
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
` (8 preceding siblings ...)
2022-10-03 11:52 ` [PATCH v2 09/12] lib: utils/ipi: Add Andes fdt ipi driver support Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:57 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 11/12] platform: andes/ae350: Add AE350 domain support Yu Chien Peter Lin
2022-10-03 11:52 ` [PATCH v2 12/12] docs: andes-ae350.md: Update ae350 documentation for fdt driver support Yu Chien Peter Lin
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
Add PLICSW as mmio memregion in root domain at boot-time.
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
lib/utils/ipi/fdt_ipi_plicsw.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/lib/utils/ipi/fdt_ipi_plicsw.c b/lib/utils/ipi/fdt_ipi_plicsw.c
index 8788f74..3af92bd 100644
--- a/lib/utils/ipi/fdt_ipi_plicsw.c
+++ b/lib/utils/ipi/fdt_ipi_plicsw.c
@@ -10,6 +10,7 @@
* Yu Chien Peter Lin <peterlin@andestech.com>
*/
+#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_ipi.h>
#include <sbi_utils/fdt/fdt_helper.h>
@@ -34,6 +35,34 @@ static int plicsw_warm_ipi_init(void)
return 0;
}
+static int andes_plicsw_add_regions(unsigned long addr, unsigned long size)
+{
+#define PLICSW_ADD_REGION_ALIGN 0x1000
+ int rc;
+ unsigned long pos, end, region_size;
+ struct sbi_domain_memregion reg;
+
+ pos = addr;
+ end = addr + size;
+ while (pos < end) {
+ if (pos & (PLICSW_ADD_REGION_ALIGN - 1))
+ region_size = 1UL << sbi_ffs(pos);
+ else
+ region_size = ((end - pos) < PLICSW_ADD_REGION_ALIGN)
+ ? (end - pos)
+ : PLICSW_ADD_REGION_ALIGN;
+
+ sbi_domain_memregion_init(pos, region_size,
+ SBI_DOMAIN_MEMREGION_MMIO, ®);
+ rc = sbi_domain_root_add_memregion(®);
+ if (rc)
+ return rc;
+ pos += region_size;
+ }
+
+ return 0;
+}
+
static int plicsw_cold_ipi_init(void *fdt, int nodeoff,
const struct fdt_match *match)
{
@@ -61,6 +90,11 @@ static int plicsw_cold_ipi_init(void *fdt, int nodeoff,
enable_mask <<= 1;
}
+ /* Add PLICSW region to the root domain */
+ rc = andes_plicsw_add_regions(plicsw.addr, plicsw.size);
+ if (rc)
+ return rc;
+
sbi_ipi_set_device(&plicsw_ipi);
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 10/12] lib: utils/ipi: Add PLICSW mmio region to root domain
2022-10-03 11:52 ` [PATCH v2 10/12] lib: utils/ipi: Add PLICSW mmio region to root domain Yu Chien Peter Lin
@ 2022-10-11 16:57 ` Anup Patel
2022-10-13 9:40 ` Yu-Chien Peter Lin
0 siblings, 1 reply; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:57 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:24 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> Add PLICSW as mmio memregion in root domain at boot-time.
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
> ---
> lib/utils/ipi/fdt_ipi_plicsw.c | 34 ++++++++++++++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
>
> diff --git a/lib/utils/ipi/fdt_ipi_plicsw.c b/lib/utils/ipi/fdt_ipi_plicsw.c
> index 8788f74..3af92bd 100644
> --- a/lib/utils/ipi/fdt_ipi_plicsw.c
> +++ b/lib/utils/ipi/fdt_ipi_plicsw.c
> @@ -10,6 +10,7 @@
> * Yu Chien Peter Lin <peterlin@andestech.com>
> */
>
> +#include <sbi/sbi_domain.h>
> #include <sbi/sbi_error.h>
> #include <sbi/sbi_ipi.h>
> #include <sbi_utils/fdt/fdt_helper.h>
> @@ -34,6 +35,34 @@ static int plicsw_warm_ipi_init(void)
> return 0;
> }
>
> +static int andes_plicsw_add_regions(unsigned long addr, unsigned long size)
> +{
> +#define PLICSW_ADD_REGION_ALIGN 0x1000
> + int rc;
> + unsigned long pos, end, region_size;
> + struct sbi_domain_memregion reg;
> +
> + pos = addr;
> + end = addr + size;
> + while (pos < end) {
> + if (pos & (PLICSW_ADD_REGION_ALIGN - 1))
> + region_size = 1UL << sbi_ffs(pos);
> + else
> + region_size = ((end - pos) < PLICSW_ADD_REGION_ALIGN)
> + ? (end - pos)
> + : PLICSW_ADD_REGION_ALIGN;
> +
> + sbi_domain_memregion_init(pos, region_size,
> + SBI_DOMAIN_MEMREGION_MMIO, ®);
> + rc = sbi_domain_root_add_memregion(®);
> + if (rc)
> + return rc;
> + pos += region_size;
> + }
> +
> + return 0;
> +}
> +
This is exactly same as your PATCH5 and aclint_mtimer_add_regions()
defined in lib/utils/timer/aclint_mtimer.c
I suggest adding a common function in sbi_domain.c and sbi_domain.h
with following function prototype:
int sbi_domain_root_add_memrange(unsigned long addr,
unsigned long size,
unsigned long align,
unsigned
long region_flags);
You can have one patch at the beginning of the series which adds
above function in sbi_domain.c and remove it from aclint_mtimer.c
Your PATCH4 and PATCH9 can directly use this new function
which will allow you to drop your PATCH5 and PATCH10
Regards,
Anup
> static int plicsw_cold_ipi_init(void *fdt, int nodeoff,
> const struct fdt_match *match)
> {
> @@ -61,6 +90,11 @@ static int plicsw_cold_ipi_init(void *fdt, int nodeoff,
> enable_mask <<= 1;
> }
>
> + /* Add PLICSW region to the root domain */
> + rc = andes_plicsw_add_regions(plicsw.addr, plicsw.size);
> + if (rc)
> + return rc;
> +
> sbi_ipi_set_device(&plicsw_ipi);
>
> return 0;
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread* [PATCH v2 10/12] lib: utils/ipi: Add PLICSW mmio region to root domain
2022-10-11 16:57 ` Anup Patel
@ 2022-10-13 9:40 ` Yu-Chien Peter Lin
0 siblings, 0 replies; 25+ messages in thread
From: Yu-Chien Peter Lin @ 2022-10-13 9:40 UTC (permalink / raw)
To: opensbi
On Tue, Oct 11, 2022 at 10:27:23PM +0530, Anup Patel wrote:
> On Mon, Oct 3, 2022 at 5:24 PM Yu Chien Peter Lin
> <peterlin@andestech.com> wrote:
> >
> > Add PLICSW as mmio memregion in root domain at boot-time.
> >
> > Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> > Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
> > ---
> > lib/utils/ipi/fdt_ipi_plicsw.c | 34 ++++++++++++++++++++++++++++++++++
> > 1 file changed, 34 insertions(+)
> >
> > diff --git a/lib/utils/ipi/fdt_ipi_plicsw.c b/lib/utils/ipi/fdt_ipi_plicsw.c
> > index 8788f74..3af92bd 100644
> > --- a/lib/utils/ipi/fdt_ipi_plicsw.c
> > +++ b/lib/utils/ipi/fdt_ipi_plicsw.c
> > @@ -10,6 +10,7 @@
> > * Yu Chien Peter Lin <peterlin@andestech.com>
> > */
> >
> > +#include <sbi/sbi_domain.h>
> > #include <sbi/sbi_error.h>
> > #include <sbi/sbi_ipi.h>
> > #include <sbi_utils/fdt/fdt_helper.h>
> > @@ -34,6 +35,34 @@ static int plicsw_warm_ipi_init(void)
> > return 0;
> > }
> >
> > +static int andes_plicsw_add_regions(unsigned long addr, unsigned long size)
> > +{
> > +#define PLICSW_ADD_REGION_ALIGN 0x1000
> > + int rc;
> > + unsigned long pos, end, region_size;
> > + struct sbi_domain_memregion reg;
> > +
> > + pos = addr;
> > + end = addr + size;
> > + while (pos < end) {
> > + if (pos & (PLICSW_ADD_REGION_ALIGN - 1))
> > + region_size = 1UL << sbi_ffs(pos);
> > + else
> > + region_size = ((end - pos) < PLICSW_ADD_REGION_ALIGN)
> > + ? (end - pos)
> > + : PLICSW_ADD_REGION_ALIGN;
> > +
> > + sbi_domain_memregion_init(pos, region_size,
> > + SBI_DOMAIN_MEMREGION_MMIO, ®);
> > + rc = sbi_domain_root_add_memregion(®);
> > + if (rc)
> > + return rc;
> > + pos += region_size;
> > + }
> > +
> > + return 0;
> > +}
> > +
>
> This is exactly same as your PATCH5 and aclint_mtimer_add_regions()
> defined in lib/utils/timer/aclint_mtimer.c
>
> I suggest adding a common function in sbi_domain.c and sbi_domain.h
> with following function prototype:
> int sbi_domain_root_add_memrange(unsigned long addr,
> unsigned long size,
> unsigned long align,
> unsigned
> long region_flags);
>
> You can have one patch at the beginning of the series which adds
> above function in sbi_domain.c and remove it from aclint_mtimer.c
>
> Your PATCH4 and PATCH9 can directly use this new function
> which will allow you to drop your PATCH5 and PATCH10
>
> Regards,
> Anup
Hi Anup,
Thanks for your suggestion, I'll resend patches with this function
factored out into sbi_domain.c.
Best Regards,
Peter Lin
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 11/12] platform: andes/ae350: Add AE350 domain support
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
` (9 preceding siblings ...)
2022-10-03 11:52 ` [PATCH v2 10/12] lib: utils/ipi: Add PLICSW mmio region to root domain Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:43 ` Anup Patel
2022-10-03 11:52 ` [PATCH v2 12/12] docs: andes-ae350.md: Update ae350 documentation for fdt driver support Yu Chien Peter Lin
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
Add domains_init platform hook for Andes AE350, users can add domain
description in device tree and select FDT domain support in Kconfig
to achieve system-level partitioning.
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
platform/andes/ae350/platform.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
index 30e4606..d36d11e 100644
--- a/platform/andes/ae350/platform.c
+++ b/platform/andes/ae350/platform.c
@@ -19,13 +19,14 @@
#include <sbi/sbi_platform.h>
#include <sbi/sbi_string.h>
#include <sbi/sbi_trap.h>
-#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/fdt/fdt_domain.h>
#include <sbi_utils/fdt/fdt_fixup.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/ipi/fdt_ipi.h>
#include <sbi_utils/irqchip/fdt_irqchip.h>
#include <sbi_utils/reset/fdt_reset.h>
#include <sbi_utils/serial/fdt_serial.h>
#include <sbi_utils/timer/fdt_timer.h>
-#include <sbi_utils/ipi/fdt_ipi.h>
#include "platform.h"
#include "cache.h"
@@ -84,6 +85,7 @@ static int ae350_final_init(bool cold_boot)
fdt = fdt_get_address();
fdt_fixups(fdt);
+ fdt_domain_fixup(fdt);
return 0;
}
@@ -132,10 +134,17 @@ static int ae350_vendor_ext_provider(long extid, long funcid,
return ret;
}
+static int ae350_domains_init(void)
+{
+ return fdt_domains_populate(fdt_get_address());
+}
+
/* Platform descriptor. */
const struct sbi_platform_operations platform_ops = {
.final_init = ae350_final_init,
+ .domains_init = ae350_domains_init,
+
.console_init = fdt_serial_init,
.irqchip_init = fdt_irqchip_init,
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 11/12] platform: andes/ae350: Add AE350 domain support
2022-10-03 11:52 ` [PATCH v2 11/12] platform: andes/ae350: Add AE350 domain support Yu Chien Peter Lin
@ 2022-10-11 16:43 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:43 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:24 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> Add domains_init platform hook for Andes AE350, users can add domain
> description in device tree and select FDT domain support in Kconfig
> to achieve system-level partitioning.
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Looks good to me.
Reviewed-by: Anup Patel <anup@brainfault.org>
Regards,
Anup
> ---
> platform/andes/ae350/platform.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/platform/andes/ae350/platform.c b/platform/andes/ae350/platform.c
> index 30e4606..d36d11e 100644
> --- a/platform/andes/ae350/platform.c
> +++ b/platform/andes/ae350/platform.c
> @@ -19,13 +19,14 @@
> #include <sbi/sbi_platform.h>
> #include <sbi/sbi_string.h>
> #include <sbi/sbi_trap.h>
> -#include <sbi_utils/fdt/fdt_helper.h>
> +#include <sbi_utils/fdt/fdt_domain.h>
> #include <sbi_utils/fdt/fdt_fixup.h>
> +#include <sbi_utils/fdt/fdt_helper.h>
> +#include <sbi_utils/ipi/fdt_ipi.h>
> #include <sbi_utils/irqchip/fdt_irqchip.h>
> #include <sbi_utils/reset/fdt_reset.h>
> #include <sbi_utils/serial/fdt_serial.h>
> #include <sbi_utils/timer/fdt_timer.h>
> -#include <sbi_utils/ipi/fdt_ipi.h>
> #include "platform.h"
> #include "cache.h"
>
> @@ -84,6 +85,7 @@ static int ae350_final_init(bool cold_boot)
>
> fdt = fdt_get_address();
> fdt_fixups(fdt);
> + fdt_domain_fixup(fdt);
>
> return 0;
> }
> @@ -132,10 +134,17 @@ static int ae350_vendor_ext_provider(long extid, long funcid,
> return ret;
> }
>
> +static int ae350_domains_init(void)
> +{
> + return fdt_domains_populate(fdt_get_address());
> +}
> +
> /* Platform descriptor. */
> const struct sbi_platform_operations platform_ops = {
> .final_init = ae350_final_init,
>
> + .domains_init = ae350_domains_init,
> +
> .console_init = fdt_serial_init,
>
> .irqchip_init = fdt_irqchip_init,
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 12/12] docs: andes-ae350.md: Update ae350 documentation for fdt driver support
2022-10-03 11:52 [PATCH v2 00/12] Add Andes AE350 fdt driver support Yu Chien Peter Lin
` (10 preceding siblings ...)
2022-10-03 11:52 ` [PATCH v2 11/12] platform: andes/ae350: Add AE350 domain support Yu Chien Peter Lin
@ 2022-10-03 11:52 ` Yu Chien Peter Lin
2022-10-11 16:45 ` Anup Patel
11 siblings, 1 reply; 25+ messages in thread
From: Yu Chien Peter Lin @ 2022-10-03 11:52 UTC (permalink / raw)
To: opensbi
We update ae350 documentation to add details about platform device tree.
The nodes and their properties must be provided to properly initialize
data of underlying hardware and access their mmio registers.
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
---
docs/platform/andes-ae350.md | 191 ++++++++++++++++++++++++++++++++++-
1 file changed, 187 insertions(+), 4 deletions(-)
diff --git a/docs/platform/andes-ae350.md b/docs/platform/andes-ae350.md
index 1cf83cf..bfbfcf8 100644
--- a/docs/platform/andes-ae350.md
+++ b/docs/platform/andes-ae350.md
@@ -18,13 +18,196 @@ The Andes AE350 platform does not have any platform-specific options.
Building Andes AE350 Platform
-----------------------------
-To use Linux v5.2 should be used to build Andes AE350 OpenSBI binaries by using
-the compile time option FW_FDT_PATH.
-
-AE350's dts is included in https://github.com/andestech/linux/tree/ast-v3_2_0-release-public
+AE350's dts is included in https://github.com/andestech/linux/tree/RISCV-Linux-5.4-ast-v5_1_0-branch
**Linux Kernel Payload**
```
make PLATFORM=andes/ae350 FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image FW_FDT_PATH=<ae350.dtb path>
```
+
+DTS Example: (Quad-core AX45MP)
+-------------------------------
+
+```
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <60000000>;
+
+ CPU0: cpu at 0 {
+ device_type = "cpu";
+ reg = <0>;
+ status = "okay";
+ compatible = "riscv";
+ riscv,isa = "rv64imafdc";
+ riscv,priv-major = <1>;
+ riscv,priv-minor = <10>;
+ mmu-type = "riscv,sv48";
+ clock-frequency = <60000000>;
+ i-cache-size = <0x8000>;
+ i-cache-sets = <256>;
+ i-cache-line-size = <64>;
+ i-cache-block-size = <64>;
+ d-cache-size = <0x8000>;
+ d-cache-sets = <128>;
+ d-cache-line-size = <64>;
+ d-cache-block-size = <64>;
+ next-level-cache = <&L2>;
+ CPU0_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "riscv,cpu-intc";
+ };
+ };
+ CPU1: cpu at 1 {
+ device_type = "cpu";
+ reg = <1>;
+ status = "okay";
+ compatible = "riscv";
+ riscv,isa = "rv64imafdc";
+ riscv,priv-major = <1>;
+ riscv,priv-minor = <10>;
+ mmu-type = "riscv,sv48";
+ clock-frequency = <60000000>;
+ i-cache-size = <0x8000>;
+ i-cache-sets = <256>;
+ i-cache-line-size = <64>;
+ i-cache-block-size = <64>;
+ d-cache-size = <0x8000>;
+ d-cache-sets = <128>;
+ d-cache-line-size = <64>;
+ d-cache-block-size = <64>;
+ next-level-cache = <&L2>;
+ CPU1_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "riscv,cpu-intc";
+ };
+ };
+ CPU2: cpu at 2 {
+ device_type = "cpu";
+ reg = <2>;
+ status = "okay";
+ compatible = "riscv";
+ riscv,isa = "rv64imafdc";
+ riscv,priv-major = <1>;
+ riscv,priv-minor = <10>;
+ mmu-type = "riscv,sv48";
+ clock-frequency = <60000000>;
+ i-cache-size = <0x8000>;
+ i-cache-sets = <256>;
+ i-cache-line-size = <64>;
+ i-cache-block-size = <64>;
+ d-cache-size = <0x8000>;
+ d-cache-sets = <128>;
+ d-cache-line-size = <64>;
+ d-cache-block-size = <64>;
+ next-level-cache = <&L2>;
+ CPU2_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "riscv,cpu-intc";
+ };
+ };
+ CPU3: cpu at 3 {
+ device_type = "cpu";
+ reg = <3>;
+ status = "okay";
+ compatible = "riscv";
+ riscv,isa = "rv64imafdc";
+ riscv,priv-major = <1>;
+ riscv,priv-minor = <10>;
+ mmu-type = "riscv,sv48";
+ clock-frequency = <60000000>;
+ i-cache-size = <0x8000>;
+ i-cache-sets = <256>;
+ i-cache-line-size = <64>;
+ i-cache-block-size = <64>;
+ d-cache-size = <0x8000>;
+ d-cache-sets = <128>;
+ d-cache-line-size = <64>;
+ d-cache-block-size = <64>;
+ next-level-cache = <&L2>;
+ CPU3_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "riscv,cpu-intc";
+ };
+ };
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "andestech,riscv-ae350-soc", "simple-bus";
+ ranges;
+
+ plic0: interrupt-controller at e4000000 {
+ compatible = "riscv,plic0";
+ reg = <0x00000000 0xe4000000 0x00000000 0x02000000>;
+ interrupts-extended = <
+ &CPU0_intc 11 &CPU0_intc 9
+ &CPU1_intc 11 &CPU1_intc 9
+ &CPU2_intc 11 &CPU2_intc 9
+ &CPU3_intc 11 &CPU3_intc 9
+ >;
+ interrupt-controller;
+ #address-cells = <2>;
+ #interrupt-cells = <2>;
+ riscv,ndev = <71>;
+ };
+
+ plicsw: interrupt-controller at e6400000 {
+ compatible = "andestech,plicsw";
+ reg = <0x00000000 0xe6400000 0x00000000 0x00400000>;
+ interrupts-extended = <
+ &CPU0_intc 3
+ &CPU1_intc 3
+ &CPU2_intc 3
+ &CPU3_intc 3
+ >;
+ interrupt-controller;
+ #address-cells = <2>;
+ #interrupt-cells = <2>;
+ riscv,ndev = <4>;
+ };
+
+ plmt0: plmt0 at e6000000 {
+ compatible = "andestech,plmt0";
+ reg = <0x00000000 0xe6000000 0x00000000 0x00100000>;
+ interrupts-extended = <
+ &CPU0_intc 7
+ &CPU1_intc 7
+ &CPU2_intc 7
+ &CPU3_intc 7
+ >;
+ };
+
+ wdt: wdt at f0500000 {
+ compatible = "andestech,atcwdt200";
+ reg = <0x00000000 0xf0500000 0x00000000 0x00001000>;
+ interrupts = <3 4>;
+ interrupt-parent = <&plic0>;
+ clock-frequency = <15000000>;
+ };
+
+ serial0: serial at f0300000 {
+ compatible = "andestech,uart16550", "ns16550a";
+ reg = <0x00000000 0xf0300000 0x00000000 0x00001000>;
+ interrupts = <9 4>;
+ interrupt-parent = <&plic0>;
+ clock-frequency = <19660800>;
+ current-speed = <38400>;
+ reg-shift = <2>;
+ reg-offset = <32>;
+ reg-io-width = <4>;
+ no-loopback-test = <1>;
+ };
+
+ smu: smu at f0100000 {
+ compatible = "andestech,atcsmu";
+ reg = <0x00000000 0xf0100000 0x00000000 0x00001000>;
+ };
+ };
+```
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v2 12/12] docs: andes-ae350.md: Update ae350 documentation for fdt driver support
2022-10-03 11:52 ` [PATCH v2 12/12] docs: andes-ae350.md: Update ae350 documentation for fdt driver support Yu Chien Peter Lin
@ 2022-10-11 16:45 ` Anup Patel
0 siblings, 0 replies; 25+ messages in thread
From: Anup Patel @ 2022-10-11 16:45 UTC (permalink / raw)
To: opensbi
On Mon, Oct 3, 2022 at 5:24 PM Yu Chien Peter Lin
<peterlin@andestech.com> wrote:
>
> We update ae350 documentation to add details about platform device tree.
> The nodes and their properties must be provided to properly initialize
> data of underlying hardware and access their mmio registers.
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> ---
> docs/platform/andes-ae350.md | 191 ++++++++++++++++++++++++++++++++++-
> 1 file changed, 187 insertions(+), 4 deletions(-)
>
> diff --git a/docs/platform/andes-ae350.md b/docs/platform/andes-ae350.md
> index 1cf83cf..bfbfcf8 100644
> --- a/docs/platform/andes-ae350.md
> +++ b/docs/platform/andes-ae350.md
> @@ -18,13 +18,196 @@ The Andes AE350 platform does not have any platform-specific options.
> Building Andes AE350 Platform
> -----------------------------
>
> -To use Linux v5.2 should be used to build Andes AE350 OpenSBI binaries by using
> -the compile time option FW_FDT_PATH.
> -
> -AE350's dts is included in https://github.com/andestech/linux/tree/ast-v3_2_0-release-public
> +AE350's dts is included in https://github.com/andestech/linux/tree/RISCV-Linux-5.4-ast-v5_1_0-branch
>
> **Linux Kernel Payload**
>
> ```
> make PLATFORM=andes/ae350 FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image FW_FDT_PATH=<ae350.dtb path>
> ```
> +
> +DTS Example: (Quad-core AX45MP)
> +-------------------------------
> +
> +```
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + timebase-frequency = <60000000>;
> +
> + CPU0: cpu at 0 {
> + device_type = "cpu";
> + reg = <0>;
> + status = "okay";
> + compatible = "riscv";
> + riscv,isa = "rv64imafdc";
> + riscv,priv-major = <1>;
> + riscv,priv-minor = <10>;
> + mmu-type = "riscv,sv48";
> + clock-frequency = <60000000>;
> + i-cache-size = <0x8000>;
> + i-cache-sets = <256>;
> + i-cache-line-size = <64>;
> + i-cache-block-size = <64>;
> + d-cache-size = <0x8000>;
> + d-cache-sets = <128>;
> + d-cache-line-size = <64>;
> + d-cache-block-size = <64>;
> + next-level-cache = <&L2>;
> + CPU0_intc: interrupt-controller {
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + compatible = "riscv,cpu-intc";
> + };
> + };
> + CPU1: cpu at 1 {
> + device_type = "cpu";
> + reg = <1>;
> + status = "okay";
> + compatible = "riscv";
> + riscv,isa = "rv64imafdc";
> + riscv,priv-major = <1>;
> + riscv,priv-minor = <10>;
> + mmu-type = "riscv,sv48";
> + clock-frequency = <60000000>;
> + i-cache-size = <0x8000>;
> + i-cache-sets = <256>;
> + i-cache-line-size = <64>;
> + i-cache-block-size = <64>;
> + d-cache-size = <0x8000>;
> + d-cache-sets = <128>;
> + d-cache-line-size = <64>;
> + d-cache-block-size = <64>;
> + next-level-cache = <&L2>;
> + CPU1_intc: interrupt-controller {
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + compatible = "riscv,cpu-intc";
> + };
> + };
> + CPU2: cpu at 2 {
> + device_type = "cpu";
> + reg = <2>;
> + status = "okay";
> + compatible = "riscv";
> + riscv,isa = "rv64imafdc";
> + riscv,priv-major = <1>;
> + riscv,priv-minor = <10>;
> + mmu-type = "riscv,sv48";
> + clock-frequency = <60000000>;
> + i-cache-size = <0x8000>;
> + i-cache-sets = <256>;
> + i-cache-line-size = <64>;
> + i-cache-block-size = <64>;
> + d-cache-size = <0x8000>;
> + d-cache-sets = <128>;
> + d-cache-line-size = <64>;
> + d-cache-block-size = <64>;
> + next-level-cache = <&L2>;
> + CPU2_intc: interrupt-controller {
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + compatible = "riscv,cpu-intc";
> + };
> + };
> + CPU3: cpu at 3 {
> + device_type = "cpu";
> + reg = <3>;
> + status = "okay";
> + compatible = "riscv";
> + riscv,isa = "rv64imafdc";
> + riscv,priv-major = <1>;
> + riscv,priv-minor = <10>;
> + mmu-type = "riscv,sv48";
> + clock-frequency = <60000000>;
> + i-cache-size = <0x8000>;
> + i-cache-sets = <256>;
> + i-cache-line-size = <64>;
> + i-cache-block-size = <64>;
> + d-cache-size = <0x8000>;
> + d-cache-sets = <128>;
> + d-cache-line-size = <64>;
> + d-cache-block-size = <64>;
> + next-level-cache = <&L2>;
> + CPU3_intc: interrupt-controller {
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + compatible = "riscv,cpu-intc";
> + };
> + };
> + };
> +
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> + compatible = "andestech,riscv-ae350-soc", "simple-bus";
> + ranges;
> +
> + plic0: interrupt-controller at e4000000 {
> + compatible = "riscv,plic0";
> + reg = <0x00000000 0xe4000000 0x00000000 0x02000000>;
> + interrupts-extended = <
> + &CPU0_intc 11 &CPU0_intc 9
> + &CPU1_intc 11 &CPU1_intc 9
> + &CPU2_intc 11 &CPU2_intc 9
> + &CPU3_intc 11 &CPU3_intc 9
> + >;
> + interrupt-controller;
> + #address-cells = <2>;
> + #interrupt-cells = <2>;
> + riscv,ndev = <71>;
> + };
> +
> + plicsw: interrupt-controller at e6400000 {
> + compatible = "andestech,plicsw";
> + reg = <0x00000000 0xe6400000 0x00000000 0x00400000>;
> + interrupts-extended = <
> + &CPU0_intc 3
> + &CPU1_intc 3
> + &CPU2_intc 3
> + &CPU3_intc 3
> + >;
> + interrupt-controller;
> + #address-cells = <2>;
> + #interrupt-cells = <2>;
> + riscv,ndev = <4>;
plicsw doesn't seem to need the "riscv,ndev" DT property so please
drop it from here.
> + };
> +
> + plmt0: plmt0 at e6000000 {
> + compatible = "andestech,plmt0";
> + reg = <0x00000000 0xe6000000 0x00000000 0x00100000>;
> + interrupts-extended = <
> + &CPU0_intc 7
> + &CPU1_intc 7
> + &CPU2_intc 7
> + &CPU3_intc 7
> + >;
> + };
> +
> + wdt: wdt at f0500000 {
> + compatible = "andestech,atcwdt200";
> + reg = <0x00000000 0xf0500000 0x00000000 0x00001000>;
> + interrupts = <3 4>;
> + interrupt-parent = <&plic0>;
> + clock-frequency = <15000000>;
> + };
> +
> + serial0: serial at f0300000 {
> + compatible = "andestech,uart16550", "ns16550a";
> + reg = <0x00000000 0xf0300000 0x00000000 0x00001000>;
> + interrupts = <9 4>;
> + interrupt-parent = <&plic0>;
> + clock-frequency = <19660800>;
> + current-speed = <38400>;
> + reg-shift = <2>;
> + reg-offset = <32>;
> + reg-io-width = <4>;
> + no-loopback-test = <1>;
> + };
> +
> + smu: smu at f0100000 {
> + compatible = "andestech,atcsmu";
> + reg = <0x00000000 0xf0100000 0x00000000 0x00001000>;
> + };
> + };
> +```
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
Apart from a minor comment above, it looks good to me.
Reviewed-by: Anup Patel <anup@brainfault.org>
Regards,
Anup
^ permalink raw reply [flat|nested] 25+ messages in thread