Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
   4 * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
   5 * Copyright (c) 2024, David Wronek <david@mainlining.org>
   6 */
   7
   8#include <linux/clk-provider.h>
   9#include <linux/mod_devicetable.h>
  10#include <linux/module.h>
  11#include <linux/of.h>
  12#include <linux/platform_device.h>
  13#include <linux/regmap.h>
  14
  15#include <dt-bindings/clock/qcom,sm7150-dispcc.h>
  16
  17#include "clk-alpha-pll.h"
  18#include "clk-branch.h"
  19#include "clk-rcg.h"
  20#include "clk-regmap.h"
  21#include "clk-regmap-divider.h"
  22#include "common.h"
  23#include "gdsc.h"
  24
  25enum {
  26	DT_BI_TCXO,
  27	DT_BI_TCXO_AO,
  28	DT_GCC_DISP_GPLL0_CLK,
  29	DT_CHIP_SLEEP_CLK,
  30	DT_DSI0_PHY_PLL_OUT_BYTECLK,
  31	DT_DSI0_PHY_PLL_OUT_DSICLK,
  32	DT_DSI1_PHY_PLL_OUT_BYTECLK,
  33	DT_DSI1_PHY_PLL_OUT_DSICLK,
  34	DT_DP_PHY_PLL_LINK_CLK,
  35	DT_DP_PHY_PLL_VCO_DIV_CLK,
  36};
  37
  38enum {
  39	P_BI_TCXO,
  40	P_CHIP_SLEEP_CLK,
  41	P_DISPCC_PLL0_OUT_EVEN,
  42	P_DISPCC_PLL0_OUT_MAIN,
  43	P_DP_PHY_PLL_LINK_CLK,
  44	P_DP_PHY_PLL_VCO_DIV_CLK,
  45	P_DSI0_PHY_PLL_OUT_BYTECLK,
  46	P_DSI0_PHY_PLL_OUT_DSICLK,
  47	P_DSI1_PHY_PLL_OUT_BYTECLK,
  48	P_DSI1_PHY_PLL_OUT_DSICLK,
  49	P_GCC_DISP_GPLL0_CLK,
  50};
  51
  52static const struct pll_vco fabia_vco[] = {
  53	{ 249600000, 2000000000, 0 },
  54	{ 125000000, 1000000000, 1 },
  55};
  56
  57/* 860MHz configuration */
  58static const struct alpha_pll_config dispcc_pll0_config = {
  59	.l = 0x2c,
  60	.alpha = 0xcaaa,
  61	.test_ctl_val = 0x40000000,
  62};
  63
  64static struct clk_alpha_pll dispcc_pll0 = {
  65	.offset = 0x0,
  66	.vco_table = fabia_vco,
  67	.num_vco = ARRAY_SIZE(fabia_vco),
  68	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
  69	.clkr = {
  70		.hw.init = &(const struct clk_init_data) {
  71			.name = "dispcc_pll0",
  72			.parent_data = &(const struct clk_parent_data) {
  73				.index = DT_BI_TCXO,
  74			},
  75			.num_parents = 1,
  76			.ops = &clk_alpha_pll_fabia_ops,
  77		},
  78	},
  79};
  80
  81static const struct parent_map dispcc_parent_map_0[] = {
  82	{ P_BI_TCXO, 0 },
  83	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
  84	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
  85};
  86
  87static const struct clk_parent_data dispcc_parent_data_0[] = {
  88	{ .index = DT_BI_TCXO },
  89	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
  90	{ .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
  91};
  92
  93static const struct parent_map dispcc_parent_map_1[] = {
  94	{ P_BI_TCXO, 0 },
  95	{ P_DP_PHY_PLL_LINK_CLK, 1 },
  96	{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
  97};
  98
  99static const struct clk_parent_data dispcc_parent_data_1[] = {
 100	{ .index = DT_BI_TCXO },
 101	{ .index = DT_DP_PHY_PLL_LINK_CLK },
 102	{ .index = DT_DP_PHY_PLL_VCO_DIV_CLK },
 103};
 104
 105static const struct parent_map dispcc_parent_map_2[] = {
 106	{ P_BI_TCXO, 0 },
 107};
 108
 109static const struct clk_parent_data dispcc_parent_data_2[] = {
 110	{ .index = DT_BI_TCXO },
 111};
 112
 113static const struct clk_parent_data dispcc_parent_data_2_ao[] = {
 114	{ .index = DT_BI_TCXO_AO },
 115};
 116
 117static const struct parent_map dispcc_parent_map_3[] = {
 118	{ P_BI_TCXO, 0 },
 119	{ P_DISPCC_PLL0_OUT_MAIN, 1 },
 120	{ P_GCC_DISP_GPLL0_CLK, 4 },
 121	{ P_DISPCC_PLL0_OUT_EVEN, 5 },
 122};
 123
 124static const struct clk_parent_data dispcc_parent_data_3[] = {
 125	{ .index = DT_BI_TCXO },
 126	{ .hw = &dispcc_pll0.clkr.hw },
 127	{ .index = DT_GCC_DISP_GPLL0_CLK },
 128	{ .hw = &dispcc_pll0.clkr.hw },
 129};
 130
 131static const struct parent_map dispcc_parent_map_4[] = {
 132	{ P_BI_TCXO, 0 },
 133	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
 134	{ P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
 135};
 136
 137static const struct clk_parent_data dispcc_parent_data_4[] = {
 138	{ .index = DT_BI_TCXO },
 139	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
 140	{ .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
 141};
 142
 143static const struct parent_map dispcc_parent_map_5[] = {
 144	{ P_BI_TCXO, 0 },
 145	{ P_GCC_DISP_GPLL0_CLK, 4 },
 146};
 147
 148static const struct clk_parent_data dispcc_parent_data_5[] = {
 149	{ .index = DT_BI_TCXO },
 150	{ .index = DT_GCC_DISP_GPLL0_CLK },
 151};
 152
 153static const struct parent_map dispcc_parent_map_6[] = {
 154	{ P_CHIP_SLEEP_CLK, 0 },
 155};
 156
 157static const struct clk_parent_data dispcc_parent_data_6[] = {
 158	{ .index = DT_CHIP_SLEEP_CLK },
 159};
 160
 161static const struct freq_tbl ftbl_dispcc_mdss_ahb_clk_src[] = {
 162	F(19200000, P_BI_TCXO, 1, 0, 0),
 163	F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0),
 164	F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),
 165	{ }
 166};
 167
 168static struct clk_rcg2 dispcc_mdss_ahb_clk_src = {
 169	.cmd_rcgr = 0x22bc,
 170	.mnd_width = 0,
 171	.hid_width = 5,
 172	.parent_map = dispcc_parent_map_5,
 173	.freq_tbl = ftbl_dispcc_mdss_ahb_clk_src,
 174	.clkr.hw.init = &(const struct clk_init_data) {
 175		.name = "dispcc_mdss_ahb_clk_src",
 176		.parent_data = dispcc_parent_data_5,
 177		.num_parents = ARRAY_SIZE(dispcc_parent_data_5),
 178		.flags = CLK_SET_RATE_PARENT,
 179		.ops = &clk_rcg2_shared_ops,
 180	},
 181};
 182
 183static const struct freq_tbl ftbl_dispcc_mdss_byte0_clk_src[] = {
 184	F(19200000, P_BI_TCXO, 1, 0, 0),
 185	{ }
 186};
 187
 188static struct clk_rcg2 dispcc_mdss_byte0_clk_src = {
 189	.cmd_rcgr = 0x2110,
 190	.mnd_width = 0,
 191	.hid_width = 5,
 192	.parent_map = dispcc_parent_map_0,
 193	.clkr.hw.init = &(const struct clk_init_data) {
 194		.name = "dispcc_mdss_byte0_clk_src",
 195		.parent_data = dispcc_parent_data_0,
 196		.num_parents = ARRAY_SIZE(dispcc_parent_data_0),
 197		.flags = CLK_SET_RATE_PARENT,
 198		.ops = &clk_byte2_ops,
 199	},
 200};
 201
 202static struct clk_rcg2 dispcc_mdss_byte1_clk_src = {
 203	.cmd_rcgr = 0x212c,
 204	.mnd_width = 0,
 205	.hid_width = 5,
 206	.parent_map = dispcc_parent_map_0,
 207	.clkr.hw.init = &(const struct clk_init_data) {
 208		.name = "dispcc_mdss_byte1_clk_src",
 209		.parent_data = dispcc_parent_data_0,
 210		.num_parents = ARRAY_SIZE(dispcc_parent_data_0),
 211		.flags = CLK_SET_RATE_PARENT,
 212		.ops = &clk_byte2_ops,
 213	},
 214};
 215
 216static struct clk_rcg2 dispcc_mdss_dp_aux_clk_src = {
 217	.cmd_rcgr = 0x21dc,
 218	.mnd_width = 0,
 219	.hid_width = 5,
 220	.parent_map = dispcc_parent_map_2,
 221	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
 222	.clkr.hw.init = &(const struct clk_init_data) {
 223		.name = "dispcc_mdss_dp_aux_clk_src",
 224		.parent_data = dispcc_parent_data_2,
 225		.num_parents = ARRAY_SIZE(dispcc_parent_data_2),
 226		.ops = &clk_rcg2_ops,
 227	},
 228};
 229
 230static const struct freq_tbl ftbl_dispcc_mdss_dp_crypto_clk_src[] = {
 231	F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
 232	F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
 233	F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
 234	F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
 235	{ }
 236};
 237
 238static struct clk_rcg2 dispcc_mdss_dp_crypto_clk_src = {
 239	.cmd_rcgr = 0x2194,
 240	.mnd_width = 0,
 241	.hid_width = 5,
 242	.parent_map = dispcc_parent_map_1,
 243	.freq_tbl = ftbl_dispcc_mdss_dp_crypto_clk_src,
 244	.clkr.hw.init = &(const struct clk_init_data) {
 245		.name = "dispcc_mdss_dp_crypto_clk_src",
 246		.parent_data = dispcc_parent_data_1,
 247		.num_parents = ARRAY_SIZE(dispcc_parent_data_1),
 248		.ops = &clk_rcg2_ops,
 249	},
 250};
 251
 252static struct clk_rcg2 dispcc_mdss_dp_link_clk_src = {
 253	.cmd_rcgr = 0x2178,
 254	.mnd_width = 0,
 255	.hid_width = 5,
 256	.parent_map = dispcc_parent_map_1,
 257	.clkr.hw.init = &(const struct clk_init_data) {
 258		.name = "dispcc_mdss_dp_link_clk_src",
 259		.parent_data = dispcc_parent_data_1,
 260		.num_parents = ARRAY_SIZE(dispcc_parent_data_1),
 261		.flags = CLK_SET_RATE_PARENT,
 262		.ops = &clk_byte2_ops,
 263	},
 264};
 265
 266static struct clk_rcg2 dispcc_mdss_dp_pixel1_clk_src = {
 267	.cmd_rcgr = 0x21c4,
 268	.mnd_width = 16,
 269	.hid_width = 5,
 270	.parent_map = dispcc_parent_map_1,
 271	.clkr.hw.init = &(const struct clk_init_data) {
 272		.name = "dispcc_mdss_dp_pixel1_clk_src",
 273		.parent_data = dispcc_parent_data_1,
 274		.num_parents = ARRAY_SIZE(dispcc_parent_data_1),
 275		.flags = CLK_SET_RATE_PARENT,
 276		.ops = &clk_dp_ops,
 277	},
 278};
 279
 280static struct clk_rcg2 dispcc_mdss_dp_pixel_clk_src = {
 281	.cmd_rcgr = 0x21ac,
 282	.mnd_width = 16,
 283	.hid_width = 5,
 284	.parent_map = dispcc_parent_map_1,
 285	.clkr.hw.init = &(const struct clk_init_data) {
 286		.name = "dispcc_mdss_dp_pixel_clk_src",
 287		.parent_data = dispcc_parent_data_1,
 288		.num_parents = ARRAY_SIZE(dispcc_parent_data_1),
 289		.flags = CLK_SET_RATE_PARENT,
 290		.ops = &clk_dp_ops,
 291	},
 292};
 293
 294static struct clk_rcg2 dispcc_mdss_esc0_clk_src = {
 295	.cmd_rcgr = 0x2148,
 296	.mnd_width = 0,
 297	.hid_width = 5,
 298	.parent_map = dispcc_parent_map_0,
 299	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
 300	.clkr.hw.init = &(const struct clk_init_data) {
 301		.name = "dispcc_mdss_esc0_clk_src",
 302		.parent_data = dispcc_parent_data_0,
 303		.num_parents = ARRAY_SIZE(dispcc_parent_data_0),
 304		.ops = &clk_rcg2_ops,
 305	},
 306};
 307
 308static struct clk_rcg2 dispcc_mdss_esc1_clk_src = {
 309	.cmd_rcgr = 0x2160,
 310	.mnd_width = 0,
 311	.hid_width = 5,
 312	.parent_map = dispcc_parent_map_0,
 313	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
 314	.clkr.hw.init = &(const struct clk_init_data) {
 315		.name = "dispcc_mdss_esc1_clk_src",
 316		.parent_data = dispcc_parent_data_0,
 317		.num_parents = ARRAY_SIZE(dispcc_parent_data_0),
 318		.ops = &clk_rcg2_ops,
 319	},
 320};
 321
 322static const struct freq_tbl ftbl_dispcc_mdss_mdp_clk_src[] = {
 323	F(19200000, P_BI_TCXO, 1, 0, 0),
 324	F(85714286, P_GCC_DISP_GPLL0_CLK, 7, 0, 0),
 325	F(100000000, P_GCC_DISP_GPLL0_CLK, 6, 0, 0),
 326	F(150000000, P_GCC_DISP_GPLL0_CLK, 4, 0, 0),
 327	F(172000000, P_DISPCC_PLL0_OUT_MAIN, 5, 0, 0),
 328	F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
 329	F(286666667, P_DISPCC_PLL0_OUT_MAIN, 3, 0, 0),
 330	F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
 331	F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0),
 332	F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0),
 333	{ }
 334};
 335
 336static struct clk_rcg2 dispcc_mdss_mdp_clk_src = {
 337	.cmd_rcgr = 0x20c8,
 338	.mnd_width = 0,
 339	.hid_width = 5,
 340	.parent_map = dispcc_parent_map_3,
 341	.freq_tbl = ftbl_dispcc_mdss_mdp_clk_src,
 342	.clkr.hw.init = &(const struct clk_init_data) {
 343		.name = "dispcc_mdss_mdp_clk_src",
 344		.parent_data = dispcc_parent_data_3,
 345		.num_parents = ARRAY_SIZE(dispcc_parent_data_3),
 346		.flags = CLK_SET_RATE_PARENT,
 347		.ops = &clk_rcg2_shared_ops,
 348	},
 349};
 350
 351static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = {
 352	.cmd_rcgr = 0x2098,
 353	.mnd_width = 8,
 354	.hid_width = 5,
 355	.parent_map = dispcc_parent_map_4,
 356	.clkr.hw.init = &(const struct clk_init_data) {
 357		.name = "dispcc_mdss_pclk0_clk_src",
 358		.parent_data = dispcc_parent_data_4,
 359		.num_parents = ARRAY_SIZE(dispcc_parent_data_4),
 360		.flags = CLK_SET_RATE_PARENT,
 361		.ops = &clk_pixel_ops,
 362	},
 363};
 364
 365static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = {
 366	.cmd_rcgr = 0x20b0,
 367	.mnd_width = 8,
 368	.hid_width = 5,
 369	.parent_map = dispcc_parent_map_4,
 370	.clkr.hw.init = &(const struct clk_init_data) {
 371		.name = "dispcc_mdss_pclk1_clk_src",
 372		.parent_data = dispcc_parent_data_4,
 373		.num_parents = ARRAY_SIZE(dispcc_parent_data_4),
 374		.flags = CLK_SET_RATE_PARENT,
 375		.ops = &clk_pixel_ops,
 376	},
 377};
 378
 379static const struct freq_tbl ftbl_dispcc_mdss_rot_clk_src[] = {
 380	F(19200000, P_BI_TCXO, 1, 0, 0),
 381	F(171428571, P_GCC_DISP_GPLL0_CLK, 3.5, 0, 0),
 382	F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
 383	F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
 384	F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0),
 385	F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0),
 386	{ }
 387};
 388
 389static struct clk_rcg2 dispcc_mdss_rot_clk_src = {
 390	.cmd_rcgr = 0x20e0,
 391	.mnd_width = 0,
 392	.hid_width = 5,
 393	.parent_map = dispcc_parent_map_3,
 394	.freq_tbl = ftbl_dispcc_mdss_rot_clk_src,
 395	.clkr.hw.init = &(const struct clk_init_data) {
 396		.name = "dispcc_mdss_rot_clk_src",
 397		.parent_data = dispcc_parent_data_3,
 398		.num_parents = ARRAY_SIZE(dispcc_parent_data_3),
 399		.ops = &clk_rcg2_shared_ops,
 400	},
 401};
 402
 403static struct clk_rcg2 dispcc_mdss_vsync_clk_src = {
 404	.cmd_rcgr = 0x20f8,
 405	.mnd_width = 0,
 406	.hid_width = 5,
 407	.parent_map = dispcc_parent_map_2,
 408	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
 409	.clkr.hw.init = &(const struct clk_init_data) {
 410		.name = "dispcc_mdss_vsync_clk_src",
 411		.parent_data = dispcc_parent_data_2,
 412		.num_parents = ARRAY_SIZE(dispcc_parent_data_2),
 413		.ops = &clk_rcg2_ops,
 414	},
 415};
 416
 417static const struct freq_tbl ftbl_dispcc_sleep_clk_src[] = {
 418	F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0),
 419	{ }
 420};
 421
 422static struct clk_rcg2 dispcc_sleep_clk_src = {
 423	.cmd_rcgr = 0x6060,
 424	.mnd_width = 0,
 425	.hid_width = 5,
 426	.parent_map = dispcc_parent_map_6,
 427	.freq_tbl = ftbl_dispcc_sleep_clk_src,
 428	.clkr.hw.init = &(const struct clk_init_data) {
 429		.name = "dispcc_sleep_clk_src",
 430		.parent_data = dispcc_parent_data_6,
 431		.num_parents = ARRAY_SIZE(dispcc_parent_data_6),
 432		.ops = &clk_rcg2_ops,
 433	},
 434};
 435
 436static struct clk_rcg2 dispcc_xo_clk_src = {
 437	.cmd_rcgr = 0x6044,
 438	.mnd_width = 0,
 439	.hid_width = 5,
 440	.parent_map = dispcc_parent_map_2,
 441	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
 442	.clkr.hw.init = &(const struct clk_init_data) {
 443		.name = "dispcc_xo_clk_src",
 444		.parent_data = dispcc_parent_data_2_ao,
 445		.num_parents = ARRAY_SIZE(dispcc_parent_data_2_ao),
 446		.ops = &clk_rcg2_ops,
 447	},
 448};
 449
 450static struct clk_branch dispcc_mdss_ahb_clk = {
 451	.halt_reg = 0x2080,
 452	.halt_check = BRANCH_HALT,
 453	.clkr = {
 454		.enable_reg = 0x2080,
 455		.enable_mask = BIT(0),
 456		.hw.init = &(const struct clk_init_data) {
 457			.name = "dispcc_mdss_ahb_clk",
 458			.parent_hws = (const struct clk_hw*[]) {
 459				&dispcc_mdss_ahb_clk_src.clkr.hw,
 460			},
 461			.num_parents = 1,
 462			.flags = CLK_SET_RATE_PARENT,
 463			.ops = &clk_branch2_ops,
 464		},
 465	},
 466};
 467
 468static struct clk_branch dispcc_mdss_byte0_clk = {
 469	.halt_reg = 0x2028,
 470	.halt_check = BRANCH_HALT,
 471	.clkr = {
 472		.enable_reg = 0x2028,
 473		.enable_mask = BIT(0),
 474		.hw.init = &(const struct clk_init_data) {
 475			.name = "dispcc_mdss_byte0_clk",
 476			.parent_hws = (const struct clk_hw*[]) {
 477				&dispcc_mdss_byte0_clk_src.clkr.hw,
 478			},
 479			.num_parents = 1,
 480			.flags = CLK_SET_RATE_PARENT,
 481			.ops = &clk_branch2_ops,
 482		},
 483	},
 484};
 485
 486static struct clk_regmap_div dispcc_mdss_byte0_div_clk_src = {
 487	.reg = 0x2128,
 488	.shift = 0,
 489	.width = 2,
 490	.clkr = {
 491		.hw.init = &(const struct clk_init_data) {
 492			.name = "dispcc_mdss_byte0_div_clk_src",
 493			.parent_hws = (const struct clk_hw*[]) {
 494				&dispcc_mdss_byte0_clk_src.clkr.hw,
 495			},
 496			.num_parents = 1,
 497			.ops = &clk_regmap_div_ops,
 498		},
 499	},
 500};
 501
 502static struct clk_branch dispcc_mdss_byte0_intf_clk = {
 503	.halt_reg = 0x202c,
 504	.halt_check = BRANCH_HALT,
 505	.clkr = {
 506		.enable_reg = 0x202c,
 507		.enable_mask = BIT(0),
 508		.hw.init = &(const struct clk_init_data) {
 509			.name = "dispcc_mdss_byte0_intf_clk",
 510			.parent_hws = (const struct clk_hw*[]) {
 511				&dispcc_mdss_byte0_div_clk_src.clkr.hw,
 512			},
 513			.num_parents = 1,
 514			.ops = &clk_branch2_ops,
 515		},
 516	},
 517};
 518
 519static struct clk_branch dispcc_mdss_byte1_clk = {
 520	.halt_reg = 0x2030,
 521	.halt_check = BRANCH_HALT,
 522	.clkr = {
 523		.enable_reg = 0x2030,
 524		.enable_mask = BIT(0),
 525		.hw.init = &(const struct clk_init_data) {
 526			.name = "dispcc_mdss_byte1_clk",
 527			.parent_hws = (const struct clk_hw*[]) {
 528				&dispcc_mdss_byte1_clk_src.clkr.hw,
 529			},
 530			.num_parents = 1,
 531			.flags = CLK_SET_RATE_PARENT,
 532			.ops = &clk_branch2_ops,
 533		},
 534	},
 535};
 536
 537static struct clk_regmap_div dispcc_mdss_byte1_div_clk_src = {
 538	.reg = 0x2144,
 539	.shift = 0,
 540	.width = 2,
 541	.clkr = {
 542		.hw.init = &(const struct clk_init_data) {
 543			.name = "dispcc_mdss_byte1_div_clk_src",
 544			.parent_hws = (const struct clk_hw*[]) {
 545				&dispcc_mdss_byte1_clk_src.clkr.hw,
 546			},
 547			.num_parents = 1,
 548			.ops = &clk_regmap_div_ops,
 549		},
 550	},
 551};
 552
 553static struct clk_branch dispcc_mdss_byte1_intf_clk = {
 554	.halt_reg = 0x2034,
 555	.halt_check = BRANCH_HALT,
 556	.clkr = {
 557		.enable_reg = 0x2034,
 558		.enable_mask = BIT(0),
 559		.hw.init = &(const struct clk_init_data) {
 560			.name = "dispcc_mdss_byte1_intf_clk",
 561			.parent_hws = (const struct clk_hw*[]) {
 562				&dispcc_mdss_byte1_div_clk_src.clkr.hw,
 563			},
 564			.num_parents = 1,
 565			.flags = CLK_SET_RATE_PARENT,
 566			.ops = &clk_branch2_ops,
 567		},
 568	},
 569};
 570
 571static struct clk_branch dispcc_mdss_dp_aux_clk = {
 572	.halt_reg = 0x2054,
 573	.halt_check = BRANCH_HALT,
 574	.clkr = {
 575		.enable_reg = 0x2054,
 576		.enable_mask = BIT(0),
 577		.hw.init = &(const struct clk_init_data) {
 578			.name = "dispcc_mdss_dp_aux_clk",
 579			.parent_hws = (const struct clk_hw*[]) {
 580				&dispcc_mdss_dp_aux_clk_src.clkr.hw,
 581			},
 582			.num_parents = 1,
 583			.flags = CLK_SET_RATE_PARENT,
 584			.ops = &clk_branch2_ops,
 585		},
 586	},
 587};
 588
 589static struct clk_branch dispcc_mdss_dp_crypto_clk = {
 590	.halt_reg = 0x2048,
 591	.halt_check = BRANCH_HALT,
 592	.clkr = {
 593		.enable_reg = 0x2048,
 594		.enable_mask = BIT(0),
 595		.hw.init = &(const struct clk_init_data) {
 596			.name = "dispcc_mdss_dp_crypto_clk",
 597			.parent_hws = (const struct clk_hw*[]) {
 598				&dispcc_mdss_dp_crypto_clk_src.clkr.hw,
 599			},
 600			.num_parents = 1,
 601			.flags = CLK_SET_RATE_PARENT,
 602			.ops = &clk_branch2_ops,
 603		},
 604	},
 605};
 606
 607static struct clk_branch dispcc_mdss_dp_link_clk = {
 608	.halt_reg = 0x2040,
 609	.halt_check = BRANCH_HALT,
 610	.clkr = {
 611		.enable_reg = 0x2040,
 612		.enable_mask = BIT(0),
 613		.hw.init = &(const struct clk_init_data) {
 614			.name = "dispcc_mdss_dp_link_clk",
 615			.parent_hws = (const struct clk_hw*[]) {
 616				&dispcc_mdss_dp_link_clk_src.clkr.hw,
 617			},
 618			.num_parents = 1,
 619			.flags = CLK_SET_RATE_PARENT,
 620			.ops = &clk_branch2_ops,
 621		},
 622	},
 623};
 624
 625static struct clk_branch dispcc_mdss_dp_link_intf_clk = {
 626	.halt_reg = 0x2044,
 627	.halt_check = BRANCH_HALT,
 628	.clkr = {
 629		.enable_reg = 0x2044,
 630		.enable_mask = BIT(0),
 631		.hw.init = &(const struct clk_init_data) {
 632			.name = "dispcc_mdss_dp_link_intf_clk",
 633			.parent_hws = (const struct clk_hw*[]) {
 634				&dispcc_mdss_dp_link_clk_src.clkr.hw,
 635			},
 636			.num_parents = 1,
 637			.ops = &clk_branch2_ops,
 638		},
 639	},
 640};
 641
 642static struct clk_branch dispcc_mdss_dp_pixel1_clk = {
 643	.halt_reg = 0x2050,
 644	.halt_check = BRANCH_HALT,
 645	.clkr = {
 646		.enable_reg = 0x2050,
 647		.enable_mask = BIT(0),
 648		.hw.init = &(const struct clk_init_data) {
 649			.name = "dispcc_mdss_dp_pixel1_clk",
 650			.parent_hws = (const struct clk_hw*[]) {
 651				&dispcc_mdss_dp_pixel1_clk_src.clkr.hw,
 652			},
 653			.num_parents = 1,
 654			.flags = CLK_SET_RATE_PARENT,
 655			.ops = &clk_branch2_ops,
 656		},
 657	},
 658};
 659
 660static struct clk_branch dispcc_mdss_dp_pixel_clk = {
 661	.halt_reg = 0x204c,
 662	.halt_check = BRANCH_HALT,
 663	.clkr = {
 664		.enable_reg = 0x204c,
 665		.enable_mask = BIT(0),
 666		.hw.init = &(const struct clk_init_data) {
 667			.name = "dispcc_mdss_dp_pixel_clk",
 668			.parent_hws = (const struct clk_hw*[]) {
 669				&dispcc_mdss_dp_pixel_clk_src.clkr.hw,
 670			},
 671			.num_parents = 1,
 672			.flags = CLK_SET_RATE_PARENT,
 673			.ops = &clk_branch2_ops,
 674		},
 675	},
 676};
 677
 678static struct clk_branch dispcc_mdss_esc0_clk = {
 679	.halt_reg = 0x2038,
 680	.halt_check = BRANCH_HALT,
 681	.clkr = {
 682		.enable_reg = 0x2038,
 683		.enable_mask = BIT(0),
 684		.hw.init = &(const struct clk_init_data) {
 685			.name = "dispcc_mdss_esc0_clk",
 686			.parent_hws = (const struct clk_hw*[]) {
 687				&dispcc_mdss_esc0_clk_src.clkr.hw,
 688			},
 689			.num_parents = 1,
 690			.flags = CLK_SET_RATE_PARENT,
 691			.ops = &clk_branch2_ops,
 692		},
 693	},
 694};
 695
 696static struct clk_branch dispcc_mdss_esc1_clk = {
 697	.halt_reg = 0x203c,
 698	.halt_check = BRANCH_HALT,
 699	.clkr = {
 700		.enable_reg = 0x203c,
 701		.enable_mask = BIT(0),
 702		.hw.init = &(const struct clk_init_data) {
 703			.name = "dispcc_mdss_esc1_clk",
 704			.parent_hws = (const struct clk_hw*[]) {
 705				&dispcc_mdss_esc1_clk_src.clkr.hw,
 706			},
 707			.num_parents = 1,
 708			.flags = CLK_SET_RATE_PARENT,
 709			.ops = &clk_branch2_ops,
 710		},
 711	},
 712};
 713
 714static struct clk_branch dispcc_mdss_mdp_clk = {
 715	.halt_reg = 0x200c,
 716	.halt_check = BRANCH_HALT,
 717	.clkr = {
 718		.enable_reg = 0x200c,
 719		.enable_mask = BIT(0),
 720		.hw.init = &(const struct clk_init_data) {
 721			.name = "dispcc_mdss_mdp_clk",
 722			.parent_hws = (const struct clk_hw*[]) {
 723				&dispcc_mdss_mdp_clk_src.clkr.hw,
 724			},
 725			.num_parents = 1,
 726			.flags = CLK_SET_RATE_PARENT,
 727			.ops = &clk_branch2_ops,
 728		},
 729	},
 730};
 731
 732static struct clk_branch dispcc_mdss_mdp_lut_clk = {
 733	.halt_reg = 0x201c,
 734	.halt_check = BRANCH_VOTED,
 735	.clkr = {
 736		.enable_reg = 0x201c,
 737		.enable_mask = BIT(0),
 738		.hw.init = &(const struct clk_init_data) {
 739			.name = "dispcc_mdss_mdp_lut_clk",
 740			.parent_hws = (const struct clk_hw*[]) {
 741				&dispcc_mdss_mdp_clk_src.clkr.hw,
 742			},
 743			.num_parents = 1,
 744			.ops = &clk_branch2_ops,
 745		},
 746	},
 747};
 748
 749static struct clk_branch dispcc_mdss_non_gdsc_ahb_clk = {
 750	.halt_reg = 0x4004,
 751	.halt_check = BRANCH_VOTED,
 752	.clkr = {
 753		.enable_reg = 0x4004,
 754		.enable_mask = BIT(0),
 755		.hw.init = &(const struct clk_init_data) {
 756			.name = "dispcc_mdss_non_gdsc_ahb_clk",
 757			.parent_hws = (const struct clk_hw*[]) {
 758				&dispcc_mdss_ahb_clk_src.clkr.hw,
 759			},
 760			.num_parents = 1,
 761			.flags = CLK_SET_RATE_PARENT,
 762			.ops = &clk_branch2_ops,
 763		},
 764	},
 765};
 766
 767static struct clk_branch dispcc_mdss_pclk0_clk = {
 768	.halt_reg = 0x2004,
 769	.halt_check = BRANCH_HALT,
 770	.clkr = {
 771		.enable_reg = 0x2004,
 772		.enable_mask = BIT(0),
 773		.hw.init = &(const struct clk_init_data) {
 774			.name = "dispcc_mdss_pclk0_clk",
 775			.parent_hws = (const struct clk_hw*[]) {
 776				&dispcc_mdss_pclk0_clk_src.clkr.hw,
 777			},
 778			.num_parents = 1,
 779			.flags = CLK_SET_RATE_PARENT,
 780			.ops = &clk_branch2_ops,
 781		},
 782	},
 783};
 784
 785static struct clk_branch dispcc_mdss_pclk1_clk = {
 786	.halt_reg = 0x2008,
 787	.halt_check = BRANCH_HALT,
 788	.clkr = {
 789		.enable_reg = 0x2008,
 790		.enable_mask = BIT(0),
 791		.hw.init = &(const struct clk_init_data) {
 792			.name = "dispcc_mdss_pclk1_clk",
 793			.parent_hws = (const struct clk_hw*[]) {
 794				&dispcc_mdss_pclk1_clk_src.clkr.hw,
 795			},
 796			.num_parents = 1,
 797			.flags = CLK_SET_RATE_PARENT,
 798			.ops = &clk_branch2_ops,
 799		},
 800	},
 801};
 802
 803static struct clk_branch dispcc_mdss_rot_clk = {
 804	.halt_reg = 0x2014,
 805	.halt_check = BRANCH_HALT,
 806	.clkr = {
 807		.enable_reg = 0x2014,
 808		.enable_mask = BIT(0),
 809		.hw.init = &(const struct clk_init_data) {
 810			.name = "dispcc_mdss_rot_clk",
 811			.parent_hws = (const struct clk_hw*[]) {
 812				&dispcc_mdss_rot_clk_src.clkr.hw,
 813			},
 814			.num_parents = 1,
 815			.flags = CLK_SET_RATE_PARENT,
 816			.ops = &clk_branch2_ops,
 817		},
 818	},
 819};
 820
 821static struct clk_branch dispcc_mdss_rscc_ahb_clk = {
 822	.halt_reg = 0x400c,
 823	.halt_check = BRANCH_HALT,
 824	.clkr = {
 825		.enable_reg = 0x400c,
 826		.enable_mask = BIT(0),
 827		.hw.init = &(const struct clk_init_data) {
 828			.name = "dispcc_mdss_rscc_ahb_clk",
 829			.parent_names = (const char *[]) {
 830				"dispcc_mdss_ahb_clk_src",
 831			},
 832			.num_parents = 1,
 833			.flags = CLK_SET_RATE_PARENT,
 834			.ops = &clk_branch2_ops,
 835		},
 836	},
 837};
 838
 839static struct clk_branch dispcc_mdss_rscc_vsync_clk = {
 840	.halt_reg = 0x4008,
 841	.halt_check = BRANCH_HALT,
 842	.clkr = {
 843		.enable_reg = 0x4008,
 844		.enable_mask = BIT(0),
 845		.hw.init = &(const struct clk_init_data) {
 846			.name = "dispcc_mdss_rscc_vsync_clk",
 847			.parent_hws = (const struct clk_hw*[]) {
 848				&dispcc_mdss_vsync_clk_src.clkr.hw,
 849			},
 850			.num_parents = 1,
 851			.flags = CLK_SET_RATE_PARENT,
 852			.ops = &clk_branch2_ops,
 853		},
 854	},
 855};
 856
 857static struct clk_branch dispcc_mdss_vsync_clk = {
 858	.halt_reg = 0x2024,
 859	.halt_check = BRANCH_HALT,
 860	.clkr = {
 861		.enable_reg = 0x2024,
 862		.enable_mask = BIT(0),
 863		.hw.init = &(const struct clk_init_data) {
 864			.name = "dispcc_mdss_vsync_clk",
 865			.parent_hws = (const struct clk_hw*[]) {
 866				&dispcc_mdss_vsync_clk_src.clkr.hw,
 867			},
 868			.num_parents = 1,
 869			.flags = CLK_SET_RATE_PARENT,
 870			.ops = &clk_branch2_ops,
 871		},
 872	},
 873};
 874
 875static struct clk_branch dispcc_sleep_clk = {
 876	.halt_reg = 0x6078,
 877	.halt_check = BRANCH_HALT,
 878	.clkr = {
 879		.enable_reg = 0x6078,
 880		.enable_mask = BIT(0),
 881		.hw.init = &(const struct clk_init_data) {
 882			.name = "dispcc_sleep_clk",
 883			.parent_names = (const char *[]) {
 884				"dispcc_sleep_clk_src",
 885			},
 886			.num_parents = 1,
 887			.flags = CLK_SET_RATE_PARENT,
 888			.ops = &clk_branch2_ops,
 889		},
 890	},
 891};
 892
 893static struct gdsc mdss_gdsc = {
 894	.gdscr = 0x3000,
 895	.en_rest_wait_val = 0x2,
 896	.en_few_wait_val = 0x2,
 897	.clk_dis_wait_val = 0xf,
 898	.pd = {
 899		.name = "mdss_gdsc",
 900	},
 901	.pwrsts = PWRSTS_OFF_ON,
 902	.flags = HW_CTRL,
 903};
 904
 905static struct clk_regmap *dispcc_sm7150_clocks[] = {
 906	[DISPCC_MDSS_AHB_CLK] = &dispcc_mdss_ahb_clk.clkr,
 907	[DISPCC_MDSS_AHB_CLK_SRC] = &dispcc_mdss_ahb_clk_src.clkr,
 908	[DISPCC_MDSS_BYTE0_CLK] = &dispcc_mdss_byte0_clk.clkr,
 909	[DISPCC_MDSS_BYTE0_CLK_SRC] = &dispcc_mdss_byte0_clk_src.clkr,
 910	[DISPCC_MDSS_BYTE0_DIV_CLK_SRC] = &dispcc_mdss_byte0_div_clk_src.clkr,
 911	[DISPCC_MDSS_BYTE0_INTF_CLK] = &dispcc_mdss_byte0_intf_clk.clkr,
 912	[DISPCC_MDSS_BYTE1_CLK] = &dispcc_mdss_byte1_clk.clkr,
 913	[DISPCC_MDSS_BYTE1_CLK_SRC] = &dispcc_mdss_byte1_clk_src.clkr,
 914	[DISPCC_MDSS_BYTE1_DIV_CLK_SRC] = &dispcc_mdss_byte1_div_clk_src.clkr,
 915	[DISPCC_MDSS_BYTE1_INTF_CLK] = &dispcc_mdss_byte1_intf_clk.clkr,
 916	[DISPCC_MDSS_DP_AUX_CLK] = &dispcc_mdss_dp_aux_clk.clkr,
 917	[DISPCC_MDSS_DP_AUX_CLK_SRC] = &dispcc_mdss_dp_aux_clk_src.clkr,
 918	[DISPCC_MDSS_DP_CRYPTO_CLK] = &dispcc_mdss_dp_crypto_clk.clkr,
 919	[DISPCC_MDSS_DP_CRYPTO_CLK_SRC] = &dispcc_mdss_dp_crypto_clk_src.clkr,
 920	[DISPCC_MDSS_DP_LINK_CLK] = &dispcc_mdss_dp_link_clk.clkr,
 921	[DISPCC_MDSS_DP_LINK_CLK_SRC] = &dispcc_mdss_dp_link_clk_src.clkr,
 922	[DISPCC_MDSS_DP_LINK_INTF_CLK] = &dispcc_mdss_dp_link_intf_clk.clkr,
 923	[DISPCC_MDSS_DP_PIXEL1_CLK] = &dispcc_mdss_dp_pixel1_clk.clkr,
 924	[DISPCC_MDSS_DP_PIXEL1_CLK_SRC] = &dispcc_mdss_dp_pixel1_clk_src.clkr,
 925	[DISPCC_MDSS_DP_PIXEL_CLK] = &dispcc_mdss_dp_pixel_clk.clkr,
 926	[DISPCC_MDSS_DP_PIXEL_CLK_SRC] = &dispcc_mdss_dp_pixel_clk_src.clkr,
 927	[DISPCC_MDSS_ESC0_CLK] = &dispcc_mdss_esc0_clk.clkr,
 928	[DISPCC_MDSS_ESC0_CLK_SRC] = &dispcc_mdss_esc0_clk_src.clkr,
 929	[DISPCC_MDSS_ESC1_CLK] = &dispcc_mdss_esc1_clk.clkr,
 930	[DISPCC_MDSS_ESC1_CLK_SRC] = &dispcc_mdss_esc1_clk_src.clkr,
 931	[DISPCC_MDSS_MDP_CLK] = &dispcc_mdss_mdp_clk.clkr,
 932	[DISPCC_MDSS_MDP_CLK_SRC] = &dispcc_mdss_mdp_clk_src.clkr,
 933	[DISPCC_MDSS_MDP_LUT_CLK] = &dispcc_mdss_mdp_lut_clk.clkr,
 934	[DISPCC_MDSS_NON_GDSC_AHB_CLK] = &dispcc_mdss_non_gdsc_ahb_clk.clkr,
 935	[DISPCC_MDSS_PCLK0_CLK] = &dispcc_mdss_pclk0_clk.clkr,
 936	[DISPCC_MDSS_PCLK0_CLK_SRC] = &dispcc_mdss_pclk0_clk_src.clkr,
 937	[DISPCC_MDSS_PCLK1_CLK] = &dispcc_mdss_pclk1_clk.clkr,
 938	[DISPCC_MDSS_PCLK1_CLK_SRC] = &dispcc_mdss_pclk1_clk_src.clkr,
 939	[DISPCC_MDSS_ROT_CLK] = &dispcc_mdss_rot_clk.clkr,
 940	[DISPCC_MDSS_ROT_CLK_SRC] = &dispcc_mdss_rot_clk_src.clkr,
 941	[DISPCC_MDSS_RSCC_AHB_CLK] = &dispcc_mdss_rscc_ahb_clk.clkr,
 942	[DISPCC_MDSS_RSCC_VSYNC_CLK] = &dispcc_mdss_rscc_vsync_clk.clkr,
 943	[DISPCC_MDSS_VSYNC_CLK] = &dispcc_mdss_vsync_clk.clkr,
 944	[DISPCC_MDSS_VSYNC_CLK_SRC] = &dispcc_mdss_vsync_clk_src.clkr,
 945	[DISPCC_PLL0] = &dispcc_pll0.clkr,
 946	[DISPCC_SLEEP_CLK] = &dispcc_sleep_clk.clkr,
 947	[DISPCC_SLEEP_CLK_SRC] = &dispcc_sleep_clk_src.clkr,
 948	[DISPCC_XO_CLK_SRC] = &dispcc_xo_clk_src.clkr,
 949};
 950
 951static struct gdsc *dispcc_sm7150_gdscs[] = {
 952	[MDSS_GDSC] = &mdss_gdsc,
 953};
 954
 955static const struct regmap_config dispcc_sm7150_regmap_config = {
 956	.reg_bits	= 32,
 957	.reg_stride	= 4,
 958	.val_bits	= 32,
 959	.max_register	= 0x10000,
 960	.fast_io	= true,
 961};
 962
 963static const struct qcom_cc_desc dispcc_sm7150_desc = {
 964	.config = &dispcc_sm7150_regmap_config,
 965	.clks = dispcc_sm7150_clocks,
 966	.num_clks = ARRAY_SIZE(dispcc_sm7150_clocks),
 967	.gdscs = dispcc_sm7150_gdscs,
 968	.num_gdscs = ARRAY_SIZE(dispcc_sm7150_gdscs),
 969};
 970
 971static const struct of_device_id dispcc_sm7150_match_table[] = {
 972	{ .compatible = "qcom,sm7150-dispcc" },
 973	{ }
 974};
 975MODULE_DEVICE_TABLE(of, dispcc_sm7150_match_table);
 976
 977static int dispcc_sm7150_probe(struct platform_device *pdev)
 978{
 979	struct regmap *regmap;
 980
 981	regmap = qcom_cc_map(pdev, &dispcc_sm7150_desc);
 982	if (IS_ERR(regmap))
 983		return PTR_ERR(regmap);
 984
 985	clk_fabia_pll_configure(&dispcc_pll0, regmap, &dispcc_pll0_config);
 986	/* Enable clock gating for DSI and MDP clocks */
 987	regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
 988
 989	/* Keep some clocks always-on */
 990	qcom_branch_set_clk_en(regmap, 0x605c); /* DISPCC_XO_CLK */
 991
 992	return qcom_cc_really_probe(&pdev->dev, &dispcc_sm7150_desc, regmap);
 993}
 994
 995static struct platform_driver dispcc_sm7150_driver = {
 996	.probe = dispcc_sm7150_probe,
 997	.driver = {
 998		.name = "dispcc-sm7150",
 999		.of_match_table = dispcc_sm7150_match_table,
1000	},
1001};
1002
1003module_platform_driver(dispcc_sm7150_driver);
1004
1005MODULE_DESCRIPTION("Qualcomm SM7150 Display Clock Controller");
1006MODULE_LICENSE("GPL");