brintos

brintos / linux-shallow public Read only

0
0
Text · 11.5 KiB · ed9163d Raw
450 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.4 */5 6#include <linux/clk-provider.h>7#include <linux/mod_devicetable.h>8#include <linux/module.h>9#include <linux/platform_device.h>10#include <linux/pm_runtime.h>11#include <linux/regmap.h>12 13#include <dt-bindings/clock/qcom,sm8450-videocc.h>14 15#include "clk-alpha-pll.h"16#include "clk-branch.h"17#include "clk-rcg.h"18#include "clk-regmap.h"19#include "clk-regmap-divider.h"20#include "common.h"21#include "gdsc.h"22#include "reset.h"23 24enum {25	DT_BI_TCXO,26};27 28enum {29	P_BI_TCXO,30	P_VIDEO_CC_PLL0_OUT_MAIN,31	P_VIDEO_CC_PLL1_OUT_MAIN,32};33 34static const struct pll_vco lucid_evo_vco[] = {35	{ 249600000, 2020000000, 0 },36};37 38static const struct alpha_pll_config video_cc_pll0_config = {39	/* .l includes CAL_L_VAL, L_VAL fields */40	.l = 0x0044001e,41	.alpha = 0x0,42	.config_ctl_val = 0x20485699,43	.config_ctl_hi_val = 0x00182261,44	.config_ctl_hi1_val = 0x32aa299c,45	.user_ctl_val = 0x00000000,46	.user_ctl_hi_val = 0x00000805,47};48 49static struct clk_alpha_pll video_cc_pll0 = {50	.offset = 0x0,51	.vco_table = lucid_evo_vco,52	.num_vco = ARRAY_SIZE(lucid_evo_vco),53	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],54	.clkr = {55		.hw.init = &(const struct clk_init_data) {56			.name = "video_cc_pll0",57			.parent_data = &(const struct clk_parent_data) {58				.index = DT_BI_TCXO,59			},60			.num_parents = 1,61			.ops = &clk_alpha_pll_lucid_evo_ops,62		},63	},64};65 66static const struct alpha_pll_config video_cc_pll1_config = {67	/* .l includes CAL_L_VAL, L_VAL fields */68	.l = 0x0044002b,69	.alpha = 0xc000,70	.config_ctl_val = 0x20485699,71	.config_ctl_hi_val = 0x00182261,72	.config_ctl_hi1_val = 0x32aa299c,73	.user_ctl_val = 0x00000000,74	.user_ctl_hi_val = 0x00000805,75};76 77static struct clk_alpha_pll video_cc_pll1 = {78	.offset = 0x1000,79	.vco_table = lucid_evo_vco,80	.num_vco = ARRAY_SIZE(lucid_evo_vco),81	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],82	.clkr = {83		.hw.init = &(const struct clk_init_data) {84			.name = "video_cc_pll1",85			.parent_data = &(const struct clk_parent_data) {86				.index = DT_BI_TCXO,87			},88			.num_parents = 1,89			.ops = &clk_alpha_pll_lucid_evo_ops,90		},91	},92};93 94static const struct parent_map video_cc_parent_map_0[] = {95	{ P_BI_TCXO, 0 },96	{ P_VIDEO_CC_PLL0_OUT_MAIN, 1 },97};98 99static const struct clk_parent_data video_cc_parent_data_0[] = {100	{ .index = DT_BI_TCXO },101	{ .hw = &video_cc_pll0.clkr.hw },102};103 104static const struct parent_map video_cc_parent_map_1[] = {105	{ P_BI_TCXO, 0 },106	{ P_VIDEO_CC_PLL1_OUT_MAIN, 1 },107};108 109static const struct clk_parent_data video_cc_parent_data_1[] = {110	{ .index = DT_BI_TCXO },111	{ .hw = &video_cc_pll1.clkr.hw },112};113 114static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {115	F(576000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),116	F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),117	F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),118	F(1098000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),119	F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),120	{ }121};122 123static struct clk_rcg2 video_cc_mvs0_clk_src = {124	.cmd_rcgr = 0x8000,125	.mnd_width = 0,126	.hid_width = 5,127	.parent_map = video_cc_parent_map_0,128	.freq_tbl = ftbl_video_cc_mvs0_clk_src,129	.clkr.hw.init = &(const struct clk_init_data) {130		.name = "video_cc_mvs0_clk_src",131		.parent_data = video_cc_parent_data_0,132		.num_parents = ARRAY_SIZE(video_cc_parent_data_0),133		.flags = CLK_SET_RATE_PARENT,134		.ops = &clk_rcg2_shared_ops,135	},136};137 138static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = {139	F(840000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),140	F(1050000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),141	F(1350000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),142	F(1500000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),143	F(1650000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0),144	{ }145};146 147static struct clk_rcg2 video_cc_mvs1_clk_src = {148	.cmd_rcgr = 0x8018,149	.mnd_width = 0,150	.hid_width = 5,151	.parent_map = video_cc_parent_map_1,152	.freq_tbl = ftbl_video_cc_mvs1_clk_src,153	.clkr.hw.init = &(const struct clk_init_data) {154		.name = "video_cc_mvs1_clk_src",155		.parent_data = video_cc_parent_data_1,156		.num_parents = ARRAY_SIZE(video_cc_parent_data_1),157		.flags = CLK_SET_RATE_PARENT,158		.ops = &clk_rcg2_shared_ops,159	},160};161 162static struct clk_regmap_div video_cc_mvs0_div_clk_src = {163	.reg = 0x80b8,164	.shift = 0,165	.width = 4,166	.clkr.hw.init = &(const struct clk_init_data) {167		.name = "video_cc_mvs0_div_clk_src",168		.parent_hws = (const struct clk_hw*[]) {169			&video_cc_mvs0_clk_src.clkr.hw,170		},171		.num_parents = 1,172		.flags = CLK_SET_RATE_PARENT,173		.ops = &clk_regmap_div_ro_ops,174	},175};176 177static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = {178	.reg = 0x806c,179	.shift = 0,180	.width = 4,181	.clkr.hw.init = &(const struct clk_init_data) {182		.name = "video_cc_mvs0c_div2_div_clk_src",183		.parent_hws = (const struct clk_hw*[]) {184			&video_cc_mvs0_clk_src.clkr.hw,185		},186		.num_parents = 1,187		.flags = CLK_SET_RATE_PARENT,188		.ops = &clk_regmap_div_ro_ops,189	},190};191 192static struct clk_regmap_div video_cc_mvs1_div_clk_src = {193	.reg = 0x80dc,194	.shift = 0,195	.width = 4,196	.clkr.hw.init = &(const struct clk_init_data) {197		.name = "video_cc_mvs1_div_clk_src",198		.parent_hws = (const struct clk_hw*[]) {199			&video_cc_mvs1_clk_src.clkr.hw,200		},201		.num_parents = 1,202		.flags = CLK_SET_RATE_PARENT,203		.ops = &clk_regmap_div_ro_ops,204	},205};206 207static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = {208	.reg = 0x8094,209	.shift = 0,210	.width = 4,211	.clkr.hw.init = &(const struct clk_init_data) {212		.name = "video_cc_mvs1c_div2_div_clk_src",213		.parent_hws = (const struct clk_hw*[]) {214			&video_cc_mvs1_clk_src.clkr.hw,215		},216		.num_parents = 1,217		.flags = CLK_SET_RATE_PARENT,218		.ops = &clk_regmap_div_ro_ops,219	},220};221 222static struct clk_branch video_cc_mvs0_clk = {223	.halt_reg = 0x80b0,224	.halt_check = BRANCH_HALT_SKIP,225	.hwcg_reg = 0x80b0,226	.hwcg_bit = 1,227	.clkr = {228		.enable_reg = 0x80b0,229		.enable_mask = BIT(0),230		.hw.init = &(const struct clk_init_data) {231			.name = "video_cc_mvs0_clk",232			.parent_hws = (const struct clk_hw*[]) {233				&video_cc_mvs0_div_clk_src.clkr.hw,234			},235			.num_parents = 1,236			.flags = CLK_SET_RATE_PARENT,237			.ops = &clk_branch2_ops,238		},239	},240};241 242static struct clk_branch video_cc_mvs0c_clk = {243	.halt_reg = 0x8064,244	.halt_check = BRANCH_HALT,245	.clkr = {246		.enable_reg = 0x8064,247		.enable_mask = BIT(0),248		.hw.init = &(const struct clk_init_data) {249			.name = "video_cc_mvs0c_clk",250			.parent_hws = (const struct clk_hw*[]) {251				&video_cc_mvs0c_div2_div_clk_src.clkr.hw,252			},253			.num_parents = 1,254			.flags = CLK_SET_RATE_PARENT,255			.ops = &clk_branch2_ops,256		},257	},258};259 260static struct clk_branch video_cc_mvs1_clk = {261	.halt_reg = 0x80d4,262	.halt_check = BRANCH_HALT_SKIP,263	.hwcg_reg = 0x80d4,264	.hwcg_bit = 1,265	.clkr = {266		.enable_reg = 0x80d4,267		.enable_mask = BIT(0),268		.hw.init = &(const struct clk_init_data) {269			.name = "video_cc_mvs1_clk",270			.parent_hws = (const struct clk_hw*[]) {271				&video_cc_mvs1_div_clk_src.clkr.hw,272			},273			.num_parents = 1,274			.flags = CLK_SET_RATE_PARENT,275			.ops = &clk_branch2_ops,276		},277	},278};279 280static struct clk_branch video_cc_mvs1c_clk = {281	.halt_reg = 0x808c,282	.halt_check = BRANCH_HALT,283	.clkr = {284		.enable_reg = 0x808c,285		.enable_mask = BIT(0),286		.hw.init = &(const struct clk_init_data) {287			.name = "video_cc_mvs1c_clk",288			.parent_hws = (const struct clk_hw*[]) {289				&video_cc_mvs1c_div2_div_clk_src.clkr.hw,290			},291			.num_parents = 1,292			.flags = CLK_SET_RATE_PARENT,293			.ops = &clk_branch2_ops,294		},295	},296};297 298static struct gdsc video_cc_mvs0c_gdsc = {299	.gdscr = 0x804c,300	.en_rest_wait_val = 0x2,301	.en_few_wait_val = 0x2,302	.clk_dis_wait_val = 0x6,303	.pd = {304		.name = "video_cc_mvs0c_gdsc",305	},306	.pwrsts = PWRSTS_OFF_ON,307	.flags = RETAIN_FF_ENABLE,308};309 310static struct gdsc video_cc_mvs0_gdsc = {311	.gdscr = 0x809c,312	.en_rest_wait_val = 0x2,313	.en_few_wait_val = 0x2,314	.clk_dis_wait_val = 0x6,315	.pd = {316		.name = "video_cc_mvs0_gdsc",317	},318	.pwrsts = PWRSTS_OFF_ON,319	.parent = &video_cc_mvs0c_gdsc.pd,320	.flags = RETAIN_FF_ENABLE | HW_CTRL,321};322 323static struct gdsc video_cc_mvs1c_gdsc = {324	.gdscr = 0x8074,325	.en_rest_wait_val = 0x2,326	.en_few_wait_val = 0x2,327	.clk_dis_wait_val = 0x6,328	.pd = {329		.name = "video_cc_mvs1c_gdsc",330	},331	.pwrsts = PWRSTS_OFF_ON,332	.flags = RETAIN_FF_ENABLE,333};334 335static struct gdsc video_cc_mvs1_gdsc = {336	.gdscr = 0x80c0,337	.en_rest_wait_val = 0x2,338	.en_few_wait_val = 0x2,339	.clk_dis_wait_val = 0x6,340	.pd = {341		.name = "video_cc_mvs1_gdsc",342	},343	.pwrsts = PWRSTS_OFF_ON,344	.parent = &video_cc_mvs1c_gdsc.pd,345	.flags = RETAIN_FF_ENABLE | HW_CTRL,346};347 348static struct clk_regmap *video_cc_sm8450_clocks[] = {349	[VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,350	[VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,351	[VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr,352	[VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,353	[VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr,354	[VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr,355	[VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr,356	[VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr,357	[VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr,358	[VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr,359	[VIDEO_CC_PLL0] = &video_cc_pll0.clkr,360	[VIDEO_CC_PLL1] = &video_cc_pll1.clkr,361};362 363static struct gdsc *video_cc_sm8450_gdscs[] = {364	[VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc,365	[VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc,366	[VIDEO_CC_MVS1C_GDSC] = &video_cc_mvs1c_gdsc,367	[VIDEO_CC_MVS1_GDSC] = &video_cc_mvs1_gdsc,368};369 370static const struct qcom_reset_map video_cc_sm8450_resets[] = {371	[CVP_VIDEO_CC_INTERFACE_BCR] = { 0x80e0 },372	[CVP_VIDEO_CC_MVS0_BCR] = { 0x8098 },373	[CVP_VIDEO_CC_MVS0C_BCR] = { 0x8048 },374	[CVP_VIDEO_CC_MVS1_BCR] = { 0x80bc },375	[CVP_VIDEO_CC_MVS1C_BCR] = { 0x8070 },376	[VIDEO_CC_MVS0C_CLK_ARES] = { .reg = 0x8064, .bit = 2, .udelay = 1000 },377	[VIDEO_CC_MVS1C_CLK_ARES] = { .reg = 0x808c, .bit = 2, .udelay = 1000 },378};379 380static const struct regmap_config video_cc_sm8450_regmap_config = {381	.reg_bits = 32,382	.reg_stride = 4,383	.val_bits = 32,384	.max_register = 0x9f4c,385	.fast_io = true,386};387 388static struct qcom_cc_desc video_cc_sm8450_desc = {389	.config = &video_cc_sm8450_regmap_config,390	.clks = video_cc_sm8450_clocks,391	.num_clks = ARRAY_SIZE(video_cc_sm8450_clocks),392	.resets = video_cc_sm8450_resets,393	.num_resets = ARRAY_SIZE(video_cc_sm8450_resets),394	.gdscs = video_cc_sm8450_gdscs,395	.num_gdscs = ARRAY_SIZE(video_cc_sm8450_gdscs),396};397 398static const struct of_device_id video_cc_sm8450_match_table[] = {399	{ .compatible = "qcom,sm8450-videocc" },400	{ }401};402MODULE_DEVICE_TABLE(of, video_cc_sm8450_match_table);403 404static int video_cc_sm8450_probe(struct platform_device *pdev)405{406	struct regmap *regmap;407	int ret;408 409	ret = devm_pm_runtime_enable(&pdev->dev);410	if (ret)411		return ret;412 413	ret = pm_runtime_resume_and_get(&pdev->dev);414	if (ret)415		return ret;416 417	regmap = qcom_cc_map(pdev, &video_cc_sm8450_desc);418	if (IS_ERR(regmap)) {419		pm_runtime_put(&pdev->dev);420		return PTR_ERR(regmap);421	}422 423	clk_lucid_evo_pll_configure(&video_cc_pll0, regmap, &video_cc_pll0_config);424	clk_lucid_evo_pll_configure(&video_cc_pll1, regmap, &video_cc_pll1_config);425 426	/* Keep some clocks always-on */427	qcom_branch_set_clk_en(regmap, 0x80e4); /* VIDEO_CC_AHB_CLK */428	qcom_branch_set_clk_en(regmap, 0x8130); /* VIDEO_CC_SLEEP_CLK */429	qcom_branch_set_clk_en(regmap, 0x8114); /* VIDEO_CC_XO_CLK */430 431	ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8450_desc, regmap);432 433	pm_runtime_put(&pdev->dev);434 435	return ret;436}437 438static struct platform_driver video_cc_sm8450_driver = {439	.probe = video_cc_sm8450_probe,440	.driver = {441		.name = "video_cc-sm8450",442		.of_match_table = video_cc_sm8450_match_table,443	},444};445 446module_platform_driver(video_cc_sm8450_driver);447 448MODULE_DESCRIPTION("QTI VIDEOCC SM8450 Driver");449MODULE_LICENSE("GPL");450