From: Palmer Dabbelt <palmer@dabbelt.com>
To: Damien Le Moal <Damien.LeMoal@wdc.com>,
Olof Johansson <olof@lixom.net>, Arnd Bergmann <arnd@arndb.de>,
tglx@linutronix.de, gregkh@linuxfoundation.org
Cc: linux-riscv@lists.infradead.org, Anup Patel <Anup.Patel@wdc.com>,
Paul Walmsley <paul.walmsley@sifive.com>
Subject: Re: [PATCH 06/10] riscv: Add Kendryte K210 SoC support
Date: Wed, 04 Mar 2020 11:38:29 -0800 (PST) [thread overview]
Message-ID: <mhng-da7768b8-0c67-4120-8aae-7f9f08a34567@palmerdabbelt-glaptop1> (raw)
In-Reply-To: <20200212103432.660256-7-damien.lemoal@wdc.com>
On Wed, 12 Feb 2020 02:34:28 PST (-0800), Damien Le Moal wrote:
> From: Christoph Hellwig <hch@lst.de>
>
> Add support for the Kendryte K210 RISC-V SoC. For now, this support
> only provides a simple sysctl driver allowing to setup the CPU and
> uart clock. This support is enabled through the new Kconfig option
> SOC_KENDRYTE and defines the config option CONFIG_K210_SYSCTL
> to enable the K210 SoC sysctl driver compilation.
>
> The sysctl driver also registers an early SoC initialization function
> allowing enabling the general purpose use of the 2MB of SRAM normally
> reserved for the SoC AI engine. This initialization function is
> automatically called before the dt early initialization using the flat
> dt root node compatible property matching the value "kendryte,k210".
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> ---
> arch/riscv/Kconfig.socs | 6 +
> drivers/soc/Kconfig | 1 +
> drivers/soc/Makefile | 1 +
> drivers/soc/kendryte/Kconfig | 14 ++
> drivers/soc/kendryte/Makefile | 3 +
> drivers/soc/kendryte/k210-sysctl.c | 245 +++++++++++++++++++++++++++++
> 6 files changed, 270 insertions(+)
> create mode 100644 drivers/soc/kendryte/Kconfig
> create mode 100644 drivers/soc/kendryte/Makefile
> create mode 100644 drivers/soc/kendryte/k210-sysctl.c
+Olof, Arnd, Thomas, and Greg (from get-maintainers)
LMK if you want this to go in through the RISC-V tree -- I can keep it
building, but I don't have hardware to test on. If you want to take it,
otherwise
Acked-by: Palmer Dabbelt <palmerdabbelt@google.com>
either way
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
Thanks!
> diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
> index d325b67d00df..4d5d4a65b2a2 100644
> --- a/arch/riscv/Kconfig.socs
> +++ b/arch/riscv/Kconfig.socs
> @@ -10,4 +10,10 @@ config SOC_SIFIVE
> help
> This enables support for SiFive SoC platform hardware.
>
> +config SOC_KENDRYTE
> + bool "Kendryte K210 SoC"
> + depends on !MMU
> + help
> + This enables support for Kendryte K210 SoC hardware.
> +
> endmenu
> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
> index 1778f8c62861..425ab6f7e375 100644
> --- a/drivers/soc/Kconfig
> +++ b/drivers/soc/Kconfig
> @@ -22,5 +22,6 @@ source "drivers/soc/ux500/Kconfig"
> source "drivers/soc/versatile/Kconfig"
> source "drivers/soc/xilinx/Kconfig"
> source "drivers/soc/zte/Kconfig"
> +source "drivers/soc/kendryte/Kconfig"
>
> endmenu
> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
> index 8b49d782a1ab..af58063bb989 100644
> --- a/drivers/soc/Makefile
> +++ b/drivers/soc/Makefile
> @@ -28,3 +28,4 @@ obj-$(CONFIG_ARCH_U8500) += ux500/
> obj-$(CONFIG_PLAT_VERSATILE) += versatile/
> obj-y += xilinx/
> obj-$(CONFIG_ARCH_ZX) += zte/
> +obj-$(CONFIG_SOC_KENDRYTE) += kendryte/
> diff --git a/drivers/soc/kendryte/Kconfig b/drivers/soc/kendryte/Kconfig
> new file mode 100644
> index 000000000000..49785b1b0217
> --- /dev/null
> +++ b/drivers/soc/kendryte/Kconfig
> @@ -0,0 +1,14 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +if SOC_KENDRYTE
> +
> +config K210_SYSCTL
> + bool "Kendryte K210 system controller"
> + default y
> + depends on RISCV
> + help
> + Enables controlling the K210 various clocks and to enable
> + general purpose use of the extra 2MB of SRAM normally
> + reserved for the AI engine.
> +
> +endif
> diff --git a/drivers/soc/kendryte/Makefile b/drivers/soc/kendryte/Makefile
> new file mode 100644
> index 000000000000..002d9ce95c0d
> --- /dev/null
> +++ b/drivers/soc/kendryte/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_K210_SYSCTL) += k210-sysctl.o
> diff --git a/drivers/soc/kendryte/k210-sysctl.c b/drivers/soc/kendryte/k210-sysctl.c
> new file mode 100644
> index 000000000000..7d4ecd954af0
> --- /dev/null
> +++ b/drivers/soc/kendryte/k210-sysctl.c
> @@ -0,0 +1,245 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2019 Christoph Hellwig.
> + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> + */
> +#include <linux/types.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <asm/soc.h>
> +
> +#define K210_SYSCTL_CLK0_FREQ 26000000UL
> +
> +/* Registers base address */
> +#define K210_SYSCTL_SYSCTL_BASE_ADDR 0x50440000ULL
> +
> +/* Registers */
> +#define K210_SYSCTL_PLL0 0x08
> +#define K210_SYSCTL_PLL1 0x0c
> +/* clkr: 4bits, clkf1: 6bits, clkod: 4bits, bwadj: 4bits */
> +#define PLL_RESET (1 << 20)
> +#define PLL_PWR (1 << 21)
> +#define PLL_INTFB (1 << 22)
> +#define PLL_BYPASS (1 << 23)
> +#define PLL_TEST (1 << 24)
> +#define PLL_OUT_EN (1 << 25)
> +#define PLL_TEST_EN (1 << 26)
> +#define K210_SYSCTL_PLL_LOCK 0x18
> +#define PLL0_LOCK1 (1 << 0)
> +#define PLL0_LOCK2 (1 << 1)
> +#define PLL0_SLIP_CLEAR (1 << 2)
> +#define PLL0_TEST_CLK_OUT (1 << 3)
> +#define PLL1_LOCK1 (1 << 8)
> +#define PLL1_LOCK2 (1 << 9)
> +#define PLL1_SLIP_CLEAR (1 << 10)
> +#define PLL1_TEST_CLK_OUT (1 << 11)
> +#define PLL2_LOCK1 (1 << 16)
> +#define PLL2_LOCK2 (1 << 16)
> +#define PLL2_SLIP_CLEAR (1 << 18)
> +#define PLL2_TEST_CLK_OUT (1 << 19)
> +#define K210_SYSCTL_CLKSEL0 0x20
> +#define CLKSEL_ACLK (1 << 0)
> +#define K210_SYSCTL_CLKEN_CENT 0x28
> +#define CLKEN_CPU (1 << 0)
> +#define CLKEN_SRAM0 (1 << 1)
> +#define CLKEN_SRAM1 (1 << 2)
> +#define CLKEN_APB0 (1 << 3)
> +#define CLKEN_APB1 (1 << 4)
> +#define CLKEN_APB2 (1 << 5)
> +#define K210_SYSCTL_CLKEN_PERI 0x2c
> +#define CLKEN_ROM (1 << 0)
> +#define CLKEN_DMA (1 << 1)
> +#define CLKEN_AI (1 << 2)
> +#define CLKEN_DVP (1 << 3)
> +#define CLKEN_FFT (1 << 4)
> +#define CLKEN_GPIO (1 << 5)
> +#define CLKEN_SPI0 (1 << 6)
> +#define CLKEN_SPI1 (1 << 7)
> +#define CLKEN_SPI2 (1 << 8)
> +#define CLKEN_SPI3 (1 << 9)
> +#define CLKEN_I2S0 (1 << 10)
> +#define CLKEN_I2S1 (1 << 11)
> +#define CLKEN_I2S2 (1 << 12)
> +#define CLKEN_I2C0 (1 << 13)
> +#define CLKEN_I2C1 (1 << 14)
> +#define CLKEN_I2C2 (1 << 15)
> +#define CLKEN_UART1 (1 << 16)
> +#define CLKEN_UART2 (1 << 17)
> +#define CLKEN_UART3 (1 << 18)
> +#define CLKEN_AES (1 << 19)
> +#define CLKEN_FPIO (1 << 20)
> +#define CLKEN_TIMER0 (1 << 21)
> +#define CLKEN_TIMER1 (1 << 22)
> +#define CLKEN_TIMER2 (1 << 23)
> +#define CLKEN_WDT0 (1 << 24)
> +#define CLKEN_WDT1 (1 << 25)
> +#define CLKEN_SHA (1 << 26)
> +#define CLKEN_OTP (1 << 27)
> +#define CLKEN_RTC (1 << 29)
> +
> +struct k210_sysctl {
> + void __iomem *regs;
> + struct clk_hw hw;
> +};
> +
> +static void k210_set_bits(u32 val, void __iomem *reg)
> +{
> + writel(readl(reg) | val, reg);
> +}
> +
> +static void k210_clear_bits(u32 val, void __iomem *reg)
> +{
> + writel(readl(reg) & ~val, reg);
> +}
> +
> +static void k210_pll1_enable(void __iomem *regs)
> +{
> + u32 val;
> +
> + val = readl(regs + K210_SYSCTL_PLL1);
> + val &= ~0xfffff;
> + val |= (59 << 4) | (3 << 10) | (59 << 15);
> + writel(val, regs + K210_SYSCTL_PLL1);
> +
> + k210_clear_bits(PLL_BYPASS, regs + K210_SYSCTL_PLL1);
> + k210_set_bits(PLL_PWR, regs + K210_SYSCTL_PLL1);
> +
> + /*
> + * Reset the pll. The magic NOPs come from the Kendryte reference SDK.
> + */
> + k210_clear_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
> + k210_set_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
> + nop();
> + nop();
I don't actually have one of these to test this on.
> + k210_clear_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
> +
> + for (;;) {
> + val = readl(regs + K210_SYSCTL_PLL_LOCK);
> + if (val & PLL1_LOCK2)
> + break;
> + writel(val | PLL1_SLIP_CLEAR, regs + K210_SYSCTL_PLL_LOCK);
> + }
> +
> + k210_set_bits(PLL_OUT_EN, regs + K210_SYSCTL_PLL1);
> +}
> +
> +static unsigned long k210_sysctl_clk_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct k210_sysctl *s = container_of(hw, struct k210_sysctl, hw);
> + u32 clksel0, pll0;
> + u64 pll0_freq, clkr0, clkf0, clkod0;
> +
> + /*
> + * If the clock selector is not set, use the base frequency.
> + * Otherwise, use PLL0 frequency with a frequency divisor.
> + */
> + clksel0 = readl(s->regs + K210_SYSCTL_CLKSEL0);
> + if (!(clksel0 & CLKSEL_ACLK))
> + return K210_SYSCTL_CLK0_FREQ;
> +
> + /*
> + * Get PLL0 frequency:
> + * freq = base frequency * clkf0 / (clkr0 * clkod0)
> + */
> + pll0 = readl(s->regs + K210_SYSCTL_PLL0);
> + clkr0 = 1 + (pll0 & 0x0000000f);
> + clkf0 = 1 + ((pll0 & 0x000003f0) >> 4);
> + clkod0 = 1 + ((pll0 & 0x00003c00) >> 10);
> + pll0_freq = clkf0 * K210_SYSCTL_CLK0_FREQ / (clkr0 * clkod0);
> +
> + /* Get the frequency divisor from the clock selector */
> + return pll0_freq / (2ULL << ((clksel0 & 0x00000006) >> 1));
> +}
> +
> +static const struct clk_ops k210_sysctl_clk_ops = {
> + .recalc_rate = k210_sysctl_clk_recalc_rate,
> +};
> +
> +static const struct clk_init_data k210_clk_init_data = {
> + .name = "k210-sysctl-pll1",
> + .ops = &k210_sysctl_clk_ops,
> +};
> +
> +static int k210_sysctl_probe(struct platform_device *pdev)
> +{
> + struct k210_sysctl *s;
> + int error;
> +
> + pr_info("Kendryte K210 SoC sysctl\n");
> +
> + s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
> + if (!s)
> + return -ENOMEM;
> +
> + s->regs = devm_ioremap_resource(&pdev->dev,
> + platform_get_resource(pdev, IORESOURCE_MEM, 0));
> + if (IS_ERR(s->regs))
> + return PTR_ERR(s->regs);
> +
> + s->hw.init = &k210_clk_init_data;
> + error = devm_clk_hw_register(&pdev->dev, &s->hw);
> + if (error) {
> + dev_err(&pdev->dev, "failed to register clk");
> + return error;
> + }
> +
> + error = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get,
> + &s->hw);
> + if (error) {
> + dev_err(&pdev->dev, "adding clk provider failed\n");
> + return error;
> + }
> +
> + return 0;
> +}
> +
> +static const struct of_device_id k210_sysctl_of_match[] = {
> + { .compatible = "kendryte,k210-sysctl", },
> + {}
> +};
> +
> +static struct platform_driver k210_sysctl_driver = {
> + .driver = {
> + .name = "k210-sysctl",
> + .of_match_table = k210_sysctl_of_match,
> + },
> + .probe = k210_sysctl_probe,
> +};
> +
> +static int __init k210_sysctl_init(void)
> +{
> + return platform_driver_register(&k210_sysctl_driver);
> +}
> +core_initcall(k210_sysctl_init);
> +
> +/*
> + * This needs to be called very early during initialization, given that
> + * PLL1 needs to be enabled to be able to use all SRAM.
> + */
> +static void __init k210_soc_early_init(const void *fdt)
> +{
> + void __iomem *regs;
> +
> + regs = ioremap(K210_SYSCTL_SYSCTL_BASE_ADDR, 0x1000);
> + if (!regs)
> + panic("K210 sysctl ioremap");
> +
> + /* Enable PLL1 to make the KPU SRAM useable */
> + k210_pll1_enable(regs);
> +
> + k210_set_bits(PLL_OUT_EN, regs + K210_SYSCTL_PLL0);
> +
> + k210_set_bits(CLKEN_CPU | CLKEN_SRAM0 | CLKEN_SRAM1,
> + regs + K210_SYSCTL_CLKEN_CENT);
> + k210_set_bits(CLKEN_ROM | CLKEN_TIMER0 | CLKEN_RTC,
> + regs + K210_SYSCTL_CLKEN_PERI);
> +
> + k210_set_bits(CLKSEL_ACLK, regs + K210_SYSCTL_CLKSEL0);
> +
> + iounmap(regs);
> +}
> +SOC_EARLY_INIT_DECLARE("kendryte,k210", k210_soc_early_init);
next prev parent reply other threads:[~2020-03-04 19:38 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-12 10:34 [PATCH 00/10] Kendryte k210 SoC boards support Damien Le Moal
2020-02-12 10:34 ` [PATCH 01/10] riscv: Fix gitignore Damien Le Moal
2020-02-20 0:15 ` Palmer Dabbelt
2020-02-12 10:34 ` [PATCH 02/10] riscv: Force flat memory model with no-mmu Damien Le Moal
2020-02-14 20:18 ` Sean Anderson
2020-02-15 2:15 ` Damien Le Moal
2020-02-15 2:26 ` Sean Anderson
2020-02-15 2:40 ` Damien Le Moal
2020-03-02 3:48 ` Anup Patel
2020-03-04 18:38 ` Palmer Dabbelt
2020-02-12 10:34 ` [PATCH 03/10] riscv: Unaligned load/store handling for M_MODE Damien Le Moal
2020-03-02 3:57 ` Anup Patel
2020-03-04 19:28 ` Palmer Dabbelt
2020-02-12 10:34 ` [PATCH 04/10] riscv: Add BUILTIN_DTB support Damien Le Moal
2020-03-02 3:58 ` Anup Patel
2020-03-04 19:28 ` Palmer Dabbelt
2020-03-05 4:58 ` Anup Patel
2020-03-05 5:14 ` Damien Le Moal
2020-03-05 5:37 ` Anup Patel
2020-03-05 6:13 ` Damien Le Moal
2020-03-08 6:10 ` Anup Patel
2020-03-05 8:18 ` Atish Patra
2020-03-07 0:02 ` Sean Anderson
2020-03-07 1:51 ` Atish Patra
2020-03-07 2:08 ` Sean Anderson
2020-03-06 23:56 ` Sean Anderson
2020-02-12 10:34 ` [PATCH 05/10] riscv: Add SOC early init support Damien Le Moal
2020-03-04 19:28 ` Palmer Dabbelt
2020-02-12 10:34 ` [PATCH 06/10] riscv: Add Kendryte K210 SoC support Damien Le Moal
2020-02-14 20:31 ` Sean Anderson
2020-03-04 19:38 ` Palmer Dabbelt [this message]
2020-02-12 10:34 ` [PATCH 07/10] riscv: Select required drivers for Kendryte SOC Damien Le Moal
2020-03-02 3:59 ` Anup Patel
2020-03-04 19:44 ` Palmer Dabbelt
2020-02-12 10:34 ` [PATCH 08/10] riscv: Add Kendryte K210 device tree Damien Le Moal
2020-02-14 20:51 ` Sean Anderson
2020-02-15 2:34 ` Damien Le Moal
2020-02-15 2:48 ` Sean Anderson
2020-02-15 3:00 ` Damien Le Moal
2020-02-18 14:12 ` Carlos Eduardo de Paula
2020-02-18 14:18 ` Sean Anderson
2020-02-18 14:30 ` Carlos Eduardo de Paula
2020-02-18 17:48 ` Sean Anderson
2020-02-18 19:26 ` Carlos Eduardo de Paula
2020-02-19 9:06 ` Wladimir J. van der Laan
2020-02-19 22:28 ` Sean Anderson
2020-02-20 10:48 ` Wladimir J. van der Laan
2020-02-22 19:07 ` Wladimir J. van der Laan
2020-04-01 17:55 ` Drew Fustini
2020-04-02 2:24 ` Damien Le Moal
2020-02-19 8:50 ` Wladimir J. van der Laan
2020-02-27 19:43 ` Sean Anderson
2020-03-02 4:06 ` Anup Patel
2020-03-02 4:15 ` Damien Le Moal
2020-03-02 4:22 ` Anup Patel
2020-03-02 4:51 ` Damien Le Moal
2020-03-02 5:05 ` Anup Patel
2020-03-02 5:08 ` Damien Le Moal
2020-03-07 0:18 ` Sean Anderson
2020-03-07 4:11 ` Anup Patel
2020-03-04 19:44 ` Palmer Dabbelt
2020-02-12 10:34 ` [PATCH 09/10] riscv: Kendryte K210 default config Damien Le Moal
2020-03-02 4:07 ` Anup Patel
2020-03-04 19:44 ` Palmer Dabbelt
2020-02-12 10:34 ` [PATCH 10/10] riscv: create a loader.bin for the kendryte kflash.py tool Damien Le Moal
2020-03-02 4:08 ` Anup Patel
2020-03-04 19:44 ` Palmer Dabbelt
2020-02-14 15:05 ` [PATCH 00/10] Kendryte k210 SoC boards support Carlos Eduardo de Paula
2020-02-15 2:02 ` Damien Le Moal
2020-02-17 13:28 ` Carlos Eduardo de Paula
2020-02-26 21:31 ` Carlos Eduardo de Paula
2020-02-27 2:18 ` Damien Le Moal
2020-02-28 20:32 ` Sean Anderson
2020-03-02 3:01 ` Damien Le Moal
2020-03-02 3:53 ` Sean Anderson
2020-03-02 4:11 ` Damien Le Moal
2020-03-02 4:18 ` Sean Anderson
2020-03-02 4:54 ` Damien Le Moal
2020-03-02 4:56 ` Sean Anderson
2020-03-02 5:03 ` Damien Le Moal
2020-03-02 4:17 ` Anup Patel
2020-03-02 4:21 ` Sean Anderson
2020-03-02 4:48 ` Damien Le Moal
2020-03-02 4:51 ` Damien Le Moal
2020-03-02 5:02 ` Sean Anderson
2020-03-02 5:11 ` Damien Le Moal
2020-03-02 5:25 ` Sean Anderson
2020-03-02 5:43 ` Damien Le Moal
2020-03-04 19:44 ` Palmer Dabbelt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=mhng-da7768b8-0c67-4120-8aae-7f9f08a34567@palmerdabbelt-glaptop1 \
--to=palmer@dabbelt.com \
--cc=Anup.Patel@wdc.com \
--cc=Damien.LeMoal@wdc.com \
--cc=arnd@arndb.de \
--cc=gregkh@linuxfoundation.org \
--cc=linux-riscv@lists.infradead.org \
--cc=olof@lixom.net \
--cc=paul.walmsley@sifive.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).