clk: Add K210 clock support

Due to the large number of clocks, I decided to use the CCF. The overall
structure is modeled after the imx code. Clocks parameters are stored in
several arrays, and are then instantiated at run-time. There are some
translation macros (FOOIFY()) which allow for more dense packing.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
CC: Lukasz Majewski <lukma@denx.de>
diff --git a/include/dt-bindings/clock/k210-sysctl.h b/include/dt-bindings/clock/k210-sysctl.h
new file mode 100644
index 0000000..0e3ed3f
--- /dev/null
+++ b/include/dt-bindings/clock/k210-sysctl.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019-20 Sean Anderson <seanga2@gmail.com>
+ */
+
+#ifndef CLOCK_K210_SYSCTL_H
+#define CLOCK_K210_SYSCTL_H
+
+/*
+ * Arbitrary identifiers for clocks.
+ */
+#define K210_CLK_NONE   0
+#define K210_CLK_IN0_H  1
+#define K210_CLK_PLL0_H 2
+#define K210_CLK_PLL0   3
+#define K210_CLK_PLL1   4
+#define K210_CLK_PLL2   5
+#define K210_CLK_PLL2_H 6
+#define K210_CLK_CPU    7
+#define K210_CLK_SRAM0  8
+#define K210_CLK_SRAM1  9
+#define K210_CLK_APB0   10
+#define K210_CLK_APB1   11
+#define K210_CLK_APB2   12
+#define K210_CLK_ROM    13
+#define K210_CLK_DMA    14
+#define K210_CLK_AI     15
+#define K210_CLK_DVP    16
+#define K210_CLK_FFT    17
+#define K210_CLK_GPIO   18
+#define K210_CLK_SPI0   19
+#define K210_CLK_SPI1   20
+#define K210_CLK_SPI2   21
+#define K210_CLK_SPI3   22
+#define K210_CLK_I2S0   23
+#define K210_CLK_I2S1   24
+#define K210_CLK_I2S2   25
+#define K210_CLK_I2S0_M 26
+#define K210_CLK_I2S1_M 27
+#define K210_CLK_I2S2_M 28
+#define K210_CLK_I2C0   29
+#define K210_CLK_I2C1   30
+#define K210_CLK_I2C2   31
+#define K210_CLK_UART1  32
+#define K210_CLK_UART2  33
+#define K210_CLK_UART3  34
+#define K210_CLK_AES    35
+#define K210_CLK_FPIOA  36
+#define K210_CLK_TIMER0 37
+#define K210_CLK_TIMER1 38
+#define K210_CLK_TIMER2 39
+#define K210_CLK_WDT0   40
+#define K210_CLK_WDT1   41
+#define K210_CLK_SHA    42
+#define K210_CLK_OTP    43
+#define K210_CLK_RTC    44
+#define K210_CLK_ACLK   45
+
+#endif /* CLOCK_K210_SYSCTL_H */
diff --git a/include/dt-bindings/mfd/k210-sysctl.h b/include/dt-bindings/mfd/k210-sysctl.h
new file mode 100644
index 0000000..bfc918d
--- /dev/null
+++ b/include/dt-bindings/mfd/k210-sysctl.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
+ */
+
+#ifndef K210_SYSCTL_H
+#define K210_SYSCTL_H
+
+/* Taken from kendryte-standalone-sdk/lib/drivers/include/sysctl.h */
+#define K210_SYSCTL_GIT_ID     0x00 /* Git short commit id */
+#define K210_SYSCTL_UART_BAUD  0x04 /* Default UARTHS baud rate */
+#define K210_SYSCTL_PLL0       0x08 /* PLL0 controller */
+#define K210_SYSCTL_PLL1       0x0C /* PLL1 controller */
+#define K210_SYSCTL_PLL2       0x10 /* PLL2 controller */
+#define K210_SYSCTL_PLL_LOCK   0x18 /* PLL lock tester */
+#define K210_SYSCTL_ROM_ERROR  0x1C /* AXI ROM detector */
+#define K210_SYSCTL_SEL0       0x20 /* Clock select controller 0 */
+#define K210_SYSCTL_SEL1       0x24 /* Clock select controller 1 */
+#define K210_SYSCTL_EN_CENT    0x28 /* Central clock enable */
+#define K210_SYSCTL_EN_PERI    0x2C /* Peripheral clock enable */
+#define K210_SYSCTL_SOFT_RESET 0x30 /* Soft reset ctrl */
+#define K210_SYSCTL_PERI_RESET 0x34 /* Peripheral reset controller */
+#define K210_SYSCTL_THR0       0x38 /* Clock threshold controller 0 */
+#define K210_SYSCTL_THR1       0x3C /* Clock threshold controller 1 */
+#define K210_SYSCTL_THR2       0x40 /* Clock threshold controller 2 */
+#define K210_SYSCTL_THR3       0x44 /* Clock threshold controller 3 */
+#define K210_SYSCTL_THR4       0x48 /* Clock threshold controller 4 */
+#define K210_SYSCTL_THR5       0x4C /* Clock threshold controller 5 */
+#define K210_SYSCTL_THR6       0x50 /* Clock threshold controller 6 */
+#define K210_SYSCTL_MISC       0x54 /* Miscellaneous controller */
+#define K210_SYSCTL_PERI       0x58 /* Peripheral controller */
+#define K210_SYSCTL_SPI_SLEEP  0x5C /* SPI sleep controller */
+#define K210_SYSCTL_RESET_STAT 0x60 /* Reset source status */
+#define K210_SYSCTL_DMA_SEL0   0x64 /* DMA handshake selector 0 */
+#define K210_SYSCTL_DMA_SEL1   0x68 /* DMA handshake selector 1 */
+#define K210_SYSCTL_POWER_SEL  0x6C /* IO Power Mode Select controller */
+
+#endif /* K210_SYSCTL_H */
diff --git a/include/kendryte/clk.h b/include/kendryte/clk.h
new file mode 100644
index 0000000..9c6245d
--- /dev/null
+++ b/include/kendryte/clk.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019-20 Sean Anderson <seanga2@gmail.com>
+ */
+
+#ifndef K210_CLK_H
+#define K210_CLK_H
+
+#define LOG_CATEGORY UCLASS_CLK
+#include <linux/types.h>
+#include <linux/clk-provider.h>
+
+static inline struct clk *k210_clk_gate(const char *name,
+					const char *parent_name,
+					void __iomem *reg, u8 bit_idx)
+{
+	return clk_register_gate(NULL, name, parent_name, 0, reg, bit_idx, 0,
+				 NULL);
+}
+
+static inline struct clk *k210_clk_half(const char *name,
+					const char *parent_name)
+{
+	return clk_register_fixed_factor(NULL, name, parent_name, 0, 1, 2);
+}
+
+static inline struct clk *k210_clk_div(const char *name,
+				       const char *parent_name,
+				       void __iomem *reg, u8 shift, u8 width)
+{
+	return clk_register_divider(NULL, name, parent_name, 0, reg, shift,
+				    width, 0);
+}
+
+#endif /* K210_CLK_H */