diff mbox series

[08/10] riscv: Add Kendryte K210 device tree

Message ID 20200212103432.660256-9-damien.lemoal@wdc.com (mailing list archive)
State New, archived
Headers show
Series Kendryte k210 SoC boards support | expand

Commit Message

Damien Le Moal Feb. 12, 2020, 10:34 a.m. UTC
Add a generic device tree for Kendryte K210 SoC based boards. This (for
now) very simple device tree works for the Kendryte KD233 development
board, the Sipeed MAIX M1 Dock based boards and the Sipeed MAIXDUINO
board.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 arch/riscv/boot/dts/Makefile           |   1 +
 arch/riscv/boot/dts/kendryte/Makefile  |   2 +
 arch/riscv/boot/dts/kendryte/k210.dts  |  23 +++++
 arch/riscv/boot/dts/kendryte/k210.dtsi | 123 +++++++++++++++++++++++++
 4 files changed, 149 insertions(+)
 create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
 create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
 create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi

Comments

Sean Anderson Feb. 14, 2020, 8:51 p.m. UTC | #1
On 2/12/20 5:34 AM, Damien Le Moal wrote:
> Add a generic device tree for Kendryte K210 SoC based boards. This (for
> now) very simple device tree works for the Kendryte KD233 development
> board, the Sipeed MAIX M1 Dock based boards and the Sipeed MAIXDUINO
> board.
> 
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> ---
>  arch/riscv/boot/dts/Makefile           |   1 +
>  arch/riscv/boot/dts/kendryte/Makefile  |   2 +
>  arch/riscv/boot/dts/kendryte/k210.dts  |  23 +++++
>  arch/riscv/boot/dts/kendryte/k210.dtsi | 123 +++++++++++++++++++++++++
>  4 files changed, 149 insertions(+)
>  create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
> 
> diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
> index 0bf2669aa12d..87815557f2db 100644
> --- a/arch/riscv/boot/dts/Makefile
> +++ b/arch/riscv/boot/dts/Makefile
> @@ -3,4 +3,5 @@ ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
>  obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
>  else
>  subdir-y += sifive
> +subdir-y += kendryte
>  endif
> diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile
> new file mode 100644
> index 000000000000..815444e69e89
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb
> diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts
> new file mode 100644
> index 000000000000..0d1f28fce6b2
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/k210.dts
> @@ -0,0 +1,23 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +
> +/dts-v1/;
> +
> +#include "k210.dtsi"
> +
> +/ {
> +	model = "Kendryte K210 generic";
> +	compatible = "kendryte,k210";
> +
> +	chosen {
> +		bootargs = "earlycon console=ttySIF0";
> +		stdout-path = "serial0";
> +	};
> +};
> +
> +&uarths0 {
> +	status = "okay";
> +};
> +
> diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi
> new file mode 100644
> index 000000000000..4b9eeabb07f7
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/k210.dtsi
> @@ -0,0 +1,123 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>

Glad to see this is getting some use :)

This appears to be an old-ish version, and I've made some updates in the
past month or so. My current work is availible from [1].

[1] https://github.com/Forty-Bot/u-boot/blob/maix_v6/arch/riscv/dts/k210.dtsi

> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +
> +/ {
> +	/*
> +	 * Although the K210 is a 64-bit CPU, the address bus is only 32-bits
> +	 * wide, and the upper half of all addresses is ignored.
> +	 */
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	compatible = "kendryte,k210";
> +
> +	aliases {
> +		serial0 = &uarths0;
> +	};
> +
> +	clocks {
> +		in0: oscillator {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <26000000>;
> +		};
> +	};
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		timebase-frequency = <7800000>;

This is true only for the default frequency. I wonder if there is a
better way to encode this.

> +		cpu0: cpu@0 {
> +			device_type = "cpu";
> +			reg = <0>;
> +			compatible = "riscv";
> +			riscv,isa = "rv64imafdc";
> +			mmu-type = "none";

This should be "sv36".

> +			i-cache-size = <0x8000>;
> +			i-cache-block-size = <64>; /* bogus */

I emailed some people at Kendryte and they confirmed the 64-byte
cacheline. The cpus are rocket cores.

> +			d-cache-size = <0x8000>;
> +			d-cache-block-size = <64>; /* bogus */
> +			clocks = <&sysctl 0>;

This is correct only by coincidence. The clock structure is

in0 -> pll0 -> aclk -> cpu

aclk divides by two by default, so it runs at 390 MHz, which is also
what you set pll1 to. However, if someone else (such as the bootloader)
changes the pll0 frequency then this will be completely off.

> +			clock-frequency = <390000000>;
> +			cpu0_intc: interrupt-controller {
> +				#interrupt-cells = <1>;
> +				interrupt-controller;
> +				compatible = "riscv,cpu-intc";
> +			};
> +		};
> +		cpu1: cpu@1 {
> +			device_type = "cpu";
> +			reg = <1>;
> +			compatible = "riscv";
> +			riscv,isa = "rv64imafdc";
> +			mmu-type = "none";
> +			i-cache-size = <0x8000>;
> +			i-cache-block-size = <64>; /* bogus */
> +			d-cache-size = <0x8000>;
> +			d-cache-block-size = <64>; /* bogus */
> +			clocks = <&sysctl 0>;
> +			clock-frequency = <390000000>;
> +			cpu1_intc: interrupt-controller {
> +				#interrupt-cells = <1>;
> +				interrupt-controller;
> +				compatible = "riscv,cpu-intc";
> +			};
> +		};
> +	};
> +
> +	sram0: memory@80000000 {
> +		device_type = "memory";
> +		reg = <0x80000000 0x400000>;
> +	};
> +
> +	sram1: memory@80400000 {
> +		device_type = "memory";
> +		reg = <0x80400000 0x200000>;
> +	};
> +
> +	kpu_sram: memory@80600000 {
> +		device_type = "memory";
> +		reg = <0x80600000 0x200000>;
> +	};
> +
> +	soc {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "kendryte,k210-soc", "simple-bus";

Should the -soc suffix be here? I saw it was absent from the fu540
device tree.

> +		ranges;
> +		interrupt-parent = <&plic0>;
> +
> +		sysctl: sysctl@50440000 {
> +			compatible = "kendryte,k210-sysctl", "syscon";
> +			reg = <0x50440000 0x1000>;
> +			#clock-cells = <1>;
> +		};

Would it be possible to model this as an MFD? There are a lot of
different registers in here, many of which are unrelated to clocks. For
example, there are also reset registers, a reboot register, and DMA
handshake controls. I think modeling this as a clock controller only
does not correctly reflect the hardware, and will be awkward in the
future.

> +
> +		clint0: interrupt-controller@2000000 {
> +			compatible = "riscv,clint0";
> +			reg = <0x2000000 0xC000>;
> +			interrupts-extended = <&cpu0_intc 3>,  <&cpu1_intc 3>;
> +			clocks = <&sysctl 0>;

Again, this is wrong; it should be running off ACLK.

> +		};
> +
> +		plic0: interrupt-controller@c000000 {
> +			#interrupt-cells = <1>;
> +			interrupt-controller;
> +			compatible = "kendryte,k210-plic0", "riscv,plic0";
> +			reg = <0xC000000 0x3FFF008>;

With regard to the size of registers, I had the following exchange on
the U-Boot mailing list.

On Tue, Feb 4, 2020 at 10:23 PM Sean Anderson <seanga2@gmail.com> wrote:
>
> On 2/4/20 6:32 AM, Bin Meng wrote:
>> Hi Sean,
>>
>> On Mon, Feb 3, 2020 at 4:10 AM Sean Anderson <seanga2@gmail.com> wrote:
>>> Should the size of a reg be the size of the documented registers, or the size
>>> of the address space which will be routed to that device?
>>
>> Perhaps we need use the size of the address space routed to that
>> device, in case there is some undocumented registers we need handle.
>
> Ok, I'll go with the whole address space then.

You may want to make similar changes for Linux; I didn't see any
documentation about what the preferred size was.

> +			interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
> +					      <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
> +			riscv,ndev = <65>;
> +			riscv,max-priority = <0x07>;
> +		};
> +
> +		uarths0: serial@38000000 {
> +			compatible = "kendryte,k210-uart0", "sifive,uart0";

I would change the first compatible string to "kendryte,k210-uarths",
since that is how this uart is described in their documentation.

> +			reg = <0x38000000 0x20>;

Same thing as the size comments above.

> +			interrupts = <33>;
> +			clocks = <&sysctl 0>;

Same clock comments.

> +		};
> +	};
> +};
> 

--Sean
Damien Le Moal Feb. 15, 2020, 2:34 a.m. UTC | #2
On 2020/02/15 5:51, Sean Anderson wrote:
> On 2/12/20 5:34 AM, Damien Le Moal wrote:
>> Add a generic device tree for Kendryte K210 SoC based boards. This (for
>> now) very simple device tree works for the Kendryte KD233 development
>> board, the Sipeed MAIX M1 Dock based boards and the Sipeed MAIXDUINO
>> board.
>>
>> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
>> ---
>>  arch/riscv/boot/dts/Makefile           |   1 +
>>  arch/riscv/boot/dts/kendryte/Makefile  |   2 +
>>  arch/riscv/boot/dts/kendryte/k210.dts  |  23 +++++
>>  arch/riscv/boot/dts/kendryte/k210.dtsi | 123 +++++++++++++++++++++++++
>>  4 files changed, 149 insertions(+)
>>  create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
>>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
>>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
>>
>> diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
>> index 0bf2669aa12d..87815557f2db 100644
>> --- a/arch/riscv/boot/dts/Makefile
>> +++ b/arch/riscv/boot/dts/Makefile
>> @@ -3,4 +3,5 @@ ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
>>  obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
>>  else
>>  subdir-y += sifive
>> +subdir-y += kendryte
>>  endif
>> diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile
>> new file mode 100644
>> index 000000000000..815444e69e89
>> --- /dev/null
>> +++ b/arch/riscv/boot/dts/kendryte/Makefile
>> @@ -0,0 +1,2 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb
>> diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts
>> new file mode 100644
>> index 000000000000..0d1f28fce6b2
>> --- /dev/null
>> +++ b/arch/riscv/boot/dts/kendryte/k210.dts
>> @@ -0,0 +1,23 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "k210.dtsi"
>> +
>> +/ {
>> +	model = "Kendryte K210 generic";
>> +	compatible = "kendryte,k210";
>> +
>> +	chosen {
>> +		bootargs = "earlycon console=ttySIF0";
>> +		stdout-path = "serial0";
>> +	};
>> +};
>> +
>> +&uarths0 {
>> +	status = "okay";
>> +};
>> +
>> diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi
>> new file mode 100644
>> index 000000000000..4b9eeabb07f7
>> --- /dev/null
>> +++ b/arch/riscv/boot/dts/kendryte/k210.dtsi
>> @@ -0,0 +1,123 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
> 
> Glad to see this is getting some use :)

Seeing what you did for uboot, I used a lot of it and naturally gave credit
where it is due :)

> This appears to be an old-ish version, and I've made some updates in the
> past month or so. My current work is availible from [1].
> 
> [1] https://github.com/Forty-Bot/u-boot/blob/maix_v6/arch/riscv/dts/k210.dtsi

OK. Will check again.

>> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
>> + */
>> +
>> +/ {
>> +	/*
>> +	 * Although the K210 is a 64-bit CPU, the address bus is only 32-bits
>> +	 * wide, and the upper half of all addresses is ignored.
>> +	 */
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>> +	compatible = "kendryte,k210";
>> +
>> +	aliases {
>> +		serial0 = &uarths0;
>> +	};
>> +
>> +	clocks {
>> +		in0: oscillator {
>> +			compatible = "fixed-clock";
>> +			#clock-cells = <0>;
>> +			clock-frequency = <26000000>;
>> +		};
>> +	};
>> +
>> +	cpus {
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +		timebase-frequency = <7800000>;
> 
> This is true only for the default frequency. I wonder if there is a
> better way to encode this.

Yes, I suspected that. Seeing that the CPU frequency can be changed, I
wondered how this should all go together. But since the current code does
not change the cpu frequency, I simply stayed with the default here. I
suspect that we may want the default hard-coded in the code, and use the
value specified here as the one that should be setup by sysctl.

>> +		cpu0: cpu@0 {
>> +			device_type = "cpu";
>> +			reg = <0>;
>> +			compatible = "riscv";
>> +			riscv,isa = "rv64imafdc";
>> +			mmu-type = "none";
> 
> This should be "sv36".

If we want to run the MMU, yes. For a nommu kernel, I would rather stick
with "none". Not that it really matters since the nommu kernel will not
look at this entry anyway. No strong opinion either way in the end.
I have not checked the specs yet, but does sv36 necessarily implies older
specs 1.9 too ? If not, then we may want something else in there for this
soc special case.

>> +			i-cache-size = <0x8000>;
>> +			i-cache-block-size = <64>; /* bogus */
> 
> I emailed some people at Kendryte and they confirmed the 64-byte
> cacheline. The cpus are rocket cores.

Good to know. I will remove the comment then.

> 
>> +			d-cache-size = <0x8000>;
>> +			d-cache-block-size = <64>; /* bogus */
>> +			clocks = <&sysctl 0>;
> 
> This is correct only by coincidence. The clock structure is
> 
> in0 -> pll0 -> aclk -> cpu
> 
> aclk divides by two by default, so it runs at 390 MHz, which is also
> what you set pll1 to. However, if someone else (such as the bootloader)
> changes the pll0 frequency then this will be completely off.

Yes... The clock management needs more work as mentioned in the cover
letter. All of this works for now with direct m-mode boot (no boot loader)
and relies on the hardware defaults which are coded here. The sysctl driver
also relies on those defaults. A more solid implementation will need the
soc_early_init() code to discover and set things up correctly.

As mentioned in the cover letter, this is all a base. It works, but
definitely is not complete.

>> +			clock-frequency = <390000000>;
>> +			cpu0_intc: interrupt-controller {
>> +				#interrupt-cells = <1>;
>> +				interrupt-controller;
>> +				compatible = "riscv,cpu-intc";
>> +			};
>> +		};
>> +		cpu1: cpu@1 {
>> +			device_type = "cpu";
>> +			reg = <1>;
>> +			compatible = "riscv";
>> +			riscv,isa = "rv64imafdc";
>> +			mmu-type = "none";
>> +			i-cache-size = <0x8000>;
>> +			i-cache-block-size = <64>; /* bogus */
>> +			d-cache-size = <0x8000>;
>> +			d-cache-block-size = <64>; /* bogus */
>> +			clocks = <&sysctl 0>;
>> +			clock-frequency = <390000000>;
>> +			cpu1_intc: interrupt-controller {
>> +				#interrupt-cells = <1>;
>> +				interrupt-controller;
>> +				compatible = "riscv,cpu-intc";
>> +			};
>> +		};
>> +	};
>> +
>> +	sram0: memory@80000000 {
>> +		device_type = "memory";
>> +		reg = <0x80000000 0x400000>;
>> +	};
>> +
>> +	sram1: memory@80400000 {
>> +		device_type = "memory";
>> +		reg = <0x80400000 0x200000>;
>> +	};
>> +
>> +	kpu_sram: memory@80600000 {
>> +		device_type = "memory";
>> +		reg = <0x80600000 0x200000>;
>> +	};
>> +
>> +	soc {
>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
>> +		compatible = "kendryte,k210-soc", "simple-bus";
> 
> Should the -soc suffix be here? I saw it was absent from the fu540
> device tree.

Yes, I guess it can be removed.

>> +		ranges;
>> +		interrupt-parent = <&plic0>;
>> +
>> +		sysctl: sysctl@50440000 {
>> +			compatible = "kendryte,k210-sysctl", "syscon";
>> +			reg = <0x50440000 0x1000>;
>> +			#clock-cells = <1>;
>> +		};
> 
> Would it be possible to model this as an MFD? There are a lot of
> different registers in here, many of which are unrelated to clocks. For
> example, there are also reset registers, a reboot register, and DMA
> handshake controls. I think modeling this as a clock controller only
> does not correctly reflect the hardware, and will be awkward in the
> future.

Absolutely. It is far from complete. And seeing your complete device tree,
there are likely a lot of peripherals for which Linux already has drivers
and that could be used if the clocks/sysctl are improved. As mentioned in
the cover letter, this is left as an exercise for interested people :)
Note that I am indeed interested in working on this a little more. I simply
lack the time to do it :)

>> +
>> +		clint0: interrupt-controller@2000000 {
>> +			compatible = "riscv,clint0";
>> +			reg = <0x2000000 0xC000>;
>> +			interrupts-extended = <&cpu0_intc 3>,  <&cpu1_intc 3>;
>> +			clocks = <&sysctl 0>;
> 
> Again, this is wrong; it should be running off ACLK.

Yep. As you said, it works because we use the defaults for everything.

>> +		};
>> +
>> +		plic0: interrupt-controller@c000000 {
>> +			#interrupt-cells = <1>;
>> +			interrupt-controller;
>> +			compatible = "kendryte,k210-plic0", "riscv,plic0";
>> +			reg = <0xC000000 0x3FFF008>;
> 
> With regard to the size of registers, I had the following exchange on
> the U-Boot mailing list.
> 
> On Tue, Feb 4, 2020 at 10:23 PM Sean Anderson <seanga2@gmail.com> wrote:
>>
>> On 2/4/20 6:32 AM, Bin Meng wrote:
>>> Hi Sean,
>>>
>>> On Mon, Feb 3, 2020 at 4:10 AM Sean Anderson <seanga2@gmail.com> wrote:
>>>> Should the size of a reg be the size of the documented registers, or the size
>>>> of the address space which will be routed to that device?
>>>
>>> Perhaps we need use the size of the address space routed to that
>>> device, in case there is some undocumented registers we need handle.
>>
>> Ok, I'll go with the whole address space then.
> 
> You may want to make similar changes for Linux; I didn't see any
> documentation about what the preferred size was.

I wondered about it too. Not really sure what to do about it.

>> +			interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
>> +					      <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
>> +			riscv,ndev = <65>;
>> +			riscv,max-priority = <0x07>;
>> +		};
>> +
>> +		uarths0: serial@38000000 {
>> +			compatible = "kendryte,k210-uart0", "sifive,uart0";
> 
> I would change the first compatible string to "kendryte,k210-uarths",
> since that is how this uart is described in their documentation.

OK. It makes sense.

> 
>> +			reg = <0x38000000 0x20>;
> 
> Same thing as the size comments above.
> 
>> +			interrupts = <33>;
>> +			clocks = <&sysctl 0>;
> 
> Same clock comments.
> 
>> +		};
>> +	};
>> +};
>>
> 
> --Sean
>
Sean Anderson Feb. 15, 2020, 2:48 a.m. UTC | #3
On 2/14/20 9:34 PM, Damien Le Moal wrote:
> On 2020/02/15 5:51, Sean Anderson wrote:
>> On 2/12/20 5:34 AM, Damien Le Moal wrote:
>>> Add a generic device tree for Kendryte K210 SoC based boards. This (for
>>> now) very simple device tree works for the Kendryte KD233 development
>>> board, the Sipeed MAIX M1 Dock based boards and the Sipeed MAIXDUINO
>>> board.
>>>
>>> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
>>> ---
>>>  arch/riscv/boot/dts/Makefile           |   1 +
>>>  arch/riscv/boot/dts/kendryte/Makefile  |   2 +
>>>  arch/riscv/boot/dts/kendryte/k210.dts  |  23 +++++
>>>  arch/riscv/boot/dts/kendryte/k210.dtsi | 123 +++++++++++++++++++++++++
>>>  4 files changed, 149 insertions(+)
>>>  create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
>>>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
>>>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
>>>
>>> diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
>>> index 0bf2669aa12d..87815557f2db 100644
>>> --- a/arch/riscv/boot/dts/Makefile
>>> +++ b/arch/riscv/boot/dts/Makefile
>>> @@ -3,4 +3,5 @@ ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
>>>  obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
>>>  else
>>>  subdir-y += sifive
>>> +subdir-y += kendryte
>>>  endif
>>> diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile
>>> new file mode 100644
>>> index 000000000000..815444e69e89
>>> --- /dev/null
>>> +++ b/arch/riscv/boot/dts/kendryte/Makefile
>>> @@ -0,0 +1,2 @@
>>> +# SPDX-License-Identifier: GPL-2.0
>>> +dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb
>>> diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts
>>> new file mode 100644
>>> index 000000000000..0d1f28fce6b2
>>> --- /dev/null
>>> +++ b/arch/riscv/boot/dts/kendryte/k210.dts
>>> @@ -0,0 +1,23 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
>>> + */
>>> +
>>> +/dts-v1/;
>>> +
>>> +#include "k210.dtsi"
>>> +
>>> +/ {
>>> +	model = "Kendryte K210 generic";
>>> +	compatible = "kendryte,k210";
>>> +
>>> +	chosen {
>>> +		bootargs = "earlycon console=ttySIF0";
>>> +		stdout-path = "serial0";
>>> +	};
>>> +};
>>> +
>>> +&uarths0 {
>>> +	status = "okay";
>>> +};
>>> +
>>> diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi
>>> new file mode 100644
>>> index 000000000000..4b9eeabb07f7
>>> --- /dev/null
>>> +++ b/arch/riscv/boot/dts/kendryte/k210.dtsi
>>> @@ -0,0 +1,123 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
>>
>> Glad to see this is getting some use :)
> 
> Seeing what you did for uboot, I used a lot of it and naturally gave credit
> where it is due :)
> 
>> This appears to be an old-ish version, and I've made some updates in the
>> past month or so. My current work is availible from [1].
>>
>> [1] https://github.com/Forty-Bot/u-boot/blob/maix_v6/arch/riscv/dts/k210.dtsi
> 
> OK. Will check again.
> 
>>> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
>>> + */
>>> +
>>> +/ {
>>> +	/*
>>> +	 * Although the K210 is a 64-bit CPU, the address bus is only 32-bits
>>> +	 * wide, and the upper half of all addresses is ignored.
>>> +	 */
>>> +	#address-cells = <1>;
>>> +	#size-cells = <1>;
>>> +	compatible = "kendryte,k210";
>>> +
>>> +	aliases {
>>> +		serial0 = &uarths0;
>>> +	};
>>> +
>>> +	clocks {
>>> +		in0: oscillator {
>>> +			compatible = "fixed-clock";
>>> +			#clock-cells = <0>;
>>> +			clock-frequency = <26000000>;
>>> +		};
>>> +	};
>>> +
>>> +	cpus {
>>> +		#address-cells = <1>;
>>> +		#size-cells = <0>;
>>> +		timebase-frequency = <7800000>;
>>
>> This is true only for the default frequency. I wonder if there is a
>> better way to encode this.
> 
> Yes, I suspected that. Seeing that the CPU frequency can be changed, I
> wondered how this should all go together. But since the current code does
> not change the cpu frequency, I simply stayed with the default here. I
> suspect that we may want the default hard-coded in the code, and use the
> value specified here as the one that should be setup by sysctl.
> 
>>> +		cpu0: cpu@0 {
>>> +			device_type = "cpu";
>>> +			reg = <0>;
>>> +			compatible = "riscv";
>>> +			riscv,isa = "rv64imafdc";
>>> +			mmu-type = "none";
>>
>> This should be "sv36".
> 
> If we want to run the MMU, yes. For a nommu kernel, I would rather stick
> with "none". Not that it really matters since the nommu kernel will not
> look at this entry anyway. No strong opinion either way in the end.
> I have not checked the specs yet, but does sv36 necessarily implies older
> specs 1.9 too ? If not, then we may want something else in there for this
> soc special case.

Ah, this should be "sv39", sorry. Ideally we would put something like
the priv spec version in the isa string, or perhaps as a separate
property. From reading the dt docs, it seems like one should try to
describe the hardware as best as possible to allow for
foward-compatibility.

>>> +			i-cache-size = <0x8000>;
>>> +			i-cache-block-size = <64>; /* bogus */
>>
>> I emailed some people at Kendryte and they confirmed the 64-byte
>> cacheline. The cpus are rocket cores.
> 
> Good to know. I will remove the comment then.
> 
>>
>>> +			d-cache-size = <0x8000>;
>>> +			d-cache-block-size = <64>; /* bogus */
>>> +			clocks = <&sysctl 0>;
>>
>> This is correct only by coincidence. The clock structure is
>>
>> in0 -> pll0 -> aclk -> cpu
>>
>> aclk divides by two by default, so it runs at 390 MHz, which is also
>> what you set pll1 to. However, if someone else (such as the bootloader)
>> changes the pll0 frequency then this will be completely off.
> 
> Yes... The clock management needs more work as mentioned in the cover
> letter. All of this works for now with direct m-mode boot (no boot loader)
> and relies on the hardware defaults which are coded here. The sysctl driver
> also relies on those defaults. A more solid implementation will need the
> soc_early_init() code to discover and set things up correctly.
> 
> As mentioned in the cover letter, this is all a base. It works, but
> definitely is not complete.

At the very least, I would different identifiers for each clock. That
way you can ignore them now and add support later. There isn't a
"natural" ordering (since the clocks are in a different order in every
register), so I am using this arbitrary numbering scheme [1].

[1] https://github.com/Forty-Bot/u-boot/blob/maix_v6/include/dt-bindings/clock/k210-sysctl.h

>>> +			clock-frequency = <390000000>;
>>> +			cpu0_intc: interrupt-controller {
>>> +				#interrupt-cells = <1>;
>>> +				interrupt-controller;
>>> +				compatible = "riscv,cpu-intc";
>>> +			};
>>> +		};
>>> +		cpu1: cpu@1 {
>>> +			device_type = "cpu";
>>> +			reg = <1>;
>>> +			compatible = "riscv";
>>> +			riscv,isa = "rv64imafdc";
>>> +			mmu-type = "none";
>>> +			i-cache-size = <0x8000>;
>>> +			i-cache-block-size = <64>; /* bogus */
>>> +			d-cache-size = <0x8000>;
>>> +			d-cache-block-size = <64>; /* bogus */
>>> +			clocks = <&sysctl 0>;
>>> +			clock-frequency = <390000000>;
>>> +			cpu1_intc: interrupt-controller {
>>> +				#interrupt-cells = <1>;
>>> +				interrupt-controller;
>>> +				compatible = "riscv,cpu-intc";
>>> +			};
>>> +		};
>>> +	};
>>> +
>>> +	sram0: memory@80000000 {
>>> +		device_type = "memory";
>>> +		reg = <0x80000000 0x400000>;
>>> +	};
>>> +
>>> +	sram1: memory@80400000 {
>>> +		device_type = "memory";
>>> +		reg = <0x80400000 0x200000>;
>>> +	};
>>> +
>>> +	kpu_sram: memory@80600000 {
>>> +		device_type = "memory";
>>> +		reg = <0x80600000 0x200000>;
>>> +	};
>>> +
>>> +	soc {
>>> +		#address-cells = <1>;
>>> +		#size-cells = <1>;
>>> +		compatible = "kendryte,k210-soc", "simple-bus";
>>
>> Should the -soc suffix be here? I saw it was absent from the fu540
>> device tree.
> 
> Yes, I guess it can be removed.
> 
>>> +		ranges;
>>> +		interrupt-parent = <&plic0>;
>>> +
>>> +		sysctl: sysctl@50440000 {
>>> +			compatible = "kendryte,k210-sysctl", "syscon";
>>> +			reg = <0x50440000 0x1000>;
>>> +			#clock-cells = <1>;
>>> +		};
>>
>> Would it be possible to model this as an MFD? There are a lot of
>> different registers in here, many of which are unrelated to clocks. For
>> example, there are also reset registers, a reboot register, and DMA
>> handshake controls. I think modeling this as a clock controller only
>> does not correctly reflect the hardware, and will be awkward in the
>> future.
> 
> Absolutely. It is far from complete. And seeing your complete device tree,
> there are likely a lot of peripherals for which Linux already has drivers
> and that could be used if the clocks/sysctl are improved. As mentioned in
> the cover letter, this is left as an exercise for interested people :)
> Note that I am indeed interested in working on this a little more. I simply
> lack the time to do it :)

