mbox series

[v7,00/22] RISC-V Kendryte K210 support improvements

Message ID 20201210034003.222297-1-damien.lemoal@wdc.com (mailing list archive)
Headers show
Series RISC-V Kendryte K210 support improvements | expand

Message

Damien Le Moal Dec. 10, 2020, 3:39 a.m. UTC
This series of patches improves support for boards based on the Canaan
Kendryte K210 RISC-V dual core SoC. Minimal support for this SoC is
already included in the kernel. These patches complete it, enabling
support for most peripherals present on the SoC as well as introducing
device trees for the various K210 boards available on the market today
from SiPeed and Kendryte.

Pathes 1 to 4 are various fixes for riscv arch code and riscv
dependent devices. Of note here is patch 3 which fix system calls
execution in the no MMU case, and patch 4 which simplifies DTB builtin
handling.

Patch 5 fixes naming of directories and configuration options to use the
K210 SoC vendor name (Canaan) instead of its branding name (Kendryte).

Patch 6 is a preparatory patch cleaning up the K210 system controller
driver to facilitate introducing the SoC clock driver.

The following patches 7 to 11 document device tree bindings for the SoC
drivers. The implementation of these drivers is provided in patches 12,
13 and 14, respectively implementing the SoC clock driver, reset
controller and SOC pin function control.

Patches 15 to 20 update the existing K210 device tree and add new
device tree files for several K210 based boards: MAIX Bit, MAIXDUINO,
MAIX Dock and MAIX Go boards from SiPeed and the KD233 development
board from Canaan.

Finally the last two patches updates the k210 nommu defconfig to include
the newly implemented drivers and provide a new default configuration
file enabling SD card support.

A lot of the work on the device tree and on the K210 drivers come from
the work by Sean Anderson for the U-Boot project support of the K210
SoC. Sean also helped with debugging many aspects of this series.

A tree with all patches applied is available here:
https://github.com/damien-lemoal/linux, k210-sysctl-v20 branch.
A demonstration of this series used on a SiPeed MAIX Dock
board together with an I2C servo controller can be seen here:
https://damien-lemoal.github.io/linux-robot-arm/#example

This tree was used to build userspace busybox environment image that is
then copied onto an SD card formatted with ext2:
https://github.com/damien-lemoal/buildroot
Of note is that running this userspace environment requires a revert of
commit 2217b982624680d19a80ebb4600d05c8586c4f96 introduced during the
5.9 development cycle. Without this revert, execution of the init
process fails. A problem with the riscv port of elf2flt is suspected but
not confirmed. I am now starting to investigate this problem.

Reviews and comments are as always much welcome.

Changes from v6:
* Annotate struct platform_driver variables with __refdata to avoid
  section mismatch compilation errors
* Add empty sentinel entry to of_device_id tables of the sysctl, reset
  and pinctrl drivers.

Changes from v5:
* Addressed Philipp's comment on the reset controller driver
* Added patch 6 to reduce the size of the clock driver patch
  (now patch 12).

Changes from v4:
* Simplified reset controller driver using of_xlate callback as
  suggested by Philipp
* Fixed compilation error when using other configs than one of the
  nommu_k210 defconfigs.
* Addressed most clock driver comments from Stephen.
* Removed CONFIG_GPIO_SYSFS from defconfigs
* Rebased on 5.10-rc7

Changes from V3:
* Add one entry per driver in MAINTAINERS file

Changes from V2:
* Add MAINTAINERS file entry for the SoC support, listing myself as
  maintainer.
* Removed use of postcore_initcall() for declaring the drivers, using
  the regular builtin_platform_driver() instead.
* Fixed fpio pinctrl driver bindings documentation as commented by
  Geert: removed input-schmitt and added input-schmitt-disable, fixed
  typo and added input-disable and output-disable.
* Fixed device tree to have cs-gpios active low, as per the default, as
  active high necessity was an artifact of the gpio level double
  inversion bug fixed recently.
* Removed CONFIG_VT from defconfigs to reduce the kernel image size as
  suggested by Geert.

Changes from v1:
* Improved DT bindings documentation
* SPI and GPIO patches removed from this series (and being processed
  directly through the relevant subsystems directly)
* Improved device trees
* Various cleanup and improvments of the drivers

