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