My next project after u-boot support was going to be Linux, so I can
lend a hand after I get everything merged on that end.

>>> +
>>> +		clint0: interrupt-controller@2000000 {
>>> +			compatible = "riscv,clint0";
>>> +			reg = <0x2000000 0xC000>;
>>> +			interrupts-extended = <&cpu0_intc 3>,  <&cpu1_intc 3>;
>>> +			clocks = <&sysctl 0>;
>>
>> Again, this is wrong; it should be running off ACLK.
> 
> Yep. As you said, it works because we use the defaults for everything.
> 
>>> +		};
>>> +
>>> +		plic0: interrupt-controller@c000000 {
>>> +			#interrupt-cells = <1>;
>>> +			interrupt-controller;
>>> +			compatible = "kendryte,k210-plic0", "riscv,plic0";
>>> +			reg = <0xC000000 0x3FFF008>;
>>
>> With regard to the size of registers, I had the following exchange on
>> the U-Boot mailing list.
>>
>> On Tue, Feb 4, 2020 at 10:23 PM Sean Anderson <seanga2@gmail.com> wrote:
>>>
>>> On 2/4/20 6:32 AM, Bin Meng wrote:
>>>> Hi Sean,
>>>>
>>>> On Mon, Feb 3, 2020 at 4:10 AM Sean Anderson <seanga2@gmail.com> wrote:
>>>>> Should the size of a reg be the size of the documented registers, or the size
>>>>> of the address space which will be routed to that device?
>>>>
>>>> Perhaps we need use the size of the address space routed to that
>>>> device, in case there is some undocumented registers we need handle.
>>>
>>> Ok, I'll go with the whole address space then.
>>
>> You may want to make similar changes for Linux; I didn't see any
>> documentation about what the preferred size was.
> 
> I wondered about it too. Not really sure what to do about it.

The sizes in my device tree are based on reading device memory and
seeing where it repeats. For example, the memory at 50210000 and
50210100 is the same, so I set the uart1 reg to <50210000 0x100>.

>>> +			interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
>>> +					      <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
>>> +			riscv,ndev = <65>;
>>> +			riscv,max-priority = <0x07>;
>>> +		};
>>> +
>>> +		uarths0: serial@38000000 {
>>> +			compatible = "kendryte,k210-uart0", "sifive,uart0";
>>
>> I would change the first compatible string to "kendryte,k210-uarths",
>> since that is how this uart is described in their documentation.
> 
> OK. It makes sense.
> 
>>
>>> +			reg = <0x38000000 0x20>;
>>
>> Same thing as the size comments above.
>>
>>> +			interrupts = <33>;
>>> +			clocks = <&sysctl 0>;
>>
>> Same clock comments.
>>
>>> +		};
>>> +	};
>>> +};
>>>
>>
>> --Sean
>>
> 
>
Damien Le Moal Feb. 15, 2020, 3 a.m. UTC | #4
On 2020/02/15 11:48, Sean Anderson wrote:
>>>> +		cpu0: cpu@0 {
>>>> +			device_type = "cpu";
>>>> +			reg = <0>;
>>>> +			compatible = "riscv";
>>>> +			riscv,isa = "rv64imafdc";
>>>> +			mmu-type = "none";
>>>
>>> This should be "sv36".
>>
>> If we want to run the MMU, yes. For a nommu kernel, I would rather stick
>> with "none". Not that it really matters since the nommu kernel will not
>> look at this entry anyway. No strong opinion either way in the end.
>> I have not checked the specs yet, but does sv36 necessarily implies older
>> specs 1.9 too ? If not, then we may want something else in there for this
>> soc special case.
> 
> Ah, this should be "sv39", sorry. Ideally we would put something like
> the priv spec version in the isa string, or perhaps as a separate
> property. From reading the dt docs, it seems like one should try to
> describe the hardware as best as possible to allow for
> foward-compatibility.

OK. But I guess we can keep the "none" here until we get to work on the MMU
support. That definitely sounds safer to me considering the specs difference.

>>>> +			d-cache-size = <0x8000>;
>>>> +			d-cache-block-size = <64>; /* bogus */
>>>> +			clocks = <&sysctl 0>;
>>>
>>> This is correct only by coincidence. The clock structure is
>>>
>>> in0 -> pll0 -> aclk -> cpu
>>>
>>> aclk divides by two by default, so it runs at 390 MHz, which is also
>>> what you set pll1 to. However, if someone else (such as the bootloader)
>>> changes the pll0 frequency then this will be completely off.
>>
>> Yes... The clock management needs more work as mentioned in the cover
>> letter. All of this works for now with direct m-mode boot (no boot loader)
>> and relies on the hardware defaults which are coded here. The sysctl driver
>> also relies on those defaults. A more solid implementation will need the
>> soc_early_init() code to discover and set things up correctly.
>>
>> As mentioned in the cover letter, this is all a base. It works, but
>> definitely is not complete.
> 
> At the very least, I would different identifiers for each clock. That
> way you can ignore them now and add support later. There isn't a
> "natural" ordering (since the clocks are in a different order in every
> register), so I am using this arbitrary numbering scheme [1].
> 
> [1] https://github.com/Forty-Bot/u-boot/blob/maix_v6/include/dt-bindings/clock/k210-sysctl.h

Good idea. I had a look at this when I used your device tree but decided on
not using it for simplicity since using the default HW setup led to that
single clock 0. But this is a good point. I will use the identifiers and
for now have all the IDs used defined to "0". As the sysctl driver is
changed and improved, the DT can remain the same and more devices added easily.

>>>> +		ranges;
>>>> +		interrupt-parent = <&plic0>;
>>>> +
>>>> +		sysctl: sysctl@50440000 {
>>>> +			compatible = "kendryte,k210-sysctl", "syscon";
>>>> +			reg = <0x50440000 0x1000>;
>>>> +			#clock-cells = <1>;
>>>> +		};
>>>
>>> Would it be possible to model this as an MFD? There are a lot of
>>> different registers in here, many of which are unrelated to clocks. For
>>> example, there are also reset registers, a reboot register, and DMA
>>> handshake controls. I think modeling this as a clock controller only
>>> does not correctly reflect the hardware, and will be awkward in the
>>> future.
>>
>> Absolutely. It is far from complete. And seeing your complete device tree,
>> there are likely a lot of peripherals for which Linux already has drivers
>> and that could be used if the clocks/sysctl are improved. As mentioned in
>> the cover letter, this is left as an exercise for interested people :)
>> Note that I am indeed interested in working on this a little more. I simply
>> lack the time to do it :)
> 
> My next project after u-boot support was going to be Linux, so I can
> lend a hand after I get everything merged on that end.

That would be great !

