brintos

brintos / linux-shallow public Read only

0
0
Text · 12.8 KiB · 1e12ad8 Raw
530 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2021, The Linux Foundation. All rights reserved.4 * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org>5 */6 7#include <linux/clk-provider.h>8#include <linux/module.h>9#include <linux/platform_device.h>10#include <linux/regmap.h>11 12#include <dt-bindings/clock/qcom,gpucc-sm6350.h>13 14#include "common.h"15#include "clk-alpha-pll.h"16#include "clk-branch.h"17#include "clk-rcg.h"18#include "clk-regmap.h"19#include "reset.h"20#include "gdsc.h"21 22#define CX_GMU_CBCR_SLEEP_MASK		0xF23#define CX_GMU_CBCR_SLEEP_SHIFT		424#define CX_GMU_CBCR_WAKE_MASK		0xF25#define CX_GMU_CBCR_WAKE_SHIFT		826 27enum {28	DT_BI_TCXO,29	DT_GPLL0_OUT_MAIN,30	DT_GPLL0_OUT_MAIN_DIV,31};32 33enum {34	P_BI_TCXO,35	P_GPLL0_OUT_MAIN,36	P_GPLL0_OUT_MAIN_DIV,37	P_GPU_CC_PLL0_OUT_MAIN,38	P_GPU_CC_PLL0_OUT_ODD,39	P_GPU_CC_PLL1_OUT_EVEN,40	P_GPU_CC_PLL1_OUT_MAIN,41	P_GPU_CC_PLL1_OUT_ODD,42	P_CRC_DIV,43};44 45static const struct pll_vco fabia_vco[] = {46	{ 249600000, 2000000000, 0 },47};48 49/* 506MHz Configuration*/50static const struct alpha_pll_config gpu_cc_pll0_config = {51	.l = 0x1A,52	.alpha = 0x5AAA,53	.config_ctl_val = 0x20485699,54	.config_ctl_hi_val = 0x00002067,55	.test_ctl_val = 0x40000000,56	.test_ctl_hi_val = 0x00000002,57	.user_ctl_val = 0x00000001,58	.user_ctl_hi_val = 0x00004805,59};60 61static struct clk_alpha_pll gpu_cc_pll0 = {62	.offset = 0x0,63	.vco_table = fabia_vco,64	.num_vco = ARRAY_SIZE(fabia_vco),65	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],66	.clkr = {67		.hw.init = &(struct clk_init_data){68			.name = "gpu_cc_pll0",69			.parent_data =  &(const struct clk_parent_data){70				.index = DT_BI_TCXO,71				.fw_name = "bi_tcxo",72			},73			.num_parents = 1,74			.ops = &clk_alpha_pll_fabia_ops,75		},76	},77};78 79static struct clk_fixed_factor crc_div = {80	.mult = 1,81	.div = 2,82	.hw.init = &(struct clk_init_data){83		.name = "crc_div",84		.parent_hws = (const struct clk_hw*[]){85			&gpu_cc_pll0.clkr.hw,86		},87		.num_parents = 1,88		.flags = CLK_SET_RATE_PARENT,89		.ops = &clk_fixed_factor_ops,90	},91};92 93/* 514MHz Configuration*/94static const struct alpha_pll_config gpu_cc_pll1_config = {95	.l = 0x1A,96	.alpha = 0xC555,97	.config_ctl_val = 0x20485699,98	.config_ctl_hi_val = 0x00002067,99	.test_ctl_val = 0x40000000,100	.test_ctl_hi_val = 0x00000002,101	.user_ctl_val = 0x00000001,102	.user_ctl_hi_val = 0x00004805,103};104 105static struct clk_alpha_pll gpu_cc_pll1 = {106	.offset = 0x100,107	.vco_table = fabia_vco,108	.num_vco = ARRAY_SIZE(fabia_vco),109	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],110	.clkr = {111		.hw.init = &(struct clk_init_data){112			.name = "gpu_cc_pll1",113			.parent_data =  &(const struct clk_parent_data){114				.index = DT_BI_TCXO,115				.fw_name = "bi_tcxo",116			},117			.num_parents = 1,118			.ops = &clk_alpha_pll_fabia_ops,119		},120	},121};122 123static const struct parent_map gpu_cc_parent_map_0[] = {124	{ P_BI_TCXO, 0 },125	{ P_GPU_CC_PLL0_OUT_MAIN, 1 },126	{ P_GPU_CC_PLL1_OUT_MAIN, 3 },127	{ P_GPLL0_OUT_MAIN, 5 },128	{ P_GPLL0_OUT_MAIN_DIV, 6 },129};130 131static const struct clk_parent_data gpu_cc_parent_data_0[] = {132	{ .index = DT_BI_TCXO, .fw_name = "bi_tcxo" },133	{ .hw = &gpu_cc_pll0.clkr.hw },134	{ .hw = &gpu_cc_pll1.clkr.hw },135	{ .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk_src" },136	{ .index = DT_GPLL0_OUT_MAIN_DIV, .fw_name = "gcc_gpu_gpll0_div_clk_src" },137};138 139static const struct parent_map gpu_cc_parent_map_1[] = {140	{ P_BI_TCXO, 0 },141	{ P_CRC_DIV, 1 },142	{ P_GPU_CC_PLL0_OUT_ODD, 2 },143	{ P_GPU_CC_PLL1_OUT_EVEN, 3 },144	{ P_GPU_CC_PLL1_OUT_ODD, 4 },145	{ P_GPLL0_OUT_MAIN, 5 },146};147 148static const struct clk_parent_data gpu_cc_parent_data_1[] = {149	{ .index = DT_BI_TCXO, .fw_name = "bi_tcxo" },150	{ .hw = &crc_div.hw },151	{ .hw = &gpu_cc_pll0.clkr.hw },152	{ .hw = &gpu_cc_pll1.clkr.hw },153	{ .hw = &gpu_cc_pll1.clkr.hw },154	{ .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk_src" },155};156 157static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {158	F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),159	{ }160};161 162static struct clk_rcg2 gpu_cc_gmu_clk_src = {163	.cmd_rcgr = 0x1120,164	.mnd_width = 0,165	.hid_width = 5,166	.parent_map = gpu_cc_parent_map_0,167	.freq_tbl = ftbl_gpu_cc_gmu_clk_src,168	.clkr.hw.init = &(struct clk_init_data){169		.name = "gpu_cc_gmu_clk_src",170		.parent_data = gpu_cc_parent_data_0,171		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),172		.flags = CLK_SET_RATE_PARENT,173		.ops = &clk_rcg2_ops,174	},175};176 177static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {178	F(253000000, P_CRC_DIV, 1, 0, 0),179	F(355000000, P_CRC_DIV, 1, 0, 0),180	F(430000000, P_CRC_DIV, 1, 0, 0),181	F(565000000, P_CRC_DIV, 1, 0, 0),182	F(650000000, P_CRC_DIV, 1, 0, 0),183	F(800000000, P_CRC_DIV, 1, 0, 0),184	F(825000000, P_CRC_DIV, 1, 0, 0),185	F(850000000, P_CRC_DIV, 1, 0, 0),186	{ }187};188 189static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {190	.cmd_rcgr = 0x101c,191	.mnd_width = 0,192	.hid_width = 5,193	.parent_map = gpu_cc_parent_map_1,194	.freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,195	.clkr.hw.init = &(struct clk_init_data){196		.name = "gpu_cc_gx_gfx3d_clk_src",197		.parent_data = gpu_cc_parent_data_1,198		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),199		.flags = CLK_SET_RATE_PARENT,200		.ops = &clk_rcg2_ops,201	},202};203 204static struct clk_branch gpu_cc_acd_ahb_clk = {205	.halt_reg = 0x1168,206	.halt_check = BRANCH_HALT,207	.clkr = {208		.enable_reg = 0x1168,209		.enable_mask = BIT(0),210		.hw.init = &(struct clk_init_data){211			.name = "gpu_cc_acd_ahb_clk",212			.ops = &clk_branch2_ops,213		},214	},215};216 217static struct clk_branch gpu_cc_acd_cxo_clk = {218	.halt_reg = 0x1164,219	.halt_check = BRANCH_HALT,220	.clkr = {221		.enable_reg = 0x1164,222		.enable_mask = BIT(0),223		.hw.init = &(struct clk_init_data){224			.name = "gpu_cc_acd_cxo_clk",225			.ops = &clk_branch2_ops,226		},227	},228};229 230static struct clk_branch gpu_cc_ahb_clk = {231	.halt_reg = 0x1078,232	.halt_check = BRANCH_HALT_DELAY,233	.clkr = {234		.enable_reg = 0x1078,235		.enable_mask = BIT(0),236		.hw.init = &(struct clk_init_data){237			.name = "gpu_cc_ahb_clk",238			.flags = CLK_IS_CRITICAL,239			.ops = &clk_branch2_ops,240		},241	},242};243 244static struct clk_branch gpu_cc_crc_ahb_clk = {245	.halt_reg = 0x107c,246	.halt_check = BRANCH_HALT_DELAY,247	.clkr = {248		.enable_reg = 0x107c,249		.enable_mask = BIT(0),250		.hw.init = &(struct clk_init_data){251			.name = "gpu_cc_crc_ahb_clk",252			.ops = &clk_branch2_ops,253		},254	},255};256 257static struct clk_branch gpu_cc_cx_gfx3d_clk = {258	.halt_reg = 0x10a4,259	.halt_check = BRANCH_HALT_DELAY,260	.clkr = {261		.enable_reg = 0x10a4,262		.enable_mask = BIT(0),263		.hw.init = &(struct clk_init_data){264			.name = "gpu_cc_cx_gfx3d_clk",265			.parent_hws = (const struct clk_hw*[]){266				&gpu_cc_gx_gfx3d_clk_src.clkr.hw,267			},268			.num_parents = 1,269			.flags = CLK_SET_RATE_PARENT,270			.ops = &clk_branch2_ops,271		},272	},273};274 275static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = {276	.halt_reg = 0x10a8,277	.halt_check = BRANCH_HALT_DELAY,278	.clkr = {279		.enable_reg = 0x10a8,280		.enable_mask = BIT(0),281		.hw.init = &(struct clk_init_data){282			.name = "gpu_cc_cx_gfx3d_slv_clk",283			.parent_hws = (const struct clk_hw*[]){284				&gpu_cc_gx_gfx3d_clk_src.clkr.hw,285			},286			.num_parents = 1,287			.flags = CLK_SET_RATE_PARENT,288			.ops = &clk_branch2_ops,289		},290	},291};292 293static struct clk_branch gpu_cc_cx_gmu_clk = {294	.halt_reg = 0x1098,295	.halt_check = BRANCH_HALT,296	.clkr = {297		.enable_reg = 0x1098,298		.enable_mask = BIT(0),299		.hw.init = &(struct clk_init_data){300			.name = "gpu_cc_cx_gmu_clk",301			.parent_hws = (const struct clk_hw*[]){302				&gpu_cc_gmu_clk_src.clkr.hw,303			},304			.num_parents = 1,305			.flags = CLK_SET_RATE_PARENT,306			.ops = &clk_branch2_ops,307		},308	},309};310 311static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {312	.halt_reg = 0x108c,313	.halt_check = BRANCH_HALT_DELAY,314	.clkr = {315		.enable_reg = 0x108c,316		.enable_mask = BIT(0),317		.hw.init = &(struct clk_init_data){318			.name = "gpu_cc_cx_snoc_dvm_clk",319			.ops = &clk_branch2_ops,320		},321	},322};323 324static struct clk_branch gpu_cc_cxo_aon_clk = {325	.halt_reg = 0x1004,326	.halt_check = BRANCH_HALT_DELAY,327	.clkr = {328		.enable_reg = 0x1004,329		.enable_mask = BIT(0),330		.hw.init = &(struct clk_init_data){331			.name = "gpu_cc_cxo_aon_clk",332			.ops = &clk_branch2_ops,333		},334	},335};336 337static struct clk_branch gpu_cc_cxo_clk = {338	.halt_reg = 0x109c,339	.halt_check = BRANCH_HALT,340	.clkr = {341		.enable_reg = 0x109c,342		.enable_mask = BIT(0),343		.hw.init = &(struct clk_init_data){344			.name = "gpu_cc_cxo_clk",345			.ops = &clk_branch2_ops,346		},347	},348};349 350static struct clk_branch gpu_cc_gx_cxo_clk = {351	.halt_reg = 0x1060,352	.halt_check = BRANCH_HALT,353	.clkr = {354		.enable_reg = 0x1060,355		.enable_mask = BIT(0),356		.hw.init = &(struct clk_init_data){357			.name = "gpu_cc_gx_cxo_clk",358			.ops = &clk_branch2_ops,359		},360	},361};362 363static struct clk_branch gpu_cc_gx_gfx3d_clk = {364	.halt_reg = 0x1054,365	.halt_check = BRANCH_HALT_SKIP,366	.clkr = {367		.enable_reg = 0x1054,368		.enable_mask = BIT(0),369		.hw.init = &(struct clk_init_data){370			.name = "gpu_cc_gx_gfx3d_clk",371			.parent_hws = (const struct clk_hw*[]){372				&gpu_cc_gx_gfx3d_clk_src.clkr.hw,373			},374			.num_parents = 1,375			.flags = CLK_SET_RATE_PARENT,376			.ops = &clk_branch2_ops,377		},378	},379};380 381static struct clk_branch gpu_cc_gx_gmu_clk = {382	.halt_reg = 0x1064,383	.halt_check = BRANCH_HALT,384	.clkr = {385		.enable_reg = 0x1064,386		.enable_mask = BIT(0),387		.hw.init = &(struct clk_init_data){388			.name = "gpu_cc_gx_gmu_clk",389			.parent_hws = (const struct clk_hw*[]){390				&gpu_cc_gmu_clk_src.clkr.hw,391			},392			.num_parents = 1,393			.flags = CLK_SET_RATE_PARENT,394			.ops = &clk_branch2_ops,395		},396	},397};398 399static struct clk_branch gpu_cc_gx_vsense_clk = {400	.halt_reg = 0x1058,401	.halt_check = BRANCH_HALT_DELAY,402	.clkr = {403		.enable_reg = 0x1058,404		.enable_mask = BIT(0),405		.hw.init = &(struct clk_init_data){406			.name = "gpu_cc_gx_vsense_clk",407			.ops = &clk_branch2_ops,408		},409	},410};411 412static struct gdsc gpu_cx_gdsc = {413	.gdscr = 0x106c,414	.gds_hw_ctrl = 0x1540,415	.pd = {416		.name = "gpu_cx_gdsc",417	},418	.pwrsts = PWRSTS_OFF_ON,419	.flags = VOTABLE,420};421 422static struct gdsc gpu_gx_gdsc = {423	.gdscr = 0x100c,424	.clamp_io_ctrl = 0x1508,425	.pd = {426		.name = "gpu_gx_gdsc",427		.power_on = gdsc_gx_do_nothing_enable,428	},429	.pwrsts = PWRSTS_OFF_ON,430	.flags = CLAMP_IO | POLL_CFG_GDSCR,431};432 433static struct clk_hw *gpu_cc_sm6350_hws[] = {434	[GPU_CC_CRC_DIV] = &crc_div.hw,435};436 437static struct clk_regmap *gpu_cc_sm6350_clocks[] = {438	[GPU_CC_ACD_AHB_CLK] = &gpu_cc_acd_ahb_clk.clkr,439	[GPU_CC_ACD_CXO_CLK] = &gpu_cc_acd_cxo_clk.clkr,440	[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,441	[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,442	[GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,443	[GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr,444	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,445	[GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,446	[GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,447	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,448	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,449	[GPU_CC_GX_CXO_CLK] = &gpu_cc_gx_cxo_clk.clkr,450	[GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,451	[GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,452	[GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,453	[GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr,454	[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,455	[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,456};457 458static struct gdsc *gpu_cc_sm6350_gdscs[] = {459	[GPU_CX_GDSC] = &gpu_cx_gdsc,460	[GPU_GX_GDSC] = &gpu_gx_gdsc,461};462 463static const struct regmap_config gpu_cc_sm6350_regmap_config = {464	.reg_bits = 32,465	.reg_stride = 4,466	.val_bits = 32,467	.max_register = 0x8008,468	.fast_io = true,469};470 471static const struct qcom_cc_desc gpu_cc_sm6350_desc = {472	.config = &gpu_cc_sm6350_regmap_config,473	.clk_hws = gpu_cc_sm6350_hws,474	.num_clk_hws = ARRAY_SIZE(gpu_cc_sm6350_hws),475	.clks = gpu_cc_sm6350_clocks,476	.num_clks = ARRAY_SIZE(gpu_cc_sm6350_clocks),477	.gdscs = gpu_cc_sm6350_gdscs,478	.num_gdscs = ARRAY_SIZE(gpu_cc_sm6350_gdscs),479};480 481static const struct of_device_id gpu_cc_sm6350_match_table[] = {482	{ .compatible = "qcom,sm6350-gpucc" },483	{ }484};485MODULE_DEVICE_TABLE(of, gpu_cc_sm6350_match_table);486 487static int gpu_cc_sm6350_probe(struct platform_device *pdev)488{489	struct regmap *regmap;490	unsigned int value, mask;491 492	regmap = qcom_cc_map(pdev, &gpu_cc_sm6350_desc);493	if (IS_ERR(regmap))494		return PTR_ERR(regmap);495 496	clk_fabia_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);497	clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);498 499	/* Configure gpu_cc_cx_gmu_clk with recommended wakeup/sleep settings */500	mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;501	mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;502	value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT;503	regmap_update_bits(regmap, 0x1098, mask, value);504 505	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm6350_desc, regmap);506}507 508static struct platform_driver gpu_cc_sm6350_driver = {509	.probe = gpu_cc_sm6350_probe,510	.driver = {511		.name = "sm6350-gpucc",512		.of_match_table = gpu_cc_sm6350_match_table,513	},514};515 516static int __init gpu_cc_sm6350_init(void)517{518	return platform_driver_register(&gpu_cc_sm6350_driver);519}520core_initcall(gpu_cc_sm6350_init);521 522static void __exit gpu_cc_sm6350_exit(void)523{524	platform_driver_unregister(&gpu_cc_sm6350_driver);525}526module_exit(gpu_cc_sm6350_exit);527 528MODULE_DESCRIPTION("QTI GPU_CC LAGOON Driver");529MODULE_LICENSE("GPL v2");530