xref: /kernel/linux/linux-5.10/arch/mips/bcm63xx/clk.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
38c2ecf20Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
48c2ecf20Sopenharmony_ci * for more details.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/init.h>
108c2ecf20Sopenharmony_ci#include <linux/export.h>
118c2ecf20Sopenharmony_ci#include <linux/mutex.h>
128c2ecf20Sopenharmony_ci#include <linux/err.h>
138c2ecf20Sopenharmony_ci#include <linux/clk.h>
148c2ecf20Sopenharmony_ci#include <linux/clkdev.h>
158c2ecf20Sopenharmony_ci#include <linux/delay.h>
168c2ecf20Sopenharmony_ci#include <bcm63xx_cpu.h>
178c2ecf20Sopenharmony_ci#include <bcm63xx_io.h>
188c2ecf20Sopenharmony_ci#include <bcm63xx_regs.h>
198c2ecf20Sopenharmony_ci#include <bcm63xx_reset.h>
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistruct clk {
228c2ecf20Sopenharmony_ci	void		(*set)(struct clk *, int);
238c2ecf20Sopenharmony_ci	unsigned int	rate;
248c2ecf20Sopenharmony_ci	unsigned int	usage;
258c2ecf20Sopenharmony_ci	int		id;
268c2ecf20Sopenharmony_ci};
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(clocks_mutex);
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic void clk_enable_unlocked(struct clk *clk)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	if (clk->set && (clk->usage++) == 0)
348c2ecf20Sopenharmony_ci		clk->set(clk, 1);
358c2ecf20Sopenharmony_ci}
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cistatic void clk_disable_unlocked(struct clk *clk)
388c2ecf20Sopenharmony_ci{
398c2ecf20Sopenharmony_ci	if (clk->set && (--clk->usage) == 0)
408c2ecf20Sopenharmony_ci		clk->set(clk, 0);
418c2ecf20Sopenharmony_ci}
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cistatic void bcm_hwclock_set(u32 mask, int enable)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	u32 reg;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	reg = bcm_perf_readl(PERF_CKCTL_REG);
488c2ecf20Sopenharmony_ci	if (enable)
498c2ecf20Sopenharmony_ci		reg |= mask;
508c2ecf20Sopenharmony_ci	else
518c2ecf20Sopenharmony_ci		reg &= ~mask;
528c2ecf20Sopenharmony_ci	bcm_perf_writel(reg, PERF_CKCTL_REG);
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/*
568c2ecf20Sopenharmony_ci * Ethernet MAC "misc" clock: dma clocks and main clock on 6348
578c2ecf20Sopenharmony_ci */
588c2ecf20Sopenharmony_cistatic void enet_misc_set(struct clk *clk, int enable)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	u32 mask;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6338())
638c2ecf20Sopenharmony_ci		mask = CKCTL_6338_ENET_EN;
648c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6345())
658c2ecf20Sopenharmony_ci		mask = CKCTL_6345_ENET_EN;
668c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6348())
678c2ecf20Sopenharmony_ci		mask = CKCTL_6348_ENET_EN;
688c2ecf20Sopenharmony_ci	else
698c2ecf20Sopenharmony_ci		/* BCMCPU_IS_6358 */
708c2ecf20Sopenharmony_ci		mask = CKCTL_6358_EMUSB_EN;
718c2ecf20Sopenharmony_ci	bcm_hwclock_set(mask, enable);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic struct clk clk_enet_misc = {
758c2ecf20Sopenharmony_ci	.set	= enet_misc_set,
768c2ecf20Sopenharmony_ci};
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/*
798c2ecf20Sopenharmony_ci * Ethernet MAC clocks: only revelant on 6358, silently enable misc
808c2ecf20Sopenharmony_ci * clocks
818c2ecf20Sopenharmony_ci */
828c2ecf20Sopenharmony_cistatic void enetx_set(struct clk *clk, int enable)
838c2ecf20Sopenharmony_ci{
848c2ecf20Sopenharmony_ci	if (enable)
858c2ecf20Sopenharmony_ci		clk_enable_unlocked(&clk_enet_misc);
868c2ecf20Sopenharmony_ci	else
878c2ecf20Sopenharmony_ci		clk_disable_unlocked(&clk_enet_misc);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
908c2ecf20Sopenharmony_ci		u32 mask;
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci		if (clk->id == 0)
938c2ecf20Sopenharmony_ci			mask = CKCTL_6358_ENET0_EN;
948c2ecf20Sopenharmony_ci		else
958c2ecf20Sopenharmony_ci			mask = CKCTL_6358_ENET1_EN;
968c2ecf20Sopenharmony_ci		bcm_hwclock_set(mask, enable);
978c2ecf20Sopenharmony_ci	}
988c2ecf20Sopenharmony_ci}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic struct clk clk_enet0 = {
1018c2ecf20Sopenharmony_ci	.id	= 0,
1028c2ecf20Sopenharmony_ci	.set	= enetx_set,
1038c2ecf20Sopenharmony_ci};
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic struct clk clk_enet1 = {
1068c2ecf20Sopenharmony_ci	.id	= 1,
1078c2ecf20Sopenharmony_ci	.set	= enetx_set,
1088c2ecf20Sopenharmony_ci};
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci/*
1118c2ecf20Sopenharmony_ci * Ethernet PHY clock
1128c2ecf20Sopenharmony_ci */
1138c2ecf20Sopenharmony_cistatic void ephy_set(struct clk *clk, int enable)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
1168c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_cistatic struct clk clk_ephy = {
1218c2ecf20Sopenharmony_ci	.set	= ephy_set,
1228c2ecf20Sopenharmony_ci};
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci/*
1258c2ecf20Sopenharmony_ci * Ethernet switch SAR clock
1268c2ecf20Sopenharmony_ci */
1278c2ecf20Sopenharmony_cistatic void swpkt_sar_set(struct clk *clk, int enable)
1288c2ecf20Sopenharmony_ci{
1298c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6368())
1308c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6368_SWPKT_SAR_EN, enable);
1318c2ecf20Sopenharmony_ci	else
1328c2ecf20Sopenharmony_ci		return;
1338c2ecf20Sopenharmony_ci}
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_cistatic struct clk clk_swpkt_sar = {
1368c2ecf20Sopenharmony_ci	.set	= swpkt_sar_set,
1378c2ecf20Sopenharmony_ci};
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci/*
1408c2ecf20Sopenharmony_ci * Ethernet switch USB clock
1418c2ecf20Sopenharmony_ci */
1428c2ecf20Sopenharmony_cistatic void swpkt_usb_set(struct clk *clk, int enable)
1438c2ecf20Sopenharmony_ci{
1448c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6368())
1458c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6368_SWPKT_USB_EN, enable);
1468c2ecf20Sopenharmony_ci	else
1478c2ecf20Sopenharmony_ci		return;
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistatic struct clk clk_swpkt_usb = {
1518c2ecf20Sopenharmony_ci	.set	= swpkt_usb_set,
1528c2ecf20Sopenharmony_ci};
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci/*
1558c2ecf20Sopenharmony_ci * Ethernet switch clock
1568c2ecf20Sopenharmony_ci */
1578c2ecf20Sopenharmony_cistatic void enetsw_set(struct clk *clk, int enable)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6328()) {
1608c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6328_ROBOSW_EN, enable);
1618c2ecf20Sopenharmony_ci	} else if (BCMCPU_IS_6362()) {
1628c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6362_ROBOSW_EN, enable);
1638c2ecf20Sopenharmony_ci	} else if (BCMCPU_IS_6368()) {
1648c2ecf20Sopenharmony_ci		if (enable) {
1658c2ecf20Sopenharmony_ci			clk_enable_unlocked(&clk_swpkt_sar);
1668c2ecf20Sopenharmony_ci			clk_enable_unlocked(&clk_swpkt_usb);
1678c2ecf20Sopenharmony_ci		} else {
1688c2ecf20Sopenharmony_ci			clk_disable_unlocked(&clk_swpkt_usb);
1698c2ecf20Sopenharmony_ci			clk_disable_unlocked(&clk_swpkt_sar);
1708c2ecf20Sopenharmony_ci		}
1718c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6368_ROBOSW_EN, enable);
1728c2ecf20Sopenharmony_ci	} else {
1738c2ecf20Sopenharmony_ci		return;
1748c2ecf20Sopenharmony_ci	}
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	if (enable) {
1778c2ecf20Sopenharmony_ci		/* reset switch core afer clock change */
1788c2ecf20Sopenharmony_ci		bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1);
1798c2ecf20Sopenharmony_ci		msleep(10);
1808c2ecf20Sopenharmony_ci		bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0);
1818c2ecf20Sopenharmony_ci		msleep(10);
1828c2ecf20Sopenharmony_ci	}
1838c2ecf20Sopenharmony_ci}
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_cistatic struct clk clk_enetsw = {
1868c2ecf20Sopenharmony_ci	.set	= enetsw_set,
1878c2ecf20Sopenharmony_ci};
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci/*
1908c2ecf20Sopenharmony_ci * PCM clock
1918c2ecf20Sopenharmony_ci */
1928c2ecf20Sopenharmony_cistatic void pcm_set(struct clk *clk, int enable)
1938c2ecf20Sopenharmony_ci{
1948c2ecf20Sopenharmony_ci	if (BCMCPU_IS_3368())
1958c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_3368_PCM_EN, enable);
1968c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6358())
1978c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
1988c2ecf20Sopenharmony_ci}
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_cistatic struct clk clk_pcm = {
2018c2ecf20Sopenharmony_ci	.set	= pcm_set,
2028c2ecf20Sopenharmony_ci};
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci/*
2058c2ecf20Sopenharmony_ci * USB host clock
2068c2ecf20Sopenharmony_ci */
2078c2ecf20Sopenharmony_cistatic void usbh_set(struct clk *clk, int enable)
2088c2ecf20Sopenharmony_ci{
2098c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6328())
2108c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6328_USBH_EN, enable);
2118c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6348())
2128c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
2138c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6362())
2148c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6362_USBH_EN, enable);
2158c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6368())
2168c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
2178c2ecf20Sopenharmony_ci}
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_cistatic struct clk clk_usbh = {
2208c2ecf20Sopenharmony_ci	.set	= usbh_set,
2218c2ecf20Sopenharmony_ci};
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci/*
2248c2ecf20Sopenharmony_ci * USB device clock
2258c2ecf20Sopenharmony_ci */
2268c2ecf20Sopenharmony_cistatic void usbd_set(struct clk *clk, int enable)
2278c2ecf20Sopenharmony_ci{
2288c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6328())
2298c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6328_USBD_EN, enable);
2308c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6362())
2318c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6362_USBD_EN, enable);
2328c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6368())
2338c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6368_USBD_EN, enable);
2348c2ecf20Sopenharmony_ci}
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_cistatic struct clk clk_usbd = {
2378c2ecf20Sopenharmony_ci	.set	= usbd_set,
2388c2ecf20Sopenharmony_ci};
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci/*
2418c2ecf20Sopenharmony_ci * SPI clock
2428c2ecf20Sopenharmony_ci */
2438c2ecf20Sopenharmony_cistatic void spi_set(struct clk *clk, int enable)
2448c2ecf20Sopenharmony_ci{
2458c2ecf20Sopenharmony_ci	u32 mask;
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6338())
2488c2ecf20Sopenharmony_ci		mask = CKCTL_6338_SPI_EN;
2498c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6348())
2508c2ecf20Sopenharmony_ci		mask = CKCTL_6348_SPI_EN;
2518c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
2528c2ecf20Sopenharmony_ci		mask = CKCTL_6358_SPI_EN;
2538c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6362())
2548c2ecf20Sopenharmony_ci		mask = CKCTL_6362_SPI_EN;
2558c2ecf20Sopenharmony_ci	else
2568c2ecf20Sopenharmony_ci		/* BCMCPU_IS_6368 */
2578c2ecf20Sopenharmony_ci		mask = CKCTL_6368_SPI_EN;
2588c2ecf20Sopenharmony_ci	bcm_hwclock_set(mask, enable);
2598c2ecf20Sopenharmony_ci}
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_cistatic struct clk clk_spi = {
2628c2ecf20Sopenharmony_ci	.set	= spi_set,
2638c2ecf20Sopenharmony_ci};
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci/*
2668c2ecf20Sopenharmony_ci * HSSPI clock
2678c2ecf20Sopenharmony_ci */
2688c2ecf20Sopenharmony_cistatic void hsspi_set(struct clk *clk, int enable)
2698c2ecf20Sopenharmony_ci{
2708c2ecf20Sopenharmony_ci	u32 mask;
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6328())
2738c2ecf20Sopenharmony_ci		mask = CKCTL_6328_HSSPI_EN;
2748c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6362())
2758c2ecf20Sopenharmony_ci		mask = CKCTL_6362_HSSPI_EN;
2768c2ecf20Sopenharmony_ci	else
2778c2ecf20Sopenharmony_ci		return;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	bcm_hwclock_set(mask, enable);
2808c2ecf20Sopenharmony_ci}
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_cistatic struct clk clk_hsspi = {
2838c2ecf20Sopenharmony_ci	.set	= hsspi_set,
2848c2ecf20Sopenharmony_ci};
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci/*
2878c2ecf20Sopenharmony_ci * HSSPI PLL
2888c2ecf20Sopenharmony_ci */
2898c2ecf20Sopenharmony_cistatic struct clk clk_hsspi_pll;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci/*
2928c2ecf20Sopenharmony_ci * XTM clock
2938c2ecf20Sopenharmony_ci */
2948c2ecf20Sopenharmony_cistatic void xtm_set(struct clk *clk, int enable)
2958c2ecf20Sopenharmony_ci{
2968c2ecf20Sopenharmony_ci	if (!BCMCPU_IS_6368())
2978c2ecf20Sopenharmony_ci		return;
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci	if (enable)
3008c2ecf20Sopenharmony_ci		clk_enable_unlocked(&clk_swpkt_sar);
3018c2ecf20Sopenharmony_ci	else
3028c2ecf20Sopenharmony_ci		clk_disable_unlocked(&clk_swpkt_sar);
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci	bcm_hwclock_set(CKCTL_6368_SAR_EN, enable);
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	if (enable) {
3078c2ecf20Sopenharmony_ci		/* reset sar core afer clock change */
3088c2ecf20Sopenharmony_ci		bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1);
3098c2ecf20Sopenharmony_ci		mdelay(1);
3108c2ecf20Sopenharmony_ci		bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0);
3118c2ecf20Sopenharmony_ci		mdelay(1);
3128c2ecf20Sopenharmony_ci	}
3138c2ecf20Sopenharmony_ci}
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_cistatic struct clk clk_xtm = {
3178c2ecf20Sopenharmony_ci	.set	= xtm_set,
3188c2ecf20Sopenharmony_ci};
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci/*
3218c2ecf20Sopenharmony_ci * IPsec clock
3228c2ecf20Sopenharmony_ci */
3238c2ecf20Sopenharmony_cistatic void ipsec_set(struct clk *clk, int enable)
3248c2ecf20Sopenharmony_ci{
3258c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6362())
3268c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6362_IPSEC_EN, enable);
3278c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6368())
3288c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable);
3298c2ecf20Sopenharmony_ci}
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_cistatic struct clk clk_ipsec = {
3328c2ecf20Sopenharmony_ci	.set	= ipsec_set,
3338c2ecf20Sopenharmony_ci};
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci/*
3368c2ecf20Sopenharmony_ci * PCIe clock
3378c2ecf20Sopenharmony_ci */
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_cistatic void pcie_set(struct clk *clk, int enable)
3408c2ecf20Sopenharmony_ci{
3418c2ecf20Sopenharmony_ci	if (BCMCPU_IS_6328())
3428c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable);
3438c2ecf20Sopenharmony_ci	else if (BCMCPU_IS_6362())
3448c2ecf20Sopenharmony_ci		bcm_hwclock_set(CKCTL_6362_PCIE_EN, enable);
3458c2ecf20Sopenharmony_ci}
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_cistatic struct clk clk_pcie = {
3488c2ecf20Sopenharmony_ci	.set	= pcie_set,
3498c2ecf20Sopenharmony_ci};
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci/*
3528c2ecf20Sopenharmony_ci * Internal peripheral clock
3538c2ecf20Sopenharmony_ci */
3548c2ecf20Sopenharmony_cistatic struct clk clk_periph = {
3558c2ecf20Sopenharmony_ci	.rate	= (50 * 1000 * 1000),
3568c2ecf20Sopenharmony_ci};
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci/*
3608c2ecf20Sopenharmony_ci * Linux clock API implementation
3618c2ecf20Sopenharmony_ci */
3628c2ecf20Sopenharmony_ciint clk_enable(struct clk *clk)
3638c2ecf20Sopenharmony_ci{
3648c2ecf20Sopenharmony_ci	if (!clk)
3658c2ecf20Sopenharmony_ci		return 0;
3668c2ecf20Sopenharmony_ci	mutex_lock(&clocks_mutex);
3678c2ecf20Sopenharmony_ci	clk_enable_unlocked(clk);
3688c2ecf20Sopenharmony_ci	mutex_unlock(&clocks_mutex);
3698c2ecf20Sopenharmony_ci	return 0;
3708c2ecf20Sopenharmony_ci}
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ciEXPORT_SYMBOL(clk_enable);
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_civoid clk_disable(struct clk *clk)
3758c2ecf20Sopenharmony_ci{
3768c2ecf20Sopenharmony_ci	if (!clk)
3778c2ecf20Sopenharmony_ci		return;
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_ci	mutex_lock(&clocks_mutex);
3808c2ecf20Sopenharmony_ci	clk_disable_unlocked(clk);
3818c2ecf20Sopenharmony_ci	mutex_unlock(&clocks_mutex);
3828c2ecf20Sopenharmony_ci}
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ciEXPORT_SYMBOL(clk_disable);
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_cistruct clk *clk_get_parent(struct clk *clk)
3878c2ecf20Sopenharmony_ci{
3888c2ecf20Sopenharmony_ci	return NULL;
3898c2ecf20Sopenharmony_ci}
3908c2ecf20Sopenharmony_ciEXPORT_SYMBOL(clk_get_parent);
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ciint clk_set_parent(struct clk *clk, struct clk *parent)
3938c2ecf20Sopenharmony_ci{
3948c2ecf20Sopenharmony_ci	return 0;
3958c2ecf20Sopenharmony_ci}
3968c2ecf20Sopenharmony_ciEXPORT_SYMBOL(clk_set_parent);
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_ciunsigned long clk_get_rate(struct clk *clk)
3998c2ecf20Sopenharmony_ci{
4008c2ecf20Sopenharmony_ci	if (!clk)
4018c2ecf20Sopenharmony_ci		return 0;
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci	return clk->rate;
4048c2ecf20Sopenharmony_ci}
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ciEXPORT_SYMBOL(clk_get_rate);
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ciint clk_set_rate(struct clk *clk, unsigned long rate)
4098c2ecf20Sopenharmony_ci{
4108c2ecf20Sopenharmony_ci	return 0;
4118c2ecf20Sopenharmony_ci}
4128c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(clk_set_rate);
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_cilong clk_round_rate(struct clk *clk, unsigned long rate)
4158c2ecf20Sopenharmony_ci{
4168c2ecf20Sopenharmony_ci	return 0;
4178c2ecf20Sopenharmony_ci}
4188c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(clk_round_rate);
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_cistatic struct clk_lookup bcm3368_clks[] = {
4218c2ecf20Sopenharmony_ci	/* fixed rate clocks */
4228c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "periph", &clk_periph),
4238c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
4248c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
4258c2ecf20Sopenharmony_ci	/* gated clocks */
4268c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
4278c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
4288c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
4298c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
4308c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
4318c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "spi", &clk_spi),
4328c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "pcm", &clk_pcm),
4338c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
4348c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
4358c2ecf20Sopenharmony_ci};
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_cistatic struct clk_lookup bcm6328_clks[] = {
4388c2ecf20Sopenharmony_ci	/* fixed rate clocks */
4398c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "periph", &clk_periph),
4408c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
4418c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
4428c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
4438c2ecf20Sopenharmony_ci	/* gated clocks */
4448c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
4458c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
4468c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
4478c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
4488c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "pcie", &clk_pcie),
4498c2ecf20Sopenharmony_ci};
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_cistatic struct clk_lookup bcm6338_clks[] = {
4528c2ecf20Sopenharmony_ci	/* fixed rate clocks */
4538c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "periph", &clk_periph),
4548c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
4558c2ecf20Sopenharmony_ci	/* gated clocks */
4568c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
4578c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
4588c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
4598c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
4608c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
4618c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "spi", &clk_spi),
4628c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
4638c2ecf20Sopenharmony_ci};
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_cistatic struct clk_lookup bcm6345_clks[] = {
4668c2ecf20Sopenharmony_ci	/* fixed rate clocks */
4678c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "periph", &clk_periph),
4688c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
4698c2ecf20Sopenharmony_ci	/* gated clocks */
4708c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
4718c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
4728c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
4738c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
4748c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
4758c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "spi", &clk_spi),
4768c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
4778c2ecf20Sopenharmony_ci};
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_cistatic struct clk_lookup bcm6348_clks[] = {
4808c2ecf20Sopenharmony_ci	/* fixed rate clocks */
4818c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "periph", &clk_periph),
4828c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
4838c2ecf20Sopenharmony_ci	/* gated clocks */
4848c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
4858c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
4868c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
4878c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
4888c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
4898c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "spi", &clk_spi),
4908c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
4918c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet_misc),
4928c2ecf20Sopenharmony_ci};
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_cistatic struct clk_lookup bcm6358_clks[] = {
4958c2ecf20Sopenharmony_ci	/* fixed rate clocks */
4968c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "periph", &clk_periph),
4978c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
4988c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
4998c2ecf20Sopenharmony_ci	/* gated clocks */
5008c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet0", &clk_enet0),
5018c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enet1", &clk_enet1),
5028c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "ephy", &clk_ephy),
5038c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
5048c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
5058c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "spi", &clk_spi),
5068c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "pcm", &clk_pcm),
5078c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "swpkt_sar", &clk_swpkt_sar),
5088c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "swpkt_usb", &clk_swpkt_usb),
5098c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
5108c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
5118c2ecf20Sopenharmony_ci};
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_cistatic struct clk_lookup bcm6362_clks[] = {
5148c2ecf20Sopenharmony_ci	/* fixed rate clocks */
5158c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "periph", &clk_periph),
5168c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
5178c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
5188c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
5198c2ecf20Sopenharmony_ci	/* gated clocks */
5208c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
5218c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
5228c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
5238c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "spi", &clk_spi),
5248c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
5258c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "pcie", &clk_pcie),
5268c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
5278c2ecf20Sopenharmony_ci};
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_cistatic struct clk_lookup bcm6368_clks[] = {
5308c2ecf20Sopenharmony_ci	/* fixed rate clocks */
5318c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "periph", &clk_periph),
5328c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
5338c2ecf20Sopenharmony_ci	CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
5348c2ecf20Sopenharmony_ci	/* gated clocks */
5358c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
5368c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbh", &clk_usbh),
5378c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "usbd", &clk_usbd),
5388c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "spi", &clk_spi),
5398c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "xtm", &clk_xtm),
5408c2ecf20Sopenharmony_ci	CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
5418c2ecf20Sopenharmony_ci};
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_ci#define HSSPI_PLL_HZ_6328	133333333
5448c2ecf20Sopenharmony_ci#define HSSPI_PLL_HZ_6362	400000000
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_cistatic int __init bcm63xx_clk_init(void)
5478c2ecf20Sopenharmony_ci{
5488c2ecf20Sopenharmony_ci	switch (bcm63xx_get_cpu_id()) {
5498c2ecf20Sopenharmony_ci	case BCM3368_CPU_ID:
5508c2ecf20Sopenharmony_ci		clkdev_add_table(bcm3368_clks, ARRAY_SIZE(bcm3368_clks));
5518c2ecf20Sopenharmony_ci		break;
5528c2ecf20Sopenharmony_ci	case BCM6328_CPU_ID:
5538c2ecf20Sopenharmony_ci		clk_hsspi_pll.rate = HSSPI_PLL_HZ_6328;
5548c2ecf20Sopenharmony_ci		clkdev_add_table(bcm6328_clks, ARRAY_SIZE(bcm6328_clks));
5558c2ecf20Sopenharmony_ci		break;
5568c2ecf20Sopenharmony_ci	case BCM6338_CPU_ID:
5578c2ecf20Sopenharmony_ci		clkdev_add_table(bcm6338_clks, ARRAY_SIZE(bcm6338_clks));
5588c2ecf20Sopenharmony_ci		break;
5598c2ecf20Sopenharmony_ci	case BCM6345_CPU_ID:
5608c2ecf20Sopenharmony_ci		clkdev_add_table(bcm6345_clks, ARRAY_SIZE(bcm6345_clks));
5618c2ecf20Sopenharmony_ci		break;
5628c2ecf20Sopenharmony_ci	case BCM6348_CPU_ID:
5638c2ecf20Sopenharmony_ci		clkdev_add_table(bcm6348_clks, ARRAY_SIZE(bcm6348_clks));
5648c2ecf20Sopenharmony_ci		break;
5658c2ecf20Sopenharmony_ci	case BCM6358_CPU_ID:
5668c2ecf20Sopenharmony_ci		clkdev_add_table(bcm6358_clks, ARRAY_SIZE(bcm6358_clks));
5678c2ecf20Sopenharmony_ci		break;
5688c2ecf20Sopenharmony_ci	case BCM6362_CPU_ID:
5698c2ecf20Sopenharmony_ci		clk_hsspi_pll.rate = HSSPI_PLL_HZ_6362;
5708c2ecf20Sopenharmony_ci		clkdev_add_table(bcm6362_clks, ARRAY_SIZE(bcm6362_clks));
5718c2ecf20Sopenharmony_ci		break;
5728c2ecf20Sopenharmony_ci	case BCM6368_CPU_ID:
5738c2ecf20Sopenharmony_ci		clkdev_add_table(bcm6368_clks, ARRAY_SIZE(bcm6368_clks));
5748c2ecf20Sopenharmony_ci		break;
5758c2ecf20Sopenharmony_ci	}
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_ci	return 0;
5788c2ecf20Sopenharmony_ci}
5798c2ecf20Sopenharmony_ciarch_initcall(bcm63xx_clk_init);
580