Damien Le Moal (22):
  riscv: Fix kernel time_init()
  riscv: Fix sifive serial driver
  riscv: Enable interrupts during syscalls with M-Mode
  riscv: Fix builtin DTB handling
  riscv: Use vendor name for K210 SoC support
  riscv: cleanup Canaan Kendryte K210 sysctl driver
  dt-bindings: Add Canaan vendor prefix
  dt-binding: clock: Document canaan,k210-clk bindings
  dt-bindings: reset: Document canaan,k210-rst bindings
  dt-bindings: pinctrl: Document canaan,k210-fpioa bindings
  dt-binding: mfd: Document canaan,k210-sysctl bindings
  riscv: Add Canaan Kendryte K210 clock driver
  riscv: Add Canaan Kendryte K210 reset controller
  riscv: Add Canaan Kendryte K210 FPIOA driver
  riscv: Update Canaan Kendryte K210 device tree
  riscv: Add SiPeed MAIX BiT board device tree
  riscv: Add SiPeed MAIX DOCK board device tree
  riscv: Add SiPeed MAIX GO board device tree
  riscv: Add SiPeed MAIXDUINO board device tree
  riscv: Add Kendryte KD233 board device tree
  riscv: Update Canaan Kendryte K210 defconfig
  riscv: Add Canaan Kendryte K210 SD card defconfig

 .../bindings/clock/canaan,k210-clk.yaml       |   54 +
 .../bindings/mfd/canaan,k210-sysctl.yaml      |  116 ++
 .../bindings/pinctrl/canaan,k210-fpioa.yaml   |  171 +++
 .../bindings/reset/canaan,k210-rst.yaml       |   40 +
 .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
 MAINTAINERS                                   |   23 +
 arch/riscv/Kconfig.socs                       |   33 +-
 arch/riscv/Makefile                           |    2 +-
 arch/riscv/boot/dts/Makefile                  |    2 +-
 arch/riscv/boot/dts/canaan/Makefile           |    5 +
 arch/riscv/boot/dts/canaan/k210.dtsi          |  622 ++++++++++
 arch/riscv/boot/dts/canaan/k210_generic.dts   |   46 +
 arch/riscv/boot/dts/canaan/k210_kd233.dts     |  178 +++
 arch/riscv/boot/dts/canaan/k210_maix_bit.dts  |  227 ++++
 arch/riscv/boot/dts/canaan/k210_maix_dock.dts |  229 ++++
 arch/riscv/boot/dts/canaan/k210_maix_go.dts   |  237 ++++
 arch/riscv/boot/dts/canaan/k210_maixduino.dts |  201 ++++
 arch/riscv/boot/dts/kendryte/Makefile         |    4 -
 arch/riscv/boot/dts/kendryte/k210.dts         |   23 -
 arch/riscv/boot/dts/kendryte/k210.dtsi        |  125 --
 arch/riscv/configs/nommu_k210_defconfig       |   39 +-
 .../riscv/configs/nommu_k210_sdcard_defconfig |   93 ++
 arch/riscv/include/asm/soc.h                  |   38 -
 arch/riscv/kernel/entry.S                     |    9 +
 arch/riscv/kernel/soc.c                       |   27 -
 arch/riscv/kernel/time.c                      |    3 +
 arch/riscv/mm/init.c                          |    6 +-
 drivers/clk/Kconfig                           |    8 +
 drivers/clk/Makefile                          |    1 +
 drivers/clk/clk-k210.c                        | 1005 +++++++++++++++++
 drivers/pinctrl/Kconfig                       |   13 +
 drivers/pinctrl/Makefile                      |    1 +
 drivers/pinctrl/pinctrl-k210.c                |  985 ++++++++++++++++
 drivers/reset/Kconfig                         |   10 +
 drivers/reset/Makefile                        |    1 +
 drivers/reset/reset-k210.c                    |  131 +++
 drivers/soc/Kconfig                           |    2 +-
 drivers/soc/Makefile                          |    2 +-
 drivers/soc/canaan/Kconfig                    |   12 +
 drivers/soc/canaan/Makefile                   |    3 +
 drivers/soc/canaan/k210-sysctl.c              |   78 ++
 drivers/soc/kendryte/Kconfig                  |   14 -
 drivers/soc/kendryte/Makefile                 |    3 -
 drivers/soc/kendryte/k210-sysctl.c            |  260 -----
 drivers/tty/serial/sifive.c                   |    1 +
 include/dt-bindings/clock/k210-clk.h          |   55 +-
 include/dt-bindings/pinctrl/k210-fpioa.h      |  276 +++++
 include/dt-bindings/reset/k210-rst.h          |   42 +
 include/soc/canaan/k210-sysctl.h              |   43 +
 49 files changed, 4970 insertions(+), 531 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/canaan,k210-clk.yaml
 create mode 100644 Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml
 create mode 100644 Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml
 create mode 100644 arch/riscv/boot/dts/canaan/Makefile
 create mode 100644 arch/riscv/boot/dts/canaan/k210.dtsi
 create mode 100644 arch/riscv/boot/dts/canaan/k210_generic.dts
 create mode 100644 arch/riscv/boot/dts/canaan/k210_kd233.dts
 create mode 100644 arch/riscv/boot/dts/canaan/k210_maix_bit.dts
 create mode 100644 arch/riscv/boot/dts/canaan/k210_maix_dock.dts
 create mode 100644 arch/riscv/boot/dts/canaan/k210_maix_go.dts
 create mode 100644 arch/riscv/boot/dts/canaan/k210_maixduino.dts
 delete mode 100644 arch/riscv/boot/dts/kendryte/Makefile
 delete mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
 delete mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
 create mode 100644 arch/riscv/configs/nommu_k210_sdcard_defconfig
 create mode 100644 drivers/clk/clk-k210.c
 create mode 100644 drivers/pinctrl/pinctrl-k210.c
 create mode 100644 drivers/reset/reset-k210.c
 create mode 100644 drivers/soc/canaan/Kconfig
 create mode 100644 drivers/soc/canaan/Makefile
 create mode 100644 drivers/soc/canaan/k210-sysctl.c
 delete mode 100644 drivers/soc/kendryte/Kconfig
 delete mode 100644 drivers/soc/kendryte/Makefile
 delete mode 100644 drivers/soc/kendryte/k210-sysctl.c
 create mode 100644 include/dt-bindings/pinctrl/k210-fpioa.h
 create mode 100644 include/dt-bindings/reset/k210-rst.h
 create mode 100644 include/soc/canaan/k210-sysctl.h

