brintos

brintos / linux-shallow public Read only

0
0
Text · 11.1 KiB · d6d8574 Raw
577 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#include <linux/clk-provider.h>4#include <linux/init.h>5#include <linux/of.h>6#include <linux/platform_device.h>7 8#include <dt-bindings/clock/bcm3368-clock.h>9#include <dt-bindings/clock/bcm6318-clock.h>10#include <dt-bindings/clock/bcm6328-clock.h>11#include <dt-bindings/clock/bcm6358-clock.h>12#include <dt-bindings/clock/bcm6362-clock.h>13#include <dt-bindings/clock/bcm6368-clock.h>14#include <dt-bindings/clock/bcm63268-clock.h>15 16struct clk_bcm63xx_table_entry {17	const char * const name;18	u8 bit;19	unsigned long flags;20};21 22struct clk_bcm63xx_hw {23	void __iomem *regs;24	spinlock_t lock;25 26	struct clk_hw_onecell_data data;27};28 29static const struct clk_bcm63xx_table_entry bcm3368_clocks[] = {30	{31		.name = "mac",32		.bit = BCM3368_CLK_MAC,33	}, {34		.name = "tc",35		.bit = BCM3368_CLK_TC,36	}, {37		.name = "us_top",38		.bit = BCM3368_CLK_US_TOP,39	}, {40		.name = "ds_top",41		.bit = BCM3368_CLK_DS_TOP,42	}, {43		.name = "acm",44		.bit = BCM3368_CLK_ACM,45	}, {46		.name = "spi",47		.bit = BCM3368_CLK_SPI,48	}, {49		.name = "usbs",50		.bit = BCM3368_CLK_USBS,51	}, {52		.name = "bmu",53		.bit = BCM3368_CLK_BMU,54	}, {55		.name = "pcm",56		.bit = BCM3368_CLK_PCM,57	}, {58		.name = "ntp",59		.bit = BCM3368_CLK_NTP,60	}, {61		.name = "acp_b",62		.bit = BCM3368_CLK_ACP_B,63	}, {64		.name = "acp_a",65		.bit = BCM3368_CLK_ACP_A,66	}, {67		.name = "emusb",68		.bit = BCM3368_CLK_EMUSB,69	}, {70		.name = "enet0",71		.bit = BCM3368_CLK_ENET0,72	}, {73		.name = "enet1",74		.bit = BCM3368_CLK_ENET1,75	}, {76		.name = "usbsu",77		.bit = BCM3368_CLK_USBSU,78	}, {79		.name = "ephy",80		.bit = BCM3368_CLK_EPHY,81	}, {82		/* sentinel */83	},84};85 86static const struct clk_bcm63xx_table_entry bcm6318_clocks[] = {87	{88		.name = "adsl_asb",89		.bit = BCM6318_CLK_ADSL_ASB,90	}, {91		.name = "usb_asb",92		.bit = BCM6318_CLK_USB_ASB,93	}, {94		.name = "mips_asb",95		.bit = BCM6318_CLK_MIPS_ASB,96	}, {97		.name = "pcie_asb",98		.bit = BCM6318_CLK_PCIE_ASB,99	}, {100		.name = "phymips_asb",101		.bit = BCM6318_CLK_PHYMIPS_ASB,102	}, {103		.name = "robosw_asb",104		.bit = BCM6318_CLK_ROBOSW_ASB,105	}, {106		.name = "sar_asb",107		.bit = BCM6318_CLK_SAR_ASB,108	}, {109		.name = "sdr_asb",110		.bit = BCM6318_CLK_SDR_ASB,111	}, {112		.name = "swreg_asb",113		.bit = BCM6318_CLK_SWREG_ASB,114	}, {115		.name = "periph_asb",116		.bit = BCM6318_CLK_PERIPH_ASB,117	}, {118		.name = "cpubus160",119		.bit = BCM6318_CLK_CPUBUS160,120	}, {121		.name = "adsl",122		.bit = BCM6318_CLK_ADSL,123	}, {124		.name = "sar125",125		.bit = BCM6318_CLK_SAR125,126	}, {127		.name = "mips",128		.bit = BCM6318_CLK_MIPS,129		.flags = CLK_IS_CRITICAL,130	}, {131		.name = "pcie",132		.bit = BCM6318_CLK_PCIE,133	}, {134		.name = "robosw250",135		.bit = BCM6318_CLK_ROBOSW250,136	}, {137		.name = "robosw025",138		.bit = BCM6318_CLK_ROBOSW025,139	}, {140		.name = "sdr",141		.bit = BCM6318_CLK_SDR,142		.flags = CLK_IS_CRITICAL,143	}, {144		.name = "usbd",145		.bit = BCM6318_CLK_USBD,146	}, {147		.name = "hsspi",148		.bit = BCM6318_CLK_HSSPI,149	}, {150		.name = "pcie25",151		.bit = BCM6318_CLK_PCIE25,152	}, {153		.name = "phymips",154		.bit = BCM6318_CLK_PHYMIPS,155	}, {156		.name = "afe",157		.bit = BCM6318_CLK_AFE,158	}, {159		.name = "qproc",160		.bit = BCM6318_CLK_QPROC,161	}, {162		/* sentinel */163	},164};165 166static const struct clk_bcm63xx_table_entry bcm6318_ubus_clocks[] = {167	{168		.name = "adsl-ubus",169		.bit = BCM6318_UCLK_ADSL,170	}, {171		.name = "arb-ubus",172		.bit = BCM6318_UCLK_ARB,173		.flags = CLK_IS_CRITICAL,174	}, {175		.name = "mips-ubus",176		.bit = BCM6318_UCLK_MIPS,177		.flags = CLK_IS_CRITICAL,178	}, {179		.name = "pcie-ubus",180		.bit = BCM6318_UCLK_PCIE,181	}, {182		.name = "periph-ubus",183		.bit = BCM6318_UCLK_PERIPH,184		.flags = CLK_IS_CRITICAL,185	}, {186		.name = "phymips-ubus",187		.bit = BCM6318_UCLK_PHYMIPS,188	}, {189		.name = "robosw-ubus",190		.bit = BCM6318_UCLK_ROBOSW,191	}, {192		.name = "sar-ubus",193		.bit = BCM6318_UCLK_SAR,194	}, {195		.name = "sdr-ubus",196		.bit = BCM6318_UCLK_SDR,197	}, {198		.name = "usb-ubus",199		.bit = BCM6318_UCLK_USB,200	}, {201		/* sentinel */202	},203};204 205static const struct clk_bcm63xx_table_entry bcm6328_clocks[] = {206	{207		.name = "phy_mips",208		.bit = BCM6328_CLK_PHYMIPS,209	}, {210		.name = "adsl_qproc",211		.bit = BCM6328_CLK_ADSL_QPROC,212	}, {213		.name = "adsl_afe",214		.bit = BCM6328_CLK_ADSL_AFE,215	}, {216		.name = "adsl",217		.bit = BCM6328_CLK_ADSL,218	}, {219		.name = "mips",220		.bit = BCM6328_CLK_MIPS,221		.flags = CLK_IS_CRITICAL,222	}, {223		.name = "sar",224		.bit = BCM6328_CLK_SAR,225	}, {226		.name = "pcm",227		.bit = BCM6328_CLK_PCM,228	}, {229		.name = "usbd",230		.bit = BCM6328_CLK_USBD,231	}, {232		.name = "usbh",233		.bit = BCM6328_CLK_USBH,234	}, {235		.name = "hsspi",236		.bit = BCM6328_CLK_HSSPI,237	}, {238		.name = "pcie",239		.bit = BCM6328_CLK_PCIE,240	}, {241		.name = "robosw",242		.bit = BCM6328_CLK_ROBOSW,243	}, {244		/* sentinel */245	},246};247 248static const struct clk_bcm63xx_table_entry bcm6358_clocks[] = {249	{250		.name = "enet",251		.bit = BCM6358_CLK_ENET,252	}, {253		.name = "adslphy",254		.bit = BCM6358_CLK_ADSLPHY,255	}, {256		.name = "pcm",257		.bit = BCM6358_CLK_PCM,258	}, {259		.name = "spi",260		.bit = BCM6358_CLK_SPI,261	}, {262		.name = "usbs",263		.bit = BCM6358_CLK_USBS,264	}, {265		.name = "sar",266		.bit = BCM6358_CLK_SAR,267	}, {268		.name = "emusb",269		.bit = BCM6358_CLK_EMUSB,270	}, {271		.name = "enet0",272		.bit = BCM6358_CLK_ENET0,273	}, {274		.name = "enet1",275		.bit = BCM6358_CLK_ENET1,276	}, {277		.name = "usbsu",278		.bit = BCM6358_CLK_USBSU,279	}, {280		.name = "ephy",281		.bit = BCM6358_CLK_EPHY,282	}, {283		/* sentinel */284	},285};286 287static const struct clk_bcm63xx_table_entry bcm6362_clocks[] = {288	{289		.name = "adsl_qproc",290		.bit = BCM6362_CLK_ADSL_QPROC,291	}, {292		.name = "adsl_afe",293		.bit = BCM6362_CLK_ADSL_AFE,294	}, {295		.name = "adsl",296		.bit = BCM6362_CLK_ADSL,297	}, {298		.name = "mips",299		.bit = BCM6362_CLK_MIPS,300		.flags = CLK_IS_CRITICAL,301	}, {302		.name = "wlan_ocp",303		.bit = BCM6362_CLK_WLAN_OCP,304	}, {305		.name = "swpkt_usb",306		.bit = BCM6362_CLK_SWPKT_USB,307	}, {308		.name = "swpkt_sar",309		.bit = BCM6362_CLK_SWPKT_SAR,310	}, {311		.name = "sar",312		.bit = BCM6362_CLK_SAR,313	}, {314		.name = "robosw",315		.bit = BCM6362_CLK_ROBOSW,316	}, {317		.name = "pcm",318		.bit = BCM6362_CLK_PCM,319	}, {320		.name = "usbd",321		.bit = BCM6362_CLK_USBD,322	}, {323		.name = "usbh",324		.bit = BCM6362_CLK_USBH,325	}, {326		.name = "ipsec",327		.bit = BCM6362_CLK_IPSEC,328	}, {329		.name = "spi",330		.bit = BCM6362_CLK_SPI,331	}, {332		.name = "hsspi",333		.bit = BCM6362_CLK_HSSPI,334	}, {335		.name = "pcie",336		.bit = BCM6362_CLK_PCIE,337	}, {338		.name = "fap",339		.bit = BCM6362_CLK_FAP,340	}, {341		.name = "phymips",342		.bit = BCM6362_CLK_PHYMIPS,343	}, {344		.name = "nand",345		.bit = BCM6362_CLK_NAND,346	}, {347		/* sentinel */348	},349};350 351static const struct clk_bcm63xx_table_entry bcm6368_clocks[] = {352	{353		.name = "vdsl_qproc",354		.bit = BCM6368_CLK_VDSL_QPROC,355	}, {356		.name = "vdsl_afe",357		.bit = BCM6368_CLK_VDSL_AFE,358	}, {359		.name = "vdsl_bonding",360		.bit = BCM6368_CLK_VDSL_BONDING,361	}, {362		.name = "vdsl",363		.bit = BCM6368_CLK_VDSL,364	}, {365		.name = "phymips",366		.bit = BCM6368_CLK_PHYMIPS,367	}, {368		.name = "swpkt_usb",369		.bit = BCM6368_CLK_SWPKT_USB,370	}, {371		.name = "swpkt_sar",372		.bit = BCM6368_CLK_SWPKT_SAR,373	}, {374		.name = "spi",375		.bit = BCM6368_CLK_SPI,376	}, {377		.name = "usbd",378		.bit = BCM6368_CLK_USBD,379	}, {380		.name = "sar",381		.bit = BCM6368_CLK_SAR,382	}, {383		.name = "robosw",384		.bit = BCM6368_CLK_ROBOSW,385	}, {386		.name = "utopia",387		.bit = BCM6368_CLK_UTOPIA,388	}, {389		.name = "pcm",390		.bit = BCM6368_CLK_PCM,391	}, {392		.name = "usbh",393		.bit = BCM6368_CLK_USBH,394	}, {395		.name = "disable_gless",396		.bit = BCM6368_CLK_DIS_GLESS,397	}, {398		.name = "nand",399		.bit = BCM6368_CLK_NAND,400	}, {401		.name = "ipsec",402		.bit = BCM6368_CLK_IPSEC,403	}, {404		/* sentinel */405	},406};407 408static const struct clk_bcm63xx_table_entry bcm63268_clocks[] = {409	{410		.name = "disable_gless",411		.bit = BCM63268_CLK_DIS_GLESS,412	}, {413		.name = "vdsl_qproc",414		.bit = BCM63268_CLK_VDSL_QPROC,415	}, {416		.name = "vdsl_afe",417		.bit = BCM63268_CLK_VDSL_AFE,418	}, {419		.name = "vdsl",420		.bit = BCM63268_CLK_VDSL,421	}, {422		.name = "mips",423		.bit = BCM63268_CLK_MIPS,424		.flags = CLK_IS_CRITICAL,425	}, {426		.name = "wlan_ocp",427		.bit = BCM63268_CLK_WLAN_OCP,428	}, {429		.name = "dect",430		.bit = BCM63268_CLK_DECT,431	}, {432		.name = "fap0",433		.bit = BCM63268_CLK_FAP0,434	}, {435		.name = "fap1",436		.bit = BCM63268_CLK_FAP1,437	}, {438		.name = "sar",439		.bit = BCM63268_CLK_SAR,440	}, {441		.name = "robosw",442		.bit = BCM63268_CLK_ROBOSW,443	}, {444		.name = "pcm",445		.bit = BCM63268_CLK_PCM,446	}, {447		.name = "usbd",448		.bit = BCM63268_CLK_USBD,449	}, {450		.name = "usbh",451		.bit = BCM63268_CLK_USBH,452	}, {453		.name = "ipsec",454		.bit = BCM63268_CLK_IPSEC,455	}, {456		.name = "spi",457		.bit = BCM63268_CLK_SPI,458	}, {459		.name = "hsspi",460		.bit = BCM63268_CLK_HSSPI,461	}, {462		.name = "pcie",463		.bit = BCM63268_CLK_PCIE,464	}, {465		.name = "phymips",466		.bit = BCM63268_CLK_PHYMIPS,467	}, {468		.name = "gmac",469		.bit = BCM63268_CLK_GMAC,470	}, {471		.name = "nand",472		.bit = BCM63268_CLK_NAND,473	}, {474		.name = "tbus",475		.bit = BCM63268_CLK_TBUS,476	}, {477		.name = "robosw250",478		.bit = BCM63268_CLK_ROBOSW250,479	}, {480		/* sentinel */481	},482};483 484static int clk_bcm63xx_probe(struct platform_device *pdev)485{486	const struct clk_bcm63xx_table_entry *entry, *table;487	struct clk_bcm63xx_hw *hw;488	u8 maxbit = 0;489	int i, ret;490 491	table = of_device_get_match_data(&pdev->dev);492	if (!table)493		return -EINVAL;494 495	for (entry = table; entry->name; entry++)496		maxbit = max_t(u8, maxbit, entry->bit);497	maxbit++;498 499	hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit),500			  GFP_KERNEL);501	if (!hw)502		return -ENOMEM;503 504	platform_set_drvdata(pdev, hw);505 506	spin_lock_init(&hw->lock);507 508	hw->data.num = maxbit;509	for (i = 0; i < maxbit; i++)510		hw->data.hws[i] = ERR_PTR(-ENODEV);511 512	hw->regs = devm_platform_ioremap_resource(pdev, 0);513	if (IS_ERR(hw->regs))514		return PTR_ERR(hw->regs);515 516	for (entry = table; entry->name; entry++) {517		struct clk_hw *clk;518 519		clk = clk_hw_register_gate(&pdev->dev, entry->name, NULL,520					   entry->flags, hw->regs, entry->bit,521					   CLK_GATE_BIG_ENDIAN, &hw->lock);522		if (IS_ERR(clk)) {523			ret = PTR_ERR(clk);524			goto out_err;525		}526 527		hw->data.hws[entry->bit] = clk;528	}529 530	ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,531				     &hw->data);532	if (!ret)533		return 0;534out_err:535	for (i = 0; i < hw->data.num; i++) {536		if (!IS_ERR(hw->data.hws[i]))537			clk_hw_unregister_gate(hw->data.hws[i]);538	}539 540	return ret;541}542 543static void clk_bcm63xx_remove(struct platform_device *pdev)544{545	struct clk_bcm63xx_hw *hw = platform_get_drvdata(pdev);546	int i;547 548	of_clk_del_provider(pdev->dev.of_node);549 550	for (i = 0; i < hw->data.num; i++) {551		if (!IS_ERR(hw->data.hws[i]))552			clk_hw_unregister_gate(hw->data.hws[i]);553	}554}555 556static const struct of_device_id clk_bcm63xx_dt_ids[] = {557	{ .compatible = "brcm,bcm3368-clocks", .data = &bcm3368_clocks, },558	{ .compatible = "brcm,bcm6318-clocks", .data = &bcm6318_clocks, },559	{ .compatible = "brcm,bcm6318-ubus-clocks", .data = &bcm6318_ubus_clocks, },560	{ .compatible = "brcm,bcm6328-clocks", .data = &bcm6328_clocks, },561	{ .compatible = "brcm,bcm6358-clocks", .data = &bcm6358_clocks, },562	{ .compatible = "brcm,bcm6362-clocks", .data = &bcm6362_clocks, },563	{ .compatible = "brcm,bcm6368-clocks", .data = &bcm6368_clocks, },564	{ .compatible = "brcm,bcm63268-clocks", .data = &bcm63268_clocks, },565	{ }566};567 568static struct platform_driver clk_bcm63xx = {569	.probe = clk_bcm63xx_probe,570	.remove = clk_bcm63xx_remove,571	.driver = {572		.name = "bcm63xx-clock",573		.of_match_table = clk_bcm63xx_dt_ids,574	},575};576builtin_platform_driver(clk_bcm63xx);577