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