Comments

Geert Uytterhoeven Dec. 10, 2020, 10:04 a.m. UTC | #1
Hi Damien,

On Thu, Dec 10, 2020 at 4:41 AM Damien Le Moal <damien.lemoal@wdc.com> wrote:
> Changes from v6:
> * Annotate struct platform_driver variables with __refdata to avoid
>   section mismatch compilation errors

Blindly following the advice from kernel test robot <lkp@intel.com> is
not always a good idea:

    The variable k210_rst_driver references
    the function __init set_reset_devices()
    If the reference is valid then annotate the
    variable with or __refdata (see linux/init.h) or name the variable:

If your driver's probe function is annotated with __init, you cannot
have a pointer to it in the driver structure, as any binding done after
the freeing of initmem will cause a crash.  Adding the __refdata merely
suppresses the warning, and won't avoid the crash.

There are two solutions for this:
  1. Remove the .probe pointer, and use platform_driver_probe() instead
     of platform_driver_register().
     This guarantees the probe method will be called only once, before
     initmem is freed, but does mean that probe deferral cannot work.
  2. Drop the __init annotation.
     This means the probe method can be called anytime, and supports
     both probe deferral and driver unbind/rebind cycles.

Given the limited amount of RAM on k210, I think option 1 is preferred,
but may require careful tuning of the initialization order using
*_initcall*(), to make sure probe deferral won't ever be needed.

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Damien Le Moal Dec. 10, 2020, 12:36 p.m. UTC | #2
On Thu, 2020-12-10 at 11:04 +0100, Geert Uytterhoeven wrote:
> Hi Damien,
> 
> On Thu, Dec 10, 2020 at 4:41 AM Damien Le Moal <damien.lemoal@wdc.com> wrote:
> > Changes from v6:
> > * Annotate struct platform_driver variables with __refdata to avoid
> >   section mismatch compilation errors
> 
> Blindly following the advice from kernel test robot <lkp@intel.com> is
> not always a good idea:
> 
>     The variable k210_rst_driver references
>     the function __init set_reset_devices()
>     If the reference is valid then annotate the
>     variable with or __refdata (see linux/init.h) or name the variable:
> 
> If your driver's probe function is annotated with __init, you cannot
> have a pointer to it in the driver structure, as any binding done after
> the freeing of initmem will cause a crash.  Adding the __refdata merely
> suppresses the warning, and won't avoid the crash.

Hmm... I must be misunderstanding something here. free_initmem() is called from
kernel_init() right before starting the user init process. That is late enough
that all drivers are already probed and initialized. At least that is what I
thought, especially considering that none of the k210 drivers can be modules
and are all builtin. What am I missing here ? 

