1e7300d04SMaxime Bizon /* 2e7300d04SMaxime Bizon * This file is subject to the terms and conditions of the GNU General Public 3e7300d04SMaxime Bizon * License. See the file "COPYING" in the main directory of this archive 4e7300d04SMaxime Bizon * for more details. 5e7300d04SMaxime Bizon * 6e7300d04SMaxime Bizon * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> 7e7300d04SMaxime Bizon */ 8e7300d04SMaxime Bizon 926dd3e4fSPaul Gortmaker #include <linux/init.h> 1026dd3e4fSPaul Gortmaker #include <linux/export.h> 11e7300d04SMaxime Bizon #include <linux/mutex.h> 12e7300d04SMaxime Bizon #include <linux/err.h> 13e7300d04SMaxime Bizon #include <linux/clk.h> 14c5af3c2dSJonas Gorski #include <linux/clkdev.h> 1504712f3fSMaxime Bizon #include <linux/delay.h> 16e7300d04SMaxime Bizon #include <bcm63xx_cpu.h> 17e7300d04SMaxime Bizon #include <bcm63xx_io.h> 18e7300d04SMaxime Bizon #include <bcm63xx_regs.h> 19ba00e2e5SJonas Gorski #include <bcm63xx_reset.h> 20042df4faSJonas Gorski 21042df4faSJonas Gorski struct clk { 22042df4faSJonas Gorski void (*set)(struct clk *, int); 23042df4faSJonas Gorski unsigned int rate; 24042df4faSJonas Gorski unsigned int usage; 25042df4faSJonas Gorski int id; 26042df4faSJonas Gorski }; 27e7300d04SMaxime Bizon 28e7300d04SMaxime Bizon static DEFINE_MUTEX(clocks_mutex); 29e7300d04SMaxime Bizon 30e7300d04SMaxime Bizon 31e7300d04SMaxime Bizon static void clk_enable_unlocked(struct clk *clk) 32e7300d04SMaxime Bizon { 33e7300d04SMaxime Bizon if (clk->set && (clk->usage++) == 0) 34e7300d04SMaxime Bizon clk->set(clk, 1); 35e7300d04SMaxime Bizon } 36e7300d04SMaxime Bizon 37e7300d04SMaxime Bizon static void clk_disable_unlocked(struct clk *clk) 38e7300d04SMaxime Bizon { 39e7300d04SMaxime Bizon if (clk->set && (--clk->usage) == 0) 40e7300d04SMaxime Bizon clk->set(clk, 0); 41e7300d04SMaxime Bizon } 42e7300d04SMaxime Bizon 43e7300d04SMaxime Bizon static void bcm_hwclock_set(u32 mask, int enable) 44e7300d04SMaxime Bizon { 45e7300d04SMaxime Bizon u32 reg; 46e7300d04SMaxime Bizon 47e7300d04SMaxime Bizon reg = bcm_perf_readl(PERF_CKCTL_REG); 48e7300d04SMaxime Bizon if (enable) 49e7300d04SMaxime Bizon reg |= mask; 50e7300d04SMaxime Bizon else 51e7300d04SMaxime Bizon reg &= ~mask; 52e7300d04SMaxime Bizon bcm_perf_writel(reg, PERF_CKCTL_REG); 53e7300d04SMaxime Bizon } 54e7300d04SMaxime Bizon 55e7300d04SMaxime Bizon /* 56e7300d04SMaxime Bizon * Ethernet MAC "misc" clock: dma clocks and main clock on 6348 57e7300d04SMaxime Bizon */ 58e7300d04SMaxime Bizon static void enet_misc_set(struct clk *clk, int enable) 59e7300d04SMaxime Bizon { 60e7300d04SMaxime Bizon u32 mask; 61e7300d04SMaxime Bizon 62e7300d04SMaxime Bizon if (BCMCPU_IS_6338()) 63e7300d04SMaxime Bizon mask = CKCTL_6338_ENET_EN; 64e7300d04SMaxime Bizon else if (BCMCPU_IS_6345()) 65e7300d04SMaxime Bizon mask = CKCTL_6345_ENET_EN; 66e7300d04SMaxime Bizon else if (BCMCPU_IS_6348()) 67e7300d04SMaxime Bizon mask = CKCTL_6348_ENET_EN; 68e7300d04SMaxime Bizon else 69e7300d04SMaxime Bizon /* BCMCPU_IS_6358 */ 70e7300d04SMaxime Bizon mask = CKCTL_6358_EMUSB_EN; 71e7300d04SMaxime Bizon bcm_hwclock_set(mask, enable); 72e7300d04SMaxime Bizon } 73e7300d04SMaxime Bizon 74e7300d04SMaxime Bizon static struct clk clk_enet_misc = { 75e7300d04SMaxime Bizon .set = enet_misc_set, 76e7300d04SMaxime Bizon }; 77e7300d04SMaxime Bizon 78e7300d04SMaxime Bizon /* 79e7300d04SMaxime Bizon * Ethernet MAC clocks: only revelant on 6358, silently enable misc 80e7300d04SMaxime Bizon * clocks 81e7300d04SMaxime Bizon */ 82e7300d04SMaxime Bizon static void enetx_set(struct clk *clk, int enable) 83e7300d04SMaxime Bizon { 84e7300d04SMaxime Bizon if (enable) 85e7300d04SMaxime Bizon clk_enable_unlocked(&clk_enet_misc); 86e7300d04SMaxime Bizon else 87e7300d04SMaxime Bizon clk_disable_unlocked(&clk_enet_misc); 88e7300d04SMaxime Bizon 897b933421SFlorian Fainelli if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) { 90e7300d04SMaxime Bizon u32 mask; 91e7300d04SMaxime Bizon 92e7300d04SMaxime Bizon if (clk->id == 0) 93e7300d04SMaxime Bizon mask = CKCTL_6358_ENET0_EN; 94e7300d04SMaxime Bizon else 95e7300d04SMaxime Bizon mask = CKCTL_6358_ENET1_EN; 96e7300d04SMaxime Bizon bcm_hwclock_set(mask, enable); 97e7300d04SMaxime Bizon } 98e7300d04SMaxime Bizon } 99e7300d04SMaxime Bizon 100e7300d04SMaxime Bizon static struct clk clk_enet0 = { 101e7300d04SMaxime Bizon .id = 0, 102e7300d04SMaxime Bizon .set = enetx_set, 103e7300d04SMaxime Bizon }; 104e7300d04SMaxime Bizon 105e7300d04SMaxime Bizon static struct clk clk_enet1 = { 106e7300d04SMaxime Bizon .id = 1, 107e7300d04SMaxime Bizon .set = enetx_set, 108e7300d04SMaxime Bizon }; 109e7300d04SMaxime Bizon 110e7300d04SMaxime Bizon /* 111e7300d04SMaxime Bizon * Ethernet PHY clock 112e7300d04SMaxime Bizon */ 113e7300d04SMaxime Bizon static void ephy_set(struct clk *clk, int enable) 114e7300d04SMaxime Bizon { 1157b933421SFlorian Fainelli if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) 116e7300d04SMaxime Bizon bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable); 117e7300d04SMaxime Bizon } 118e7300d04SMaxime Bizon 119e7300d04SMaxime Bizon 120e7300d04SMaxime Bizon static struct clk clk_ephy = { 121e7300d04SMaxime Bizon .set = ephy_set, 122e7300d04SMaxime Bizon }; 123e7300d04SMaxime Bizon 124e7300d04SMaxime Bizon /* 12504712f3fSMaxime Bizon * Ethernet switch clock 12604712f3fSMaxime Bizon */ 12704712f3fSMaxime Bizon static void enetsw_set(struct clk *clk, int enable) 12804712f3fSMaxime Bizon { 1291cd1c049SJonas Gorski if (BCMCPU_IS_6328()) 1301cd1c049SJonas Gorski bcm_hwclock_set(CKCTL_6328_ROBOSW_EN, enable); 1311cd1c049SJonas Gorski else if (BCMCPU_IS_6362()) 1321cd1c049SJonas Gorski bcm_hwclock_set(CKCTL_6362_ROBOSW_EN, enable); 1331cd1c049SJonas Gorski else if (BCMCPU_IS_6368()) 134d9831a41SFlorian Fainelli bcm_hwclock_set(CKCTL_6368_ROBOSW_EN | 13504712f3fSMaxime Bizon CKCTL_6368_SWPKT_USB_EN | 1361cd1c049SJonas Gorski CKCTL_6368_SWPKT_SAR_EN, 1371cd1c049SJonas Gorski enable); 1381cd1c049SJonas Gorski else 1391cd1c049SJonas Gorski return; 1401cd1c049SJonas Gorski 14104712f3fSMaxime Bizon if (enable) { 14204712f3fSMaxime Bizon /* reset switch core afer clock change */ 143ba00e2e5SJonas Gorski bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1); 14404712f3fSMaxime Bizon msleep(10); 145ba00e2e5SJonas Gorski bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0); 14604712f3fSMaxime Bizon msleep(10); 14704712f3fSMaxime Bizon } 14804712f3fSMaxime Bizon } 14904712f3fSMaxime Bizon 15004712f3fSMaxime Bizon static struct clk clk_enetsw = { 15104712f3fSMaxime Bizon .set = enetsw_set, 15204712f3fSMaxime Bizon }; 15304712f3fSMaxime Bizon 15404712f3fSMaxime Bizon /* 155e7300d04SMaxime Bizon * PCM clock 156e7300d04SMaxime Bizon */ 157e7300d04SMaxime Bizon static void pcm_set(struct clk *clk, int enable) 158e7300d04SMaxime Bizon { 1597b933421SFlorian Fainelli if (BCMCPU_IS_3368()) 1607b933421SFlorian Fainelli bcm_hwclock_set(CKCTL_3368_PCM_EN, enable); 1617b933421SFlorian Fainelli if (BCMCPU_IS_6358()) 162e7300d04SMaxime Bizon bcm_hwclock_set(CKCTL_6358_PCM_EN, enable); 163e7300d04SMaxime Bizon } 164e7300d04SMaxime Bizon 165e7300d04SMaxime Bizon static struct clk clk_pcm = { 166e7300d04SMaxime Bizon .set = pcm_set, 167e7300d04SMaxime Bizon }; 168e7300d04SMaxime Bizon 169e7300d04SMaxime Bizon /* 170e7300d04SMaxime Bizon * USB host clock 171e7300d04SMaxime Bizon */ 172e7300d04SMaxime Bizon static void usbh_set(struct clk *clk, int enable) 173e7300d04SMaxime Bizon { 174dd89d60cSKevin Cernekee if (BCMCPU_IS_6328()) 175dd89d60cSKevin Cernekee bcm_hwclock_set(CKCTL_6328_USBH_EN, enable); 176dd89d60cSKevin Cernekee else if (BCMCPU_IS_6348()) 177e7300d04SMaxime Bizon bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); 1781cd1c049SJonas Gorski else if (BCMCPU_IS_6362()) 1791cd1c049SJonas Gorski bcm_hwclock_set(CKCTL_6362_USBH_EN, enable); 18004712f3fSMaxime Bizon else if (BCMCPU_IS_6368()) 181d9831a41SFlorian Fainelli bcm_hwclock_set(CKCTL_6368_USBH_EN, enable); 182e7300d04SMaxime Bizon } 183e7300d04SMaxime Bizon 184e7300d04SMaxime Bizon static struct clk clk_usbh = { 185e7300d04SMaxime Bizon .set = usbh_set, 186e7300d04SMaxime Bizon }; 187e7300d04SMaxime Bizon 188e7300d04SMaxime Bizon /* 189dd89d60cSKevin Cernekee * USB device clock 190dd89d60cSKevin Cernekee */ 191dd89d60cSKevin Cernekee static void usbd_set(struct clk *clk, int enable) 192dd89d60cSKevin Cernekee { 193dd89d60cSKevin Cernekee if (BCMCPU_IS_6328()) 194dd89d60cSKevin Cernekee bcm_hwclock_set(CKCTL_6328_USBD_EN, enable); 1951cd1c049SJonas Gorski else if (BCMCPU_IS_6362()) 1961cd1c049SJonas Gorski bcm_hwclock_set(CKCTL_6362_USBD_EN, enable); 197dd89d60cSKevin Cernekee else if (BCMCPU_IS_6368()) 198dd89d60cSKevin Cernekee bcm_hwclock_set(CKCTL_6368_USBD_EN, enable); 199dd89d60cSKevin Cernekee } 200dd89d60cSKevin Cernekee 201dd89d60cSKevin Cernekee static struct clk clk_usbd = { 202dd89d60cSKevin Cernekee .set = usbd_set, 203dd89d60cSKevin Cernekee }; 204dd89d60cSKevin Cernekee 205dd89d60cSKevin Cernekee /* 206e7300d04SMaxime Bizon * SPI clock 207e7300d04SMaxime Bizon */ 208e7300d04SMaxime Bizon static void spi_set(struct clk *clk, int enable) 209e7300d04SMaxime Bizon { 210e7300d04SMaxime Bizon u32 mask; 211e7300d04SMaxime Bizon 212e7300d04SMaxime Bizon if (BCMCPU_IS_6338()) 213e7300d04SMaxime Bizon mask = CKCTL_6338_SPI_EN; 214e7300d04SMaxime Bizon else if (BCMCPU_IS_6348()) 215e7300d04SMaxime Bizon mask = CKCTL_6348_SPI_EN; 2167b933421SFlorian Fainelli else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) 217e7300d04SMaxime Bizon mask = CKCTL_6358_SPI_EN; 21808a41d12SJonas Gorski else if (BCMCPU_IS_6362()) 21908a41d12SJonas Gorski mask = CKCTL_6362_SPI_EN; 22019372b24SFlorian Fainelli else 22119372b24SFlorian Fainelli /* BCMCPU_IS_6368 */ 22219372b24SFlorian Fainelli mask = CKCTL_6368_SPI_EN; 223e7300d04SMaxime Bizon bcm_hwclock_set(mask, enable); 224e7300d04SMaxime Bizon } 225e7300d04SMaxime Bizon 226e7300d04SMaxime Bizon static struct clk clk_spi = { 227e7300d04SMaxime Bizon .set = spi_set, 228e7300d04SMaxime Bizon }; 229e7300d04SMaxime Bizon 230e7300d04SMaxime Bizon /* 2310ebe8aaeSJonas Gorski * HSSPI clock 2320ebe8aaeSJonas Gorski */ 2330ebe8aaeSJonas Gorski static void hsspi_set(struct clk *clk, int enable) 2340ebe8aaeSJonas Gorski { 2350ebe8aaeSJonas Gorski u32 mask; 2360ebe8aaeSJonas Gorski 2370ebe8aaeSJonas Gorski if (BCMCPU_IS_6328()) 2380ebe8aaeSJonas Gorski mask = CKCTL_6328_HSSPI_EN; 2390ebe8aaeSJonas Gorski else if (BCMCPU_IS_6362()) 2400ebe8aaeSJonas Gorski mask = CKCTL_6362_HSSPI_EN; 2410ebe8aaeSJonas Gorski else 2420ebe8aaeSJonas Gorski return; 2430ebe8aaeSJonas Gorski 2440ebe8aaeSJonas Gorski bcm_hwclock_set(mask, enable); 2450ebe8aaeSJonas Gorski } 2460ebe8aaeSJonas Gorski 2470ebe8aaeSJonas Gorski static struct clk clk_hsspi = { 2480ebe8aaeSJonas Gorski .set = hsspi_set, 2490ebe8aaeSJonas Gorski }; 2500ebe8aaeSJonas Gorski 251*5d691036SJonas Gorski /* 252*5d691036SJonas Gorski * HSSPI PLL 253*5d691036SJonas Gorski */ 254*5d691036SJonas Gorski static struct clk clk_hsspi_pll; 2550ebe8aaeSJonas Gorski 2560ebe8aaeSJonas Gorski /* 25704712f3fSMaxime Bizon * XTM clock 25804712f3fSMaxime Bizon */ 25904712f3fSMaxime Bizon static void xtm_set(struct clk *clk, int enable) 26004712f3fSMaxime Bizon { 26104712f3fSMaxime Bizon if (!BCMCPU_IS_6368()) 26204712f3fSMaxime Bizon return; 26304712f3fSMaxime Bizon 264d9831a41SFlorian Fainelli bcm_hwclock_set(CKCTL_6368_SAR_EN | 26504712f3fSMaxime Bizon CKCTL_6368_SWPKT_SAR_EN, enable); 26604712f3fSMaxime Bizon 26704712f3fSMaxime Bizon if (enable) { 26804712f3fSMaxime Bizon /* reset sar core afer clock change */ 269ba00e2e5SJonas Gorski bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1); 27004712f3fSMaxime Bizon mdelay(1); 271ba00e2e5SJonas Gorski bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0); 27204712f3fSMaxime Bizon mdelay(1); 27304712f3fSMaxime Bizon } 27404712f3fSMaxime Bizon } 27504712f3fSMaxime Bizon 27604712f3fSMaxime Bizon 27704712f3fSMaxime Bizon static struct clk clk_xtm = { 27804712f3fSMaxime Bizon .set = xtm_set, 27904712f3fSMaxime Bizon }; 28004712f3fSMaxime Bizon 28104712f3fSMaxime Bizon /* 2820b55561bSFlorian Fainelli * IPsec clock 2830b55561bSFlorian Fainelli */ 2840b55561bSFlorian Fainelli static void ipsec_set(struct clk *clk, int enable) 2850b55561bSFlorian Fainelli { 2861cd1c049SJonas Gorski if (BCMCPU_IS_6362()) 2871cd1c049SJonas Gorski bcm_hwclock_set(CKCTL_6362_IPSEC_EN, enable); 2881cd1c049SJonas Gorski else if (BCMCPU_IS_6368()) 2890b55561bSFlorian Fainelli bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable); 2900b55561bSFlorian Fainelli } 2910b55561bSFlorian Fainelli 2920b55561bSFlorian Fainelli static struct clk clk_ipsec = { 2930b55561bSFlorian Fainelli .set = ipsec_set, 2940b55561bSFlorian Fainelli }; 2950b55561bSFlorian Fainelli 2960b55561bSFlorian Fainelli /* 297f2d1035eSJonas Gorski * PCIe clock 298f2d1035eSJonas Gorski */ 299f2d1035eSJonas Gorski 300f2d1035eSJonas Gorski static void pcie_set(struct clk *clk, int enable) 301f2d1035eSJonas Gorski { 3021cd1c049SJonas Gorski if (BCMCPU_IS_6328()) 303f2d1035eSJonas Gorski bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable); 3041cd1c049SJonas Gorski else if (BCMCPU_IS_6362()) 3051cd1c049SJonas Gorski bcm_hwclock_set(CKCTL_6362_PCIE_EN, enable); 306f2d1035eSJonas Gorski } 307f2d1035eSJonas Gorski 308f2d1035eSJonas Gorski static struct clk clk_pcie = { 309f2d1035eSJonas Gorski .set = pcie_set, 310f2d1035eSJonas Gorski }; 311f2d1035eSJonas Gorski 312f2d1035eSJonas Gorski /* 313e7300d04SMaxime Bizon * Internal peripheral clock 314e7300d04SMaxime Bizon */ 315e7300d04SMaxime Bizon static struct clk clk_periph = { 316e7300d04SMaxime Bizon .rate = (50 * 1000 * 1000), 317e7300d04SMaxime Bizon }; 318e7300d04SMaxime Bizon 319e7300d04SMaxime Bizon 320e7300d04SMaxime Bizon /* 321e7300d04SMaxime Bizon * Linux clock API implementation 322e7300d04SMaxime Bizon */ 323e7300d04SMaxime Bizon int clk_enable(struct clk *clk) 324e7300d04SMaxime Bizon { 325e7300d04SMaxime Bizon mutex_lock(&clocks_mutex); 326e7300d04SMaxime Bizon clk_enable_unlocked(clk); 327e7300d04SMaxime Bizon mutex_unlock(&clocks_mutex); 328e7300d04SMaxime Bizon return 0; 329e7300d04SMaxime Bizon } 330e7300d04SMaxime Bizon 331e7300d04SMaxime Bizon EXPORT_SYMBOL(clk_enable); 332e7300d04SMaxime Bizon 333e7300d04SMaxime Bizon void clk_disable(struct clk *clk) 334e7300d04SMaxime Bizon { 33500ca0250SMasahiro Yamada if (!clk) 33600ca0250SMasahiro Yamada return; 33700ca0250SMasahiro Yamada 338e7300d04SMaxime Bizon mutex_lock(&clocks_mutex); 339e7300d04SMaxime Bizon clk_disable_unlocked(clk); 340e7300d04SMaxime Bizon mutex_unlock(&clocks_mutex); 341e7300d04SMaxime Bizon } 342e7300d04SMaxime Bizon 343e7300d04SMaxime Bizon EXPORT_SYMBOL(clk_disable); 344e7300d04SMaxime Bizon 345e7300d04SMaxime Bizon unsigned long clk_get_rate(struct clk *clk) 346e7300d04SMaxime Bizon { 3471b495faeSJonas Gorski if (!clk) 3481b495faeSJonas Gorski return 0; 3491b495faeSJonas Gorski 350e7300d04SMaxime Bizon return clk->rate; 351e7300d04SMaxime Bizon } 352e7300d04SMaxime Bizon 353e7300d04SMaxime Bizon EXPORT_SYMBOL(clk_get_rate); 354e7300d04SMaxime Bizon 3557aa2d052SMarkos Chandras int clk_set_rate(struct clk *clk, unsigned long rate) 3567aa2d052SMarkos Chandras { 3577aa2d052SMarkos Chandras return 0; 3587aa2d052SMarkos Chandras } 3597aa2d052SMarkos Chandras EXPORT_SYMBOL_GPL(clk_set_rate); 3607aa2d052SMarkos Chandras 3617aa2d052SMarkos Chandras long clk_round_rate(struct clk *clk, unsigned long rate) 3627aa2d052SMarkos Chandras { 3637aa2d052SMarkos Chandras return 0; 3647aa2d052SMarkos Chandras } 3657aa2d052SMarkos Chandras EXPORT_SYMBOL_GPL(clk_round_rate); 3667aa2d052SMarkos Chandras 367c5af3c2dSJonas Gorski static struct clk_lookup bcm3368_clks[] = { 368c5af3c2dSJonas Gorski /* fixed rate clocks */ 369c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "periph", &clk_periph), 370243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph), 371243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph), 372c5af3c2dSJonas Gorski /* gated clocks */ 373c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet0", &clk_enet0), 374c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet1", &clk_enet1), 375c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "ephy", &clk_ephy), 376c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbh", &clk_usbh), 377c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbd", &clk_usbd), 378c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "spi", &clk_spi), 379c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "pcm", &clk_pcm), 380c5af3c2dSJonas Gorski }; 381e7300d04SMaxime Bizon 382c5af3c2dSJonas Gorski static struct clk_lookup bcm6328_clks[] = { 383c5af3c2dSJonas Gorski /* fixed rate clocks */ 384c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "periph", &clk_periph), 385243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph), 386243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph), 387*5d691036SJonas Gorski CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll), 388c5af3c2dSJonas Gorski /* gated clocks */ 389c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enetsw", &clk_enetsw), 390c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbh", &clk_usbh), 391c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbd", &clk_usbd), 392c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "hsspi", &clk_hsspi), 393c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "pcie", &clk_pcie), 394c5af3c2dSJonas Gorski }; 395e7300d04SMaxime Bizon 396c5af3c2dSJonas Gorski static struct clk_lookup bcm6338_clks[] = { 397c5af3c2dSJonas Gorski /* fixed rate clocks */ 398c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "periph", &clk_periph), 399243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph), 400c5af3c2dSJonas Gorski /* gated clocks */ 401c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet0", &clk_enet0), 402c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet1", &clk_enet1), 403c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "ephy", &clk_ephy), 404c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbh", &clk_usbh), 405c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbd", &clk_usbd), 406c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "spi", &clk_spi), 407c5af3c2dSJonas Gorski }; 408e7300d04SMaxime Bizon 409c5af3c2dSJonas Gorski static struct clk_lookup bcm6345_clks[] = { 410c5af3c2dSJonas Gorski /* fixed rate clocks */ 411c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "periph", &clk_periph), 412243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph), 413c5af3c2dSJonas Gorski /* gated clocks */ 414c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet0", &clk_enet0), 415c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet1", &clk_enet1), 416c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "ephy", &clk_ephy), 417c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbh", &clk_usbh), 418c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbd", &clk_usbd), 419c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "spi", &clk_spi), 420c5af3c2dSJonas Gorski }; 421c5af3c2dSJonas Gorski 422c5af3c2dSJonas Gorski static struct clk_lookup bcm6348_clks[] = { 423c5af3c2dSJonas Gorski /* fixed rate clocks */ 424c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "periph", &clk_periph), 425243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph), 426c5af3c2dSJonas Gorski /* gated clocks */ 427c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet0", &clk_enet0), 428c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet1", &clk_enet1), 429c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "ephy", &clk_ephy), 430c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbh", &clk_usbh), 431c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbd", &clk_usbd), 432c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "spi", &clk_spi), 433c5af3c2dSJonas Gorski }; 434c5af3c2dSJonas Gorski 435c5af3c2dSJonas Gorski static struct clk_lookup bcm6358_clks[] = { 436c5af3c2dSJonas Gorski /* fixed rate clocks */ 437c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "periph", &clk_periph), 438243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph), 439243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph), 440c5af3c2dSJonas Gorski /* gated clocks */ 441c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet0", &clk_enet0), 442c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enet1", &clk_enet1), 443c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "ephy", &clk_ephy), 444c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbh", &clk_usbh), 445c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbd", &clk_usbd), 446c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "spi", &clk_spi), 447c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "pcm", &clk_pcm), 448c5af3c2dSJonas Gorski }; 449c5af3c2dSJonas Gorski 450c5af3c2dSJonas Gorski static struct clk_lookup bcm6362_clks[] = { 451c5af3c2dSJonas Gorski /* fixed rate clocks */ 452c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "periph", &clk_periph), 453243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph), 454243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph), 455*5d691036SJonas Gorski CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll), 456c5af3c2dSJonas Gorski /* gated clocks */ 457c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enetsw", &clk_enetsw), 458c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbh", &clk_usbh), 459c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbd", &clk_usbd), 460c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "spi", &clk_spi), 461c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "hsspi", &clk_hsspi), 462c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "pcie", &clk_pcie), 463c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "ipsec", &clk_ipsec), 464c5af3c2dSJonas Gorski }; 465c5af3c2dSJonas Gorski 466c5af3c2dSJonas Gorski static struct clk_lookup bcm6368_clks[] = { 467c5af3c2dSJonas Gorski /* fixed rate clocks */ 468c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "periph", &clk_periph), 469243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph), 470243fa279SJonas Gorski CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph), 471c5af3c2dSJonas Gorski /* gated clocks */ 472c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "enetsw", &clk_enetsw), 473c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbh", &clk_usbh), 474c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "usbd", &clk_usbd), 475c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "spi", &clk_spi), 476c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "xtm", &clk_xtm), 477c5af3c2dSJonas Gorski CLKDEV_INIT(NULL, "ipsec", &clk_ipsec), 478c5af3c2dSJonas Gorski }; 47926b8c07fSJonas Gorski 48026b8c07fSJonas Gorski #define HSSPI_PLL_HZ_6328 133333333 48126b8c07fSJonas Gorski #define HSSPI_PLL_HZ_6362 400000000 48226b8c07fSJonas Gorski 48326b8c07fSJonas Gorski static int __init bcm63xx_clk_init(void) 48426b8c07fSJonas Gorski { 48526b8c07fSJonas Gorski switch (bcm63xx_get_cpu_id()) { 486c5af3c2dSJonas Gorski case BCM3368_CPU_ID: 487c5af3c2dSJonas Gorski clkdev_add_table(bcm3368_clks, ARRAY_SIZE(bcm3368_clks)); 488c5af3c2dSJonas Gorski break; 48926b8c07fSJonas Gorski case BCM6328_CPU_ID: 490*5d691036SJonas Gorski clk_hsspi_pll.rate = HSSPI_PLL_HZ_6328; 491c5af3c2dSJonas Gorski clkdev_add_table(bcm6328_clks, ARRAY_SIZE(bcm6328_clks)); 492c5af3c2dSJonas Gorski break; 493c5af3c2dSJonas Gorski case BCM6338_CPU_ID: 494c5af3c2dSJonas Gorski clkdev_add_table(bcm6338_clks, ARRAY_SIZE(bcm6338_clks)); 495c5af3c2dSJonas Gorski break; 496c5af3c2dSJonas Gorski case BCM6345_CPU_ID: 497c5af3c2dSJonas Gorski clkdev_add_table(bcm6345_clks, ARRAY_SIZE(bcm6345_clks)); 498c5af3c2dSJonas Gorski break; 499c5af3c2dSJonas Gorski case BCM6348_CPU_ID: 500c5af3c2dSJonas Gorski clkdev_add_table(bcm6348_clks, ARRAY_SIZE(bcm6348_clks)); 501c5af3c2dSJonas Gorski break; 502c5af3c2dSJonas Gorski case BCM6358_CPU_ID: 503c5af3c2dSJonas Gorski clkdev_add_table(bcm6358_clks, ARRAY_SIZE(bcm6358_clks)); 50426b8c07fSJonas Gorski break; 50526b8c07fSJonas Gorski case BCM6362_CPU_ID: 506*5d691036SJonas Gorski clk_hsspi_pll.rate = HSSPI_PLL_HZ_6362; 507c5af3c2dSJonas Gorski clkdev_add_table(bcm6362_clks, ARRAY_SIZE(bcm6362_clks)); 508c5af3c2dSJonas Gorski break; 509c5af3c2dSJonas Gorski case BCM6368_CPU_ID: 510c5af3c2dSJonas Gorski clkdev_add_table(bcm6368_clks, ARRAY_SIZE(bcm6368_clks)); 51126b8c07fSJonas Gorski break; 51226b8c07fSJonas Gorski } 51326b8c07fSJonas Gorski 51426b8c07fSJonas Gorski return 0; 51526b8c07fSJonas Gorski } 51626b8c07fSJonas Gorski arch_initcall(bcm63xx_clk_init); 517