brintos

brintos / linux-shallow public Read only

0
0
Text · 8.7 KiB · 14ef7f5 Raw
358 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.4 * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>5 */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/regmap.h>12 13#include <dt-bindings/clock/qcom,sm7150-videocc.h>14 15#include "common.h"16#include "clk-alpha-pll.h"17#include "clk-branch.h"18#include "clk-rcg.h"19#include "clk-regmap.h"20#include "clk-pll.h"21#include "gdsc.h"22 23enum {24	DT_BI_TCXO,25	DT_BI_TCXO_AO,26};27 28enum {29	P_BI_TCXO,30	P_VIDEOCC_PLL0_OUT_EVEN,31	P_VIDEOCC_PLL0_OUT_MAIN,32	P_VIDEOCC_PLL0_OUT_ODD,33};34 35static const struct pll_vco fabia_vco[] = {36	{ 249600000, 2000000000, 0 },37	{ 125000000, 1000000000, 1 },38};39 40static struct alpha_pll_config videocc_pll0_config = {41	.l = 0x19,42	.alpha = 0x0,43	.config_ctl_val = 0x20485699,44	.config_ctl_hi_val = 0x00002067,45	.user_ctl_val = 0x00000001,46	.user_ctl_hi_val = 0x00004805,47	.test_ctl_hi_val = 0x40000000,48};49 50static struct clk_alpha_pll videocc_pll0 = {51	.offset = 0x42c,52	.vco_table = fabia_vco,53	.num_vco = ARRAY_SIZE(fabia_vco),54	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],55	.clkr = {56		.hw.init = &(const struct clk_init_data) {57			.name = "videocc_pll0",58			.parent_data = &(const struct clk_parent_data) {59				.index = DT_BI_TCXO,60			},61			.num_parents = 1,62			.ops = &clk_alpha_pll_fabia_ops,63		},64	},65};66 67static const struct parent_map videocc_parent_map_0[] = {68	{ P_BI_TCXO, 0 },69	{ P_VIDEOCC_PLL0_OUT_MAIN, 1 },70	{ P_VIDEOCC_PLL0_OUT_EVEN, 2 },71	{ P_VIDEOCC_PLL0_OUT_ODD, 3 },72};73 74static const struct clk_parent_data videocc_parent_data_0[] = {75	{ .index = DT_BI_TCXO },76	{ .hw = &videocc_pll0.clkr.hw },77	{ .hw = &videocc_pll0.clkr.hw },78	{ .hw = &videocc_pll0.clkr.hw },79};80 81static const struct parent_map videocc_parent_map_1[] = {82	{ P_BI_TCXO, 0 },83};84 85static const struct clk_parent_data videocc_parent_data_1[] = {86	{ .index = DT_BI_TCXO_AO },87};88 89static const struct freq_tbl ftbl_videocc_iris_clk_src[] = {90	F(240000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),91	F(338000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),92	F(365000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),93	F(444000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),94	F(533000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),95	{ }96};97 98static struct clk_rcg2 videocc_iris_clk_src = {99	.cmd_rcgr = 0x7f0,100	.mnd_width = 0,101	.hid_width = 5,102	.parent_map = videocc_parent_map_0,103	.freq_tbl = ftbl_videocc_iris_clk_src,104	.clkr.hw.init = &(const struct clk_init_data) {105		.name = "videocc_iris_clk_src",106		.parent_data = videocc_parent_data_0,107		.num_parents = ARRAY_SIZE(videocc_parent_data_0),108		.flags = CLK_SET_RATE_PARENT,109		.ops = &clk_rcg2_shared_ops,110	},111};112 113static const struct freq_tbl ftbl_videocc_xo_clk_src[] = {114	F(19200000, P_BI_TCXO, 1, 0, 0),115	{ }116};117 118static struct clk_rcg2 videocc_xo_clk_src = {119	.cmd_rcgr = 0xa98,120	.mnd_width = 0,121	.hid_width = 5,122	.parent_map = videocc_parent_map_1,123	.freq_tbl = ftbl_videocc_xo_clk_src,124	.clkr.hw.init = &(const struct clk_init_data) {125		.name = "videocc_xo_clk_src",126		.parent_data = videocc_parent_data_1,127		.num_parents = ARRAY_SIZE(videocc_parent_data_1),128		.ops = &clk_rcg2_ops,129	},130};131 132static struct clk_branch videocc_iris_ahb_clk = {133	.halt_reg = 0x8f4,134	.halt_check = BRANCH_VOTED,135	.clkr = {136		.enable_reg = 0x8f4,137		.enable_mask = BIT(0),138		.hw.init = &(const struct clk_init_data) {139			.name = "videocc_iris_ahb_clk",140			.parent_data = &(const struct clk_parent_data) {141				.hw = &videocc_iris_clk_src.clkr.hw,142			},143			.num_parents = 1,144			.flags = CLK_SET_RATE_PARENT,145			.ops = &clk_branch2_ops,146		},147	},148};149 150static struct clk_branch videocc_mvs0_axi_clk = {151	.halt_reg = 0x9ec,152	.halt_check = BRANCH_HALT,153	.clkr = {154		.enable_reg = 0x9ec,155		.enable_mask = BIT(0),156		.hw.init = &(const struct clk_init_data) {157			.name = "videocc_mvs0_axi_clk",158			.ops = &clk_branch2_ops,159		},160	},161};162 163static struct clk_branch videocc_mvs0_core_clk = {164	.halt_reg = 0x890,165	.halt_check = BRANCH_VOTED,166	.clkr = {167		.enable_reg = 0x890,168		.enable_mask = BIT(0),169		.hw.init = &(const struct clk_init_data) {170			.name = "videocc_mvs0_core_clk",171			.parent_data = &(const struct clk_parent_data) {172				.hw = &videocc_iris_clk_src.clkr.hw,173			},174			.num_parents = 1,175			.flags = CLK_SET_RATE_PARENT,176			.ops = &clk_branch2_ops,177		},178	},179};180 181static struct clk_branch videocc_mvs1_axi_clk = {182	.halt_reg = 0xa0c,183	.halt_check = BRANCH_HALT,184	.clkr = {185		.enable_reg = 0xa0c,186		.enable_mask = BIT(0),187		.hw.init = &(const struct clk_init_data) {188			.name = "videocc_mvs1_axi_clk",189			.ops = &clk_branch2_ops,190		},191	},192};193 194static struct clk_branch videocc_mvs1_core_clk = {195	.halt_reg = 0x8d0,196	.halt_check = BRANCH_VOTED,197	.clkr = {198		.enable_reg = 0x8d0,199		.enable_mask = BIT(0),200		.hw.init = &(const struct clk_init_data) {201			.name = "videocc_mvs1_core_clk",202			.parent_data = &(const struct clk_parent_data) {203				.hw = &videocc_iris_clk_src.clkr.hw,204			},205			.num_parents = 1,206			.flags = CLK_SET_RATE_PARENT,207			.ops = &clk_branch2_ops,208		},209	},210};211 212static struct clk_branch videocc_mvsc_core_clk = {213	.halt_reg = 0x850,214	.halt_check = BRANCH_HALT,215	.clkr = {216		.enable_reg = 0x850,217		.enable_mask = BIT(0),218		.hw.init = &(const struct clk_init_data) {219			.name = "videocc_mvsc_core_clk",220			.parent_data = &(const struct clk_parent_data) {221				.hw = &videocc_iris_clk_src.clkr.hw,222			},223			.num_parents = 1,224			.flags = CLK_SET_RATE_PARENT,225			.ops = &clk_branch2_ops,226		},227	},228};229 230static struct clk_branch videocc_mvsc_ctl_axi_clk = {231	.halt_reg = 0x9cc,232	.halt_check = BRANCH_HALT,233	.clkr = {234		.enable_reg = 0x9cc,235		.enable_mask = BIT(0),236		.hw.init = &(const struct clk_init_data) {237			.name = "videocc_mvsc_ctl_axi_clk",238			.ops = &clk_branch2_ops,239		},240	},241};242 243static struct clk_branch videocc_venus_ahb_clk = {244	.halt_reg = 0xa6c,245	.halt_check = BRANCH_HALT,246	.clkr = {247		.enable_reg = 0xa6c,248		.enable_mask = BIT(0),249		.hw.init = &(const struct clk_init_data) {250			.name = "videocc_venus_ahb_clk",251			.ops = &clk_branch2_ops,252		},253	},254};255 256static struct gdsc venus_gdsc = {257	.gdscr = 0x814,258	.pd = {259		.name = "venus_gdsc",260	},261	.cxcs = (unsigned int []){ 0x850, 0x9cc },262	.cxc_count = 2,263	.pwrsts = PWRSTS_OFF_ON,264	.flags = POLL_CFG_GDSCR,265};266 267static struct gdsc vcodec0_gdsc = {268	.gdscr = 0x874,269	.pd = {270		.name = "vcodec0_gdsc",271	},272	.cxcs = (unsigned int []){ 0x890, 0x9ec },273	.cxc_count = 2,274	.flags = HW_CTRL | POLL_CFG_GDSCR,275	.pwrsts = PWRSTS_OFF_ON,276};277 278static struct gdsc vcodec1_gdsc = {279	.gdscr = 0x8b4,280	.pd = {281		.name = "vcodec1_gdsc",282	},283	.cxcs = (unsigned int []){ 0x8d0, 0xa0c },284	.cxc_count = 2,285	.flags = HW_CTRL | POLL_CFG_GDSCR,286	.pwrsts = PWRSTS_OFF_ON,287};288 289static struct clk_regmap *videocc_sm7150_clocks[] = {290	[VIDEOCC_PLL0] = &videocc_pll0.clkr,291	[VIDEOCC_IRIS_AHB_CLK] = &videocc_iris_ahb_clk.clkr,292	[VIDEOCC_IRIS_CLK_SRC] = &videocc_iris_clk_src.clkr,293	[VIDEOCC_MVS0_AXI_CLK] = &videocc_mvs0_axi_clk.clkr,294	[VIDEOCC_MVS0_CORE_CLK] = &videocc_mvs0_core_clk.clkr,295	[VIDEOCC_MVS1_AXI_CLK] = &videocc_mvs1_axi_clk.clkr,296	[VIDEOCC_MVS1_CORE_CLK] = &videocc_mvs1_core_clk.clkr,297	[VIDEOCC_MVSC_CORE_CLK] = &videocc_mvsc_core_clk.clkr,298	[VIDEOCC_MVSC_CTL_AXI_CLK] = &videocc_mvsc_ctl_axi_clk.clkr,299	[VIDEOCC_VENUS_AHB_CLK] = &videocc_venus_ahb_clk.clkr,300	[VIDEOCC_XO_CLK_SRC] = &videocc_xo_clk_src.clkr,301};302 303static struct gdsc *videocc_sm7150_gdscs[] = {304	[VENUS_GDSC] = &venus_gdsc,305	[VCODEC0_GDSC] = &vcodec0_gdsc,306	[VCODEC1_GDSC] = &vcodec1_gdsc,307};308 309static const struct regmap_config videocc_sm7150_regmap_config = {310	.reg_bits	= 32,311	.reg_stride	= 4,312	.val_bits	= 32,313	.max_register	= 0xb94,314	.fast_io	= true,315};316 317static const struct qcom_cc_desc videocc_sm7150_desc = {318	.config = &videocc_sm7150_regmap_config,319	.clks = videocc_sm7150_clocks,320	.num_clks = ARRAY_SIZE(videocc_sm7150_clocks),321	.gdscs = videocc_sm7150_gdscs,322	.num_gdscs = ARRAY_SIZE(videocc_sm7150_gdscs),323};324 325static const struct of_device_id videocc_sm7150_match_table[] = {326	{ .compatible = "qcom,sm7150-videocc" },327	{ }328};329MODULE_DEVICE_TABLE(of, videocc_sm7150_match_table);330 331static int videocc_sm7150_probe(struct platform_device *pdev)332{333	struct regmap *regmap;334 335	regmap = qcom_cc_map(pdev, &videocc_sm7150_desc);336	if (IS_ERR(regmap))337		return PTR_ERR(regmap);338 339	clk_fabia_pll_configure(&videocc_pll0, regmap, &videocc_pll0_config);340 341	/* Keep some clocks always-on */342	qcom_branch_set_clk_en(regmap, 0x984); /* VIDEOCC_XO_CLK */343 344	return qcom_cc_really_probe(&pdev->dev, &videocc_sm7150_desc, regmap);345}346 347static struct platform_driver videocc_sm7150_driver = {348	.probe = videocc_sm7150_probe,349	.driver = {350		.name = "videocc-sm7150",351		.of_match_table = videocc_sm7150_match_table,352	},353};354module_platform_driver(videocc_sm7150_driver);355 356MODULE_DESCRIPTION("Qualcomm SM7150 Video Clock Controller");357MODULE_LICENSE("GPL");358