brintos

brintos / linux-shallow public Read only

0
0
Text · 15.3 KiB · 167dd36 Raw
601 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2021, The Linux Foundation. All rights reserved.4 * Copyright (c) 2022, Linaro Limited5 */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,sm6375-dispcc.h>13 14#include "clk-alpha-pll.h"15#include "clk-branch.h"16#include "clk-rcg.h"17#include "clk-regmap-divider.h"18#include "common.h"19#include "gdsc.h"20#include "reset.h"21 22enum {23	DT_BI_TCXO,24	DT_GCC_DISP_GPLL0_CLK,25	DT_DSI0_PHY_PLL_OUT_BYTECLK,26	DT_DSI0_PHY_PLL_OUT_DSICLK,27};28 29enum {30	P_BI_TCXO,31	P_DISP_CC_PLL0_OUT_EVEN,32	P_DISP_CC_PLL0_OUT_MAIN,33	P_DSI0_PHY_PLL_OUT_BYTECLK,34	P_DSI0_PHY_PLL_OUT_DSICLK,35	P_GCC_DISP_GPLL0_CLK,36};37 38static const struct pll_vco lucid_vco[] = {39	{ 249600000, 2000000000, 0 },40};41 42/* 615MHz */43static const struct alpha_pll_config disp_cc_pll0_config = {44	.l = 0x20,45	.alpha = 0x800,46	.config_ctl_val = 0x20485699,47	.config_ctl_hi_val = 0x00002261,48	.config_ctl_hi1_val = 0x329a299c,49	.user_ctl_val = 0x00000001,50	.user_ctl_hi_val = 0x00000805,51	.user_ctl_hi1_val = 0x00000000,52};53 54static struct clk_alpha_pll disp_cc_pll0 = {55	.offset = 0x0,56	.vco_table = lucid_vco,57	.num_vco = ARRAY_SIZE(lucid_vco),58	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],59	.clkr = {60		.hw.init = &(struct clk_init_data){61			.name = "disp_cc_pll0",62			.parent_data = &(const struct clk_parent_data){63				.index = DT_BI_TCXO,64			},65			.num_parents = 1,66			.ops = &clk_alpha_pll_lucid_ops,67		},68	},69};70 71static const struct parent_map disp_cc_parent_map_0[] = {72	{ P_BI_TCXO, 0 },73	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },74};75 76static const struct clk_parent_data disp_cc_parent_data_0[] = {77	{ .index = DT_BI_TCXO },78	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },79};80 81static const struct parent_map disp_cc_parent_map_1[] = {82	{ P_BI_TCXO, 0 },83	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },84	{ P_GCC_DISP_GPLL0_CLK, 4 },85	{ P_DISP_CC_PLL0_OUT_EVEN, 5 },86};87 88static const struct clk_parent_data disp_cc_parent_data_1[] = {89	{ .index = DT_BI_TCXO },90	{ .hw = &disp_cc_pll0.clkr.hw },91	{ .index = DT_GCC_DISP_GPLL0_CLK },92	{ .hw = &disp_cc_pll0.clkr.hw },93};94 95static const struct parent_map disp_cc_parent_map_2[] = {96	{ P_BI_TCXO, 0 },97	{ P_GCC_DISP_GPLL0_CLK, 4 },98};99 100static const struct clk_parent_data disp_cc_parent_data_2[] = {101	{ .index = DT_BI_TCXO },102	{ .index = DT_GCC_DISP_GPLL0_CLK },103};104 105static const struct parent_map disp_cc_parent_map_3[] = {106	{ P_BI_TCXO, 0 },107	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },108};109 110static const struct clk_parent_data disp_cc_parent_data_3[] = {111	{ .index = DT_BI_TCXO },112	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },113};114 115static const struct parent_map disp_cc_parent_map_4[] = {116	{ P_BI_TCXO, 0 },117};118 119static const struct clk_parent_data disp_cc_parent_data_4[] = {120	{ .index = DT_BI_TCXO },121};122 123static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {124	F(19200000, P_BI_TCXO, 1, 0, 0),125	F(37500000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),126	F(75000000, P_GCC_DISP_GPLL0_CLK, 4, 0, 0),127	{ }128};129 130static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {131	.cmd_rcgr = 0x115c,132	.mnd_width = 0,133	.hid_width = 5,134	.parent_map = disp_cc_parent_map_2,135	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,136	.clkr.hw.init = &(struct clk_init_data){137		.name = "disp_cc_mdss_ahb_clk_src",138		.parent_data = disp_cc_parent_data_2,139		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),140		.ops = &clk_rcg2_shared_ops,141	},142};143 144static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {145	.cmd_rcgr = 0x10c4,146	.mnd_width = 0,147	.hid_width = 5,148	.parent_map = disp_cc_parent_map_0,149	.clkr.hw.init = &(struct clk_init_data){150		.name = "disp_cc_mdss_byte0_clk_src",151		.parent_data = disp_cc_parent_data_0,152		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),153		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,154		.ops = &clk_byte2_ops,155	},156};157 158static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {159	F(19200000, P_BI_TCXO, 1, 0, 0),160	{ }161};162 163static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {164	.cmd_rcgr = 0x10e0,165	.mnd_width = 0,166	.hid_width = 5,167	.parent_map = disp_cc_parent_map_0,168	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,169	.clkr.hw.init = &(struct clk_init_data){170		.name = "disp_cc_mdss_esc0_clk_src",171		.parent_data = disp_cc_parent_data_0,172		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),173		.ops = &clk_rcg2_shared_ops,174	},175};176 177static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {178	F(200000000, P_GCC_DISP_GPLL0_CLK, 1.5, 0, 0),179	F(300000000, P_GCC_DISP_GPLL0_CLK, 1, 0, 0),180	F(373500000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),181	F(470000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),182	F(560000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),183	{ }184};185 186static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {187	.cmd_rcgr = 0x107c,188	.mnd_width = 0,189	.hid_width = 5,190	.parent_map = disp_cc_parent_map_1,191	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,192	.clkr.hw.init = &(struct clk_init_data){193		.name = "disp_cc_mdss_mdp_clk_src",194		.parent_data = disp_cc_parent_data_1,195		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),196		.flags = CLK_SET_RATE_PARENT,197		.ops = &clk_rcg2_shared_ops,198	},199};200 201static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {202	.cmd_rcgr = 0x1064,203	.mnd_width = 8,204	.hid_width = 5,205	.parent_map = disp_cc_parent_map_3,206	.clkr.hw.init = &(struct clk_init_data){207		.name = "disp_cc_mdss_pclk0_clk_src",208		.parent_data = disp_cc_parent_data_3,209		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),210		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,211		.ops = &clk_pixel_ops,212	},213};214 215static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {216	F(200000000, P_GCC_DISP_GPLL0_CLK, 1.5, 0, 0),217	F(300000000, P_GCC_DISP_GPLL0_CLK, 1, 0, 0),218	{ }219};220 221static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {222	.cmd_rcgr = 0x1094,223	.mnd_width = 0,224	.hid_width = 5,225	.parent_map = disp_cc_parent_map_1,226	.freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,227	.clkr.hw.init = &(struct clk_init_data){228		.name = "disp_cc_mdss_rot_clk_src",229		.parent_data = disp_cc_parent_data_1,230		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),231		.ops = &clk_rcg2_shared_ops,232	},233};234 235static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {236	.cmd_rcgr = 0x10ac,237	.mnd_width = 0,238	.hid_width = 5,239	.parent_map = disp_cc_parent_map_4,240	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,241	.clkr.hw.init = &(struct clk_init_data){242		.name = "disp_cc_mdss_vsync_clk_src",243		.parent_data = disp_cc_parent_data_4,244		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),245		.ops = &clk_rcg2_ops,246	},247};248 249static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {250	.reg = 0x10dc,251	.shift = 0,252	.width = 4,253	.clkr.hw.init = &(struct clk_init_data) {254		.name = "disp_cc_mdss_byte0_div_clk_src",255		.parent_hws = (const struct clk_hw*[]) {256			&disp_cc_mdss_byte0_clk_src.clkr.hw,257		},258		.num_parents = 1,259		.ops = &clk_regmap_div_ops,260	},261};262 263static struct clk_branch disp_cc_mdss_ahb_clk = {264	.halt_reg = 0x104c,265	.halt_check = BRANCH_HALT,266	.clkr = {267		.enable_reg = 0x104c,268		.enable_mask = BIT(0),269		.hw.init = &(struct clk_init_data){270			.name = "disp_cc_mdss_ahb_clk",271			.parent_hws = (const struct clk_hw*[]){272				&disp_cc_mdss_ahb_clk_src.clkr.hw,273			},274			.num_parents = 1,275			.flags = CLK_SET_RATE_PARENT,276			.ops = &clk_branch2_ops,277		},278	},279};280 281static struct clk_branch disp_cc_mdss_byte0_clk = {282	.halt_reg = 0x102c,283	.halt_check = BRANCH_HALT,284	.clkr = {285		.enable_reg = 0x102c,286		.enable_mask = BIT(0),287		.hw.init = &(struct clk_init_data){288			.name = "disp_cc_mdss_byte0_clk",289			.parent_hws = (const struct clk_hw*[]){290				&disp_cc_mdss_byte0_clk_src.clkr.hw,291			},292			.num_parents = 1,293			.flags = CLK_SET_RATE_PARENT,294			.ops = &clk_branch2_ops,295		},296	},297};298 299static struct clk_branch disp_cc_mdss_byte0_intf_clk = {300	.halt_reg = 0x1030,301	.halt_check = BRANCH_HALT,302	.clkr = {303		.enable_reg = 0x1030,304		.enable_mask = BIT(0),305		.hw.init = &(struct clk_init_data){306			.name = "disp_cc_mdss_byte0_intf_clk",307			.parent_hws = (const struct clk_hw*[]){308				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,309			},310			.num_parents = 1,311			.flags = CLK_SET_RATE_PARENT,312			.ops = &clk_branch2_ops,313		},314	},315};316 317static struct clk_branch disp_cc_mdss_esc0_clk = {318	.halt_reg = 0x1034,319	.halt_check = BRANCH_HALT,320	.clkr = {321		.enable_reg = 0x1034,322		.enable_mask = BIT(0),323		.hw.init = &(struct clk_init_data){324			.name = "disp_cc_mdss_esc0_clk",325			.parent_hws = (const struct clk_hw*[]){326				&disp_cc_mdss_esc0_clk_src.clkr.hw,327			},328			.num_parents = 1,329			.flags = CLK_SET_RATE_PARENT,330			.ops = &clk_branch2_ops,331		},332	},333};334 335static struct clk_branch disp_cc_mdss_mdp_clk = {336	.halt_reg = 0x1010,337	.halt_check = BRANCH_HALT,338	.clkr = {339		.enable_reg = 0x1010,340		.enable_mask = BIT(0),341		.hw.init = &(struct clk_init_data){342			.name = "disp_cc_mdss_mdp_clk",343			.parent_hws = (const struct clk_hw*[]){344				&disp_cc_mdss_mdp_clk_src.clkr.hw,345			},346			.num_parents = 1,347			.flags = CLK_SET_RATE_PARENT,348			.ops = &clk_branch2_ops,349		},350	},351};352 353static struct clk_branch disp_cc_mdss_mdp_lut_clk = {354	.halt_reg = 0x1020,355	.halt_check = BRANCH_HALT_VOTED,356	.clkr = {357		.enable_reg = 0x1020,358		.enable_mask = BIT(0),359		.hw.init = &(struct clk_init_data){360			.name = "disp_cc_mdss_mdp_lut_clk",361			.parent_hws = (const struct clk_hw*[]){362				&disp_cc_mdss_mdp_clk_src.clkr.hw,363			},364			.num_parents = 1,365			.flags = CLK_SET_RATE_PARENT,366			.ops = &clk_branch2_ops,367		},368	},369};370 371static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {372	.halt_reg = 0x2004,373	.halt_check = BRANCH_HALT_VOTED,374	.clkr = {375		.enable_reg = 0x2004,376		.enable_mask = BIT(0),377		.hw.init = &(struct clk_init_data){378			.name = "disp_cc_mdss_non_gdsc_ahb_clk",379			.parent_hws = (const struct clk_hw*[]){380				&disp_cc_mdss_ahb_clk_src.clkr.hw,381			},382			.num_parents = 1,383			.flags = CLK_SET_RATE_PARENT,384			.ops = &clk_branch2_ops,385		},386	},387};388 389static struct clk_branch disp_cc_mdss_pclk0_clk = {390	.halt_reg = 0x1168,391	.halt_check = BRANCH_HALT,392	.clkr = {393		.enable_reg = 0x1168,394		.enable_mask = BIT(0),395		.hw.init = &(struct clk_init_data){396			.name = "disp_cc_mdss_pclk0_clk",397			.parent_hws = (const struct clk_hw*[]){398				&disp_cc_mdss_pclk0_clk_src.clkr.hw,399			},400			.num_parents = 1,401			.flags = CLK_SET_RATE_PARENT,402			.ops = &clk_branch2_ops,403		},404	},405};406 407static struct clk_branch disp_cc_mdss_rot_clk = {408	.halt_reg = 0x1018,409	.halt_check = BRANCH_HALT,410	.clkr = {411		.enable_reg = 0x1018,412		.enable_mask = BIT(0),413		.hw.init = &(struct clk_init_data){414			.name = "disp_cc_mdss_rot_clk",415			.parent_hws = (const struct clk_hw*[]){416				&disp_cc_mdss_rot_clk_src.clkr.hw,417			},418			.num_parents = 1,419			.flags = CLK_SET_RATE_PARENT,420			.ops = &clk_branch2_ops,421		},422	},423};424 425static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {426	.halt_reg = 0x200c,427	.halt_check = BRANCH_HALT,428	.clkr = {429		.enable_reg = 0x200c,430		.enable_mask = BIT(0),431		.hw.init = &(struct clk_init_data){432			.name = "disp_cc_mdss_rscc_ahb_clk",433			.parent_hws = (const struct clk_hw*[]){434				&disp_cc_mdss_ahb_clk_src.clkr.hw,435			},436			.num_parents = 1,437			.flags = CLK_SET_RATE_PARENT,438			.ops = &clk_branch2_ops,439		},440	},441};442 443static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {444	.halt_reg = 0x2008,445	.halt_check = BRANCH_HALT,446	.clkr = {447		.enable_reg = 0x2008,448		.enable_mask = BIT(0),449		.hw.init = &(struct clk_init_data){450			.name = "disp_cc_mdss_rscc_vsync_clk",451			.parent_hws = (const struct clk_hw*[]){452				&disp_cc_mdss_vsync_clk_src.clkr.hw,453			},454			.num_parents = 1,455			.flags = CLK_SET_RATE_PARENT,456			.ops = &clk_branch2_ops,457		},458	},459};460 461static struct clk_branch disp_cc_mdss_vsync_clk = {462	.halt_reg = 0x1028,463	.halt_check = BRANCH_HALT,464	.clkr = {465		.enable_reg = 0x1028,466		.enable_mask = BIT(0),467		.hw.init = &(struct clk_init_data){468			.name = "disp_cc_mdss_vsync_clk",469			.parent_hws = (const struct clk_hw*[]){470				&disp_cc_mdss_vsync_clk_src.clkr.hw,471			},472			.num_parents = 1,473			.flags = CLK_SET_RATE_PARENT,474			.ops = &clk_branch2_ops,475		},476	},477};478 479static struct clk_branch disp_cc_sleep_clk = {480	.halt_check = BRANCH_HALT,481	.clkr = {482		.enable_reg = 0x5004,483		.enable_mask = BIT(0),484		.hw.init = &(struct clk_init_data){485			.name = "disp_cc_sleep_clk",486			.flags = CLK_IS_CRITICAL,487			.ops = &clk_branch2_ops,488		},489	},490};491 492static struct clk_branch disp_cc_xo_clk = {493	.halt_check = BRANCH_HALT,494	.clkr = {495		.enable_reg = 0x5008,496		.enable_mask = BIT(0),497		.hw.init = &(struct clk_init_data){498			.name = "disp_cc_xo_clk",499			.flags = CLK_IS_CRITICAL,500			.ops = &clk_branch2_ops,501		},502	},503};504 505static struct gdsc mdss_gdsc = {506	.gdscr = 0x1004,507	.en_rest_wait_val = 0x2,508	.en_few_wait_val = 0x2,509	.clk_dis_wait_val = 0xf,510	.pd = {511		.name = "mdss_gdsc",512	},513	.pwrsts = PWRSTS_OFF_ON,514	.flags = HW_CTRL,515};516 517static struct clk_regmap *disp_cc_sm6375_clocks[] = {518	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,519	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,520	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,521	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,522	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,523	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,524	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,525	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,526	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,527	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,528	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,529	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,530	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,531	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,532	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,533	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,534	[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,535	[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,536	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,537	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,538	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,539	[DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,540	[DISP_CC_XO_CLK] = &disp_cc_xo_clk.clkr,541};542 543static const struct qcom_reset_map disp_cc_sm6375_resets[] = {544	[DISP_CC_MDSS_CORE_BCR] = { 0x1000 },545	[DISP_CC_MDSS_RSCC_BCR] = { 0x2000 },546};547 548static struct gdsc *disp_cc_sm6375_gdscs[] = {549	[MDSS_GDSC] = &mdss_gdsc,550};551 552static const struct regmap_config disp_cc_sm6375_regmap_config = {553	.reg_bits = 32,554	.reg_stride = 4,555	.val_bits = 32,556	.max_register = 0x10000,557	.fast_io = true,558};559 560static const struct qcom_cc_desc disp_cc_sm6375_desc = {561	.config = &disp_cc_sm6375_regmap_config,562	.clks = disp_cc_sm6375_clocks,563	.num_clks = ARRAY_SIZE(disp_cc_sm6375_clocks),564	.resets = disp_cc_sm6375_resets,565	.num_resets = ARRAY_SIZE(disp_cc_sm6375_resets),566	.gdscs = disp_cc_sm6375_gdscs,567	.num_gdscs = ARRAY_SIZE(disp_cc_sm6375_gdscs),568};569 570static const struct of_device_id disp_cc_sm6375_match_table[] = {571	{ .compatible = "qcom,sm6375-dispcc" },572	{ }573};574MODULE_DEVICE_TABLE(of, disp_cc_sm6375_match_table);575 576static int disp_cc_sm6375_probe(struct platform_device *pdev)577{578	struct regmap *regmap;579 580	regmap = qcom_cc_map(pdev, &disp_cc_sm6375_desc);581	if (IS_ERR(regmap))582		return PTR_ERR(regmap);583 584	clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);585 586	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6375_desc, regmap);587}588 589static struct platform_driver disp_cc_sm6375_driver = {590	.probe = disp_cc_sm6375_probe,591	.driver = {592		.name = "disp_cc-sm6375",593		.of_match_table = disp_cc_sm6375_match_table,594	},595};596 597module_platform_driver(disp_cc_sm6375_driver);598 599MODULE_DESCRIPTION("QTI DISPCC SM6375 Driver");600MODULE_LICENSE("GPL");601