> There are two solutions for this:
>   1. Remove the .probe pointer, and use platform_driver_probe() instead
>      of platform_driver_register().
>      This guarantees the probe method will be called only once, before
>      initmem is freed, but does mean that probe deferral cannot work.
>   2. Drop the __init annotation.
>      This means the probe method can be called anytime, and supports
>      both probe deferral and driver unbind/rebind cycles.
> 
> Given the limited amount of RAM on k210, I think option 1 is preferred,
> but may require careful tuning of the initialization order using
> *_initcall*(), to make sure probe deferral won't ever be needed.

I really would prefer to avoid the *_initcall() dance. That is not pretty.
Simply removing the __init annotation, I see 766 pages free with "cat
/proc/vmstat" right after boot, and the same number with __init too... So it
does not look like the impact is significant. The biggest probe function is for
the clock driver and this one seems fine with __init since it uses
CLK_OF_DECLARE(). I do have a doubt about this now though. Looking at other
drivers, all seem to have the __init annotation for their clock driver init
function.

So I think I will go with option 2. It is simpler and safer. We can always
revisit and optimize later. I would prefer this series to land first :)

> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds
Geert Uytterhoeven Dec. 10, 2020, 1:22 p.m. UTC | #3
Hi Damien,

On Thu, Dec 10, 2020 at 1:36 PM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
> On Thu, 2020-12-10 at 11:04 +0100, Geert Uytterhoeven wrote:
> > On Thu, Dec 10, 2020 at 4:41 AM Damien Le Moal <damien.lemoal@wdc.com> wrote:
> > > Changes from v6:
> > > * Annotate struct platform_driver variables with __refdata to avoid
> > >   section mismatch compilation errors
> >
> > Blindly following the advice from kernel test robot <lkp@intel.com> is
> > not always a good idea:
> >
> >     The variable k210_rst_driver references
> >     the function __init set_reset_devices()
> >     If the reference is valid then annotate the
> >     variable with or __refdata (see linux/init.h) or name the variable:
> >
> > If your driver's probe function is annotated with __init, you cannot
> > have a pointer to it in the driver structure, as any binding done after
> > the freeing of initmem will cause a crash.  Adding the __refdata merely
> > suppresses the warning, and won't avoid the crash.
>
> Hmm... I must be misunderstanding something here. free_initmem() is called from
> kernel_init() right before starting the user init process. That is late enough
> that all drivers are already probed and initialized. At least that is what I
> thought, especially considering that none of the k210 drivers can be modules
> and are all builtin. What am I missing here ?

For these specific cases, binding is indeed unlikely to happen after
free_initmem(). In the generic case that is not true.
However, you can still trigger it manually by unbinding and rebinding
the device manually through sysfs.

> So I think I will go with option 2. It is simpler and safer. We can always
> revisit and optimize later. I would prefer this series to land first :)

Right. Correctness first, performance later.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Damien Le Moal Dec. 10, 2020, 1:52 p.m. UTC | #4
On 2020/12/10 22:23, Geert Uytterhoeven wrote:
> Hi Damien,
> 
> On Thu, Dec 10, 2020 at 1:36 PM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>> On Thu, 2020-12-10 at 11:04 +0100, Geert Uytterhoeven wrote:
>>> On Thu, Dec 10, 2020 at 4:41 AM Damien Le Moal <damien.lemoal@wdc.com> wrote:
>>>> Changes from v6:
>>>> * Annotate struct platform_driver variables with __refdata to avoid
>>>>   section mismatch compilation errors
>>>
>>> Blindly following the advice from kernel test robot <lkp@intel.com> is
>>> not always a good idea:
>>>
>>>     The variable k210_rst_driver references
>>>     the function __init set_reset_devices()
>>>     If the reference is valid then annotate the
>>>     variable with or __refdata (see linux/init.h) or name the variable:
>>>
>>> If your driver's probe function is annotated with __init, you cannot
>>> have a pointer to it in the driver structure, as any binding done after
>>> the freeing of initmem will cause a crash.  Adding the __refdata merely
>>> suppresses the warning, and won't avoid the crash.
>>
>> Hmm... I must be misunderstanding something here. free_initmem() is called from
>> kernel_init() right before starting the user init process. That is late enough
>> that all drivers are already probed and initialized. At least that is what I
>> thought, especially considering that none of the k210 drivers can be modules
>> and are all builtin. What am I missing here ?
> 
> For these specific cases, binding is indeed unlikely to happen after
> free_initmem(). In the generic case that is not true.
> However, you can still trigger it manually by unbinding and rebinding
> the device manually through sysfs.

Got it. Sending a v8 with the correction.

Thanks !

> 
>> So I think I will go with option 2. It is simpler and safer. We can always
>> revisit and optimize later. I would prefer this series to land first :)
> 
> Right. Correctness first, performance later.
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds
>