>>>> +		plic0: interrupt-controller@c000000 {
>>>> +			#interrupt-cells = <1>;
>>>> +			interrupt-controller;
>>>> +			compatible = "kendryte,k210-plic0", "riscv,plic0";
>>>> +			reg = <0xC000000 0x3FFF008>;
>>>
>>> With regard to the size of registers, I had the following exchange on
>>> the U-Boot mailing list.
>>>
>>> On Tue, Feb 4, 2020 at 10:23 PM Sean Anderson <seanga2@gmail.com> wrote:
>>>>
>>>> On 2/4/20 6:32 AM, Bin Meng wrote:
>>>>> Hi Sean,
>>>>>
>>>>> On Mon, Feb 3, 2020 at 4:10 AM Sean Anderson <seanga2@gmail.com> wrote:
>>>>>> Should the size of a reg be the size of the documented registers, or the size
>>>>>> of the address space which will be routed to that device?
>>>>>
>>>>> Perhaps we need use the size of the address space routed to that
>>>>> device, in case there is some undocumented registers we need handle.
>>>>
>>>> Ok, I'll go with the whole address space then.
>>>
>>> You may want to make similar changes for Linux; I didn't see any
>>> documentation about what the preferred size was.
>>
>> I wondered about it too. Not really sure what to do about it.
> 
> The sizes in my device tree are based on reading device memory and
> seeing where it repeats. For example, the memory at 50210000 and
> 50210100 is the same, so I set the uart1 reg to <50210000 0x100>.

OK. Will make changes and retest.

> 
>>>> +			interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
>>>> +					      <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
>>>> +			riscv,ndev = <65>;
>>>> +			riscv,max-priority = <0x07>;
>>>> +		};
>>>> +
>>>> +		uarths0: serial@38000000 {
>>>> +			compatible = "kendryte,k210-uart0", "sifive,uart0";
>>>
>>> I would change the first compatible string to "kendryte,k210-uarths",
>>> since that is how this uart is described in their documentation.
>>
>> OK. It makes sense.
>>
>>>
>>>> +			reg = <0x38000000 0x20>;
>>>
>>> Same thing as the size comments above.
>>>
>>>> +			interrupts = <33>;
>>>> +			clocks = <&sysctl 0>;
>>>
>>> Same clock comments.
>>>
>>>> +		};
>>>> +	};
>>>> +};
>>>>
>>>
>>> --Sean
>>>
>>
>>
> 
>
Carlos de Paula Feb. 18, 2020, 2:12 p.m. UTC | #5
On Sat, Feb 15, 2020 at 12:00 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>
> On 2020/02/15 11:48, Sean Anderson wrote:
> >>>> +          cpu0: cpu@0 {
> >>>> +                  device_type = "cpu";
> >>>> +                  reg = <0>;
> >>>> +                  compatible = "riscv";
> >>>> +                  riscv,isa = "rv64imafdc";
> >>>> +                  mmu-type = "none";
> >>>
> >>> This should be "sv36".
> >>
> >> If we want to run the MMU, yes. For a nommu kernel, I would rather stick
> >> with "none". Not that it really matters since the nommu kernel will not
> >> look at this entry anyway. No strong opinion either way in the end.
> >> I have not checked the specs yet, but does sv36 necessarily implies older
> >> specs 1.9 too ? If not, then we may want something else in there for this
> >> soc special case.
> >
> > Ah, this should be "sv39", sorry. Ideally we would put something like
> > the priv spec version in the isa string, or perhaps as a separate
> > property. From reading the dt docs, it seems like one should try to
> > describe the hardware as best as possible to allow for
> > foward-compatibility.
>
> OK. But I guess we can keep the "none" here until we get to work on the MMU
> support. That definitely sounds safer to me considering the specs difference.
>
> >>>> +                  d-cache-size = <0x8000>;
> >>>> +                  d-cache-block-size = <64>; /* bogus */
> >>>> +                  clocks = <&sysctl 0>;
> >>>
> >>> This is correct only by coincidence. The clock structure is
> >>>
> >>> in0 -> pll0 -> aclk -> cpu
> >>>
> >>> aclk divides by two by default, so it runs at 390 MHz, which is also
> >>> what you set pll1 to. However, if someone else (such as the bootloader)
> >>> changes the pll0 frequency then this will be completely off.
> >>
> >> Yes... The clock management needs more work as mentioned in the cover
> >> letter. All of this works for now with direct m-mode boot (no boot loader)
> >> and relies on the hardware defaults which are coded here. The sysctl driver
> >> also relies on those defaults. A more solid implementation will need the
> >> soc_early_init() code to discover and set things up correctly.
> >>
> >> As mentioned in the cover letter, this is all a base. It works, but
> >> definitely is not complete.
> >
> > At the very least, I would different identifiers for each clock. That
> > way you can ignore them now and add support later. There isn't a
> > "natural" ordering (since the clocks are in a different order in every
> > register), so I am using this arbitrary numbering scheme [1].
> >
> > [1] https://github.com/Forty-Bot/u-boot/blob/maix_v6/include/dt-bindings/clock/k210-sysctl.h
>
> Good idea. I had a look at this when I used your device tree but decided on
> not using it for simplicity since using the default HW setup led to that
> single clock 0. But this is a good point. I will use the identifiers and
> for now have all the IDs used defined to "0". As the sysctl driver is
> changed and improved, the DT can remain the same and more devices added easily.
>
> >>>> +          ranges;
> >>>> +          interrupt-parent = <&plic0>;
> >>>> +
> >>>> +          sysctl: sysctl@50440000 {
> >>>> +                  compatible = "kendryte,k210-sysctl", "syscon";
> >>>> +                  reg = <0x50440000 0x1000>;
> >>>> +                  #clock-cells = <1>;
> >>>> +          };
> >>>
> >>> Would it be possible to model this as an MFD? There are a lot of
> >>> different registers in here, many of which are unrelated to clocks. For
> >>> example, there are also reset registers, a reboot register, and DMA
> >>> handshake controls. I think modeling this as a clock controller only
> >>> does not correctly reflect the hardware, and will be awkward in the
> >>> future.
> >>
> >> Absolutely. It is far from complete. And seeing your complete device tree,
> >> there are likely a lot of peripherals for which Linux already has drivers
> >> and that could be used if the clocks/sysctl are improved. As mentioned in
> >> the cover letter, this is left as an exercise for interested people :)
> >> Note that I am indeed interested in working on this a little more. I simply
> >> lack the time to do it :)
> >
> > My next project after u-boot support was going to be Linux, so I can
> > lend a hand after I get everything merged on that end.
>
> That would be great !
>
> >>>> +          plic0: interrupt-controller@c000000 {
> >>>> +                  #interrupt-cells = <1>;
> >>>> +                  interrupt-controller;
> >>>> +                  compatible = "kendryte,k210-plic0", "riscv,plic0";
> >>>> +                  reg = <0xC000000 0x3FFF008>;
> >>>
> >>> With regard to the size of registers, I had the following exchange on
> >>> the U-Boot mailing list.
> >>>
> >>> On Tue, Feb 4, 2020 at 10:23 PM Sean Anderson <seanga2@gmail.com> wrote:
> >>>>
> >>>> On 2/4/20 6:32 AM, Bin Meng wrote:
> >>>>> Hi Sean,
> >>>>>
> >>>>> On Mon, Feb 3, 2020 at 4:10 AM Sean Anderson <seanga2@gmail.com> wrote:
> >>>>>> Should the size of a reg be the size of the documented registers, or the size
> >>>>>> of the address space which will be routed to that device?
> >>>>>
> >>>>> Perhaps we need use the size of the address space routed to that
> >>>>> device, in case there is some undocumented registers we need handle.
> >>>>
> >>>> Ok, I'll go with the whole address space then.
> >>>
> >>> You may want to make similar changes for Linux; I didn't see any
> >>> documentation about what the preferred size was.
> >>
> >> I wondered about it too. Not really sure what to do about it.
> >
> > The sizes in my device tree are based on reading device memory and
> > seeing where it repeats. For example, the memory at 50210000 and
> > 50210100 is the same, so I set the uart1 reg to <50210000 0x100>.
>
> OK. Will make changes and retest.
>
> >
> >>>> +                  interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
> >>>> +                                        <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
> >>>> +                  riscv,ndev = <65>;
> >>>> +                  riscv,max-priority = <0x07>;
> >>>> +          };
> >>>> +
> >>>> +          uarths0: serial@38000000 {
> >>>> +                  compatible = "kendryte,k210-uart0", "sifive,uart0";
> >>>
> >>> I would change the first compatible string to "kendryte,k210-uarths",
> >>> since that is how this uart is described in their documentation.
> >>
> >> OK. It makes sense.
> >>
> >>>
> >>>> +                  reg = <0x38000000 0x20>;
> >>>
> >>> Same thing as the size comments above.
> >>>
> >>>> +                  interrupts = <33>;
> >>>> +                  clocks = <&sysctl 0>;
> >>>
> >>> Same clock comments.
> >>>
> >>>> +          };
> >>>> +  };
> >>>> +};
> >>>>
> >>>
> >>> --Sean
> >>>
> >>
> >>
> >
> >
>
>
> --
> Damien Le Moal
> Western Digital Research
>

Maybe it's a known thing but I found an MMU implementation here:
https://gist.github.com/44670/0d8c152df7c5b59d17d469aba4dda0e5

Comes from as fork of the sdk here https://github.com/44670/libk9
implementing also the LCD and other peripheral support.

Might help out adding support to it.
Sean Anderson Feb. 18, 2020, 2:18 p.m. UTC | #6
On 2/18/20 9:12 AM, Carlos Eduardo de Paula wrote:
> Maybe it's a known thing but I found an MMU implementation here:
> https://gist.github.com/44670/0d8c152df7c5b59d17d469aba4dda0e5

Yeah, that's part of the evidence which convinced me to research the vm
capabilities of the k210 after I saw Christoph's series was NOMMU.

> Comes from as fork of the sdk here https://github.com/44670/libk9
> implementing also the LCD and other peripheral support.
> 
> Might help out adding support to it.

Hmm, maybe. I've been wrangling a bit trying to get the SD card slot to
work.

--Sean
Carlos de Paula Feb. 18, 2020, 2:30 p.m. UTC | #7
On Tue, Feb 18, 2020 at 11:18 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> On 2/18/20 9:12 AM, Carlos Eduardo de Paula wrote:
> > Maybe it's a known thing but I found an MMU implementation here:
> > https://gist.github.com/44670/0d8c152df7c5b59d17d469aba4dda0e5
>
> Yeah, that's part of the evidence which convinced me to research the vm
> capabilities of the k210 after I saw Christoph's series was NOMMU.
>
> > Comes from as fork of the sdk here https://github.com/44670/libk9
> > implementing also the LCD and other peripheral support.
> >
> > Might help out adding support to it.
>
> Hmm, maybe. I've been wrangling a bit trying to get the SD card slot to
> work.
>
> --Sean

Yes, I started looking at the SD card but had no clue on what needs to
be done regarding GPIO - FPIO - SPI pre-reqs for it.

