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) 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 index 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
Linux-RISC-V Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-riscv/0 linux-riscv/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-riscv linux-riscv/ https://lore.kernel.org/linux-riscv \ linux-riscv@lists.infradead.org public-inbox-index linux-riscv Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.infradead.lists.linux-riscv AGPL code for this site: git clone https://public-inbox.org/public-inbox.git