Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) // Copyright IBM Corp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #define pr_fmt(fmt) "clk-aspeed: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <dt-bindings/clock/aspeed-clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "clk-aspeed.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define ASPEED_NUM_CLKS		38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define ASPEED_RESET2_OFFSET	32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define ASPEED_RESET_CTRL	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define ASPEED_CLK_SELECTION	0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define ASPEED_CLK_STOP_CTRL	0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define ASPEED_MPLL_PARAM	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define ASPEED_HPLL_PARAM	0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define  AST2500_HPLL_BYPASS_EN	BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define  AST2400_HPLL_PROGRAMMED BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define  AST2400_HPLL_BYPASS_EN	BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define ASPEED_MISC_CTRL	0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define  UART_DIV13_EN		BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define ASPEED_MAC_CLK_DLY	0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define ASPEED_STRAP		0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define  CLKIN_25MHZ_EN		BIT(23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define  AST2400_CLK_SOURCE_SEL	BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define ASPEED_CLK_SELECTION_2	0xd8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define ASPEED_RESET_CTRL2	0xd4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /* Globally visible clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static DEFINE_SPINLOCK(aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) /* Keeps track of all clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static struct clk_hw_onecell_data *aspeed_clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static void __iomem *scu_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) /* TODO: ask Aspeed about the actual parent data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static const struct aspeed_gate_data aspeed_gates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	/*				 clk rst   name			parent	flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	[ASPEED_CLK_GATE_ECLK] =	{  0,  6, "eclk-gate",		"eclk",	0 }, /* Video Engine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	[ASPEED_CLK_GATE_GCLK] =	{  1,  7, "gclk-gate",		NULL,	0 }, /* 2D engine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	[ASPEED_CLK_GATE_MCLK] =	{  2, -1, "mclk-gate",		"mpll",	CLK_IS_CRITICAL }, /* SDRAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	[ASPEED_CLK_GATE_VCLK] =	{  3, -1, "vclk-gate",		NULL,	0 }, /* Video Capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	[ASPEED_CLK_GATE_BCLK] =	{  4,  8, "bclk-gate",		"bclk",	CLK_IS_CRITICAL }, /* PCIe/PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	[ASPEED_CLK_GATE_DCLK] =	{  5, -1, "dclk-gate",		NULL,	CLK_IS_CRITICAL }, /* DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	[ASPEED_CLK_GATE_REFCLK] =	{  6, -1, "refclk-gate",	"clkin", CLK_IS_CRITICAL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	[ASPEED_CLK_GATE_USBPORT2CLK] =	{  7,  3, "usb-port2-gate",	NULL,	0 }, /* USB2.0 Host port 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	[ASPEED_CLK_GATE_LCLK] =	{  8,  5, "lclk-gate",		NULL,	0 }, /* LPC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	[ASPEED_CLK_GATE_USBUHCICLK] =	{  9, 15, "usb-uhci-gate",	NULL,	0 }, /* USB1.1 (requires port 2 enabled) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	[ASPEED_CLK_GATE_D1CLK] =	{ 10, 13, "d1clk-gate",		NULL,	0 }, /* GFX CRT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	[ASPEED_CLK_GATE_YCLK] =	{ 13,  4, "yclk-gate",		NULL,	0 }, /* HAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	[ASPEED_CLK_GATE_USBPORT1CLK] = { 14, 14, "usb-port1-gate",	NULL,	0 }, /* USB2 hub/USB2 host port 1/USB1.1 dev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	[ASPEED_CLK_GATE_UART1CLK] =	{ 15, -1, "uart1clk-gate",	"uart",	0 }, /* UART1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	[ASPEED_CLK_GATE_UART2CLK] =	{ 16, -1, "uart2clk-gate",	"uart",	0 }, /* UART2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	[ASPEED_CLK_GATE_UART5CLK] =	{ 17, -1, "uart5clk-gate",	"uart",	0 }, /* UART5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	[ASPEED_CLK_GATE_ESPICLK] =	{ 19, -1, "espiclk-gate",	NULL,	0 }, /* eSPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	[ASPEED_CLK_GATE_MAC1CLK] =	{ 20, 11, "mac1clk-gate",	"mac",	0 }, /* MAC1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	[ASPEED_CLK_GATE_MAC2CLK] =	{ 21, 12, "mac2clk-gate",	"mac",	0 }, /* MAC2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	[ASPEED_CLK_GATE_RSACLK] =	{ 24, -1, "rsaclk-gate",	NULL,	0 }, /* RSA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	[ASPEED_CLK_GATE_UART3CLK] =	{ 25, -1, "uart3clk-gate",	"uart",	0 }, /* UART3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	[ASPEED_CLK_GATE_UART4CLK] =	{ 26, -1, "uart4clk-gate",	"uart",	0 }, /* UART4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	[ASPEED_CLK_GATE_SDCLK] =	{ 27, 16, "sdclk-gate",		NULL,	0 }, /* SDIO/SD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	[ASPEED_CLK_GATE_LHCCLK] =	{ 28, -1, "lhclk-gate",		"lhclk", 0 }, /* LPC master/LPC+ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static const char * const eclk_parent_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	"mpll",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	"hpll",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	"dpll",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static const struct clk_div_table ast2500_eclk_div_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	{ 0x0, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	{ 0x1, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	{ 0x2, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	{ 0x3, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	{ 0x4, 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	{ 0x5, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	{ 0x6, 7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	{ 0x7, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	{ 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static const struct clk_div_table ast2500_mac_div_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	{ 0x0, 4 }, /* Yep, really. Aspeed confirmed this is correct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	{ 0x1, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	{ 0x2, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	{ 0x3, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	{ 0x4, 10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	{ 0x5, 12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	{ 0x6, 14 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	{ 0x7, 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	{ 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static const struct clk_div_table ast2400_div_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	{ 0x0, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	{ 0x1, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	{ 0x2, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	{ 0x3, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	{ 0x4, 10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	{ 0x5, 12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	{ 0x6, 14 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	{ 0x7, 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	{ 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static const struct clk_div_table ast2500_div_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	{ 0x0, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	{ 0x1, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	{ 0x2, 12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	{ 0x3, 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	{ 0x4, 20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	{ 0x5, 24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	{ 0x6, 28 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	{ 0x7, 32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	{ 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static struct clk_hw *aspeed_ast2400_calc_pll(const char *name, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	unsigned int mult, div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (val & AST2400_HPLL_BYPASS_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		/* Pass through mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		mult = div = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		/* F = 24Mhz * (2-OD) * [(N + 2) / (D + 1)] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		u32 n = (val >> 5) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		u32 od = (val >> 4) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		u32 d = val & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		mult = (2 - od) * (n + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		div = d + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return clk_hw_register_fixed_factor(NULL, name, "clkin", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			mult, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static struct clk_hw *aspeed_ast2500_calc_pll(const char *name, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	unsigned int mult, div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (val & AST2500_HPLL_BYPASS_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		/* Pass through mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		mult = div = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		/* F = clkin * [(M+1) / (N+1)] / (P + 1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		u32 p = (val >> 13) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		u32 m = (val >> 5) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		u32 n = val & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		mult = (m + 1) / (n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		div = p + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	return clk_hw_register_fixed_factor(NULL, name, "clkin", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			mult, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static const struct aspeed_clk_soc_data ast2500_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	.div_table = ast2500_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	.eclk_div_table = ast2500_eclk_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	.mac_div_table = ast2500_mac_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	.calc_pll = aspeed_ast2500_calc_pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static const struct aspeed_clk_soc_data ast2400_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	.div_table = ast2400_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	.eclk_div_table = ast2400_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	.mac_div_table = ast2400_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	.calc_pll = aspeed_ast2400_calc_pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static int aspeed_clk_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	u32 clk = BIT(gate->clock_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	u32 rst = BIT(gate->reset_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	u32 enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	 * If the IP is in reset, treat the clock as not enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	 * this happens with some clocks such as the USB one when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	 * coming from cold reset. Without this, aspeed_clk_enable()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	 * will fail to lift the reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (gate->reset_idx >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		regmap_read(gate->map, ASPEED_RESET_CTRL, &reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		if (reg & rst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, &reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	return ((reg & clk) == enval) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static int aspeed_clk_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	u32 clk = BIT(gate->clock_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	u32 rst = BIT(gate->reset_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	u32 enval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	spin_lock_irqsave(gate->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (aspeed_clk_is_enabled(hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		spin_unlock_irqrestore(gate->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (gate->reset_idx >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		/* Put IP in reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		/* Delay 100us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	/* Enable clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, enval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (gate->reset_idx >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		/* A delay of 10ms is specified by the ASPEED docs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		/* Take IP out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	spin_unlock_irqrestore(gate->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static void aspeed_clk_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	u32 clk = BIT(gate->clock_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	u32 enval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	spin_lock_irqsave(gate->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? clk : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, enval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	spin_unlock_irqrestore(gate->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static const struct clk_ops aspeed_clk_gate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	.enable = aspeed_clk_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	.disable = aspeed_clk_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	.is_enabled = aspeed_clk_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static const u8 aspeed_resets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	/* SCU04 resets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	[ASPEED_RESET_XDMA]	= 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	[ASPEED_RESET_MCTP]	= 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	[ASPEED_RESET_ADC]	= 23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	[ASPEED_RESET_JTAG_MASTER] = 22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	[ASPEED_RESET_MIC]	= 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	[ASPEED_RESET_PWM]	=  9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	[ASPEED_RESET_PECI]	= 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	[ASPEED_RESET_I2C]	=  2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	[ASPEED_RESET_AHB]	=  1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	 * SCUD4 resets start at an offset to separate them from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	 * the SCU04 resets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	[ASPEED_RESET_CRT1]	= ASPEED_RESET2_OFFSET + 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int aspeed_reset_deassert(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 				 unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	struct aspeed_reset *ar = to_aspeed_reset(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	u32 reg = ASPEED_RESET_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	u32 bit = aspeed_resets[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	if (bit >= ASPEED_RESET2_OFFSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		bit -= ASPEED_RESET2_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		reg = ASPEED_RESET_CTRL2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	return regmap_update_bits(ar->map, reg, BIT(bit), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int aspeed_reset_assert(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			       unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	struct aspeed_reset *ar = to_aspeed_reset(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	u32 reg = ASPEED_RESET_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	u32 bit = aspeed_resets[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	if (bit >= ASPEED_RESET2_OFFSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		bit -= ASPEED_RESET2_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		reg = ASPEED_RESET_CTRL2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	return regmap_update_bits(ar->map, reg, BIT(bit), BIT(bit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static int aspeed_reset_status(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			       unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	struct aspeed_reset *ar = to_aspeed_reset(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	u32 reg = ASPEED_RESET_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	u32 bit = aspeed_resets[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	int ret, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	if (bit >= ASPEED_RESET2_OFFSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		bit -= ASPEED_RESET2_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		reg = ASPEED_RESET_CTRL2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	ret = regmap_read(ar->map, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	return !!(val & BIT(bit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static const struct reset_control_ops aspeed_reset_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	.assert = aspeed_reset_assert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	.deassert = aspeed_reset_deassert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	.status = aspeed_reset_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static struct clk_hw *aspeed_clk_hw_register_gate(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		const char *name, const char *parent_name, unsigned long flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		struct regmap *map, u8 clock_idx, u8 reset_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		u8 clk_gate_flags, spinlock_t *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	struct aspeed_clk_gate *gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	if (!gate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	init.ops = &aspeed_clk_gate_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	init.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	init.parent_names = parent_name ? &parent_name : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	init.num_parents = parent_name ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	gate->map = map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	gate->clock_idx = clock_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	gate->reset_idx = reset_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	gate->flags = clk_gate_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	gate->lock = lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	gate->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	hw = &gate->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	ret = clk_hw_register(dev, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		kfree(gate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		hw = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static int aspeed_clk_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	const struct aspeed_clk_soc_data *soc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	struct aspeed_reset *ar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	struct regmap *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	u32 val, rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	map = syscon_node_to_regmap(dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	if (IS_ERR(map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		dev_err(dev, "no syscon regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		return PTR_ERR(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	ar = devm_kzalloc(dev, sizeof(*ar), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	if (!ar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	ar->map = map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	ar->rcdev.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	ar->rcdev.nr_resets = ARRAY_SIZE(aspeed_resets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	ar->rcdev.ops = &aspeed_reset_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	ar->rcdev.of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	ret = devm_reset_controller_register(dev, &ar->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		dev_err(dev, "could not register reset controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	/* SoC generations share common layouts but have different divisors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	soc_data = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	if (!soc_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		dev_err(dev, "no match data for platform\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	/* UART clock div13 setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	regmap_read(map, ASPEED_MISC_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	if (val & UART_DIV13_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		rate = 24000000 / 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		rate = 24000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	/* TODO: Find the parent data for the uart clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	hw = clk_hw_register_fixed_rate(dev, "uart", NULL, 0, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	aspeed_clk_data->hws[ASPEED_CLK_UART] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	 * Memory controller (M-PLL) PLL. This clock is configured by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	 * bootloader, and is exposed to Linux as a read-only clock rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	regmap_read(map, ASPEED_MPLL_PARAM, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	hw = soc_data->calc_pll("mpll", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	aspeed_clk_data->hws[ASPEED_CLK_MPLL] =	hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	/* SD/SDIO clock divider and gate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	hw = clk_hw_register_gate(dev, "sd_extclk_gate", "hpll", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 				  scu_base + ASPEED_CLK_SELECTION, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 				  &aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	hw = clk_hw_register_divider_table(dev, "sd_extclk", "sd_extclk_gate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			0, scu_base + ASPEED_CLK_SELECTION, 12, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			soc_data->div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			&aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	aspeed_clk_data->hws[ASPEED_CLK_SDIO] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	/* MAC AHB bus clock divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	hw = clk_hw_register_divider_table(dev, "mac", "hpll", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			scu_base + ASPEED_CLK_SELECTION, 16, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			soc_data->mac_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			&aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	aspeed_clk_data->hws[ASPEED_CLK_MAC] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-scu")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		/* RMII 50MHz RCLK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		hw = clk_hw_register_fixed_rate(dev, "mac12rclk", "hpll", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 						50000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		/* RMII1 50MHz (RCLK) output enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		hw = clk_hw_register_gate(dev, "mac1rclk", "mac12rclk", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 				scu_base + ASPEED_MAC_CLK_DLY, 29, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 				&aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		aspeed_clk_data->hws[ASPEED_CLK_MAC1RCLK] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		/* RMII2 50MHz (RCLK) output enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		hw = clk_hw_register_gate(dev, "mac2rclk", "mac12rclk", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 				scu_base + ASPEED_MAC_CLK_DLY, 30, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 				&aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		aspeed_clk_data->hws[ASPEED_CLK_MAC2RCLK] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	/* LPC Host (LHCLK) clock divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			scu_base + ASPEED_CLK_SELECTION, 20, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			soc_data->div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 			&aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	aspeed_clk_data->hws[ASPEED_CLK_LHCLK] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	/* P-Bus (BCLK) clock divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			scu_base + ASPEED_CLK_SELECTION_2, 0, 2, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 			soc_data->div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			&aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	aspeed_clk_data->hws[ASPEED_CLK_BCLK] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	/* Fixed 24MHz clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	hw = clk_hw_register_fixed_rate(NULL, "fixed-24m", "clkin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 					0, 24000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	aspeed_clk_data->hws[ASPEED_CLK_24M] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	hw = clk_hw_register_mux(dev, "eclk-mux", eclk_parent_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 				 ARRAY_SIZE(eclk_parent_names), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 				 scu_base + ASPEED_CLK_SELECTION, 2, 0x3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 				 &aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	aspeed_clk_data->hws[ASPEED_CLK_ECLK_MUX] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	hw = clk_hw_register_divider_table(dev, "eclk", "eclk-mux", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 					   scu_base + ASPEED_CLK_SELECTION, 28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 					   3, 0, soc_data->eclk_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 					   &aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	aspeed_clk_data->hws[ASPEED_CLK_ECLK] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	 * TODO: There are a number of clocks that not included in this driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	 * as more information is required:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	 *   D2-PLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	 *   D-PLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	 *   YCLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	 *   RGMII
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	 *   RMII
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	 *   UART[1..5] clock source mux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	for (i = 0; i < ARRAY_SIZE(aspeed_gates); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		const struct aspeed_gate_data *gd = &aspeed_gates[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		u32 gate_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		/* Special case: the USB port 1 clock (bit 14) is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		 * working the opposite way from the other ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		gate_flags = (gd->clock_idx == 14) ? 0 : CLK_GATE_SET_TO_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		hw = aspeed_clk_hw_register_gate(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 				gd->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 				gd->parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 				gd->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 				map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 				gd->clock_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 				gd->reset_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 				gate_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 				&aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 			return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		aspeed_clk_data->hws[i] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static const struct of_device_id aspeed_clk_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	{ .compatible = "aspeed,ast2400-scu", .data = &ast2400_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	{ .compatible = "aspeed,ast2500-scu", .data = &ast2500_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static struct platform_driver aspeed_clk_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	.probe  = aspeed_clk_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		.name = "aspeed-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		.of_match_table = aspeed_clk_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		.suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) builtin_platform_driver(aspeed_clk_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static void __init aspeed_ast2400_cc(struct regmap *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	u32 val, div, clkin, hpll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	const u16 hpll_rates[][4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		{384, 360, 336, 408},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		{400, 375, 350, 425},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	 * CLKIN is the crystal oscillator, 24, 48 or 25MHz selected by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	 * strapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	regmap_read(map, ASPEED_STRAP, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	rate = (val >> 8) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	if (val & CLKIN_25MHZ_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		clkin = 25000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		hpll = hpll_rates[1][rate];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	} else if (val & AST2400_CLK_SOURCE_SEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		clkin = 48000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		hpll = hpll_rates[0][rate];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		clkin = 24000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		hpll = hpll_rates[0][rate];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	hw = clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, clkin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	pr_debug("clkin @%u MHz\n", clkin / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	 * High-speed PLL clock derived from the crystal. This the CPU clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	 * and we assume that it is enabled. It can be configured through the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	 * HPLL_PARAM register, or set to a specified frequency by strapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	regmap_read(map, ASPEED_HPLL_PARAM, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	if (val & AST2400_HPLL_PROGRAMMED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		hw = aspeed_ast2400_calc_pll("hpll", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		hw = clk_hw_register_fixed_rate(NULL, "hpll", "clkin", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 				hpll * 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	aspeed_clk_data->hws[ASPEED_CLK_HPLL] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	 * Strap bits 11:10 define the CPU/AHB clock frequency ratio (aka HCLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	 *   00: Select CPU:AHB = 1:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	 *   01: Select CPU:AHB = 2:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	 *   10: Select CPU:AHB = 4:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	 *   11: Select CPU:AHB = 3:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	regmap_read(map, ASPEED_STRAP, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	val = (val >> 10) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	div = val + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	if (div == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		div = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	else if (div == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		div = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	aspeed_clk_data->hws[ASPEED_CLK_AHB] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	/* APB clock clock selection register SCU08 (aka PCLK) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	hw = clk_hw_register_divider_table(NULL, "apb", "hpll", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 			scu_base + ASPEED_CLK_SELECTION, 23, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 			ast2400_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 			&aspeed_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	aspeed_clk_data->hws[ASPEED_CLK_APB] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static void __init aspeed_ast2500_cc(struct regmap *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	u32 val, freq, div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	/* CLKIN is the crystal oscillator, 24 or 25MHz selected by strapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	regmap_read(map, ASPEED_STRAP, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	if (val & CLKIN_25MHZ_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		freq = 25000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		freq = 24000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	hw = clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	pr_debug("clkin @%u MHz\n", freq / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	 * High-speed PLL clock derived from the crystal. This the CPU clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	 * and we assume that it is enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	regmap_read(map, ASPEED_HPLL_PARAM, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	aspeed_clk_data->hws[ASPEED_CLK_HPLL] = aspeed_ast2500_calc_pll("hpll", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	/* Strap bits 11:9 define the AXI/AHB clock frequency ratio (aka HCLK)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	regmap_read(map, ASPEED_STRAP, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	val = (val >> 9) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	WARN(val == 0, "strapping is zero: cannot determine ahb clock");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	div = 2 * (val + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	aspeed_clk_data->hws[ASPEED_CLK_AHB] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	/* APB clock clock selection register SCU08 (aka PCLK) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	regmap_read(map, ASPEED_CLK_SELECTION, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	val = (val >> 23) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	div = 4 * (val + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	hw = clk_hw_register_fixed_factor(NULL, "apb", "hpll", 0, 1, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	aspeed_clk_data->hws[ASPEED_CLK_APB] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static void __init aspeed_cc_init(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	struct regmap *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	scu_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	if (!scu_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	aspeed_clk_data = kzalloc(struct_size(aspeed_clk_data, hws,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 					      ASPEED_NUM_CLKS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 				  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	if (!aspeed_clk_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	 * This way all clocks fetched before the platform device probes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	 * except those we assign here for early use, will be deferred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	for (i = 0; i < ASPEED_NUM_CLKS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		aspeed_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	map = syscon_node_to_regmap(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	if (IS_ERR(map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		pr_err("no syscon regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	 * We check that the regmap works on this very first access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	 * but as this is an MMIO-backed regmap, subsequent regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	 * access is not going to fail and we skip error checks from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	 * this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	ret = regmap_read(map, ASPEED_STRAP, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		pr_err("failed to read strapping register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	if (of_device_is_compatible(np, "aspeed,ast2400-scu"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		aspeed_ast2400_cc(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	else if (of_device_is_compatible(np, "aspeed,ast2500-scu"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		aspeed_ast2500_cc(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		pr_err("unknown platform, failed to add clocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	aspeed_clk_data->num = ASPEED_NUM_CLKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		pr_err("failed to add DT provider: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) CLK_OF_DECLARE_DRIVER(aspeed_cc_g5, "aspeed,ast2500-scu", aspeed_cc_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) CLK_OF_DECLARE_DRIVER(aspeed_cc_g4, "aspeed,ast2400-scu", aspeed_cc_init);