brintos

brintos / linux-shallow public Read only

0
0
Text · 24.9 KiB · 7b7329a Raw
1011 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2019-20 Sean Anderson <seanga2@gmail.com>4 * Copyright (c) 2019 Western Digital Corporation or its affiliates.5 */6#define pr_fmt(fmt)     "k210-clk: " fmt7 8#include <linux/io.h>9#include <linux/slab.h>10#include <linux/spinlock.h>11#include <linux/platform_device.h>12#include <linux/of.h>13#include <linux/of_clk.h>14#include <linux/of_address.h>15#include <linux/clk-provider.h>16#include <linux/bitfield.h>17#include <linux/delay.h>18#include <soc/canaan/k210-sysctl.h>19 20#include <dt-bindings/clock/k210-clk.h>21 22struct k210_sysclk;23 24struct k210_clk {25	int id;26	struct k210_sysclk *ksc;27	struct clk_hw hw;28};29 30struct k210_clk_cfg {31	const char *name;32	u8 gate_reg;33	u8 gate_bit;34	u8 div_reg;35	u8 div_shift;36	u8 div_width;37	u8 div_type;38	u8 mux_reg;39	u8 mux_bit;40};41 42enum k210_clk_div_type {43	K210_DIV_NONE,44	K210_DIV_ONE_BASED,45	K210_DIV_DOUBLE_ONE_BASED,46	K210_DIV_POWER_OF_TWO,47};48 49#define K210_GATE(_reg, _bit)	\50	.gate_reg = (_reg),	\51	.gate_bit = (_bit)52 53#define K210_DIV(_reg, _shift, _width, _type)	\54	.div_reg = (_reg),			\55	.div_shift = (_shift),			\56	.div_width = (_width),			\57	.div_type = (_type)58 59#define K210_MUX(_reg, _bit)	\60	.mux_reg = (_reg),	\61	.mux_bit = (_bit)62 63static struct k210_clk_cfg k210_clk_cfgs[K210_NUM_CLKS] = {64	/* Gated clocks, no mux, no divider */65	[K210_CLK_CPU] = {66		.name = "cpu",67		K210_GATE(K210_SYSCTL_EN_CENT, 0)68	},69	[K210_CLK_DMA] = {70		.name = "dma",71		K210_GATE(K210_SYSCTL_EN_PERI, 1)72	},73	[K210_CLK_FFT] = {74		.name = "fft",75		K210_GATE(K210_SYSCTL_EN_PERI, 4)76	},77	[K210_CLK_GPIO] = {78		.name = "gpio",79		K210_GATE(K210_SYSCTL_EN_PERI, 5)80	},81	[K210_CLK_UART1] = {82		.name = "uart1",83		K210_GATE(K210_SYSCTL_EN_PERI, 16)84	},85	[K210_CLK_UART2] = {86		.name = "uart2",87		K210_GATE(K210_SYSCTL_EN_PERI, 17)88	},89	[K210_CLK_UART3] = {90		.name = "uart3",91		K210_GATE(K210_SYSCTL_EN_PERI, 18)92	},93	[K210_CLK_FPIOA] = {94		.name = "fpioa",95		K210_GATE(K210_SYSCTL_EN_PERI, 20)96	},97	[K210_CLK_SHA] = {98		.name = "sha",99		K210_GATE(K210_SYSCTL_EN_PERI, 26)100	},101	[K210_CLK_AES] = {102		.name = "aes",103		K210_GATE(K210_SYSCTL_EN_PERI, 19)104	},105	[K210_CLK_OTP] = {106		.name = "otp",107		K210_GATE(K210_SYSCTL_EN_PERI, 27)108	},109	[K210_CLK_RTC] = {110		.name = "rtc",111		K210_GATE(K210_SYSCTL_EN_PERI, 29)112	},113 114	/* Gated divider clocks */115	[K210_CLK_SRAM0] = {116		.name = "sram0",117		K210_GATE(K210_SYSCTL_EN_CENT, 1),118		K210_DIV(K210_SYSCTL_THR0, 0, 4, K210_DIV_ONE_BASED)119	},120	[K210_CLK_SRAM1] = {121		.name = "sram1",122		K210_GATE(K210_SYSCTL_EN_CENT, 2),123		K210_DIV(K210_SYSCTL_THR0, 4, 4, K210_DIV_ONE_BASED)124	},125	[K210_CLK_ROM] = {126		.name = "rom",127		K210_GATE(K210_SYSCTL_EN_PERI, 0),128		K210_DIV(K210_SYSCTL_THR0, 16, 4, K210_DIV_ONE_BASED)129	},130	[K210_CLK_DVP] = {131		.name = "dvp",132		K210_GATE(K210_SYSCTL_EN_PERI, 3),133		K210_DIV(K210_SYSCTL_THR0, 12, 4, K210_DIV_ONE_BASED)134	},135	[K210_CLK_APB0] = {136		.name = "apb0",137		K210_GATE(K210_SYSCTL_EN_CENT, 3),138		K210_DIV(K210_SYSCTL_SEL0, 3, 3, K210_DIV_ONE_BASED)139	},140	[K210_CLK_APB1] = {141		.name = "apb1",142		K210_GATE(K210_SYSCTL_EN_CENT, 4),143		K210_DIV(K210_SYSCTL_SEL0, 6, 3, K210_DIV_ONE_BASED)144	},145	[K210_CLK_APB2] = {146		.name = "apb2",147		K210_GATE(K210_SYSCTL_EN_CENT, 5),148		K210_DIV(K210_SYSCTL_SEL0, 9, 3, K210_DIV_ONE_BASED)149	},150	[K210_CLK_AI] = {151		.name = "ai",152		K210_GATE(K210_SYSCTL_EN_PERI, 2),153		K210_DIV(K210_SYSCTL_THR0, 8, 4, K210_DIV_ONE_BASED)154	},155	[K210_CLK_SPI0] = {156		.name = "spi0",157		K210_GATE(K210_SYSCTL_EN_PERI, 6),158		K210_DIV(K210_SYSCTL_THR1, 0, 8, K210_DIV_DOUBLE_ONE_BASED)159	},160	[K210_CLK_SPI1] = {161		.name = "spi1",162		K210_GATE(K210_SYSCTL_EN_PERI, 7),163		K210_DIV(K210_SYSCTL_THR1, 8, 8, K210_DIV_DOUBLE_ONE_BASED)164	},165	[K210_CLK_SPI2] = {166		.name = "spi2",167		K210_GATE(K210_SYSCTL_EN_PERI, 8),168		K210_DIV(K210_SYSCTL_THR1, 16, 8, K210_DIV_DOUBLE_ONE_BASED)169	},170	[K210_CLK_I2C0] = {171		.name = "i2c0",172		K210_GATE(K210_SYSCTL_EN_PERI, 13),173		K210_DIV(K210_SYSCTL_THR5, 8, 8, K210_DIV_DOUBLE_ONE_BASED)174	},175	[K210_CLK_I2C1] = {176		.name = "i2c1",177		K210_GATE(K210_SYSCTL_EN_PERI, 14),178		K210_DIV(K210_SYSCTL_THR5, 16, 8, K210_DIV_DOUBLE_ONE_BASED)179	},180	[K210_CLK_I2C2] = {181		.name = "i2c2",182		K210_GATE(K210_SYSCTL_EN_PERI, 15),183		K210_DIV(K210_SYSCTL_THR5, 24, 8, K210_DIV_DOUBLE_ONE_BASED)184	},185	[K210_CLK_WDT0] = {186		.name = "wdt0",187		K210_GATE(K210_SYSCTL_EN_PERI, 24),188		K210_DIV(K210_SYSCTL_THR6, 0, 8, K210_DIV_DOUBLE_ONE_BASED)189	},190	[K210_CLK_WDT1] = {191		.name = "wdt1",192		K210_GATE(K210_SYSCTL_EN_PERI, 25),193		K210_DIV(K210_SYSCTL_THR6, 8, 8, K210_DIV_DOUBLE_ONE_BASED)194	},195	[K210_CLK_I2S0] = {196		.name = "i2s0",197		K210_GATE(K210_SYSCTL_EN_PERI, 10),198		K210_DIV(K210_SYSCTL_THR3, 0, 16, K210_DIV_DOUBLE_ONE_BASED)199	},200	[K210_CLK_I2S1] = {201		.name = "i2s1",202		K210_GATE(K210_SYSCTL_EN_PERI, 11),203		K210_DIV(K210_SYSCTL_THR3, 16, 16, K210_DIV_DOUBLE_ONE_BASED)204	},205	[K210_CLK_I2S2] = {206		.name = "i2s2",207		K210_GATE(K210_SYSCTL_EN_PERI, 12),208		K210_DIV(K210_SYSCTL_THR4, 0, 16, K210_DIV_DOUBLE_ONE_BASED)209	},210 211	/* Divider clocks, no gate, no mux */212	[K210_CLK_I2S0_M] = {213		.name = "i2s0_m",214		K210_DIV(K210_SYSCTL_THR4, 16, 8, K210_DIV_DOUBLE_ONE_BASED)215	},216	[K210_CLK_I2S1_M] = {217		.name = "i2s1_m",218		K210_DIV(K210_SYSCTL_THR4, 24, 8, K210_DIV_DOUBLE_ONE_BASED)219	},220	[K210_CLK_I2S2_M] = {221		.name = "i2s2_m",222		K210_DIV(K210_SYSCTL_THR4, 0, 8, K210_DIV_DOUBLE_ONE_BASED)223	},224 225	/* Muxed gated divider clocks */226	[K210_CLK_SPI3] = {227		.name = "spi3",228		K210_GATE(K210_SYSCTL_EN_PERI, 9),229		K210_DIV(K210_SYSCTL_THR1, 24, 8, K210_DIV_DOUBLE_ONE_BASED),230		K210_MUX(K210_SYSCTL_SEL0, 12)231	},232	[K210_CLK_TIMER0] = {233		.name = "timer0",234		K210_GATE(K210_SYSCTL_EN_PERI, 21),235		K210_DIV(K210_SYSCTL_THR2,  0, 8, K210_DIV_DOUBLE_ONE_BASED),236		K210_MUX(K210_SYSCTL_SEL0, 13)237	},238	[K210_CLK_TIMER1] = {239		.name = "timer1",240		K210_GATE(K210_SYSCTL_EN_PERI, 22),241		K210_DIV(K210_SYSCTL_THR2, 8, 8, K210_DIV_DOUBLE_ONE_BASED),242		K210_MUX(K210_SYSCTL_SEL0, 14)243	},244	[K210_CLK_TIMER2] = {245		.name = "timer2",246		K210_GATE(K210_SYSCTL_EN_PERI, 23),247		K210_DIV(K210_SYSCTL_THR2, 16, 8, K210_DIV_DOUBLE_ONE_BASED),248		K210_MUX(K210_SYSCTL_SEL0, 15)249	},250};251 252/*253 * PLL control register bits.254 */255#define K210_PLL_CLKR		GENMASK(3, 0)256#define K210_PLL_CLKF		GENMASK(9, 4)257#define K210_PLL_CLKOD		GENMASK(13, 10)258#define K210_PLL_BWADJ		GENMASK(19, 14)259#define K210_PLL_RESET		(1 << 20)260#define K210_PLL_PWRD		(1 << 21)261#define K210_PLL_INTFB		(1 << 22)262#define K210_PLL_BYPASS		(1 << 23)263#define K210_PLL_TEST		(1 << 24)264#define K210_PLL_EN		(1 << 25)265#define K210_PLL_SEL		GENMASK(27, 26) /* PLL2 only */266 267/*268 * PLL lock register bits.269 */270#define K210_PLL_LOCK		0271#define K210_PLL_CLEAR_SLIP	2272#define K210_PLL_TEST_OUT	3273 274/*275 * Clock selector register bits.276 */277#define K210_ACLK_SEL		BIT(0)278#define K210_ACLK_DIV		GENMASK(2, 1)279 280/*281 * PLLs.282 */283enum k210_pll_id {284	K210_PLL0, K210_PLL1, K210_PLL2, K210_PLL_NUM285};286 287struct k210_pll {288	enum k210_pll_id id;289	struct k210_sysclk *ksc;290	void __iomem *base;291	void __iomem *reg;292	void __iomem *lock;293	u8 lock_shift;294	u8 lock_width;295	struct clk_hw hw;296};297#define to_k210_pll(_hw)	container_of(_hw, struct k210_pll, hw)298 299/*300 * PLLs configuration: by default PLL0 runs at 780 MHz and PLL1 at 299 MHz.301 * The first 2 SRAM banks depend on ACLK/CPU clock which is by default PLL0302 * rate divided by 2. Set PLL1 to 390 MHz so that the third SRAM bank has the303 * same clock as the first 2.304 */305struct k210_pll_cfg {306	u32 reg;307	u8 lock_shift;308	u8 lock_width;309	u32 r;310	u32 f;311	u32 od;312	u32 bwadj;313};314 315static struct k210_pll_cfg k210_plls_cfg[] = {316	{ K210_SYSCTL_PLL0,  0, 2, 0, 59, 1, 59 }, /* 780 MHz */317	{ K210_SYSCTL_PLL1,  8, 1, 0, 59, 3, 59 }, /* 390 MHz */318	{ K210_SYSCTL_PLL2, 16, 1, 0, 22, 1, 22 }, /* 299 MHz */319};320 321/**322 * struct k210_sysclk - sysclk driver data323 * @regs: system controller registers start address324 * @clk_lock: clock setting spinlock325 * @plls: SoC PLLs descriptors326 * @aclk: ACLK clock327 * @clks: All other clocks328 */329struct k210_sysclk {330	void __iomem			*regs;331	spinlock_t			clk_lock;332	struct k210_pll			plls[K210_PLL_NUM];333	struct clk_hw			aclk;334	struct k210_clk			clks[K210_NUM_CLKS];335};336 337#define to_k210_sysclk(_hw)	container_of(_hw, struct k210_sysclk, aclk)338 339/*340 * Set ACLK parent selector: 0 for IN0, 1 for PLL0.341 */342static void k210_aclk_set_selector(void __iomem *regs, u8 sel)343{344	u32 reg = readl(regs + K210_SYSCTL_SEL0);345 346	if (sel)347		reg |= K210_ACLK_SEL;348	else349		reg &= K210_ACLK_SEL;350	writel(reg, regs + K210_SYSCTL_SEL0);351}352 353static void k210_init_pll(void __iomem *regs, enum k210_pll_id pllid,354			  struct k210_pll *pll)355{356	pll->id = pllid;357	pll->reg = regs + k210_plls_cfg[pllid].reg;358	pll->lock = regs + K210_SYSCTL_PLL_LOCK;359	pll->lock_shift = k210_plls_cfg[pllid].lock_shift;360	pll->lock_width = k210_plls_cfg[pllid].lock_width;361}362 363static void k210_pll_wait_for_lock(struct k210_pll *pll)364{365	u32 reg, mask = GENMASK(pll->lock_shift + pll->lock_width - 1,366				pll->lock_shift);367 368	while (true) {369		reg = readl(pll->lock);370		if ((reg & mask) == mask)371			break;372 373		reg |= BIT(pll->lock_shift + K210_PLL_CLEAR_SLIP);374		writel(reg, pll->lock);375	}376}377 378static bool k210_pll_hw_is_enabled(struct k210_pll *pll)379{380	u32 reg = readl(pll->reg);381	u32 mask = K210_PLL_PWRD | K210_PLL_EN;382 383	if (reg & K210_PLL_RESET)384		return false;385 386	return (reg & mask) == mask;387}388 389static void k210_pll_enable_hw(void __iomem *regs, struct k210_pll *pll)390{391	struct k210_pll_cfg *pll_cfg = &k210_plls_cfg[pll->id];392	u32 reg;393 394	if (k210_pll_hw_is_enabled(pll))395		return;396 397	/*398	 * For PLL0, we need to re-parent ACLK to IN0 to keep the CPU cores and399	 * SRAM running.400	 */401	if (pll->id == K210_PLL0)402		k210_aclk_set_selector(regs, 0);403 404	/* Set PLL factors */405	reg = readl(pll->reg);406	reg &= ~GENMASK(19, 0);407	reg |= FIELD_PREP(K210_PLL_CLKR, pll_cfg->r);408	reg |= FIELD_PREP(K210_PLL_CLKF, pll_cfg->f);409	reg |= FIELD_PREP(K210_PLL_CLKOD, pll_cfg->od);410	reg |= FIELD_PREP(K210_PLL_BWADJ, pll_cfg->bwadj);411	reg |= K210_PLL_PWRD;412	writel(reg, pll->reg);413 414	/*415	 * Reset the PLL: ensure reset is low before asserting it.416	 * The magic NOPs come from the Kendryte reference SDK.417	 */418	reg &= ~K210_PLL_RESET;419	writel(reg, pll->reg);420	reg |= K210_PLL_RESET;421	writel(reg, pll->reg);422	nop();423	nop();424	reg &= ~K210_PLL_RESET;425	writel(reg, pll->reg);426 427	k210_pll_wait_for_lock(pll);428 429	reg &= ~K210_PLL_BYPASS;430	reg |= K210_PLL_EN;431	writel(reg, pll->reg);432 433	if (pll->id == K210_PLL0)434		k210_aclk_set_selector(regs, 1);435}436 437static int k210_pll_enable(struct clk_hw *hw)438{439	struct k210_pll *pll = to_k210_pll(hw);440	struct k210_sysclk *ksc = pll->ksc;441	unsigned long flags;442 443	spin_lock_irqsave(&ksc->clk_lock, flags);444 445	k210_pll_enable_hw(ksc->regs, pll);446 447	spin_unlock_irqrestore(&ksc->clk_lock, flags);448 449	return 0;450}451 452static void k210_pll_disable(struct clk_hw *hw)453{454	struct k210_pll *pll = to_k210_pll(hw);455	struct k210_sysclk *ksc = pll->ksc;456	unsigned long flags;457	u32 reg;458 459	/*460	 * Bypassing before powering off is important so child clocks do not461	 * stop working. This is especially important for pll0, the indirect462	 * parent of the cpu clock.463	 */464	spin_lock_irqsave(&ksc->clk_lock, flags);465	reg = readl(pll->reg);466	reg |= K210_PLL_BYPASS;467	writel(reg, pll->reg);468 469	reg &= ~K210_PLL_PWRD;470	reg &= ~K210_PLL_EN;471	writel(reg, pll->reg);472	spin_unlock_irqrestore(&ksc->clk_lock, flags);473}474 475static int k210_pll_is_enabled(struct clk_hw *hw)476{477	return k210_pll_hw_is_enabled(to_k210_pll(hw));478}479 480static unsigned long k210_pll_get_rate(struct clk_hw *hw,481				       unsigned long parent_rate)482{483	struct k210_pll *pll = to_k210_pll(hw);484	u32 reg = readl(pll->reg);485	u32 r, f, od;486 487	if (reg & K210_PLL_BYPASS)488		return parent_rate;489 490	if (!(reg & K210_PLL_PWRD))491		return 0;492 493	r = FIELD_GET(K210_PLL_CLKR, reg) + 1;494	f = FIELD_GET(K210_PLL_CLKF, reg) + 1;495	od = FIELD_GET(K210_PLL_CLKOD, reg) + 1;496 497	return div_u64((u64)parent_rate * f, r * od);498}499 500static const struct clk_ops k210_pll_ops = {501	.enable		= k210_pll_enable,502	.disable	= k210_pll_disable,503	.is_enabled	= k210_pll_is_enabled,504	.recalc_rate	= k210_pll_get_rate,505};506 507static int k210_pll2_set_parent(struct clk_hw *hw, u8 index)508{509	struct k210_pll *pll = to_k210_pll(hw);510	struct k210_sysclk *ksc = pll->ksc;511	unsigned long flags;512	u32 reg;513 514	spin_lock_irqsave(&ksc->clk_lock, flags);515 516	reg = readl(pll->reg);517	reg &= ~K210_PLL_SEL;518	reg |= FIELD_PREP(K210_PLL_SEL, index);519	writel(reg, pll->reg);520 521	spin_unlock_irqrestore(&ksc->clk_lock, flags);522 523	return 0;524}525 526static u8 k210_pll2_get_parent(struct clk_hw *hw)527{528	struct k210_pll *pll = to_k210_pll(hw);529	u32 reg = readl(pll->reg);530 531	return FIELD_GET(K210_PLL_SEL, reg);532}533 534static const struct clk_ops k210_pll2_ops = {535	.enable		= k210_pll_enable,536	.disable	= k210_pll_disable,537	.is_enabled	= k210_pll_is_enabled,538	.recalc_rate	= k210_pll_get_rate,539	.determine_rate = clk_hw_determine_rate_no_reparent,540	.set_parent	= k210_pll2_set_parent,541	.get_parent	= k210_pll2_get_parent,542};543 544static int __init k210_register_pll(struct device_node *np,545				    struct k210_sysclk *ksc,546				    enum k210_pll_id pllid, const char *name,547				    int num_parents, const struct clk_ops *ops)548{549	struct k210_pll *pll = &ksc->plls[pllid];550	struct clk_init_data init = {};551	const struct clk_parent_data parent_data[] = {552		{ /* .index = 0 for in0 */ },553		{ .hw = &ksc->plls[K210_PLL0].hw },554		{ .hw = &ksc->plls[K210_PLL1].hw },555	};556 557	init.name = name;558	init.parent_data = parent_data;559	init.num_parents = num_parents;560	init.ops = ops;561 562	pll->hw.init = &init;563	pll->ksc = ksc;564 565	return of_clk_hw_register(np, &pll->hw);566}567 568static int __init k210_register_plls(struct device_node *np,569				     struct k210_sysclk *ksc)570{571	int i, ret;572 573	for (i = 0; i < K210_PLL_NUM; i++)574		k210_init_pll(ksc->regs, i, &ksc->plls[i]);575 576	/* PLL0 and PLL1 only have IN0 as parent */577	ret = k210_register_pll(np, ksc, K210_PLL0, "pll0", 1, &k210_pll_ops);578	if (ret) {579		pr_err("%pOFP: register PLL0 failed\n", np);580		return ret;581	}582	ret = k210_register_pll(np, ksc, K210_PLL1, "pll1", 1, &k210_pll_ops);583	if (ret) {584		pr_err("%pOFP: register PLL1 failed\n", np);585		return ret;586	}587 588	/* PLL2 has IN0, PLL0 and PLL1 as parents */589	ret = k210_register_pll(np, ksc, K210_PLL2, "pll2", 3, &k210_pll2_ops);590	if (ret) {591		pr_err("%pOFP: register PLL2 failed\n", np);592		return ret;593	}594 595	return 0;596}597 598static int k210_aclk_set_parent(struct clk_hw *hw, u8 index)599{600	struct k210_sysclk *ksc = to_k210_sysclk(hw);601	unsigned long flags;602 603	spin_lock_irqsave(&ksc->clk_lock, flags);604 605	k210_aclk_set_selector(ksc->regs, index);606 607	spin_unlock_irqrestore(&ksc->clk_lock, flags);608 609	return 0;610}611 612static u8 k210_aclk_get_parent(struct clk_hw *hw)613{614	struct k210_sysclk *ksc = to_k210_sysclk(hw);615	u32 sel;616 617	sel = readl(ksc->regs + K210_SYSCTL_SEL0) & K210_ACLK_SEL;618 619	return sel ? 1 : 0;620}621 622static unsigned long k210_aclk_get_rate(struct clk_hw *hw,623					unsigned long parent_rate)624{625	struct k210_sysclk *ksc = to_k210_sysclk(hw);626	u32 reg = readl(ksc->regs + K210_SYSCTL_SEL0);627	unsigned int shift;628 629	if (!(reg & 0x1))630		return parent_rate;631 632	shift = FIELD_GET(K210_ACLK_DIV, reg);633 634	return parent_rate / (2UL << shift);635}636 637static const struct clk_ops k210_aclk_ops = {638	.determine_rate = clk_hw_determine_rate_no_reparent,639	.set_parent	= k210_aclk_set_parent,640	.get_parent	= k210_aclk_get_parent,641	.recalc_rate	= k210_aclk_get_rate,642};643 644/*645 * ACLK has IN0 and PLL0 as parents.646 */647static int __init k210_register_aclk(struct device_node *np,648				     struct k210_sysclk *ksc)649{650	struct clk_init_data init = {};651	const struct clk_parent_data parent_data[] = {652		{ /* .index = 0 for in0 */ },653		{ .hw = &ksc->plls[K210_PLL0].hw },654	};655	int ret;656 657	init.name = "aclk";658	init.parent_data = parent_data;659	init.num_parents = 2;660	init.ops = &k210_aclk_ops;661	ksc->aclk.init = &init;662 663	ret = of_clk_hw_register(np, &ksc->aclk);664	if (ret) {665		pr_err("%pOFP: register aclk failed\n", np);666		return ret;667	}668 669	return 0;670}671 672#define to_k210_clk(_hw)	container_of(_hw, struct k210_clk, hw)673 674static int k210_clk_enable(struct clk_hw *hw)675{676	struct k210_clk *kclk = to_k210_clk(hw);677	struct k210_sysclk *ksc = kclk->ksc;678	struct k210_clk_cfg *cfg = &k210_clk_cfgs[kclk->id];679	unsigned long flags;680	u32 reg;681 682	if (!cfg->gate_reg)683		return 0;684 685	spin_lock_irqsave(&ksc->clk_lock, flags);686	reg = readl(ksc->regs + cfg->gate_reg);687	reg |= BIT(cfg->gate_bit);688	writel(reg, ksc->regs + cfg->gate_reg);689	spin_unlock_irqrestore(&ksc->clk_lock, flags);690 691	return 0;692}693 694static void k210_clk_disable(struct clk_hw *hw)695{696	struct k210_clk *kclk = to_k210_clk(hw);697	struct k210_sysclk *ksc = kclk->ksc;698	struct k210_clk_cfg *cfg = &k210_clk_cfgs[kclk->id];699	unsigned long flags;700	u32 reg;701 702	if (!cfg->gate_reg)703		return;704 705	spin_lock_irqsave(&ksc->clk_lock, flags);706	reg = readl(ksc->regs + cfg->gate_reg);707	reg &= ~BIT(cfg->gate_bit);708	writel(reg, ksc->regs + cfg->gate_reg);709	spin_unlock_irqrestore(&ksc->clk_lock, flags);710}711 712static int k210_clk_set_parent(struct clk_hw *hw, u8 index)713{714	struct k210_clk *kclk = to_k210_clk(hw);715	struct k210_sysclk *ksc = kclk->ksc;716	struct k210_clk_cfg *cfg = &k210_clk_cfgs[kclk->id];717	unsigned long flags;718	u32 reg;719 720	spin_lock_irqsave(&ksc->clk_lock, flags);721	reg = readl(ksc->regs + cfg->mux_reg);722	if (index)723		reg |= BIT(cfg->mux_bit);724	else725		reg &= ~BIT(cfg->mux_bit);726	writel(reg, ksc->regs + cfg->mux_reg);727	spin_unlock_irqrestore(&ksc->clk_lock, flags);728 729	return 0;730}731 732static u8 k210_clk_get_parent(struct clk_hw *hw)733{734	struct k210_clk *kclk = to_k210_clk(hw);735	struct k210_sysclk *ksc = kclk->ksc;736	struct k210_clk_cfg *cfg = &k210_clk_cfgs[kclk->id];737	unsigned long flags;738	u32 reg, idx;739 740	spin_lock_irqsave(&ksc->clk_lock, flags);741	reg = readl(ksc->regs + cfg->mux_reg);742	idx = (reg & BIT(cfg->mux_bit)) ? 1 : 0;743	spin_unlock_irqrestore(&ksc->clk_lock, flags);744 745	return idx;746}747 748static unsigned long k210_clk_get_rate(struct clk_hw *hw,749				       unsigned long parent_rate)750{751	struct k210_clk *kclk = to_k210_clk(hw);752	struct k210_sysclk *ksc = kclk->ksc;753	struct k210_clk_cfg *cfg = &k210_clk_cfgs[kclk->id];754	u32 reg, div_val;755 756	if (!cfg->div_reg)757		return parent_rate;758 759	reg = readl(ksc->regs + cfg->div_reg);760	div_val = (reg >> cfg->div_shift) & GENMASK(cfg->div_width - 1, 0);761 762	switch (cfg->div_type) {763	case K210_DIV_ONE_BASED:764		return parent_rate / (div_val + 1);765	case K210_DIV_DOUBLE_ONE_BASED:766		return parent_rate / ((div_val + 1) * 2);767	case K210_DIV_POWER_OF_TWO:768		return parent_rate / (2UL << div_val);769	case K210_DIV_NONE:770	default:771		return 0;772	}773}774 775static const struct clk_ops k210_clk_mux_ops = {776	.enable		= k210_clk_enable,777	.disable	= k210_clk_disable,778	.determine_rate = clk_hw_determine_rate_no_reparent,779	.set_parent	= k210_clk_set_parent,780	.get_parent	= k210_clk_get_parent,781	.recalc_rate	= k210_clk_get_rate,782};783 784static const struct clk_ops k210_clk_ops = {785	.enable		= k210_clk_enable,786	.disable	= k210_clk_disable,787	.recalc_rate	= k210_clk_get_rate,788};789 790static void __init k210_register_clk(struct device_node *np,791				     struct k210_sysclk *ksc, int id,792				     const struct clk_parent_data *parent_data,793				     int num_parents, unsigned long flags)794{795	struct k210_clk *kclk = &ksc->clks[id];796	struct clk_init_data init = {};797	int ret;798 799	init.name = k210_clk_cfgs[id].name;800	init.flags = flags;801	init.parent_data = parent_data;802	init.num_parents = num_parents;803	if (num_parents > 1)804		init.ops = &k210_clk_mux_ops;805	else806		init.ops = &k210_clk_ops;807 808	kclk->id = id;809	kclk->ksc = ksc;810	kclk->hw.init = &init;811 812	ret = of_clk_hw_register(np, &kclk->hw);813	if (ret) {814		pr_err("%pOFP: register clock %s failed\n",815		       np, k210_clk_cfgs[id].name);816		kclk->id = -1;817	}818}819 820/*821 * All muxed clocks have IN0 and PLL0 as parents.822 */823static inline void __init k210_register_mux_clk(struct device_node *np,824						struct k210_sysclk *ksc, int id)825{826	const struct clk_parent_data parent_data[2] = {827		{ /* .index = 0 for in0 */ },828		{ .hw = &ksc->plls[K210_PLL0].hw }829	};830 831	k210_register_clk(np, ksc, id, parent_data, 2, 0);832}833 834static inline void __init k210_register_in0_child(struct device_node *np,835						struct k210_sysclk *ksc, int id)836{837	const struct clk_parent_data parent_data = {838		/* .index = 0 for in0 */839	};840 841	k210_register_clk(np, ksc, id, &parent_data, 1, 0);842}843 844static inline void __init k210_register_pll_child(struct device_node *np,845						struct k210_sysclk *ksc, int id,846						enum k210_pll_id pllid,847						unsigned long flags)848{849	const struct clk_parent_data parent_data = {850		.hw = &ksc->plls[pllid].hw,851	};852 853	k210_register_clk(np, ksc, id, &parent_data, 1, flags);854}855 856static inline void __init k210_register_aclk_child(struct device_node *np,857						struct k210_sysclk *ksc, int id,858						unsigned long flags)859{860	const struct clk_parent_data parent_data = {861		.hw = &ksc->aclk,862	};863 864	k210_register_clk(np, ksc, id, &parent_data, 1, flags);865}866 867static inline void __init k210_register_clk_child(struct device_node *np,868						struct k210_sysclk *ksc, int id,869						int parent_id)870{871	const struct clk_parent_data parent_data = {872		.hw = &ksc->clks[parent_id].hw,873	};874 875	k210_register_clk(np, ksc, id, &parent_data, 1, 0);876}877 878static struct clk_hw *k210_clk_hw_onecell_get(struct of_phandle_args *clkspec,879					      void *data)880{881	struct k210_sysclk *ksc = data;882	unsigned int idx = clkspec->args[0];883 884	if (idx >= K210_NUM_CLKS)885		return ERR_PTR(-EINVAL);886 887	return &ksc->clks[idx].hw;888}889 890static void __init k210_clk_init(struct device_node *np)891{892	struct device_node *sysctl_np;893	struct k210_sysclk *ksc;894	int i, ret;895 896	ksc = kzalloc(sizeof(*ksc), GFP_KERNEL);897	if (!ksc)898		return;899 900	spin_lock_init(&ksc->clk_lock);901	sysctl_np = of_get_parent(np);902	ksc->regs = of_iomap(sysctl_np, 0);903	of_node_put(sysctl_np);904	if (!ksc->regs) {905		pr_err("%pOFP: failed to map registers\n", np);906		return;907	}908 909	ret = k210_register_plls(np, ksc);910	if (ret)911		return;912 913	ret = k210_register_aclk(np, ksc);914	if (ret)915		return;916 917	/*918	 * Critical clocks: there are no consumers of the SRAM clocks,919	 * including the AI clock for the third SRAM bank. The CPU clock920	 * is only referenced by the uarths serial device and so would be921	 * disabled if the serial console is disabled to switch to another922	 * console. Mark all these clocks as critical so that they are never923	 * disabled by the core clock management.924	 */925	k210_register_aclk_child(np, ksc, K210_CLK_CPU, CLK_IS_CRITICAL);926	k210_register_aclk_child(np, ksc, K210_CLK_SRAM0, CLK_IS_CRITICAL);927	k210_register_aclk_child(np, ksc, K210_CLK_SRAM1, CLK_IS_CRITICAL);928	k210_register_pll_child(np, ksc, K210_CLK_AI, K210_PLL1,929				CLK_IS_CRITICAL);930 931	/* Clocks with aclk as source */932	k210_register_aclk_child(np, ksc, K210_CLK_DMA, 0);933	k210_register_aclk_child(np, ksc, K210_CLK_FFT, 0);934	k210_register_aclk_child(np, ksc, K210_CLK_ROM, 0);935	k210_register_aclk_child(np, ksc, K210_CLK_DVP, 0);936	k210_register_aclk_child(np, ksc, K210_CLK_APB0, 0);937	k210_register_aclk_child(np, ksc, K210_CLK_APB1, 0);938	k210_register_aclk_child(np, ksc, K210_CLK_APB2, 0);939 940	/* Clocks with PLL0 as source */941	k210_register_pll_child(np, ksc, K210_CLK_SPI0, K210_PLL0, 0);942	k210_register_pll_child(np, ksc, K210_CLK_SPI1, K210_PLL0, 0);943	k210_register_pll_child(np, ksc, K210_CLK_SPI2, K210_PLL0, 0);944	k210_register_pll_child(np, ksc, K210_CLK_I2C0, K210_PLL0, 0);945	k210_register_pll_child(np, ksc, K210_CLK_I2C1, K210_PLL0, 0);946	k210_register_pll_child(np, ksc, K210_CLK_I2C2, K210_PLL0, 0);947 948	/* Clocks with PLL2 as source */949	k210_register_pll_child(np, ksc, K210_CLK_I2S0, K210_PLL2, 0);950	k210_register_pll_child(np, ksc, K210_CLK_I2S1, K210_PLL2, 0);951	k210_register_pll_child(np, ksc, K210_CLK_I2S2, K210_PLL2, 0);952	k210_register_pll_child(np, ksc, K210_CLK_I2S0_M, K210_PLL2, 0);953	k210_register_pll_child(np, ksc, K210_CLK_I2S1_M, K210_PLL2, 0);954	k210_register_pll_child(np, ksc, K210_CLK_I2S2_M, K210_PLL2, 0);955 956	/* Clocks with IN0 as source */957	k210_register_in0_child(np, ksc, K210_CLK_WDT0);958	k210_register_in0_child(np, ksc, K210_CLK_WDT1);959	k210_register_in0_child(np, ksc, K210_CLK_RTC);960 961	/* Clocks with APB0 as source */962	k210_register_clk_child(np, ksc, K210_CLK_GPIO, K210_CLK_APB0);963	k210_register_clk_child(np, ksc, K210_CLK_UART1, K210_CLK_APB0);964	k210_register_clk_child(np, ksc, K210_CLK_UART2, K210_CLK_APB0);965	k210_register_clk_child(np, ksc, K210_CLK_UART3, K210_CLK_APB0);966	k210_register_clk_child(np, ksc, K210_CLK_FPIOA, K210_CLK_APB0);967	k210_register_clk_child(np, ksc, K210_CLK_SHA, K210_CLK_APB0);968 969	/* Clocks with APB1 as source */970	k210_register_clk_child(np, ksc, K210_CLK_AES, K210_CLK_APB1);971	k210_register_clk_child(np, ksc, K210_CLK_OTP, K210_CLK_APB1);972 973	/* Mux clocks with in0 or pll0 as source */974	k210_register_mux_clk(np, ksc, K210_CLK_SPI3);975	k210_register_mux_clk(np, ksc, K210_CLK_TIMER0);976	k210_register_mux_clk(np, ksc, K210_CLK_TIMER1);977	k210_register_mux_clk(np, ksc, K210_CLK_TIMER2);978 979	/* Check for registration errors */980	for (i = 0; i < K210_NUM_CLKS; i++) {981		if (ksc->clks[i].id != i)982			return;983	}984 985	ret = of_clk_add_hw_provider(np, k210_clk_hw_onecell_get, ksc);986	if (ret) {987		pr_err("%pOFP: add clock provider failed %d\n", np, ret);988		return;989	}990 991	pr_info("%pOFP: CPU running at %lu MHz\n",992		np, clk_hw_get_rate(&ksc->clks[K210_CLK_CPU].hw) / 1000000);993}994 995CLK_OF_DECLARE(k210_clk, "canaan,k210-clk", k210_clk_init);996 997/*998 * Enable PLL1 to be able to use the AI SRAM.999 */1000void __init k210_clk_early_init(void __iomem *regs)1001{1002	struct k210_pll pll1;1003 1004	/* Make sure ACLK selector is set to PLL0 */1005	k210_aclk_set_selector(regs, 1);1006 1007	/* Startup PLL1 to enable the aisram bank for general memory use */1008	k210_init_pll(regs, K210_PLL1, &pll1);1009	k210_pll_enable_hw(regs, &pll1);1010}1011