Wladimir (don't know his email) started playing with UART1 interface
to the 8285 module to allow WiFi communication. We thought about
having a TUN/TAP interface over it to bring the TCP/IP stack up.
https://twitter.com/orionwl/status/1229442145628585990

Carlos
Sean Anderson Feb. 18, 2020, 5:48 p.m. UTC | #8
On 2/18/20 9:30 AM, Carlos Eduardo de Paula wrote:
> On Tue, Feb 18, 2020 at 11:18 AM Sean Anderson <seanga2@gmail.com> wrote:
>>
>> On 2/18/20 9:12 AM, Carlos Eduardo de Paula wrote:
>>> Maybe it's a known thing but I found an MMU implementation here:
>>> https://gist.github.com/44670/0d8c152df7c5b59d17d469aba4dda0e5
>>
>> Yeah, that's part of the evidence which convinced me to research the vm
>> capabilities of the k210 after I saw Christoph's series was NOMMU.
>>
>>> Comes from as fork of the sdk here https://github.com/44670/libk9
>>> implementing also the LCD and other peripheral support.

So the LCD connector is supposed to be for a ST7789V controller, but
there doesn't appear to be a driver in Linux for it. I don't have an
appropriate LCD screen, so I will not be able to write a driver.

>>>
>>> Might help out adding support to it.
>>
>> Hmm, maybe. I've been wrangling a bit trying to get the SD card slot to
>> work.
>>
>> --Sean
> 
> Yes, I started looking at the SD card but had no clue on what needs to
> be done regarding GPIO - FPIO - SPI pre-reqs for it.

There is no need for GPIOs. The datasheet shows SPI0 as hooked up to the
SD card, but the default pinconf doesn't have it hooked up. In addition,
the dedicated SPI0 data lines are already connected to the LCD. For
these reasons, I decided to hook up SPI1 to the card slot. I have some
preliminary patches to add FPIOA support to u-boot. If you are
interested in my current progress, it is availible from [1]. This is not
a "stable" branch though, and I frequently rebase/force-push to it.

[1] https://github.com/Forty-Bot/u-boot/tree/maix_v6

> Wladimir (don't know his email) started playing with UART1 interface
> to the 8285 module to allow WiFi communication. We thought about
> having a TUN/TAP interface over it to bring the TCP/IP stack up.
> https://twitter.com/orionwl/status/1229442145628585990

Nice. I don't think too many raw register pokes should be needed,
because you are just using a uart to communicate...

--Sean
Carlos de Paula Feb. 18, 2020, 7:26 p.m. UTC | #9
On Tue, Feb 18, 2020 at 2:48 PM Sean Anderson <seanga2@gmail.com> wrote:
>
> So the LCD connector is supposed to be for a ST7789V controller, but
> there doesn't appear to be a driver in Linux for it. I don't have an
> appropriate LCD screen, so I will not be able to write a driver.
>

Actually there is a driver and config DRM_PANEL_SITRONIX_ST7789V, in
gpu/drm/panel/panel-sitronix-st7789v.c and also FB_TFT_ST7789V and
CONFIG_FB_TFT_ST7789V with the driver a in
staging/fbtft/fb_st7789v.c. Might be easier :)

Weird that the Kendryte SDK refers to the LCD as NT35310
(https://github.com/kendryte/kendryte-standalone-demo/tree/develop/lcd).

> >>>
> >>> Might help out adding support to it.
> >>
> >> Hmm, maybe. I've been wrangling a bit trying to get the SD card slot to
> >> work.
> >>
> >> --Sean
> >
> > Yes, I started looking at the SD card but had no clue on what needs to
> > be done regarding GPIO - FPIO - SPI pre-reqs for it.
>
> There is no need for GPIOs. The datasheet shows SPI0 as hooked up to the
> SD card, but the default pinconf doesn't have it hooked up. In addition,
> the dedicated SPI0 data lines are already connected to the LCD. For
> these reasons, I decided to hook up SPI1 to the card slot. I have some
> preliminary patches to add FPIOA support to u-boot. If you are
> interested in my current progress, it is availible from [1]. This is not
> a "stable" branch though, and I frequently rebase/force-push to it.
>
> [1] https://github.com/Forty-Bot/u-boot/tree/maix_v6
>

Nice, gonna take a look at it.

> > Wladimir (don't know his email) started playing with UART1 interface
> > to the 8285 module to allow WiFi communication. We thought about
> > having a TUN/TAP interface over it to bring the TCP/IP stack up.
> > https://twitter.com/orionwl/status/1229442145628585990
>
> Nice. I don't think too many raw register pokes should be needed,
> because you are just using a uart to communicate...
>
> --Sean
>
Wladimir J. van der Laan Feb. 19, 2020, 8:50 a.m. UTC | #10
> > Wladimir (don't know his email) started playing with UART1 interface
> > to the 8285 module to allow WiFi communication. We thought about
> > having a TUN/TAP interface over it to bring the TCP/IP stack up.
> > https://twitter.com/orionwl/status/1229442145628585990
> 
> Nice. I don't think too many raw register pokes should be needed,
> because you are just using a uart to communicate...

The reason I needed any raw register pokes at all is because I don't have a sysctl / fpioa driver, and didn't
feel like writing one at this time, so just write the appropriate values to the registers to map the UART1 to the
correct pins and enable WIFI_EN. After setting up those, Linux's driver works as-is for the UART!

Wladimir
Wladimir J. van der Laan Feb. 19, 2020, 9:06 a.m. UTC | #11
On Tue, Feb 18, 2020 at 04:26:17PM -0300, Carlos Eduardo de Paula wrote:
> On Tue, Feb 18, 2020 at 2:48 PM Sean Anderson <seanga2@gmail.com> wrote:
> >
> > So the LCD connector is supposed to be for a ST7789V controller, but
> > there doesn't appear to be a driver in Linux for it. I don't have an
> > appropriate LCD screen, so I will not be able to write a driver.
> >
> 
> Actually there is a driver and config DRM_PANEL_SITRONIX_ST7789V, in
> gpu/drm/panel/panel-sitronix-st7789v.c and also FB_TFT_ST7789V and
> CONFIG_FB_TFT_ST7789V with the driver a in
> staging/fbtft/fb_st7789v.c. Might be easier :)
> 
> Weird that the Kendryte SDK refers to the LCD as NT35310
> (https://github.com/kendryte/kendryte-standalone-demo/tree/develop/lcd).

I remember checking the datasheet for both a while ago and NT35310 and ST7789V
seem to be more or less compatible, with only register differences
for more obscure functionality.

The more involved part is likely to adapt the spi-dw driver, apart from making the
ctrlr0 shifts configurable, there's the "OCTAL" mode that is used and extra
register that isn't set in the Linux driver (spi_ctrlr0 / 0xf4) concerning
"instruction address translation mode" and other things that needs to
be set correctly for LCD transfers to work.

> > There is no need for GPIOs. The datasheet shows SPI0 as hooked up to the
> > SD card, but the default pinconf doesn't have it hooked up. In addition,
> > the dedicated SPI0 data lines are already connected to the LCD. For

Yes - apparently only if you set sysctl spi_dvp_data_enable to route the
SPI0_0-7 pins to to the LCD data pins (bypassing FPIOA).

BTW speaking of which, does anyone know what's up with the K210's DMA
controller? It looks like it can only transfer 32-bit values from and to
peripherals? At least the kendryte-standalone-sdk goes to great lengths to
first allocate a 32-bit buffer then manually copy it to say, bytes or 16-bit
words. Seems quite a silly workaround with a lot of overhead.

Wladimir
Sean Anderson Feb. 19, 2020, 10:28 p.m. UTC | #12
On 2/19/20 4:06 AM, Wladimir J. van der Laan wrote:
> On Tue, Feb 18, 2020 at 04:26:17PM -0300, Carlos Eduardo de Paula wrote:
>> On Tue, Feb 18, 2020 at 2:48 PM Sean Anderson <seanga2@gmail.com> wrote:
>>>
>>> So the LCD connector is supposed to be for a ST7789V controller, but
>>> there doesn't appear to be a driver in Linux for it. I don't have an
>>> appropriate LCD screen, so I will not be able to write a driver.
>>>
>>
>> Actually there is a driver and config DRM_PANEL_SITRONIX_ST7789V, in
>> gpu/drm/panel/panel-sitronix-st7789v.c and also FB_TFT_ST7789V and
>> CONFIG_FB_TFT_ST7789V with the driver a in
>> staging/fbtft/fb_st7789v.c. Might be easier :)

Ah, I didn't notice that, thanks.

>>
>> Weird that the Kendryte SDK refers to the LCD as NT35310
>> (https://github.com/kendryte/kendryte-standalone-demo/tree/develop/lcd).
> 
> I remember checking the datasheet for both a while ago and NT35310 and ST7789V
> seem to be more or less compatible, with only register differences
> for more obscure functionality.
> 
> The more involved part is likely to adapt the spi-dw driver, apart from making the
> ctrlr0 shifts configurable, there's the "OCTAL" mode that is used and extra
> register that isn't set in the Linux driver (spi_ctrlr0 / 0xf4) concerning
> "instruction address translation mode" and other things that needs to
> be set correctly for LCD transfers to work.
> 
>>> There is no need for GPIOs. The datasheet shows SPI0 as hooked up to the
>>> SD card, but the default pinconf doesn't have it hooked up. In addition,
>>> the dedicated SPI0 data lines are already connected to the LCD. For
> 
> Yes - apparently only if you set sysctl spi_dvp_data_enable to route the
> SPI0_0-7 pins to to the LCD data pins (bypassing FPIOA).
> 
> BTW speaking of which, does anyone know what's up with the K210's DMA
> controller? It looks like it can only transfer 32-bit values from and to
> peripherals? At least the kendryte-standalone-sdk goes to great lengths to
> first allocate a 32-bit buffer then manually copy it to say, bytes or 16-bit
> words. Seems quite a silly workaround with a lot of overhead.

Do you have a link to that section?

--Sean
Wladimir J. van der Laan Feb. 20, 2020, 10:48 a.m. UTC | #13
> > BTW speaking of which, does anyone know what's up with the K210's DMA
> > controller? It looks like it can only transfer 32-bit values from and to
> > peripherals? At least the kendryte-standalone-sdk goes to great lengths to
> > first allocate a 32-bit buffer then manually copy it to say, bytes or 16-bit
> > words. Seems quite a silly workaround with a lot of overhead.
> 
> Do you have a link to that section?

It's not really one section but all over the place in all clients of the DMA.

See for example the SPI here:
https://github.com/kendryte/kendryte-standalone-sdk/blob/develop/lib/drivers/spi.c#L372

Or serial (this one tripped me up):
https://github.com/kendryte/kendryte-standalone-sdk/blob/develop/lib/drivers/uart.c#L265
https://github.com/kendryte/kendryte-standalone-sdk/blob/develop/lib/drivers/uart.c#L163

One can fairly reliably find them by looking for 'malloc' in the drivers.

A few months back I did some experiments with different values for transfer
sizes and such and wasn't able to get the DMA controller to do this, myself.

The "FIX_CACHE" define is new, BTW. They don't DMA directly from/to cached
memory anymore but use an intermediate copy in uncached special I/O memory in
the 4xxxxxxx range. I haven't had problems with e.g. manually DMAing to the screen
through SPI myself but there might be a coherency edge case (their commit messages
are not exactly enlightening).

Kind regards,
Wladimir
Wladimir J. van der Laan Feb. 22, 2020, 7:07 p.m. UTC | #14
> > > So the LCD connector is supposed to be for a ST7789V controller, but
> > > there doesn't appear to be a driver in Linux for it. I don't have an
> > > appropriate LCD screen, so I will not be able to write a driver.
> > >
> > 
> > Actually there is a driver and config DRM_PANEL_SITRONIX_ST7789V, in
> > gpu/drm/panel/panel-sitronix-st7789v.c and also FB_TFT_ST7789V and
> > CONFIG_FB_TFT_ST7789V with the driver a in
> > staging/fbtft/fb_st7789v.c. Might be easier :)
> > 
> > Weird that the Kendryte SDK refers to the LCD as NT35310
> > (https://github.com/kendryte/kendryte-standalone-demo/tree/develop/lcd).
> 
> I remember checking the datasheet for both a while ago and NT35310 and ST7789V
> seem to be more or less compatible, with only register differences
> for more obscure functionality.

I just stumbled on this:
https://forum.kendryte.com/topic/68/a-guide-to-adapt-kendryte-kd233-kpu-demo-to-sipeed-m1
under "LCD Driver".

So it looks like the K233 uses a nt35310, while Sipeed M1 uses st7789. This is
a likely explanation for them mentioning both chips in the SDKs.

Kind regards,
Wladimir
Sean Anderson Feb. 27, 2020, 7:43 p.m. UTC | #15
On 2/14/20 9:34 PM, Damien Le Moal wrote:
> On 2020/02/15 5:51, Sean Anderson wrote:
>> On 2/12/20 5:34 AM, Damien Le Moal wrote:
>>> +	soc {
>>> +		#address-cells = <1>;
>>> +		#size-cells = <1>;
>>> +		compatible = "kendryte,k210-soc", "simple-bus";
>>
>> Should the -soc suffix be here? I saw it was absent from the fu540
>> device tree.
> 
> Yes, I guess it can be removed.

Actually, I think it is removed from the fu540 bits beccause sifive has
different names for the cores (rocket, U54, etc.) and the SoC (FU540).
Since for this chip there is no separate name, we should probably keep
the SoC suffix.

--Sean
Anup Patel March 2, 2020, 4:06 a.m. UTC | #16
On Wed, Feb 12, 2020 at 4:05 PM Damien Le Moal <damien.lemoal@wdc.com> wrote:
>
> Add a generic device tree for Kendryte K210 SoC based boards. This (for
> now) very simple device tree works for the Kendryte KD233 development
> board, the Sipeed MAIX M1 Dock based boards and the Sipeed MAIXDUINO
> board.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> ---
>  arch/riscv/boot/dts/Makefile           |   1 +
>  arch/riscv/boot/dts/kendryte/Makefile  |   2 +
>  arch/riscv/boot/dts/kendryte/k210.dts  |  23 +++++
>  arch/riscv/boot/dts/kendryte/k210.dtsi | 123 +++++++++++++++++++++++++
>  4 files changed, 149 insertions(+)
>  create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
>
> diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
> index 0bf2669aa12d..87815557f2db 100644
> --- a/arch/riscv/boot/dts/Makefile
> +++ b/arch/riscv/boot/dts/Makefile
> @@ -3,4 +3,5 @@ ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
>  obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
>  else
>  subdir-y += sifive
> +subdir-y += kendryte
>  endif
> diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile
> new file mode 100644
> index 000000000000..815444e69e89
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb
> diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts
> new file mode 100644
> index 000000000000..0d1f28fce6b2
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/k210.dts
> @@ -0,0 +1,23 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +
> +/dts-v1/;
> +
> +#include "k210.dtsi"
> +
> +/ {
> +       model = "Kendryte K210 generic";
> +       compatible = "kendryte,k210";
> +
> +       chosen {
> +               bootargs = "earlycon console=ttySIF0";
> +               stdout-path = "serial0";
> +       };
> +};
> +
> +&uarths0 {
> +       status = "okay";
> +};
> +
> diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi
> new file mode 100644
> index 000000000000..4b9eeabb07f7
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/k210.dtsi
> @@ -0,0 +1,123 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +
> +/ {
> +       /*
> +        * Although the K210 is a 64-bit CPU, the address bus is only 32-bits
> +        * wide, and the upper half of all addresses is ignored.
> +        */
> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +       compatible = "kendryte,k210";
> +
> +       aliases {
> +               serial0 = &uarths0;
> +       };
> +
> +       clocks {
> +               in0: oscillator {
> +                       compatible = "fixed-clock";
> +                       #clock-cells = <0>;
> +                       clock-frequency = <26000000>;
> +               };
> +       };

Move the "clocks" DT node just before "soc" DT node. The usual (unsaid)
convention is to keep "cpus", "memory", "aliases", and "chosen" DT nodes
before everything else.

> +
> +       cpus {
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +               timebase-frequency = <7800000>;
> +               cpu0: cpu@0 {
> +                       device_type = "cpu";
> +                       reg = <0>;
> +                       compatible = "riscv";
> +                       riscv,isa = "rv64imafdc";
> +                       mmu-type = "none";
> +                       i-cache-size = <0x8000>;
> +                       i-cache-block-size = <64>; /* bogus */
> +                       d-cache-size = <0x8000>;
> +                       d-cache-block-size = <64>; /* bogus */
> +                       clocks = <&sysctl 0>;
> +                       clock-frequency = <390000000>;
> +                       cpu0_intc: interrupt-controller {
> +                               #interrupt-cells = <1>;
> +                               interrupt-controller;
> +                               compatible = "riscv,cpu-intc";
> +                       };
> +               };
> +               cpu1: cpu@1 {
> +                       device_type = "cpu";
> +                       reg = <1>;
> +                       compatible = "riscv";
> +                       riscv,isa = "rv64imafdc";
> +                       mmu-type = "none";
> +                       i-cache-size = <0x8000>;
> +                       i-cache-block-size = <64>; /* bogus */
> +                       d-cache-size = <0x8000>;
> +                       d-cache-block-size = <64>; /* bogus */
> +                       clocks = <&sysctl 0>;
> +                       clock-frequency = <390000000>;
> +                       cpu1_intc: interrupt-controller {
> +                               #interrupt-cells = <1>;
> +                               interrupt-controller;
> +                               compatible = "riscv,cpu-intc";
> +                       };
> +               };
> +       };
> +
> +       sram0: memory@80000000 {
> +               device_type = "memory";
> +               reg = <0x80000000 0x400000>;
> +       };
> +
> +       sram1: memory@80400000 {
> +               device_type = "memory";
> +               reg = <0x80400000 0x200000>;
> +       };
> +
> +       kpu_sram: memory@80600000 {
> +               device_type = "memory";
> +               reg = <0x80600000 0x200000>;
> +       };

No need to have separate DT node for each RAM bank. This can be
express as single DT node as follows:

sram: memory@80000000 {
        device_type = "memory";
        reg = <0x80000000 0x400000>,
                  <0x80400000 0x200000>,
                  <0x80600000 0x200000>;
};

> +
> +       soc {
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               compatible = "kendryte,k210-soc", "simple-bus";
> +               ranges;
> +               interrupt-parent = <&plic0>;
> +
> +               sysctl: sysctl@50440000 {
> +                       compatible = "kendryte,k210-sysctl", "syscon";
> +                       reg = <0x50440000 0x1000>;
> +                       #clock-cells = <1>;
> +               };
> +
> +               clint0: interrupt-controller@2000000 {
> +                       compatible = "riscv,clint0";
> +                       reg = <0x2000000 0xC000>;
> +                       interrupts-extended = <&cpu0_intc 3>,  <&cpu1_intc 3>;
> +                       clocks = <&sysctl 0>;
> +               };
> +
> +               plic0: interrupt-controller@c000000 {
> +                       #interrupt-cells = <1>;
> +                       interrupt-controller;
> +                       compatible = "kendryte,k210-plic0", "riscv,plic0";
> +                       reg = <0xC000000 0x3FFF008>;
> +                       interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
> +                                             <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
> +                       riscv,ndev = <65>;
> +                       riscv,max-priority = <0x07>;
> +               };
> +
> +               uarths0: serial@38000000 {
> +                       compatible = "kendryte,k210-uart0", "sifive,uart0";
> +                       reg = <0x38000000 0x20>;
> +                       interrupts = <33>;
> +                       clocks = <&sysctl 0>;
> +               };
> +       };
> +};
> --
> 2.24.1
>
>

Regards,
Anup
Damien Le Moal March 2, 2020, 4:15 a.m. UTC | #17
On 2020/03/02 13:07, Anup Patel wrote:
[...]
>> +       sram0: memory@80000000 {
>> +               device_type = "memory";
>> +               reg = <0x80000000 0x400000>;
>> +       };
>> +
>> +       sram1: memory@80400000 {
>> +               device_type = "memory";
>> +               reg = <0x80400000 0x200000>;
>> +       };
>> +
>> +       kpu_sram: memory@80600000 {
>> +               device_type = "memory";
>> +               reg = <0x80600000 0x200000>;
>> +       };
> 
> No need to have separate DT node for each RAM bank. This can be
> express as single DT node as follows:
> 
> sram: memory@80000000 {
>         device_type = "memory";
>         reg = <0x80000000 0x400000>,
>                   <0x80400000 0x200000>,
>                   <0x80600000 0x200000>;
> };

This is to match the U-boot device tree that Sean wrote. So I would rather keep
it like this. And strictly speaking, if one wants to add a driver for the KPU,
having the kpu memory segment for it separate makes it easy to reference it from
a kpu device entry. But granted, the two sram segments can be declared with a
single memory entry.
Anup Patel March 2, 2020, 4:22 a.m. UTC | #18
On Mon, Mar 2, 2020 at 9:46 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>
> On 2020/03/02 13:07, Anup Patel wrote:
> [...]
> >> +       sram0: memory@80000000 {
> >> +               device_type = "memory";
> >> +               reg = <0x80000000 0x400000>;
> >> +       };
> >> +
> >> +       sram1: memory@80400000 {
> >> +               device_type = "memory";
> >> +               reg = <0x80400000 0x200000>;
> >> +       };
> >> +
> >> +       kpu_sram: memory@80600000 {
> >> +               device_type = "memory";
> >> +               reg = <0x80600000 0x200000>;
> >> +       };
> >
> > No need to have separate DT node for each RAM bank. This can be
> > express as single DT node as follows:
> >
> > sram: memory@80000000 {
> >         device_type = "memory";
> >         reg = <0x80000000 0x400000>,
> >                   <0x80400000 0x200000>,
> >                   <0x80600000 0x200000>;
> > };
>
> This is to match the U-boot device tree that Sean wrote. So I would rather keep
> it like this. And strictly speaking, if one wants to add a driver for the KPU,
> having the kpu memory segment for it separate makes it easy to reference it from
> a kpu device entry. But granted, the two sram segments can be declared with a
> single memory entry.

But, that's not the preferred way of describing memory banks on the
same machine.
Usually, we create multiple memory DT nodes for NUMA systems.

You can also refer various ARM/ARM64 DTS files.

Regards,
Anup

>
>
>
>
> --
> Damien Le Moal
> Western Digital Research
Damien Le Moal March 2, 2020, 4:51 a.m. UTC | #19
On 2020/03/02 13:22, Anup Patel wrote:
> On Mon, Mar 2, 2020 at 9:46 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>>
>> On 2020/03/02 13:07, Anup Patel wrote:
>> [...]
>>>> +       sram0: memory@80000000 {
>>>> +               device_type = "memory";
>>>> +               reg = <0x80000000 0x400000>;
>>>> +       };
>>>> +
>>>> +       sram1: memory@80400000 {
>>>> +               device_type = "memory";
>>>> +               reg = <0x80400000 0x200000>;
>>>> +       };
>>>> +
>>>> +       kpu_sram: memory@80600000 {
>>>> +               device_type = "memory";
>>>> +               reg = <0x80600000 0x200000>;
>>>> +       };
>>>
>>> No need to have separate DT node for each RAM bank. This can be
>>> express as single DT node as follows:
>>>
>>> sram: memory@80000000 {
>>>         device_type = "memory";
>>>         reg = <0x80000000 0x400000>,
>>>                   <0x80400000 0x200000>,
>>>                   <0x80600000 0x200000>;
>>> };
>>
>> This is to match the U-boot device tree that Sean wrote. So I would rather keep
>> it like this. And strictly speaking, if one wants to add a driver for the KPU,
>> having the kpu memory segment for it separate makes it easy to reference it from
>> a kpu device entry. But granted, the two sram segments can be declared with a
>> single memory entry.
> 
> But, that's not the preferred way of describing memory banks on the
> same machine.
> Usually, we create multiple memory DT nodes for NUMA systems.
> 
> You can also refer various ARM/ARM64 DTS files.

Oops... Sent an answer to this to the wrong email... Here it is again:

Yes, I understand. But in the case of the K210, that last 2MB segment is really
special as by default it is not usable as regular SRAM. I think it may be better
to reflect that in the device tree. The K210 soc_early_init() call back can
probe for that special entry too to see if it has to be turned on for use as
regular memory or not (i.e. if a kpu driver will use it).

Since booting Linux with 6MB of memory will be even more challenging than with
8, I agree that we may never see the case of a kpu driver being used. But I
personally like making that special case clear in the device tree. No strong
objection to your simplification though. So if you really object, I will go with it.

Cheers.
Anup Patel March 2, 2020, 5:05 a.m. UTC | #20
On Mon, Mar 2, 2020 at 10:21 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>
> On 2020/03/02 13:22, Anup Patel wrote:
> > On Mon, Mar 2, 2020 at 9:46 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
> >>
> >> On 2020/03/02 13:07, Anup Patel wrote:
> >> [...]
> >>>> +       sram0: memory@80000000 {
> >>>> +               device_type = "memory";
> >>>> +               reg = <0x80000000 0x400000>;
> >>>> +       };
> >>>> +
> >>>> +       sram1: memory@80400000 {
> >>>> +               device_type = "memory";
> >>>> +               reg = <0x80400000 0x200000>;
> >>>> +       };
> >>>> +
> >>>> +       kpu_sram: memory@80600000 {
> >>>> +               device_type = "memory";
> >>>> +               reg = <0x80600000 0x200000>;
> >>>> +       };
> >>>
> >>> No need to have separate DT node for each RAM bank. This can be
> >>> express as single DT node as follows:
> >>>
> >>> sram: memory@80000000 {
> >>>         device_type = "memory";
> >>>         reg = <0x80000000 0x400000>,
> >>>                   <0x80400000 0x200000>,
> >>>                   <0x80600000 0x200000>;
> >>> };
> >>
> >> This is to match the U-boot device tree that Sean wrote. So I would rather keep
> >> it like this. And strictly speaking, if one wants to add a driver for the KPU,
> >> having the kpu memory segment for it separate makes it easy to reference it from
> >> a kpu device entry. But granted, the two sram segments can be declared with a
> >> single memory entry.
> >
> > But, that's not the preferred way of describing memory banks on the
> > same machine.
> > Usually, we create multiple memory DT nodes for NUMA systems.
> >
> > You can also refer various ARM/ARM64 DTS files.
>
> Oops... Sent an answer to this to the wrong email... Here it is again:
>
> Yes, I understand. But in the case of the K210, that last 2MB segment is really
> special as by default it is not usable as regular SRAM. I think it may be better
> to reflect that in the device tree. The K210 soc_early_init() call back can
> probe for that special entry too to see if it has to be turned on for use as
> regular memory or not (i.e. if a kpu driver will use it).
>
> Since booting Linux with 6MB of memory will be even more challenging than with
> 8, I agree that we may never see the case of a kpu driver being used. But I
> personally like making that special case clear in the device tree. No strong
> objection to your simplification though. So if you really object, I will go with it.
>

I understand that it is helping you to distinguish last 2MB segment but this is
also possible using with single memory DT node as follows:

sram: memory@80000000 {
        device_type = "memory";
        reg = <0x80000000 0x400000>,
                  <0x80400000 0x200000>,
                  <0x80600000 0x200000>;
        reg-names = "sram0", "sram1", "kpu_sram";
};

The K210 soc_early_init() can do the following:
1. Find memory DT node having device_type = "memory"
2. Find bank number for "kpu_sram" based on "reg-names DT property
3. Get based address of KPU SRAM from "reg" property based on bank
number found in step2 above.

The reg-names is a standard DT property used to distinguish multiple
memory regions of device. Same can be used to distinguish multiple
banks of memory DT node.

I am not adamant on having single memory DT node but just wanted
to let you know that this is not a preferred way for non-NUMA system.

Regards,
Anup
Damien Le Moal March 2, 2020, 5:08 a.m. UTC | #21
On 2020/03/02 14:05, Anup Patel wrote:
> On Mon, Mar 2, 2020 at 10:21 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>>
>> On 2020/03/02 13:22, Anup Patel wrote:
>>> On Mon, Mar 2, 2020 at 9:46 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>>>>
>>>> On 2020/03/02 13:07, Anup Patel wrote:
>>>> [...]
>>>>>> +       sram0: memory@80000000 {
>>>>>> +               device_type = "memory";
>>>>>> +               reg = <0x80000000 0x400000>;
>>>>>> +       };
>>>>>> +
>>>>>> +       sram1: memory@80400000 {
>>>>>> +               device_type = "memory";
>>>>>> +               reg = <0x80400000 0x200000>;
>>>>>> +       };
>>>>>> +
>>>>>> +       kpu_sram: memory@80600000 {
>>>>>> +               device_type = "memory";
>>>>>> +               reg = <0x80600000 0x200000>;
>>>>>> +       };
>>>>>
>>>>> No need to have separate DT node for each RAM bank. This can be
>>>>> express as single DT node as follows:
>>>>>
>>>>> sram: memory@80000000 {
>>>>>         device_type = "memory";
>>>>>         reg = <0x80000000 0x400000>,
>>>>>                   <0x80400000 0x200000>,
>>>>>                   <0x80600000 0x200000>;
>>>>> };
>>>>
>>>> This is to match the U-boot device tree that Sean wrote. So I would rather keep
>>>> it like this. And strictly speaking, if one wants to add a driver for the KPU,
>>>> having the kpu memory segment for it separate makes it easy to reference it from
>>>> a kpu device entry. But granted, the two sram segments can be declared with a
>>>> single memory entry.
>>>
>>> But, that's not the preferred way of describing memory banks on the
>>> same machine.
>>> Usually, we create multiple memory DT nodes for NUMA systems.
>>>
>>> You can also refer various ARM/ARM64 DTS files.
>>
>> Oops... Sent an answer to this to the wrong email... Here it is again:
>>
>> Yes, I understand. But in the case of the K210, that last 2MB segment is really
>> special as by default it is not usable as regular SRAM. I think it may be better
>> to reflect that in the device tree. The K210 soc_early_init() call back can
>> probe for that special entry too to see if it has to be turned on for use as
>> regular memory or not (i.e. if a kpu driver will use it).
>>
>> Since booting Linux with 6MB of memory will be even more challenging than with
>> 8, I agree that we may never see the case of a kpu driver being used. But I
>> personally like making that special case clear in the device tree. No strong
>> objection to your simplification though. So if you really object, I will go with it.
>>
> 
> I understand that it is helping you to distinguish last 2MB segment but this is
> also possible using with single memory DT node as follows:
> 
> sram: memory@80000000 {
>         device_type = "memory";
>         reg = <0x80000000 0x400000>,
>                   <0x80400000 0x200000>,
>                   <0x80600000 0x200000>;
>         reg-names = "sram0", "sram1", "kpu_sram";
> };

Nice trick. I did not know about it. Will use that then !
> 
> The K210 soc_early_init() can do the following:
> 1. Find memory DT node having device_type = "memory"
> 2. Find bank number for "kpu_sram" based on "reg-names DT property
> 3. Get based address of KPU SRAM from "reg" property based on bank
> number found in step2 above.
> 
> The reg-names is a standard DT property used to distinguish multiple
> memory regions of device. Same can be used to distinguish multiple
> banks of memory DT node.
> 
> I am not adamant on having single memory DT node but just wanted
> to let you know that this is not a preferred way for non-NUMA system.

Understood. Will use your proposed syntax.

> 
> Regards,
> Anup
>
Palmer Dabbelt March 4, 2020, 7:44 p.m. UTC | #22
On Wed, 12 Feb 2020 02:34:30 PST (-0800), Damien Le Moal wrote:
> Add a generic device tree for Kendryte K210 SoC based boards. This (for
> now) very simple device tree works for the Kendryte KD233 development
> board, the Sipeed MAIX M1 Dock based boards and the Sipeed MAIXDUINO
> board.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> ---
>  arch/riscv/boot/dts/Makefile           |   1 +
>  arch/riscv/boot/dts/kendryte/Makefile  |   2 +
>  arch/riscv/boot/dts/kendryte/k210.dts  |  23 +++++
>  arch/riscv/boot/dts/kendryte/k210.dtsi | 123 +++++++++++++++++++++++++
>  4 files changed, 149 insertions(+)
>  create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
>  create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi

OK, so if the same DTB works for all of these anyway then that at least lets us
kick the can down the road on the "how to look up a DT for a board" problem.

Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>

> diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
> index 0bf2669aa12d..87815557f2db 100644
> --- a/arch/riscv/boot/dts/Makefile
> +++ b/arch/riscv/boot/dts/Makefile
> @@ -3,4 +3,5 @@ ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
>  obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
>  else
>  subdir-y += sifive
> +subdir-y += kendryte
>  endif
> diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile
> new file mode 100644
> index 000000000000..815444e69e89
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb
> diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts
> new file mode 100644
> index 000000000000..0d1f28fce6b2
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/k210.dts
> @@ -0,0 +1,23 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +
> +/dts-v1/;
> +
> +#include "k210.dtsi"
> +
> +/ {
> +	model = "Kendryte K210 generic";
> +	compatible = "kendryte,k210";
> +
> +	chosen {
> +		bootargs = "earlycon console=ttySIF0";
> +		stdout-path = "serial0";
> +	};
> +};
> +
> +&uarths0 {
> +	status = "okay";
> +};
> +
> diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi
> new file mode 100644
> index 000000000000..4b9eeabb07f7
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/k210.dtsi
> @@ -0,0 +1,123 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +
> +/ {
> +	/*
> +	 * Although the K210 is a 64-bit CPU, the address bus is only 32-bits
> +	 * wide, and the upper half of all addresses is ignored.
> +	 */
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	compatible = "kendryte,k210";
> +
> +	aliases {
> +		serial0 = &uarths0;
> +	};
> +
> +	clocks {
> +		in0: oscillator {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <26000000>;
> +		};
> +	};
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		timebase-frequency = <7800000>;
> +		cpu0: cpu@0 {
> +			device_type = "cpu";
> +			reg = <0>;
> +			compatible = "riscv";
> +			riscv,isa = "rv64imafdc";
> +			mmu-type = "none";
> +			i-cache-size = <0x8000>;
> +			i-cache-block-size = <64>; /* bogus */
> +			d-cache-size = <0x8000>;
> +			d-cache-block-size = <64>; /* bogus */
> +			clocks = <&sysctl 0>;
> +			clock-frequency = <390000000>;
> +			cpu0_intc: interrupt-controller {
> +				#interrupt-cells = <1>;
> +				interrupt-controller;
> +				compatible = "riscv,cpu-intc";
> +			};
> +		};
> +		cpu1: cpu@1 {
> +			device_type = "cpu";
> +			reg = <1>;
> +			compatible = "riscv";
> +			riscv,isa = "rv64imafdc";
> +			mmu-type = "none";
> +			i-cache-size = <0x8000>;
> +			i-cache-block-size = <64>; /* bogus */
> +			d-cache-size = <0x8000>;
> +			d-cache-block-size = <64>; /* bogus */
> +			clocks = <&sysctl 0>;
> +			clock-frequency = <390000000>;
> +			cpu1_intc: interrupt-controller {
> +				#interrupt-cells = <1>;
> +				interrupt-controller;
> +				compatible = "riscv,cpu-intc";
> +			};
> +		};
> +	};
> +
> +	sram0: memory@80000000 {
> +		device_type = "memory";
> +		reg = <0x80000000 0x400000>;
> +	};
> +
> +	sram1: memory@80400000 {
> +		device_type = "memory";
> +		reg = <0x80400000 0x200000>;
> +	};
> +
> +	kpu_sram: memory@80600000 {
> +		device_type = "memory";
> +		reg = <0x80600000 0x200000>;
> +	};
> +
> +	soc {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "kendryte,k210-soc", "simple-bus";
> +		ranges;
> +		interrupt-parent = <&plic0>;
> +
> +		sysctl: sysctl@50440000 {
> +			compatible = "kendryte,k210-sysctl", "syscon";
> +			reg = <0x50440000 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		clint0: interrupt-controller@2000000 {
> +			compatible = "riscv,clint0";
> +			reg = <0x2000000 0xC000>;
> +			interrupts-extended = <&cpu0_intc 3>,  <&cpu1_intc 3>;
> +			clocks = <&sysctl 0>;
> +		};
> +
> +		plic0: interrupt-controller@c000000 {
> +			#interrupt-cells = <1>;
> +			interrupt-controller;
> +			compatible = "kendryte,k210-plic0", "riscv,plic0";
> +			reg = <0xC000000 0x3FFF008>;
> +			interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
> +					      <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
> +			riscv,ndev = <65>;
> +			riscv,max-priority = <0x07>;
> +		};
> +
> +		uarths0: serial@38000000 {
> +			compatible = "kendryte,k210-uart0", "sifive,uart0";
> +			reg = <0x38000000 0x20>;
> +			interrupts = <33>;
> +			clocks = <&sysctl 0>;
> +		};
> +	};
> +};
Sean Anderson March 7, 2020, 12:18 a.m. UTC | #23
On 3/2/20 12:08 AM, Damien Le Moal wrote:
> On 2020/03/02 14:05, Anup Patel wrote:
>> On Mon, Mar 2, 2020 at 10:21 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>>>
>>> On 2020/03/02 13:22, Anup Patel wrote:
>>>> On Mon, Mar 2, 2020 at 9:46 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>>>>>
>>>>> On 2020/03/02 13:07, Anup Patel wrote:
>>>>> [...]
>>>>>>> +       sram0: memory@80000000 {
>>>>>>> +               device_type = "memory";
>>>>>>> +               reg = <0x80000000 0x400000>;
>>>>>>> +       };
>>>>>>> +
>>>>>>> +       sram1: memory@80400000 {
>>>>>>> +               device_type = "memory";
>>>>>>> +               reg = <0x80400000 0x200000>;
>>>>>>> +       };
>>>>>>> +
>>>>>>> +       kpu_sram: memory@80600000 {
>>>>>>> +               device_type = "memory";
>>>>>>> +               reg = <0x80600000 0x200000>;
>>>>>>> +       };
>>>>>>
>>>>>> No need to have separate DT node for each RAM bank. This can be
>>>>>> express as single DT node as follows:
>>>>>>
>>>>>> sram: memory@80000000 {
>>>>>>         device_type = "memory";
>>>>>>         reg = <0x80000000 0x400000>,
>>>>>>                   <0x80400000 0x200000>,
>>>>>>                   <0x80600000 0x200000>;
>>>>>> };
>>>>>
>>>>> This is to match the U-boot device tree that Sean wrote. So I would rather keep
>>>>> it like this. And strictly speaking, if one wants to add a driver for the KPU,
>>>>> having the kpu memory segment for it separate makes it easy to reference it from
>>>>> a kpu device entry. But granted, the two sram segments can be declared with a
>>>>> single memory entry.

There is no clear documentation on how to do this, so I have been mostly
just trying things until they work. In U-Boot, separate memory device
nodes are treated as different "banks".

>>>>
>>>> But, that's not the preferred way of describing memory banks on the
>>>> same machine.
>>>> Usually, we create multiple memory DT nodes for NUMA systems.
>>>>
>>>> You can also refer various ARM/ARM64 DTS files.
>>>
>>> Oops... Sent an answer to this to the wrong email... Here it is again:
>>>
>>> Yes, I understand. But in the case of the K210, that last 2MB segment is really
>>> special as by default it is not usable as regular SRAM. I think it may be better
>>> to reflect that in the device tree. The K210 soc_early_init() call back can
>>> probe for that special entry too to see if it has to be turned on for use as
>>> regular memory or not (i.e. if a kpu driver will use it).
>>>
>>> Since booting Linux with 6MB of memory will be even more challenging than with
>>> 8, I agree that we may never see the case of a kpu driver being used. But I
>>> personally like making that special case clear in the device tree. No strong
>>> objection to your simplification though. So if you really object, I will go with it.
>>>
>>
>> I understand that it is helping you to distinguish last 2MB segment but this is
>> also possible using with single memory DT node as follows:
>>
>> sram: memory@80000000 {
>>         device_type = "memory";
>>         reg = <0x80000000 0x400000>,
>>                   <0x80400000 0x200000>,
>>                   <0x80600000 0x200000>;
>>         reg-names = "sram0", "sram1", "kpu_sram";
>> };
> 
> Nice trick. I did not know about it. Will use that then !
>>
>> The K210 soc_early_init() can do the following:
>> 1. Find memory DT node having device_type = "memory"
>> 2. Find bank number for "kpu_sram" based on "reg-names DT property
>> 3. Get based address of KPU SRAM from "reg" property based on bank
>> number found in step2 above.
>>
>> The reg-names is a standard DT property used to distinguish multiple
>> memory regions of device. Same can be used to distinguish multiple
>> banks of memory DT node.
>>
>> I am not adamant on having single memory DT node but just wanted
>> to let you know that this is not a preferred way for non-NUMA system.

Anup, do you have any suggestions on how to describe clocks for each
bank? I think the kpu sram may need some clock manipulation to work
properly. Perhaps something like

sram: memory@80000000 {
	device_type = "memory";
	reg = <0x80000000 0x400000>,
	      <0x80400000 0x200000>,
	      <0x80600000 0x200000>;
	reg-names = "sram0", "sram1", "kpu_sram";
	clocks = <&sysclk K210_CLK_SRAM0>,
		 <&sysclk K210_CLK_SRAM1>,
		 <&sysclk K210_CLK_PLL1>;
	clock-names = "sram0", "sram1", "kpu";
};

--Sean
Anup Patel March 7, 2020, 4:11 a.m. UTC | #24
On Sat, Mar 7, 2020 at 5:48 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> On 3/2/20 12:08 AM, Damien Le Moal wrote:
> > On 2020/03/02 14:05, Anup Patel wrote:
> >> On Mon, Mar 2, 2020 at 10:21 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
> >>>
> >>> On 2020/03/02 13:22, Anup Patel wrote:
> >>>> On Mon, Mar 2, 2020 at 9:46 AM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
> >>>>>
> >>>>> On 2020/03/02 13:07, Anup Patel wrote:
> >>>>> [...]
> >>>>>>> +       sram0: memory@80000000 {
> >>>>>>> +               device_type = "memory";
> >>>>>>> +               reg = <0x80000000 0x400000>;
> >>>>>>> +       };
> >>>>>>> +
> >>>>>>> +       sram1: memory@80400000 {
> >>>>>>> +               device_type = "memory";
> >>>>>>> +               reg = <0x80400000 0x200000>;
> >>>>>>> +       };
> >>>>>>> +
> >>>>>>> +       kpu_sram: memory@80600000 {
> >>>>>>> +               device_type = "memory";
> >>>>>>> +               reg = <0x80600000 0x200000>;
> >>>>>>> +       };
> >>>>>>
> >>>>>> No need to have separate DT node for each RAM bank. This can be
> >>>>>> express as single DT node as follows:
> >>>>>>
> >>>>>> sram: memory@80000000 {
> >>>>>>         device_type = "memory";
> >>>>>>         reg = <0x80000000 0x400000>,
> >>>>>>                   <0x80400000 0x200000>,
> >>>>>>                   <0x80600000 0x200000>;
> >>>>>> };
> >>>>>
> >>>>> This is to match the U-boot device tree that Sean wrote. So I would rather keep
> >>>>> it like this. And strictly speaking, if one wants to add a driver for the KPU,
> >>>>> having the kpu memory segment for it separate makes it easy to reference it from
> >>>>> a kpu device entry. But granted, the two sram segments can be declared with a
> >>>>> single memory entry.
>
> There is no clear documentation on how to do this, so I have been mostly
> just trying things until they work. In U-Boot, separate memory device
> nodes are treated as different "banks".
>
> >>>>
> >>>> But, that's not the preferred way of describing memory banks on the
> >>>> same machine.
> >>>> Usually, we create multiple memory DT nodes for NUMA systems.
> >>>>
> >>>> You can also refer various ARM/ARM64 DTS files.
> >>>
> >>> Oops... Sent an answer to this to the wrong email... Here it is again:
> >>>
> >>> Yes, I understand. But in the case of the K210, that last 2MB segment is really
> >>> special as by default it is not usable as regular SRAM. I think it may be better
> >>> to reflect that in the device tree. The K210 soc_early_init() call back can
> >>> probe for that special entry too to see if it has to be turned on for use as
> >>> regular memory or not (i.e. if a kpu driver will use it).
> >>>
> >>> Since booting Linux with 6MB of memory will be even more challenging than with
> >>> 8, I agree that we may never see the case of a kpu driver being used. But I
> >>> personally like making that special case clear in the device tree. No strong
> >>> objection to your simplification though. So if you really object, I will go with it.
> >>>
> >>
> >> I understand that it is helping you to distinguish last 2MB segment but this is
> >> also possible using with single memory DT node as follows:
> >>
> >> sram: memory@80000000 {
> >>         device_type = "memory";
> >>         reg = <0x80000000 0x400000>,
> >>                   <0x80400000 0x200000>,
> >>                   <0x80600000 0x200000>;
> >>         reg-names = "sram0", "sram1", "kpu_sram";
> >> };
> >
> > Nice trick. I did not know about it. Will use that then !
> >>
> >> The K210 soc_early_init() can do the following:
> >> 1. Find memory DT node having device_type = "memory"
> >> 2. Find bank number for "kpu_sram" based on "reg-names DT property
> >> 3. Get based address of KPU SRAM from "reg" property based on bank
> >> number found in step2 above.
> >>
> >> The reg-names is a standard DT property used to distinguish multiple
> >> memory regions of device. Same can be used to distinguish multiple
> >> banks of memory DT node.
> >>
> >> I am not adamant on having single memory DT node but just wanted
> >> to let you know that this is not a preferred way for non-NUMA system.
>
> Anup, do you have any suggestions on how to describe clocks for each
> bank? I think the kpu sram may need some clock manipulation to work
> properly. Perhaps something like
>
> sram: memory@80000000 {
>         device_type = "memory";
>         reg = <0x80000000 0x400000>,
>               <0x80400000 0x200000>,
>               <0x80600000 0x200000>;
>         reg-names = "sram0", "sram1", "kpu_sram";
>         clocks = <&sysclk K210_CLK_SRAM0>,
>                  <&sysclk K210_CLK_SRAM1>,
>                  <&sysclk K210_CLK_PLL1>;
>         clock-names = "sram0", "sram1", "kpu";

Yes, using "clock-names" to distinguish different clocks
of same device is the right way.

Regards,
Anup

> };
>
> --Sean
>
Drew Fustini April 1, 2020, 5:55 p.m. UTC | #25
On Sat, Feb 22, 2020 at 8:07 PM Wladimir J. van der Laan
<laanwj@gmail.com> wrote:
> > > > So the LCD connector is supposed to be for a ST7789V controller, but
> > > > there doesn't appear to be a driver in Linux for it. I don't have an
> > > > appropriate LCD screen, so I will not be able to write a driver.
> > > >
> > >
> > > Actually there is a driver and config DRM_PANEL_SITRONIX_ST7789V, in
> > > gpu/drm/panel/panel-sitronix-st7789v.c and also FB_TFT_ST7789V and
> > > CONFIG_FB_TFT_ST7789V with the driver a in
> > > staging/fbtft/fb_st7789v.c. Might be easier :)
> > >
> > > Weird that the Kendryte SDK refers to the LCD as NT35310
> > > (https://github.com/kendryte/kendryte-standalone-demo/tree/develop/lcd).
> >
> > I remember checking the datasheet for both a while ago and NT35310 and ST7789V
> > seem to be more or less compatible, with only register differences
> > for more obscure functionality.
>
> I just stumbled on this:
> https://forum.kendryte.com/topic/68/a-guide-to-adapt-kendryte-kd233-kpu-demo-to-sipeed-m1
> under "LCD Driver".
>
> So it looks like the K233 uses a nt35310, while Sipeed M1 uses st7789. This is
> a likely explanation for them mentioning both chips in the SDKs.

Hello all,

I have the Sipeed MAiX Go and was wondering if any has made anymore
progress with the LCD.

Is it reasonable to try to use a tinydrm driver to put basic
framebuffer on the LCD?

(so we could see the adorable Tux at boot, etc)

thanks,
drew
Damien Le Moal April 2, 2020, 2:24 a.m. UTC | #26
On 2020/04/02 2:55, Drew Fustini wrote:
> On Sat, Feb 22, 2020 at 8:07 PM Wladimir J. van der Laan
> <laanwj@gmail.com> wrote:
>>>>> So the LCD connector is supposed to be for a ST7789V controller, but
>>>>> there doesn't appear to be a driver in Linux for it. I don't have an
>>>>> appropriate LCD screen, so I will not be able to write a driver.
>>>>>
>>>>
>>>> Actually there is a driver and config DRM_PANEL_SITRONIX_ST7789V, in
>>>> gpu/drm/panel/panel-sitronix-st7789v.c and also FB_TFT_ST7789V and
>>>> CONFIG_FB_TFT_ST7789V with the driver a in
>>>> staging/fbtft/fb_st7789v.c. Might be easier :)
>>>>
>>>> Weird that the Kendryte SDK refers to the LCD as NT35310
>>>> (https://github.com/kendryte/kendryte-standalone-demo/tree/develop/lcd).
>>>
>>> I remember checking the datasheet for both a while ago and NT35310 and ST7789V
>>> seem to be more or less compatible, with only register differences
>>> for more obscure functionality.
>>
>> I just stumbled on this:
>> https://forum.kendryte.com/topic/68/a-guide-to-adapt-kendryte-kd233-kpu-demo-to-sipeed-m1
>> under "LCD Driver".
>>
>> So it looks like the K233 uses a nt35310, while Sipeed M1 uses st7789. This is
>> a likely explanation for them mentioning both chips in the SDKs.
> 
> Hello all,
> 
> I have the Sipeed MAiX Go and was wondering if any has made anymore
> progress with the LCD.
> 
> Is it reasonable to try to use a tinydrm driver to put basic
> framebuffer on the LCD?
> 
> (so we could see the adorable Tux at boot, etc)

I have not tried. But it may be good to first start with the LCD in text mode
only :)

There are tons of LCD controller drivers under drivers/auxdisplay and
drivers/gpu/drm/panel. The  MAIX Go LCD controller is likely already supported.
But you will need to add it to the device tree and fix k210-sysctl driver to
have the proper clock for it. Sean did a lot of work in this area already. We
can use it as a base for improving the device tree and driver I think.

Waiting to get the base series accepted first.

Palmer ? Any update ? You still had concerns about the embedded device tree and
I replied to that. Please let me know what you think.
diff mbox series

Patch

diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
index 0bf2669aa12d..87815557f2db 100644
--- a/arch/riscv/boot/dts/Makefile
+++ b/arch/riscv/boot/dts/Makefile
@@ -3,4 +3,5 @@  ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
 obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
 else
 subdir-y += sifive
+subdir-y += kendryte
 endif
diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile
new file mode 100644
index 000000000000..815444e69e89
--- /dev/null
+++ b/arch/riscv/boot/dts/kendryte/Makefile
@@ -0,0 +1,2 @@ 
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb
diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts
new file mode 100644
index 000000000000..0d1f28fce6b2
--- /dev/null
+++ b/arch/riscv/boot/dts/kendryte/k210.dts
@@ -0,0 +1,23 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+
+/dts-v1/;
+
+#include "k210.dtsi"
+
+/ {
+	model = "Kendryte K210 generic";
+	compatible = "kendryte,k210";
+
+	chosen {
+		bootargs = "earlycon console=ttySIF0";
+		stdout-path = "serial0";
+	};
+};
+
+&uarths0 {
+	status = "okay";
+};
+
diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi
new file mode 100644
index 000000000000..4b9eeabb07f7
--- /dev/null
+++ b/arch/riscv/boot/dts/kendryte/k210.dtsi
@@ -0,0 +1,123 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+
+/ {
+	/*
+	 * Although the K210 is a 64-bit CPU, the address bus is only 32-bits
+	 * wide, and the upper half of all addresses is ignored.
+	 */
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "kendryte,k210";
+
+	aliases {
+		serial0 = &uarths0;
+	};
+
+	clocks {
+		in0: oscillator {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <26000000>;
+		};
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		timebase-frequency = <7800000>;
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			reg = <0>;
+			compatible = "riscv";
+			riscv,isa = "rv64imafdc";
+			mmu-type = "none";
+			i-cache-size = <0x8000>;
+			i-cache-block-size = <64>; /* bogus */
+			d-cache-size = <0x8000>;
+			d-cache-block-size = <64>; /* bogus */
+			clocks = <&sysctl 0>;
+			clock-frequency = <390000000>;
+			cpu0_intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+			};
+		};
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			reg = <1>;
+			compatible = "riscv";
+			riscv,isa = "rv64imafdc";
+			mmu-type = "none";
+			i-cache-size = <0x8000>;
+			i-cache-block-size = <64>; /* bogus */
+			d-cache-size = <0x8000>;
+			d-cache-block-size = <64>; /* bogus */
+			clocks = <&sysctl 0>;
+			clock-frequency = <390000000>;
+			cpu1_intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+			};
+		};
+	};
+
+	sram0: memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x400000>;
+	};
+
+	sram1: memory@80400000 {
+		device_type = "memory";
+		reg = <0x80400000 0x200000>;
+	};
+
+	kpu_sram: memory@80600000 {
+		device_type = "memory";
+		reg = <0x80600000 0x200000>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "kendryte,k210-soc", "simple-bus";
+		ranges;
+		interrupt-parent = <&plic0>;
+
+		sysctl: sysctl@50440000 {
+			compatible = "kendryte,k210-sysctl", "syscon";
+			reg = <0x50440000 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		clint0: interrupt-controller@2000000 {
+			compatible = "riscv,clint0";
+			reg = <0x2000000 0xC000>;
+			interrupts-extended = <&cpu0_intc 3>,  <&cpu1_intc 3>;
+			clocks = <&sysctl 0>;
+		};
+
+		plic0: interrupt-controller@c000000 {
+			#interrupt-cells = <1>;
+			interrupt-controller;
+			compatible = "kendryte,k210-plic0", "riscv,plic0";
+			reg = <0xC000000 0x3FFF008>;
+			interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
+					      <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
+			riscv,ndev = <65>;
+			riscv,max-priority = <0x07>;
+		};
+
+		uarths0: serial@38000000 {
+			compatible = "kendryte,k210-uart0", "sifive,uart0";
+			reg = <0x38000000 0x20>;
+			interrupts = <33>;
+			clocks = <&sysctl 0>;
+		};
+	};
+};