162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include <linux/clk-provider.h>
462306a36Sopenharmony_ci#include <linux/init.h>
562306a36Sopenharmony_ci#include <linux/of.h>
662306a36Sopenharmony_ci#include <linux/platform_device.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <dt-bindings/clock/bcm3368-clock.h>
962306a36Sopenharmony_ci#include <dt-bindings/clock/bcm6318-clock.h>
1062306a36Sopenharmony_ci#include <dt-bindings/clock/bcm6328-clock.h>
1162306a36Sopenharmony_ci#include <dt-bindings/clock/bcm6358-clock.h>
1262306a36Sopenharmony_ci#include <dt-bindings/clock/bcm6362-clock.h>
1362306a36Sopenharmony_ci#include <dt-bindings/clock/bcm6368-clock.h>
1462306a36Sopenharmony_ci#include <dt-bindings/clock/bcm63268-clock.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistruct clk_bcm63xx_table_entry {
1762306a36Sopenharmony_ci	const char * const name;
1862306a36Sopenharmony_ci	u8 bit;
1962306a36Sopenharmony_ci	unsigned long flags;
2062306a36Sopenharmony_ci};
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistruct clk_bcm63xx_hw {
2362306a36Sopenharmony_ci	void __iomem *regs;
2462306a36Sopenharmony_ci	spinlock_t lock;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	struct clk_hw_onecell_data data;
2762306a36Sopenharmony_ci};
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic const struct clk_bcm63xx_table_entry bcm3368_clocks[] = {
3062306a36Sopenharmony_ci	{
3162306a36Sopenharmony_ci		.name = "mac",
3262306a36Sopenharmony_ci		.bit = BCM3368_CLK_MAC,
3362306a36Sopenharmony_ci	}, {
3462306a36Sopenharmony_ci		.name = "tc",
3562306a36Sopenharmony_ci		.bit = BCM3368_CLK_TC,
3662306a36Sopenharmony_ci	}, {
3762306a36Sopenharmony_ci		.name = "us_top",
3862306a36Sopenharmony_ci		.bit = BCM3368_CLK_US_TOP,
3962306a36Sopenharmony_ci	}, {
4062306a36Sopenharmony_ci		.name = "ds_top",
4162306a36Sopenharmony_ci		.bit = BCM3368_CLK_DS_TOP,
4262306a36Sopenharmony_ci	}, {
4362306a36Sopenharmony_ci		.name = "acm",
4462306a36Sopenharmony_ci		.bit = BCM3368_CLK_ACM,
4562306a36Sopenharmony_ci	}, {
4662306a36Sopenharmony_ci		.name = "spi",
4762306a36Sopenharmony_ci		.bit = BCM3368_CLK_SPI,
4862306a36Sopenharmony_ci	}, {
4962306a36Sopenharmony_ci		.name = "usbs",
5062306a36Sopenharmony_ci		.bit = BCM3368_CLK_USBS,
5162306a36Sopenharmony_ci	}, {
5262306a36Sopenharmony_ci		.name = "bmu",
5362306a36Sopenharmony_ci		.bit = BCM3368_CLK_BMU,
5462306a36Sopenharmony_ci	}, {
5562306a36Sopenharmony_ci		.name = "pcm",
5662306a36Sopenharmony_ci		.bit = BCM3368_CLK_PCM,
5762306a36Sopenharmony_ci	}, {
5862306a36Sopenharmony_ci		.name = "ntp",
5962306a36Sopenharmony_ci		.bit = BCM3368_CLK_NTP,
6062306a36Sopenharmony_ci	}, {
6162306a36Sopenharmony_ci		.name = "acp_b",
6262306a36Sopenharmony_ci		.bit = BCM3368_CLK_ACP_B,
6362306a36Sopenharmony_ci	}, {
6462306a36Sopenharmony_ci		.name = "acp_a",
6562306a36Sopenharmony_ci		.bit = BCM3368_CLK_ACP_A,
6662306a36Sopenharmony_ci	}, {
6762306a36Sopenharmony_ci		.name = "emusb",
6862306a36Sopenharmony_ci		.bit = BCM3368_CLK_EMUSB,
6962306a36Sopenharmony_ci	}, {
7062306a36Sopenharmony_ci		.name = "enet0",
7162306a36Sopenharmony_ci		.bit = BCM3368_CLK_ENET0,
7262306a36Sopenharmony_ci	}, {
7362306a36Sopenharmony_ci		.name = "enet1",
7462306a36Sopenharmony_ci		.bit = BCM3368_CLK_ENET1,
7562306a36Sopenharmony_ci	}, {
7662306a36Sopenharmony_ci		.name = "usbsu",
7762306a36Sopenharmony_ci		.bit = BCM3368_CLK_USBSU,
7862306a36Sopenharmony_ci	}, {
7962306a36Sopenharmony_ci		.name = "ephy",
8062306a36Sopenharmony_ci		.bit = BCM3368_CLK_EPHY,
8162306a36Sopenharmony_ci	}, {
8262306a36Sopenharmony_ci		/* sentinel */
8362306a36Sopenharmony_ci	},
8462306a36Sopenharmony_ci};
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistatic const struct clk_bcm63xx_table_entry bcm6318_clocks[] = {
8762306a36Sopenharmony_ci	{
8862306a36Sopenharmony_ci		.name = "adsl_asb",
8962306a36Sopenharmony_ci		.bit = BCM6318_CLK_ADSL_ASB,
9062306a36Sopenharmony_ci	}, {
9162306a36Sopenharmony_ci		.name = "usb_asb",
9262306a36Sopenharmony_ci		.bit = BCM6318_CLK_USB_ASB,
9362306a36Sopenharmony_ci	}, {
9462306a36Sopenharmony_ci		.name = "mips_asb",
9562306a36Sopenharmony_ci		.bit = BCM6318_CLK_MIPS_ASB,
9662306a36Sopenharmony_ci	}, {
9762306a36Sopenharmony_ci		.name = "pcie_asb",
9862306a36Sopenharmony_ci		.bit = BCM6318_CLK_PCIE_ASB,
9962306a36Sopenharmony_ci	}, {
10062306a36Sopenharmony_ci		.name = "phymips_asb",
10162306a36Sopenharmony_ci		.bit = BCM6318_CLK_PHYMIPS_ASB,
10262306a36Sopenharmony_ci	}, {
10362306a36Sopenharmony_ci		.name = "robosw_asb",
10462306a36Sopenharmony_ci		.bit = BCM6318_CLK_ROBOSW_ASB,
10562306a36Sopenharmony_ci	}, {
10662306a36Sopenharmony_ci		.name = "sar_asb",
10762306a36Sopenharmony_ci		.bit = BCM6318_CLK_SAR_ASB,
10862306a36Sopenharmony_ci	}, {
10962306a36Sopenharmony_ci		.name = "sdr_asb",
11062306a36Sopenharmony_ci		.bit = BCM6318_CLK_SDR_ASB,
11162306a36Sopenharmony_ci	}, {
11262306a36Sopenharmony_ci		.name = "swreg_asb",
11362306a36Sopenharmony_ci		.bit = BCM6318_CLK_SWREG_ASB,
11462306a36Sopenharmony_ci	}, {
11562306a36Sopenharmony_ci		.name = "periph_asb",
11662306a36Sopenharmony_ci		.bit = BCM6318_CLK_PERIPH_ASB,
11762306a36Sopenharmony_ci	}, {
11862306a36Sopenharmony_ci		.name = "cpubus160",
11962306a36Sopenharmony_ci		.bit = BCM6318_CLK_CPUBUS160,
12062306a36Sopenharmony_ci	}, {
12162306a36Sopenharmony_ci		.name = "adsl",
12262306a36Sopenharmony_ci		.bit = BCM6318_CLK_ADSL,
12362306a36Sopenharmony_ci	}, {
12462306a36Sopenharmony_ci		.name = "sar125",
12562306a36Sopenharmony_ci		.bit = BCM6318_CLK_SAR125,
12662306a36Sopenharmony_ci	}, {
12762306a36Sopenharmony_ci		.name = "mips",
12862306a36Sopenharmony_ci		.bit = BCM6318_CLK_MIPS,
12962306a36Sopenharmony_ci		.flags = CLK_IS_CRITICAL,
13062306a36Sopenharmony_ci	}, {
13162306a36Sopenharmony_ci		.name = "pcie",
13262306a36Sopenharmony_ci		.bit = BCM6318_CLK_PCIE,
13362306a36Sopenharmony_ci	}, {
13462306a36Sopenharmony_ci		.name = "robosw250",
13562306a36Sopenharmony_ci		.bit = BCM6318_CLK_ROBOSW250,
13662306a36Sopenharmony_ci	}, {
13762306a36Sopenharmony_ci		.name = "robosw025",
13862306a36Sopenharmony_ci		.bit = BCM6318_CLK_ROBOSW025,
13962306a36Sopenharmony_ci	}, {
14062306a36Sopenharmony_ci		.name = "sdr",
14162306a36Sopenharmony_ci		.bit = BCM6318_CLK_SDR,
14262306a36Sopenharmony_ci		.flags = CLK_IS_CRITICAL,
14362306a36Sopenharmony_ci	}, {
14462306a36Sopenharmony_ci		.name = "usbd",
14562306a36Sopenharmony_ci		.bit = BCM6318_CLK_USBD,
14662306a36Sopenharmony_ci	}, {
14762306a36Sopenharmony_ci		.name = "hsspi",
14862306a36Sopenharmony_ci		.bit = BCM6318_CLK_HSSPI,
14962306a36Sopenharmony_ci	}, {
15062306a36Sopenharmony_ci		.name = "pcie25",
15162306a36Sopenharmony_ci		.bit = BCM6318_CLK_PCIE25,
15262306a36Sopenharmony_ci	}, {
15362306a36Sopenharmony_ci		.name = "phymips",
15462306a36Sopenharmony_ci		.bit = BCM6318_CLK_PHYMIPS,
15562306a36Sopenharmony_ci	}, {
15662306a36Sopenharmony_ci		.name = "afe",
15762306a36Sopenharmony_ci		.bit = BCM6318_CLK_AFE,
15862306a36Sopenharmony_ci	}, {
15962306a36Sopenharmony_ci		.name = "qproc",
16062306a36Sopenharmony_ci		.bit = BCM6318_CLK_QPROC,
16162306a36Sopenharmony_ci	}, {
16262306a36Sopenharmony_ci		/* sentinel */
16362306a36Sopenharmony_ci	},
16462306a36Sopenharmony_ci};
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_cistatic const struct clk_bcm63xx_table_entry bcm6318_ubus_clocks[] = {
16762306a36Sopenharmony_ci	{
16862306a36Sopenharmony_ci		.name = "adsl-ubus",
16962306a36Sopenharmony_ci		.bit = BCM6318_UCLK_ADSL,
17062306a36Sopenharmony_ci	}, {
17162306a36Sopenharmony_ci		.name = "arb-ubus",
17262306a36Sopenharmony_ci		.bit = BCM6318_UCLK_ARB,
17362306a36Sopenharmony_ci		.flags = CLK_IS_CRITICAL,
17462306a36Sopenharmony_ci	}, {
17562306a36Sopenharmony_ci		.name = "mips-ubus",
17662306a36Sopenharmony_ci		.bit = BCM6318_UCLK_MIPS,
17762306a36Sopenharmony_ci		.flags = CLK_IS_CRITICAL,
17862306a36Sopenharmony_ci	}, {
17962306a36Sopenharmony_ci		.name = "pcie-ubus",
18062306a36Sopenharmony_ci		.bit = BCM6318_UCLK_PCIE,
18162306a36Sopenharmony_ci	}, {
18262306a36Sopenharmony_ci		.name = "periph-ubus",
18362306a36Sopenharmony_ci		.bit = BCM6318_UCLK_PERIPH,
18462306a36Sopenharmony_ci		.flags = CLK_IS_CRITICAL,
18562306a36Sopenharmony_ci	}, {
18662306a36Sopenharmony_ci		.name = "phymips-ubus",
18762306a36Sopenharmony_ci		.bit = BCM6318_UCLK_PHYMIPS,
18862306a36Sopenharmony_ci	}, {
18962306a36Sopenharmony_ci		.name = "robosw-ubus",
19062306a36Sopenharmony_ci		.bit = BCM6318_UCLK_ROBOSW,
19162306a36Sopenharmony_ci	}, {
19262306a36Sopenharmony_ci		.name = "sar-ubus",
19362306a36Sopenharmony_ci		.bit = BCM6318_UCLK_SAR,
19462306a36Sopenharmony_ci	}, {
19562306a36Sopenharmony_ci		.name = "sdr-ubus",
19662306a36Sopenharmony_ci		.bit = BCM6318_UCLK_SDR,
19762306a36Sopenharmony_ci	}, {
19862306a36Sopenharmony_ci		.name = "usb-ubus",
19962306a36Sopenharmony_ci		.bit = BCM6318_UCLK_USB,
20062306a36Sopenharmony_ci	}, {
20162306a36Sopenharmony_ci		/* sentinel */
20262306a36Sopenharmony_ci	},
20362306a36Sopenharmony_ci};
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_cistatic const struct clk_bcm63xx_table_entry bcm6328_clocks[] = {
20662306a36Sopenharmony_ci	{
20762306a36Sopenharmony_ci		.name = "phy_mips",
20862306a36Sopenharmony_ci		.bit = BCM6328_CLK_PHYMIPS,
20962306a36Sopenharmony_ci	}, {
21062306a36Sopenharmony_ci		.name = "adsl_qproc",
21162306a36Sopenharmony_ci		.bit = BCM6328_CLK_ADSL_QPROC,
21262306a36Sopenharmony_ci	}, {
21362306a36Sopenharmony_ci		.name = "adsl_afe",
21462306a36Sopenharmony_ci		.bit = BCM6328_CLK_ADSL_AFE,
21562306a36Sopenharmony_ci	}, {
21662306a36Sopenharmony_ci		.name = "adsl",
21762306a36Sopenharmony_ci		.bit = BCM6328_CLK_ADSL,
21862306a36Sopenharmony_ci	}, {
21962306a36Sopenharmony_ci		.name = "mips",
22062306a36Sopenharmony_ci		.bit = BCM6328_CLK_MIPS,
22162306a36Sopenharmony_ci		.flags = CLK_IS_CRITICAL,
22262306a36Sopenharmony_ci	}, {
22362306a36Sopenharmony_ci		.name = "sar",
22462306a36Sopenharmony_ci		.bit = BCM6328_CLK_SAR,
22562306a36Sopenharmony_ci	}, {
22662306a36Sopenharmony_ci		.name = "pcm",
22762306a36Sopenharmony_ci		.bit = BCM6328_CLK_PCM,
22862306a36Sopenharmony_ci	}, {
22962306a36Sopenharmony_ci		.name = "usbd",
23062306a36Sopenharmony_ci		.bit = BCM6328_CLK_USBD,
23162306a36Sopenharmony_ci	}, {
23262306a36Sopenharmony_ci		.name = "usbh",
23362306a36Sopenharmony_ci		.bit = BCM6328_CLK_USBH,
23462306a36Sopenharmony_ci	}, {
23562306a36Sopenharmony_ci		.name = "hsspi",
23662306a36Sopenharmony_ci		.bit = BCM6328_CLK_HSSPI,
23762306a36Sopenharmony_ci	}, {
23862306a36Sopenharmony_ci		.name = "pcie",
23962306a36Sopenharmony_ci		.bit = BCM6328_CLK_PCIE,
24062306a36Sopenharmony_ci	}, {
24162306a36Sopenharmony_ci		.name = "robosw",
24262306a36Sopenharmony_ci		.bit = BCM6328_CLK_ROBOSW,
24362306a36Sopenharmony_ci	}, {
24462306a36Sopenharmony_ci		/* sentinel */
24562306a36Sopenharmony_ci	},
24662306a36Sopenharmony_ci};
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_cistatic const struct clk_bcm63xx_table_entry bcm6358_clocks[] = {
24962306a36Sopenharmony_ci	{
25062306a36Sopenharmony_ci		.name = "enet",
25162306a36Sopenharmony_ci		.bit = BCM6358_CLK_ENET,
25262306a36Sopenharmony_ci	}, {
25362306a36Sopenharmony_ci		.name = "adslphy",
25462306a36Sopenharmony_ci		.bit = BCM6358_CLK_ADSLPHY,
25562306a36Sopenharmony_ci	}, {
25662306a36Sopenharmony_ci		.name = "pcm",
25762306a36Sopenharmony_ci		.bit = BCM6358_CLK_PCM,
25862306a36Sopenharmony_ci	}, {
25962306a36Sopenharmony_ci		.name = "spi",
26062306a36Sopenharmony_ci		.bit = BCM6358_CLK_SPI,
26162306a36Sopenharmony_ci	}, {
26262306a36Sopenharmony_ci		.name = "usbs",
26362306a36Sopenharmony_ci		.bit = BCM6358_CLK_USBS,
26462306a36Sopenharmony_ci	}, {
26562306a36Sopenharmony_ci		.name = "sar",
26662306a36Sopenharmony_ci		.bit = BCM6358_CLK_SAR,
26762306a36Sopenharmony_ci	}, {
26862306a36Sopenharmony_ci		.name = "emusb",
26962306a36Sopenharmony_ci		.bit = BCM6358_CLK_EMUSB,
27062306a36Sopenharmony_ci	}, {
27162306a36Sopenharmony_ci		.name = "enet0",
27262306a36Sopenharmony_ci		.bit = BCM6358_CLK_ENET0,
27362306a36Sopenharmony_ci	}, {
27462306a36Sopenharmony_ci		.name = "enet1",
27562306a36Sopenharmony_ci		.bit = BCM6358_CLK_ENET1,
27662306a36Sopenharmony_ci	}, {
27762306a36Sopenharmony_ci		.name = "usbsu",
27862306a36Sopenharmony_ci		.bit = BCM6358_CLK_USBSU,
27962306a36Sopenharmony_ci	}, {
28062306a36Sopenharmony_ci		.name = "ephy",
28162306a36Sopenharmony_ci		.bit = BCM6358_CLK_EPHY,
28262306a36Sopenharmony_ci	}, {
28362306a36Sopenharmony_ci		/* sentinel */
28462306a36Sopenharmony_ci	},
28562306a36Sopenharmony_ci};
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_cistatic const struct clk_bcm63xx_table_entry bcm6362_clocks[] = {
28862306a36Sopenharmony_ci	{
28962306a36Sopenharmony_ci		.name = "adsl_qproc",
29062306a36Sopenharmony_ci		.bit = BCM6362_CLK_ADSL_QPROC,
29162306a36Sopenharmony_ci	}, {
29262306a36Sopenharmony_ci		.name = "adsl_afe",
29362306a36Sopenharmony_ci		.bit = BCM6362_CLK_ADSL_AFE,
29462306a36Sopenharmony_ci	}, {
29562306a36Sopenharmony_ci		.name = "adsl",
29662306a36Sopenharmony_ci		.bit = BCM6362_CLK_ADSL,
29762306a36Sopenharmony_ci	}, {
29862306a36Sopenharmony_ci		.name = "mips",
29962306a36Sopenharmony_ci		.bit = BCM6362_CLK_MIPS,
30062306a36Sopenharmony_ci		.flags = CLK_IS_CRITICAL,
30162306a36Sopenharmony_ci	}, {
30262306a36Sopenharmony_ci		.name = "wlan_ocp",
30362306a36Sopenharmony_ci		.bit = BCM6362_CLK_WLAN_OCP,
30462306a36Sopenharmony_ci	}, {
30562306a36Sopenharmony_ci		.name = "swpkt_usb",
30662306a36Sopenharmony_ci		.bit = BCM6362_CLK_SWPKT_USB,
30762306a36Sopenharmony_ci	}, {
30862306a36Sopenharmony_ci		.name = "swpkt_sar",
30962306a36Sopenharmony_ci		.bit = BCM6362_CLK_SWPKT_SAR,
31062306a36Sopenharmony_ci	}, {
31162306a36Sopenharmony_ci		.name = "sar",
31262306a36Sopenharmony_ci		.bit = BCM6362_CLK_SAR,
31362306a36Sopenharmony_ci	}, {
31462306a36Sopenharmony_ci		.name = "robosw",
31562306a36Sopenharmony_ci		.bit = BCM6362_CLK_ROBOSW,
31662306a36Sopenharmony_ci	}, {
31762306a36Sopenharmony_ci		.name = "pcm",
31862306a36Sopenharmony_ci		.bit = BCM6362_CLK_PCM,
31962306a36Sopenharmony_ci	}, {
32062306a36Sopenharmony_ci		.name = "usbd",
32162306a36Sopenharmony_ci		.bit = BCM6362_CLK_USBD,
32262306a36Sopenharmony_ci	}, {
32362306a36Sopenharmony_ci		.name = "usbh",
32462306a36Sopenharmony_ci		.bit = BCM6362_CLK_USBH,
32562306a36Sopenharmony_ci	}, {
32662306a36Sopenharmony_ci		.name = "ipsec",
32762306a36Sopenharmony_ci		.bit = BCM6362_CLK_IPSEC,
32862306a36Sopenharmony_ci	}, {
32962306a36Sopenharmony_ci		.name = "spi",
33062306a36Sopenharmony_ci		.bit = BCM6362_CLK_SPI,
33162306a36Sopenharmony_ci	}, {
33262306a36Sopenharmony_ci		.name = "hsspi",
33362306a36Sopenharmony_ci		.bit = BCM6362_CLK_HSSPI,
33462306a36Sopenharmony_ci	}, {
33562306a36Sopenharmony_ci		.name = "pcie",
33662306a36Sopenharmony_ci		.bit = BCM6362_CLK_PCIE,
33762306a36Sopenharmony_ci	}, {
33862306a36Sopenharmony_ci		.name = "fap",
33962306a36Sopenharmony_ci		.bit = BCM6362_CLK_FAP,
34062306a36Sopenharmony_ci	}, {
34162306a36Sopenharmony_ci		.name = "phymips",
34262306a36Sopenharmony_ci		.bit = BCM6362_CLK_PHYMIPS,
34362306a36Sopenharmony_ci	}, {
34462306a36Sopenharmony_ci		.name = "nand",
34562306a36Sopenharmony_ci		.bit = BCM6362_CLK_NAND,
34662306a36Sopenharmony_ci	}, {
34762306a36Sopenharmony_ci		/* sentinel */
34862306a36Sopenharmony_ci	},
34962306a36Sopenharmony_ci};
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_cistatic const struct clk_bcm63xx_table_entry bcm6368_clocks[] = {
35262306a36Sopenharmony_ci	{
35362306a36Sopenharmony_ci		.name = "vdsl_qproc",
35462306a36Sopenharmony_ci		.bit = BCM6368_CLK_VDSL_QPROC,
35562306a36Sopenharmony_ci	}, {
35662306a36Sopenharmony_ci		.name = "vdsl_afe",
35762306a36Sopenharmony_ci		.bit = BCM6368_CLK_VDSL_AFE,
35862306a36Sopenharmony_ci	}, {
35962306a36Sopenharmony_ci		.name = "vdsl_bonding",
36062306a36Sopenharmony_ci		.bit = BCM6368_CLK_VDSL_BONDING,
36162306a36Sopenharmony_ci	}, {
36262306a36Sopenharmony_ci		.name = "vdsl",
36362306a36Sopenharmony_ci		.bit = BCM6368_CLK_VDSL,
36462306a36Sopenharmony_ci	}, {
36562306a36Sopenharmony_ci		.name = "phymips",
36662306a36Sopenharmony_ci		.bit = BCM6368_CLK_PHYMIPS,
36762306a36Sopenharmony_ci	}, {
36862306a36Sopenharmony_ci		.name = "swpkt_usb",
36962306a36Sopenharmony_ci		.bit = BCM6368_CLK_SWPKT_USB,
37062306a36Sopenharmony_ci	}, {
37162306a36Sopenharmony_ci		.name = "swpkt_sar",
37262306a36Sopenharmony_ci		.bit = BCM6368_CLK_SWPKT_SAR,
37362306a36Sopenharmony_ci	}, {
37462306a36Sopenharmony_ci		.name = "spi",
37562306a36Sopenharmony_ci		.bit = BCM6368_CLK_SPI,
37662306a36Sopenharmony_ci	}, {
37762306a36Sopenharmony_ci		.name = "usbd",
37862306a36Sopenharmony_ci		.bit = BCM6368_CLK_USBD,
37962306a36Sopenharmony_ci	}, {
38062306a36Sopenharmony_ci		.name = "sar",
38162306a36Sopenharmony_ci		.bit = BCM6368_CLK_SAR,
38262306a36Sopenharmony_ci	}, {
38362306a36Sopenharmony_ci		.name = "robosw",
38462306a36Sopenharmony_ci		.bit = BCM6368_CLK_ROBOSW,
38562306a36Sopenharmony_ci	}, {
38662306a36Sopenharmony_ci		.name = "utopia",
38762306a36Sopenharmony_ci		.bit = BCM6368_CLK_UTOPIA,
38862306a36Sopenharmony_ci	}, {
38962306a36Sopenharmony_ci		.name = "pcm",
39062306a36Sopenharmony_ci		.bit = BCM6368_CLK_PCM,
39162306a36Sopenharmony_ci	}, {
39262306a36Sopenharmony_ci		.name = "usbh",
39362306a36Sopenharmony_ci		.bit = BCM6368_CLK_USBH,
39462306a36Sopenharmony_ci	}, {
39562306a36Sopenharmony_ci		.name = "disable_gless",
39662306a36Sopenharmony_ci		.bit = BCM6368_CLK_DIS_GLESS,
39762306a36Sopenharmony_ci	}, {
39862306a36Sopenharmony_ci		.name = "nand",
39962306a36Sopenharmony_ci		.bit = BCM6368_CLK_NAND,
40062306a36Sopenharmony_ci	}, {
40162306a36Sopenharmony_ci		.name = "ipsec",
40262306a36Sopenharmony_ci		.bit = BCM6368_CLK_IPSEC,
40362306a36Sopenharmony_ci	}, {
40462306a36Sopenharmony_ci		/* sentinel */
40562306a36Sopenharmony_ci	},
40662306a36Sopenharmony_ci};
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_cistatic const struct clk_bcm63xx_table_entry bcm63268_clocks[] = {
40962306a36Sopenharmony_ci	{
41062306a36Sopenharmony_ci		.name = "disable_gless",
41162306a36Sopenharmony_ci		.bit = BCM63268_CLK_DIS_GLESS,
41262306a36Sopenharmony_ci	}, {
41362306a36Sopenharmony_ci		.name = "vdsl_qproc",
41462306a36Sopenharmony_ci		.bit = BCM63268_CLK_VDSL_QPROC,
41562306a36Sopenharmony_ci	}, {
41662306a36Sopenharmony_ci		.name = "vdsl_afe",
41762306a36Sopenharmony_ci		.bit = BCM63268_CLK_VDSL_AFE,
41862306a36Sopenharmony_ci	}, {
41962306a36Sopenharmony_ci		.name = "vdsl",
42062306a36Sopenharmony_ci		.bit = BCM63268_CLK_VDSL,
42162306a36Sopenharmony_ci	}, {
42262306a36Sopenharmony_ci		.name = "mips",
42362306a36Sopenharmony_ci		.bit = BCM63268_CLK_MIPS,
42462306a36Sopenharmony_ci		.flags = CLK_IS_CRITICAL,
42562306a36Sopenharmony_ci	}, {
42662306a36Sopenharmony_ci		.name = "wlan_ocp",
42762306a36Sopenharmony_ci		.bit = BCM63268_CLK_WLAN_OCP,
42862306a36Sopenharmony_ci	}, {
42962306a36Sopenharmony_ci		.name = "dect",
43062306a36Sopenharmony_ci		.bit = BCM63268_CLK_DECT,
43162306a36Sopenharmony_ci	}, {
43262306a36Sopenharmony_ci		.name = "fap0",
43362306a36Sopenharmony_ci		.bit = BCM63268_CLK_FAP0,
43462306a36Sopenharmony_ci	}, {
43562306a36Sopenharmony_ci		.name = "fap1",
43662306a36Sopenharmony_ci		.bit = BCM63268_CLK_FAP1,
43762306a36Sopenharmony_ci	}, {
43862306a36Sopenharmony_ci		.name = "sar",
43962306a36Sopenharmony_ci		.bit = BCM63268_CLK_SAR,
44062306a36Sopenharmony_ci	}, {
44162306a36Sopenharmony_ci		.name = "robosw",
44262306a36Sopenharmony_ci		.bit = BCM63268_CLK_ROBOSW,
44362306a36Sopenharmony_ci	}, {
44462306a36Sopenharmony_ci		.name = "pcm",
44562306a36Sopenharmony_ci		.bit = BCM63268_CLK_PCM,
44662306a36Sopenharmony_ci	}, {
44762306a36Sopenharmony_ci		.name = "usbd",
44862306a36Sopenharmony_ci		.bit = BCM63268_CLK_USBD,
44962306a36Sopenharmony_ci	}, {
45062306a36Sopenharmony_ci		.name = "usbh",
45162306a36Sopenharmony_ci		.bit = BCM63268_CLK_USBH,
45262306a36Sopenharmony_ci	}, {
45362306a36Sopenharmony_ci		.name = "ipsec",
45462306a36Sopenharmony_ci		.bit = BCM63268_CLK_IPSEC,
45562306a36Sopenharmony_ci	}, {
45662306a36Sopenharmony_ci		.name = "spi",
45762306a36Sopenharmony_ci		.bit = BCM63268_CLK_SPI,
45862306a36Sopenharmony_ci	}, {
45962306a36Sopenharmony_ci		.name = "hsspi",
46062306a36Sopenharmony_ci		.bit = BCM63268_CLK_HSSPI,
46162306a36Sopenharmony_ci	}, {
46262306a36Sopenharmony_ci		.name = "pcie",
46362306a36Sopenharmony_ci		.bit = BCM63268_CLK_PCIE,
46462306a36Sopenharmony_ci	}, {
46562306a36Sopenharmony_ci		.name = "phymips",
46662306a36Sopenharmony_ci		.bit = BCM63268_CLK_PHYMIPS,
46762306a36Sopenharmony_ci	}, {
46862306a36Sopenharmony_ci		.name = "gmac",
46962306a36Sopenharmony_ci		.bit = BCM63268_CLK_GMAC,
47062306a36Sopenharmony_ci	}, {
47162306a36Sopenharmony_ci		.name = "nand",
47262306a36Sopenharmony_ci		.bit = BCM63268_CLK_NAND,
47362306a36Sopenharmony_ci	}, {
47462306a36Sopenharmony_ci		.name = "tbus",
47562306a36Sopenharmony_ci		.bit = BCM63268_CLK_TBUS,
47662306a36Sopenharmony_ci	}, {
47762306a36Sopenharmony_ci		.name = "robosw250",
47862306a36Sopenharmony_ci		.bit = BCM63268_CLK_ROBOSW250,
47962306a36Sopenharmony_ci	}, {
48062306a36Sopenharmony_ci		/* sentinel */
48162306a36Sopenharmony_ci	},
48262306a36Sopenharmony_ci};
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_cistatic int clk_bcm63xx_probe(struct platform_device *pdev)
48562306a36Sopenharmony_ci{
48662306a36Sopenharmony_ci	const struct clk_bcm63xx_table_entry *entry, *table;
48762306a36Sopenharmony_ci	struct clk_bcm63xx_hw *hw;
48862306a36Sopenharmony_ci	u8 maxbit = 0;
48962306a36Sopenharmony_ci	int i, ret;
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	table = of_device_get_match_data(&pdev->dev);
49262306a36Sopenharmony_ci	if (!table)
49362306a36Sopenharmony_ci		return -EINVAL;
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	for (entry = table; entry->name; entry++)
49662306a36Sopenharmony_ci		maxbit = max_t(u8, maxbit, entry->bit);
49762306a36Sopenharmony_ci	maxbit++;
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit),
50062306a36Sopenharmony_ci			  GFP_KERNEL);
50162306a36Sopenharmony_ci	if (!hw)
50262306a36Sopenharmony_ci		return -ENOMEM;
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci	platform_set_drvdata(pdev, hw);
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	spin_lock_init(&hw->lock);
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	hw->data.num = maxbit;
50962306a36Sopenharmony_ci	for (i = 0; i < maxbit; i++)
51062306a36Sopenharmony_ci		hw->data.hws[i] = ERR_PTR(-ENODEV);
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	hw->regs = devm_platform_ioremap_resource(pdev, 0);
51362306a36Sopenharmony_ci	if (IS_ERR(hw->regs))
51462306a36Sopenharmony_ci		return PTR_ERR(hw->regs);
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	for (entry = table; entry->name; entry++) {
51762306a36Sopenharmony_ci		struct clk_hw *clk;
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci		clk = clk_hw_register_gate(&pdev->dev, entry->name, NULL,
52062306a36Sopenharmony_ci					   entry->flags, hw->regs, entry->bit,
52162306a36Sopenharmony_ci					   CLK_GATE_BIG_ENDIAN, &hw->lock);
52262306a36Sopenharmony_ci		if (IS_ERR(clk)) {
52362306a36Sopenharmony_ci			ret = PTR_ERR(clk);
52462306a36Sopenharmony_ci			goto out_err;
52562306a36Sopenharmony_ci		}
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci		hw->data.hws[entry->bit] = clk;
52862306a36Sopenharmony_ci	}
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
53162306a36Sopenharmony_ci				     &hw->data);
53262306a36Sopenharmony_ci	if (!ret)
53362306a36Sopenharmony_ci		return 0;
53462306a36Sopenharmony_ciout_err:
53562306a36Sopenharmony_ci	for (i = 0; i < hw->data.num; i++) {
53662306a36Sopenharmony_ci		if (!IS_ERR(hw->data.hws[i]))
53762306a36Sopenharmony_ci			clk_hw_unregister_gate(hw->data.hws[i]);
53862306a36Sopenharmony_ci	}
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	return ret;
54162306a36Sopenharmony_ci}
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_cistatic void clk_bcm63xx_remove(struct platform_device *pdev)
54462306a36Sopenharmony_ci{
54562306a36Sopenharmony_ci	struct clk_bcm63xx_hw *hw = platform_get_drvdata(pdev);
54662306a36Sopenharmony_ci	int i;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	of_clk_del_provider(pdev->dev.of_node);
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci	for (i = 0; i < hw->data.num; i++) {
55162306a36Sopenharmony_ci		if (!IS_ERR(hw->data.hws[i]))
55262306a36Sopenharmony_ci			clk_hw_unregister_gate(hw->data.hws[i]);
55362306a36Sopenharmony_ci	}
55462306a36Sopenharmony_ci}
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_cistatic const struct of_device_id clk_bcm63xx_dt_ids[] = {
55762306a36Sopenharmony_ci	{ .compatible = "brcm,bcm3368-clocks", .data = &bcm3368_clocks, },
55862306a36Sopenharmony_ci	{ .compatible = "brcm,bcm6318-clocks", .data = &bcm6318_clocks, },
55962306a36Sopenharmony_ci	{ .compatible = "brcm,bcm6318-ubus-clocks", .data = &bcm6318_ubus_clocks, },
56062306a36Sopenharmony_ci	{ .compatible = "brcm,bcm6328-clocks", .data = &bcm6328_clocks, },
56162306a36Sopenharmony_ci	{ .compatible = "brcm,bcm6358-clocks", .data = &bcm6358_clocks, },
56262306a36Sopenharmony_ci	{ .compatible = "brcm,bcm6362-clocks", .data = &bcm6362_clocks, },
56362306a36Sopenharmony_ci	{ .compatible = "brcm,bcm6368-clocks", .data = &bcm6368_clocks, },
56462306a36Sopenharmony_ci	{ .compatible = "brcm,bcm63268-clocks", .data = &bcm63268_clocks, },
56562306a36Sopenharmony_ci	{ }
56662306a36Sopenharmony_ci};
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_cistatic struct platform_driver clk_bcm63xx = {
56962306a36Sopenharmony_ci	.probe = clk_bcm63xx_probe,
57062306a36Sopenharmony_ci	.remove_new = clk_bcm63xx_remove,
57162306a36Sopenharmony_ci	.driver = {
57262306a36Sopenharmony_ci		.name = "bcm63xx-clock",
57362306a36Sopenharmony_ci		.of_match_table = clk_bcm63xx_dt_ids,
57462306a36Sopenharmony_ci	},
57562306a36Sopenharmony_ci};
57662306a36Sopenharmony_cibuiltin_platform_driver(clk_bcm63xx);
577