brintos

brintos / linux-shallow public Read only

0
0
Text · 14.1 KiB · 92d1435 Raw
584 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Mediatek MT7621 Clock Driver4 * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com>5 */6 7#include <linux/bitfield.h>8#include <linux/bitops.h>9#include <linux/clk-provider.h>10#include <linux/clk.h>11#include <linux/mfd/syscon.h>12#include <linux/platform_device.h>13#include <linux/regmap.h>14#include <linux/reset-controller.h>15#include <linux/slab.h>16#include <dt-bindings/clock/mt7621-clk.h>17#include <dt-bindings/reset/mt7621-reset.h>18 19/* Configuration registers */20#define SYSC_REG_SYSTEM_CONFIG0         0x1021#define SYSC_REG_SYSTEM_CONFIG1         0x1422#define SYSC_REG_CLKCFG0		0x2c23#define SYSC_REG_CLKCFG1		0x3024#define SYSC_REG_RESET_CTRL		0x3425#define SYSC_REG_CUR_CLK_STS		0x4426#define MEMC_REG_CPU_PLL		0x64827 28#define XTAL_MODE_SEL_MASK		GENMASK(8, 6)29#define CPU_CLK_SEL_MASK		GENMASK(31, 30)30#define CUR_CPU_FDIV_MASK		GENMASK(12, 8)31#define CUR_CPU_FFRAC_MASK		GENMASK(4, 0)32#define CPU_PLL_PREDIV_MASK		GENMASK(13, 12)33#define CPU_PLL_FBDIV_MASK		GENMASK(10, 4)34 35struct mt7621_clk_priv {36	struct regmap *sysc;37	struct regmap *memc;38};39 40struct mt7621_clk {41	struct clk_hw hw;42	struct mt7621_clk_priv *priv;43};44 45struct mt7621_fixed_clk {46	u8 idx;47	const char *name;48	const char *parent_name;49	unsigned long rate;50	struct clk_hw *hw;51};52 53struct mt7621_gate {54	u8 idx;55	const char *name;56	const char *parent_name;57	struct mt7621_clk_priv *priv;58	u32 bit_idx;59	struct clk_hw hw;60};61 62#define GATE(_id, _name, _pname, _shift)	\63	{					\64		.idx		= _id,		\65		.name		= _name,	\66		.parent_name	= _pname,	\67		.bit_idx	= _shift	\68	}69 70static struct mt7621_gate mt7621_gates[] = {71	GATE(MT7621_CLK_HSDMA, "hsdma", "150m", BIT(5)),72	GATE(MT7621_CLK_FE, "fe", "250m", BIT(6)),73	GATE(MT7621_CLK_SP_DIVTX, "sp_divtx", "270m", BIT(7)),74	GATE(MT7621_CLK_TIMER, "timer", "50m", BIT(8)),75	GATE(MT7621_CLK_PCM, "pcm", "270m", BIT(11)),76	GATE(MT7621_CLK_PIO, "pio", "50m", BIT(13)),77	GATE(MT7621_CLK_GDMA, "gdma", "bus", BIT(14)),78	GATE(MT7621_CLK_NAND, "nand", "125m", BIT(15)),79	GATE(MT7621_CLK_I2C, "i2c", "50m", BIT(16)),80	GATE(MT7621_CLK_I2S, "i2s", "270m", BIT(17)),81	GATE(MT7621_CLK_SPI, "spi", "bus", BIT(18)),82	GATE(MT7621_CLK_UART1, "uart1", "50m", BIT(19)),83	GATE(MT7621_CLK_UART2, "uart2", "50m", BIT(20)),84	GATE(MT7621_CLK_UART3, "uart3", "50m", BIT(21)),85	GATE(MT7621_CLK_ETH, "eth", "50m", BIT(23)),86	GATE(MT7621_CLK_PCIE0, "pcie0", "125m", BIT(24)),87	GATE(MT7621_CLK_PCIE1, "pcie1", "125m", BIT(25)),88	GATE(MT7621_CLK_PCIE2, "pcie2", "125m", BIT(26)),89	GATE(MT7621_CLK_CRYPTO, "crypto", "250m", BIT(29)),90	GATE(MT7621_CLK_SHXC, "shxc", "50m", BIT(30))91};92 93static inline struct mt7621_gate *to_mt7621_gate(struct clk_hw *hw)94{95	return container_of(hw, struct mt7621_gate, hw);96}97 98static int mt7621_gate_enable(struct clk_hw *hw)99{100	struct mt7621_gate *clk_gate = to_mt7621_gate(hw);101	struct regmap *sysc = clk_gate->priv->sysc;102 103	return regmap_update_bits(sysc, SYSC_REG_CLKCFG1,104				  clk_gate->bit_idx, clk_gate->bit_idx);105}106 107static void mt7621_gate_disable(struct clk_hw *hw)108{109	struct mt7621_gate *clk_gate = to_mt7621_gate(hw);110	struct regmap *sysc = clk_gate->priv->sysc;111 112	regmap_update_bits(sysc, SYSC_REG_CLKCFG1, clk_gate->bit_idx, 0);113}114 115static int mt7621_gate_is_enabled(struct clk_hw *hw)116{117	struct mt7621_gate *clk_gate = to_mt7621_gate(hw);118	struct regmap *sysc = clk_gate->priv->sysc;119	u32 val;120 121	if (regmap_read(sysc, SYSC_REG_CLKCFG1, &val))122		return 0;123 124	return val & clk_gate->bit_idx;125}126 127static const struct clk_ops mt7621_gate_ops = {128	.enable = mt7621_gate_enable,129	.disable = mt7621_gate_disable,130	.is_enabled = mt7621_gate_is_enabled,131};132 133static int mt7621_gate_ops_init(struct device *dev,134				struct mt7621_gate *sclk)135{136	/*137	 * There are drivers for this SoC that are older138	 * than clock driver and are not prepared for the clock.139	 * We don't want the kernel to disable anything so we140	 * add CLK_IS_CRITICAL flag here.141	 */142	struct clk_init_data init = {143		.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,144		.num_parents = 1,145		.parent_names = &sclk->parent_name,146		.ops = &mt7621_gate_ops,147		.name = sclk->name,148	};149 150	sclk->hw.init = &init;151	return devm_clk_hw_register(dev, &sclk->hw);152}153 154static int mt7621_register_gates(struct device *dev,155				 struct clk_hw_onecell_data *clk_data,156				 struct mt7621_clk_priv *priv)157{158	struct clk_hw **hws = clk_data->hws;159	struct mt7621_gate *sclk;160	int ret, i;161 162	for (i = 0; i < ARRAY_SIZE(mt7621_gates); i++) {163		sclk = &mt7621_gates[i];164		sclk->priv = priv;165		ret = mt7621_gate_ops_init(dev, sclk);166		if (ret) {167			dev_err(dev, "Couldn't register clock %s\n", sclk->name);168			goto err_clk_unreg;169		}170 171		hws[sclk->idx] = &sclk->hw;172	}173 174	return 0;175 176err_clk_unreg:177	while (--i >= 0) {178		sclk = &mt7621_gates[i];179		clk_hw_unregister(&sclk->hw);180	}181	return ret;182}183 184#define FIXED(_id, _name, _rate)		\185	{					\186		.idx		= _id,		\187		.name		= _name,	\188		.parent_name	= "xtal",	\189		.rate		= _rate		\190	}191 192static struct mt7621_fixed_clk mt7621_fixed_clks[] = {193	FIXED(MT7621_CLK_50M, "50m", 50000000),194	FIXED(MT7621_CLK_125M, "125m", 125000000),195	FIXED(MT7621_CLK_150M, "150m", 150000000),196	FIXED(MT7621_CLK_250M, "250m", 250000000),197	FIXED(MT7621_CLK_270M, "270m", 270000000),198};199 200static int mt7621_register_fixed_clocks(struct device *dev,201					struct clk_hw_onecell_data *clk_data)202{203	struct clk_hw **hws = clk_data->hws;204	struct mt7621_fixed_clk *sclk;205	int ret, i;206 207	for (i = 0; i < ARRAY_SIZE(mt7621_fixed_clks); i++) {208		sclk = &mt7621_fixed_clks[i];209		sclk->hw = clk_hw_register_fixed_rate(dev, sclk->name,210						      sclk->parent_name, 0,211						      sclk->rate);212		if (IS_ERR(sclk->hw)) {213			dev_err(dev, "Couldn't register clock %s\n", sclk->name);214			ret = PTR_ERR(sclk->hw);215			goto err_clk_unreg;216		}217 218		hws[sclk->idx] = sclk->hw;219	}220 221	return 0;222 223err_clk_unreg:224	while (--i >= 0) {225		sclk = &mt7621_fixed_clks[i];226		clk_hw_unregister_fixed_rate(sclk->hw);227	}228	return ret;229}230 231static inline struct mt7621_clk *to_mt7621_clk(struct clk_hw *hw)232{233	return container_of(hw, struct mt7621_clk, hw);234}235 236static unsigned long mt7621_xtal_recalc_rate(struct clk_hw *hw,237					     unsigned long parent_rate)238{239	struct mt7621_clk *clk = to_mt7621_clk(hw);240	struct regmap *sysc = clk->priv->sysc;241	u32 val;242 243	regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG0, &val);244	val = FIELD_GET(XTAL_MODE_SEL_MASK, val);245 246	if (val <= 2)247		return 20000000;248	if (val <= 5)249		return 40000000;250 251	return 25000000;252}253 254static unsigned long mt7621_cpu_recalc_rate(struct clk_hw *hw,255					    unsigned long xtal_clk)256{257	static const u32 prediv_tbl[] = { 0, 1, 2, 2 };258	struct mt7621_clk *clk = to_mt7621_clk(hw);259	struct regmap *sysc = clk->priv->sysc;260	struct regmap *memc = clk->priv->memc;261	u32 clkcfg, clk_sel, curclk, ffiv, ffrac;262	u32 pll, prediv, fbdiv;263	unsigned long cpu_clk;264 265	regmap_read(sysc, SYSC_REG_CLKCFG0, &clkcfg);266	clk_sel = FIELD_GET(CPU_CLK_SEL_MASK, clkcfg);267 268	regmap_read(sysc, SYSC_REG_CUR_CLK_STS, &curclk);269	ffiv = FIELD_GET(CUR_CPU_FDIV_MASK, curclk);270	ffrac = FIELD_GET(CUR_CPU_FFRAC_MASK, curclk);271 272	switch (clk_sel) {273	case 0:274		cpu_clk = 500000000;275		break;276	case 1:277		regmap_read(memc, MEMC_REG_CPU_PLL, &pll);278		fbdiv = FIELD_GET(CPU_PLL_FBDIV_MASK, pll);279		prediv = FIELD_GET(CPU_PLL_PREDIV_MASK, pll);280		cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv];281		break;282	default:283		cpu_clk = xtal_clk;284	}285 286	return cpu_clk / ffiv * ffrac;287}288 289static unsigned long mt7621_bus_recalc_rate(struct clk_hw *hw,290					    unsigned long parent_rate)291{292	return parent_rate / 4;293}294 295#define CLK_BASE(_name, _parent, _recalc) {				\296	.init = &(struct clk_init_data) {				\297		.name = _name,						\298		.ops = &(const struct clk_ops) {			\299			.recalc_rate = _recalc,				\300		},							\301		.parent_data = &(const struct clk_parent_data) {	\302			.name = _parent,				\303			.fw_name = _parent				\304		},							\305		.num_parents = _parent ? 1 : 0				\306	},								\307}308 309static struct mt7621_clk mt7621_clks_base[] = {310	{ CLK_BASE("xtal", NULL, mt7621_xtal_recalc_rate) },311	{ CLK_BASE("cpu", "xtal", mt7621_cpu_recalc_rate) },312	{ CLK_BASE("bus", "cpu", mt7621_bus_recalc_rate) },313};314 315static struct clk_hw *mt7621_clk_early[MT7621_CLK_MAX];316 317static int mt7621_register_early_clocks(struct device_node *np,318					struct clk_hw_onecell_data *clk_data,319					struct mt7621_clk_priv *priv)320{321	struct clk_hw **hws = clk_data->hws;322	struct mt7621_clk *sclk;323	int ret, i, j;324 325	for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++) {326		sclk = &mt7621_clks_base[i];327		sclk->priv = priv;328		ret = of_clk_hw_register(np, &sclk->hw);329		if (ret) {330			pr_err("Couldn't register top clock %i\n", i);331			goto err_clk_unreg;332		}333 334		hws[i] = &sclk->hw;335		mt7621_clk_early[i] = &sclk->hw;336	}337 338	for (j = i; j < MT7621_CLK_MAX; j++)339		mt7621_clk_early[j] = ERR_PTR(-EPROBE_DEFER);340 341	return 0;342 343err_clk_unreg:344	while (--i >= 0) {345		sclk = &mt7621_clks_base[i];346		clk_hw_unregister(&sclk->hw);347	}348	return ret;349}350 351static void __init mt7621_clk_init(struct device_node *node)352{353	struct mt7621_clk_priv *priv;354	struct clk_hw_onecell_data *clk_data;355	int ret, i, count;356 357	priv = kzalloc(sizeof(*priv), GFP_KERNEL);358	if (!priv)359		return;360 361	priv->sysc = syscon_node_to_regmap(node);362	if (IS_ERR(priv->sysc)) {363		pr_err("Could not get sysc syscon regmap\n");364		goto free_clk_priv;365	}366 367	priv->memc = syscon_regmap_lookup_by_phandle(node, "ralink,memctl");368	if (IS_ERR(priv->memc)) {369		pr_err("Could not get memc syscon regmap\n");370		goto free_clk_priv;371	}372 373	count = ARRAY_SIZE(mt7621_clks_base) +374		ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);375	clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL);376	if (!clk_data)377		goto free_clk_priv;378 379	ret = mt7621_register_early_clocks(node, clk_data, priv);380	if (ret) {381		pr_err("Couldn't register top clocks\n");382		goto free_clk_data;383	}384 385	clk_data->num = count;386 387	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);388	if (ret) {389		pr_err("Couldn't add clk hw provider\n");390		goto unreg_clk_top;391	}392 393	return;394 395unreg_clk_top:396	for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++) {397		struct mt7621_clk *sclk = &mt7621_clks_base[i];398 399		clk_hw_unregister(&sclk->hw);400	}401 402free_clk_data:403	kfree(clk_data);404 405free_clk_priv:406	kfree(priv);407}408CLK_OF_DECLARE_DRIVER(mt7621_clk, "mediatek,mt7621-sysc", mt7621_clk_init);409 410struct mt7621_rst {411	struct reset_controller_dev rcdev;412	struct regmap *sysc;413};414 415static struct mt7621_rst *to_mt7621_rst(struct reset_controller_dev *dev)416{417	return container_of(dev, struct mt7621_rst, rcdev);418}419 420static int mt7621_assert_device(struct reset_controller_dev *rcdev,421				unsigned long id)422{423	struct mt7621_rst *data = to_mt7621_rst(rcdev);424	struct regmap *sysc = data->sysc;425 426	return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), BIT(id));427}428 429static int mt7621_deassert_device(struct reset_controller_dev *rcdev,430				  unsigned long id)431{432	struct mt7621_rst *data = to_mt7621_rst(rcdev);433	struct regmap *sysc = data->sysc;434 435	return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), 0);436}437 438static int mt7621_reset_device(struct reset_controller_dev *rcdev,439			       unsigned long id)440{441	int ret;442 443	ret = mt7621_assert_device(rcdev, id);444	if (ret < 0)445		return ret;446 447	return mt7621_deassert_device(rcdev, id);448}449 450static int mt7621_rst_xlate(struct reset_controller_dev *rcdev,451			    const struct of_phandle_args *reset_spec)452{453	unsigned long id = reset_spec->args[0];454 455	if (id == MT7621_RST_SYS || id >= rcdev->nr_resets)456		return -EINVAL;457 458	return id;459}460 461static const struct reset_control_ops reset_ops = {462	.reset = mt7621_reset_device,463	.assert = mt7621_assert_device,464	.deassert = mt7621_deassert_device465};466 467static int mt7621_reset_init(struct device *dev, struct regmap *sysc)468{469	struct mt7621_rst *rst_data;470 471	rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL);472	if (!rst_data)473		return -ENOMEM;474 475	rst_data->sysc = sysc;476	rst_data->rcdev.ops = &reset_ops;477	rst_data->rcdev.owner = THIS_MODULE;478	rst_data->rcdev.nr_resets = 32;479	rst_data->rcdev.of_reset_n_cells = 1;480	rst_data->rcdev.of_xlate = mt7621_rst_xlate;481	rst_data->rcdev.of_node = dev_of_node(dev);482 483	return devm_reset_controller_register(dev, &rst_data->rcdev);484}485 486static int mt7621_clk_probe(struct platform_device *pdev)487{488	struct device_node *np = pdev->dev.of_node;489	struct clk_hw_onecell_data *clk_data;490	struct device *dev = &pdev->dev;491	struct mt7621_clk_priv *priv;492	int ret, i, count;493 494	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);495	if (!priv)496		return -ENOMEM;497 498	priv->sysc = syscon_node_to_regmap(np);499	if (IS_ERR(priv->sysc)) {500		ret = PTR_ERR(priv->sysc);501		dev_err(dev, "Could not get sysc syscon regmap\n");502		return ret;503	}504 505	priv->memc = syscon_regmap_lookup_by_phandle(np, "ralink,memctl");506	if (IS_ERR(priv->memc)) {507		ret = PTR_ERR(priv->memc);508		dev_err(dev, "Could not get memc syscon regmap\n");509		return ret;510	}511 512	ret = mt7621_reset_init(dev, priv->sysc);513	if (ret) {514		dev_err(dev, "Could not init reset controller\n");515		return ret;516	}517 518	count = ARRAY_SIZE(mt7621_clks_base) +519		ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);520	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),521				GFP_KERNEL);522	if (!clk_data)523		return -ENOMEM;524	clk_data->num = count;525 526	for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++)527		clk_data->hws[i] = mt7621_clk_early[i];528 529	ret = mt7621_register_fixed_clocks(dev, clk_data);530	if (ret) {531		dev_err(dev, "Couldn't register fixed clocks\n");532		return ret;533	}534 535	ret = mt7621_register_gates(dev, clk_data, priv);536	if (ret) {537		dev_err(dev, "Couldn't register fixed clock gates\n");538		goto unreg_clk_fixed;539	}540 541	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);542	if (ret) {543		dev_err(dev, "Couldn't add clk hw provider\n");544		goto unreg_clk_gates;545	}546 547	return 0;548 549unreg_clk_gates:550	for (i = 0; i < ARRAY_SIZE(mt7621_gates); i++) {551		struct mt7621_gate *sclk = &mt7621_gates[i];552 553		clk_hw_unregister(&sclk->hw);554	}555 556unreg_clk_fixed:557	for (i = 0; i < ARRAY_SIZE(mt7621_fixed_clks); i++) {558		struct mt7621_fixed_clk *sclk = &mt7621_fixed_clks[i];559 560		clk_hw_unregister_fixed_rate(sclk->hw);561	}562 563	return ret;564}565 566static const struct of_device_id mt7621_clk_of_match[] = {567	{ .compatible = "mediatek,mt7621-sysc" },568	{}569};570 571static struct platform_driver mt7621_clk_driver = {572	.probe = mt7621_clk_probe,573	.driver = {574		.name = "mt7621-clk",575		.of_match_table = mt7621_clk_of_match,576	},577};578 579static int __init mt7621_clk_reset_init(void)580{581	return platform_driver_register(&mt7621_clk_driver);582}583arch_initcall(mt7621_clk_reset_init);584