brintos

brintos / linux-shallow public Read only

0
0
Text · 11.4 KiB · 41f5902 Raw
475 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2021, The Linux Foundation. All rights reserved.4 * Copyright (c) 2023, Linaro Limited5 */6 7#include <linux/clk-provider.h>8#include <linux/mod_devicetable.h>9#include <linux/module.h>10#include <linux/platform_device.h>11#include <linux/pm_runtime.h>12#include <linux/regmap.h>13 14#include <dt-bindings/clock/qcom,sm6375-gpucc.h>15 16#include "clk-alpha-pll.h"17#include "clk-branch.h"18#include "clk-rcg.h"19#include "clk-regmap.h"20#include "clk-regmap-divider.h"21#include "clk-regmap-mux.h"22#include "clk-regmap-phy-mux.h"23#include "gdsc.h"24#include "reset.h"25 26enum {27	DT_BI_TCXO,28	DT_GCC_GPU_GPLL0_CLK_SRC,29	DT_GCC_GPU_GPLL0_DIV_CLK_SRC,30	DT_GCC_GPU_SNOC_DVM_GFX_CLK,31};32 33enum {34	P_BI_TCXO,35	P_GCC_GPU_GPLL0_CLK_SRC,36	P_GCC_GPU_GPLL0_DIV_CLK_SRC,37	P_GPU_CC_PLL0_OUT_EVEN,38	P_GPU_CC_PLL0_OUT_MAIN,39	P_GPU_CC_PLL0_OUT_ODD,40	P_GPU_CC_PLL1_OUT_EVEN,41	P_GPU_CC_PLL1_OUT_MAIN,42	P_GPU_CC_PLL1_OUT_ODD,43};44 45static const struct pll_vco lucid_vco[] = {46	{ 249600000, 2000000000, 0 },47};48 49/* 532MHz Configuration */50static const struct alpha_pll_config gpucc_pll0_config = {51	.l = 0x1b,52	.alpha = 0xb555,53	.config_ctl_val = 0x20485699,54	.config_ctl_hi_val = 0x00002261,55	.config_ctl_hi1_val = 0x329a299c,56	.user_ctl_val = 0x00000001,57	.user_ctl_hi_val = 0x00000805,58	.user_ctl_hi1_val = 0x00000000,59};60 61static struct clk_alpha_pll gpucc_pll0 = {62	.offset = 0x0,63	.vco_table = lucid_vco,64	.num_vco = ARRAY_SIZE(lucid_vco),65	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],66	.clkr = {67		.hw.init = &(struct clk_init_data){68			.name = "gpucc_pll0",69			.parent_data = &(const struct clk_parent_data){70				.index = P_BI_TCXO,71			},72			.num_parents = 1,73			.ops = &clk_alpha_pll_lucid_ops,74		},75	},76};77 78/* 514MHz Configuration */79static const struct alpha_pll_config gpucc_pll1_config = {80	.l = 0x1a,81	.alpha = 0xc555,82	.config_ctl_val = 0x20485699,83	.config_ctl_hi_val = 0x00002261,84	.config_ctl_hi1_val = 0x329a299c,85	.user_ctl_val = 0x00000001,86	.user_ctl_hi_val = 0x00000805,87	.user_ctl_hi1_val = 0x00000000,88};89 90static struct clk_alpha_pll gpucc_pll1 = {91	.offset = 0x100,92	.vco_table = lucid_vco,93	.num_vco = ARRAY_SIZE(lucid_vco),94	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],95	.clkr = {96		.hw.init = &(struct clk_init_data){97			.name = "gpucc_pll1",98			.parent_data = &(const struct clk_parent_data){99				.index = P_BI_TCXO,100			},101			.num_parents = 1,102			.ops = &clk_alpha_pll_lucid_ops,103		},104	},105};106 107static const struct parent_map gpucc_parent_map_0[] = {108	{ P_BI_TCXO, 0 },109	{ P_GPU_CC_PLL0_OUT_MAIN, 1 },110	{ P_GPU_CC_PLL1_OUT_MAIN, 3 },111	{ P_GCC_GPU_GPLL0_CLK_SRC, 5 },112	{ P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 },113};114 115static const struct clk_parent_data gpucc_parent_data_0[] = {116	{ .index = P_BI_TCXO },117	{ .hw = &gpucc_pll0.clkr.hw },118	{ .hw = &gpucc_pll1.clkr.hw },119	{ .index = DT_GCC_GPU_GPLL0_CLK_SRC },120	{ .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC },121};122 123static const struct parent_map gpucc_parent_map_1[] = {124	{ P_BI_TCXO, 0 },125	{ P_GPU_CC_PLL0_OUT_EVEN, 1 },126	{ P_GPU_CC_PLL0_OUT_ODD, 2 },127	{ P_GPU_CC_PLL1_OUT_EVEN, 3 },128	{ P_GPU_CC_PLL1_OUT_ODD, 4 },129	{ P_GCC_GPU_GPLL0_CLK_SRC, 5 },130};131 132static const struct clk_parent_data gpucc_parent_data_1[] = {133	{ .index = P_BI_TCXO },134	{ .hw = &gpucc_pll0.clkr.hw },135	{ .hw = &gpucc_pll0.clkr.hw },136	{ .hw = &gpucc_pll1.clkr.hw },137	{ .hw = &gpucc_pll1.clkr.hw },138	{ .index = DT_GCC_GPU_GPLL0_CLK_SRC },139};140 141static const struct freq_tbl ftbl_gpucc_gmu_clk_src[] = {142	F(200000000, P_GCC_GPU_GPLL0_DIV_CLK_SRC, 1.5, 0, 0),143	{ }144};145 146static struct clk_rcg2 gpucc_gmu_clk_src = {147	.cmd_rcgr = 0x1120,148	.mnd_width = 0,149	.hid_width = 5,150	.parent_map = gpucc_parent_map_0,151	.freq_tbl = ftbl_gpucc_gmu_clk_src,152	.clkr.hw.init = &(struct clk_init_data){153		.name = "gpucc_gmu_clk_src",154		.parent_data = gpucc_parent_data_0,155		.num_parents = ARRAY_SIZE(gpucc_parent_data_0),156		.ops = &clk_rcg2_shared_ops,157	},158};159 160static const struct freq_tbl ftbl_gpucc_gx_gfx3d_clk_src[] = {161	F(266000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),162	F(390000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),163	F(490000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),164	F(650000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),165	F(770000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),166	F(840000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),167	F(900000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),168	{ }169};170 171static struct clk_rcg2 gpucc_gx_gfx3d_clk_src = {172	.cmd_rcgr = 0x101c,173	.mnd_width = 0,174	.hid_width = 5,175	.parent_map = gpucc_parent_map_1,176	.freq_tbl = ftbl_gpucc_gx_gfx3d_clk_src,177	.clkr.hw.init = &(struct clk_init_data){178		.name = "gpucc_gx_gfx3d_clk_src",179		.parent_data = gpucc_parent_data_1,180		.num_parents = ARRAY_SIZE(gpucc_parent_data_1),181		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,182		.ops = &clk_rcg2_ops,183	},184};185 186static struct clk_branch gpucc_ahb_clk = {187	.halt_reg = 0x1078,188	.halt_check = BRANCH_HALT_DELAY,189	.clkr = {190		.enable_reg = 0x1078,191		.enable_mask = BIT(0),192		.hw.init = &(struct clk_init_data){193			.name = "gpucc_ahb_clk",194			.flags = CLK_IS_CRITICAL,195			.ops = &clk_branch2_ops,196		},197	},198};199 200static struct clk_branch gpucc_cx_gfx3d_clk = {201	.halt_reg = 0x10a4,202	.halt_check = BRANCH_HALT_DELAY,203	.clkr = {204		.enable_reg = 0x10a4,205		.enable_mask = BIT(0),206		.hw.init = &(struct clk_init_data){207			.name = "gpucc_cx_gfx3d_clk",208			.parent_hws = (const struct clk_hw*[]) {209				&gpucc_gx_gfx3d_clk_src.clkr.hw,210			},211			.num_parents = 1,212			.flags = CLK_SET_RATE_PARENT,213			.ops = &clk_branch2_ops,214		},215	},216};217 218static struct clk_branch gpucc_cx_gfx3d_slv_clk = {219	.halt_reg = 0x10a8,220	.halt_check = BRANCH_HALT_DELAY,221	.clkr = {222		.enable_reg = 0x10a8,223		.enable_mask = BIT(0),224		.hw.init = &(struct clk_init_data){225			.name = "gpucc_cx_gfx3d_slv_clk",226			.parent_hws = (const struct clk_hw*[]) {227				&gpucc_gx_gfx3d_clk_src.clkr.hw,228			},229			.num_parents = 1,230			.flags = CLK_SET_RATE_PARENT,231			.ops = &clk_branch2_ops,232		},233	},234};235 236static struct clk_branch gpucc_cx_gmu_clk = {237	.halt_reg = 0x1098,238	.halt_check = BRANCH_HALT,239	.clkr = {240		.enable_reg = 0x1098,241		.enable_mask = BIT(0),242		.hw.init = &(struct clk_init_data){243			.name = "gpucc_cx_gmu_clk",244			.parent_hws = (const struct clk_hw*[]) {245				&gpucc_gmu_clk_src.clkr.hw,246			},247			.num_parents = 1,248			.flags = CLK_SET_RATE_PARENT,249			.ops = &clk_branch2_ops,250		},251	},252};253 254static struct clk_branch gpucc_cx_snoc_dvm_clk = {255	.halt_reg = 0x108c,256	.halt_check = BRANCH_HALT_DELAY,257	.clkr = {258		.enable_reg = 0x108c,259		.enable_mask = BIT(0),260		.hw.init = &(struct clk_init_data){261			.name = "gpucc_cx_snoc_dvm_clk",262			.parent_data = &(const struct clk_parent_data){263				.index = DT_GCC_GPU_SNOC_DVM_GFX_CLK,264			},265			.num_parents = 1,266			.ops = &clk_branch2_ops,267		},268	},269};270 271static struct clk_branch gpucc_cxo_aon_clk = {272	.halt_reg = 0x1004,273	.halt_check = BRANCH_HALT_DELAY,274	.clkr = {275		.enable_reg = 0x1004,276		.enable_mask = BIT(0),277		.hw.init = &(struct clk_init_data){278			.name = "gpucc_cxo_aon_clk",279			.ops = &clk_branch2_ops,280		},281	},282};283 284static struct clk_branch gpucc_cxo_clk = {285	.halt_reg = 0x109c,286	.halt_check = BRANCH_HALT,287	.clkr = {288		.enable_reg = 0x109c,289		.enable_mask = BIT(0),290		.hw.init = &(struct clk_init_data){291			.name = "gpucc_cxo_clk",292			.ops = &clk_branch2_ops,293		},294	},295};296 297static struct clk_branch gpucc_gx_cxo_clk = {298	.halt_reg = 0x1060,299	.halt_check = BRANCH_HALT_DELAY,300	.clkr = {301		.enable_reg = 0x1060,302		.enable_mask = BIT(0),303		.hw.init = &(struct clk_init_data){304			.name = "gpucc_gx_cxo_clk",305			.flags = CLK_IS_CRITICAL,306			.ops = &clk_branch2_ops,307		},308	},309};310 311static struct clk_branch gpucc_gx_gfx3d_clk = {312	.halt_reg = 0x1054,313	.halt_check = BRANCH_HALT_DELAY,314	.clkr = {315		.enable_reg = 0x1054,316		.enable_mask = BIT(0),317		.hw.init = &(struct clk_init_data){318			.name = "gpucc_gx_gfx3d_clk",319			.parent_hws = (const struct clk_hw*[]) {320				&gpucc_gx_gfx3d_clk_src.clkr.hw,321			},322			.num_parents = 1,323			.flags = CLK_SET_RATE_PARENT,324			.ops = &clk_branch2_ops,325		},326	},327};328 329static struct clk_branch gpucc_gx_gmu_clk = {330	.halt_reg = 0x1064,331	.halt_check = BRANCH_HALT,332	.clkr = {333		.enable_reg = 0x1064,334		.enable_mask = BIT(0),335		.hw.init = &(struct clk_init_data){336			.name = "gpucc_gx_gmu_clk",337			.parent_hws = (const struct clk_hw*[]) {338				&gpucc_gmu_clk_src.clkr.hw,339			},340			.num_parents = 1,341			.flags = CLK_SET_RATE_PARENT,342			.ops = &clk_branch2_ops,343		},344	},345};346 347static struct clk_branch gpucc_sleep_clk = {348	.halt_reg = 0x1090,349	.halt_check = BRANCH_HALT_VOTED,350	.clkr = {351		.enable_reg = 0x1090,352		.enable_mask = BIT(0),353		.hw.init = &(struct clk_init_data){354			.name = "gpucc_sleep_clk",355			.ops = &clk_branch2_ops,356		},357	},358};359 360static struct gdsc gpu_cx_gdsc = {361	.gdscr = 0x106c,362	.gds_hw_ctrl = 0x1540,363	.clk_dis_wait_val = 8,364	.pd = {365		.name = "gpu_cx_gdsc",366	},367	.pwrsts = PWRSTS_OFF_ON,368	.flags = VOTABLE,369};370 371static struct gdsc gpu_gx_gdsc = {372	.gdscr = 0x100c,373	.clamp_io_ctrl = 0x1508,374	.resets = (unsigned int []){ GPU_GX_BCR, GPU_ACD_BCR, GPU_GX_ACD_MISC_BCR },375	.reset_count = 3,376	.pd = {377		.name = "gpu_gx_gdsc",378	},379	.pwrsts = PWRSTS_OFF_ON,380	.flags = CLAMP_IO | SW_RESET | AON_RESET,381};382 383static struct clk_regmap *gpucc_sm6375_clocks[] = {384	[GPU_CC_AHB_CLK] = &gpucc_ahb_clk.clkr,385	[GPU_CC_CX_GFX3D_CLK] = &gpucc_cx_gfx3d_clk.clkr,386	[GPU_CC_CX_GFX3D_SLV_CLK] = &gpucc_cx_gfx3d_slv_clk.clkr,387	[GPU_CC_CX_GMU_CLK] = &gpucc_cx_gmu_clk.clkr,388	[GPU_CC_CX_SNOC_DVM_CLK] = &gpucc_cx_snoc_dvm_clk.clkr,389	[GPU_CC_CXO_AON_CLK] = &gpucc_cxo_aon_clk.clkr,390	[GPU_CC_CXO_CLK] = &gpucc_cxo_clk.clkr,391	[GPU_CC_GMU_CLK_SRC] = &gpucc_gmu_clk_src.clkr,392	[GPU_CC_GX_CXO_CLK] = &gpucc_gx_cxo_clk.clkr,393	[GPU_CC_GX_GFX3D_CLK] = &gpucc_gx_gfx3d_clk.clkr,394	[GPU_CC_GX_GFX3D_CLK_SRC] = &gpucc_gx_gfx3d_clk_src.clkr,395	[GPU_CC_GX_GMU_CLK] = &gpucc_gx_gmu_clk.clkr,396	[GPU_CC_PLL0] = &gpucc_pll0.clkr,397	[GPU_CC_PLL1] = &gpucc_pll1.clkr,398	[GPU_CC_SLEEP_CLK] = &gpucc_sleep_clk.clkr,399};400 401static const struct qcom_reset_map gpucc_sm6375_resets[] = {402	[GPU_GX_BCR] = { 0x1008 },403	[GPU_ACD_BCR] = { 0x1160 },404	[GPU_GX_ACD_MISC_BCR] = { 0x8004 },405};406 407static struct gdsc *gpucc_sm6375_gdscs[] = {408	[GPU_CX_GDSC] = &gpu_cx_gdsc,409	[GPU_GX_GDSC] = &gpu_gx_gdsc,410};411 412static const struct regmap_config gpucc_sm6375_regmap_config = {413	.reg_bits = 32,414	.reg_stride = 4,415	.val_bits = 32,416	.max_register = 0x9000,417	.fast_io = true,418};419 420static const struct qcom_cc_desc gpucc_sm6375_desc = {421	.config = &gpucc_sm6375_regmap_config,422	.clks = gpucc_sm6375_clocks,423	.num_clks = ARRAY_SIZE(gpucc_sm6375_clocks),424	.resets = gpucc_sm6375_resets,425	.num_resets = ARRAY_SIZE(gpucc_sm6375_resets),426	.gdscs = gpucc_sm6375_gdscs,427	.num_gdscs = ARRAY_SIZE(gpucc_sm6375_gdscs),428};429 430static const struct of_device_id gpucc_sm6375_match_table[] = {431	{ .compatible = "qcom,sm6375-gpucc" },432	{ }433};434MODULE_DEVICE_TABLE(of, gpucc_sm6375_match_table);435 436static int gpucc_sm6375_probe(struct platform_device *pdev)437{438	struct regmap *regmap;439	int ret;440 441	ret = devm_pm_runtime_enable(&pdev->dev);442	if (ret)443		return ret;444 445	ret = pm_runtime_resume_and_get(&pdev->dev);446	if (ret)447		return ret;448 449	regmap = qcom_cc_map(pdev, &gpucc_sm6375_desc);450	if (IS_ERR(regmap)) {451		pm_runtime_put(&pdev->dev);452		return PTR_ERR(regmap);453	}454 455	clk_lucid_pll_configure(&gpucc_pll0, regmap, &gpucc_pll0_config);456	clk_lucid_pll_configure(&gpucc_pll1, regmap, &gpucc_pll1_config);457 458	ret = qcom_cc_really_probe(&pdev->dev, &gpucc_sm6375_desc, regmap);459	pm_runtime_put(&pdev->dev);460 461	return ret;462}463 464static struct platform_driver gpucc_sm6375_driver = {465	.probe = gpucc_sm6375_probe,466	.driver = {467		.name = "gpucc-sm6375",468		.of_match_table = gpucc_sm6375_match_table,469	},470};471module_platform_driver(gpucc_sm6375_driver);472 473MODULE_DESCRIPTION("QTI GPUCC SM6375 Driver");474MODULE_LICENSE("GPL");475