cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lcc-msm8960.c (14180B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
      4 */
      5
      6#include <linux/kernel.h>
      7#include <linux/bitops.h>
      8#include <linux/err.h>
      9#include <linux/platform_device.h>
     10#include <linux/module.h>
     11#include <linux/of.h>
     12#include <linux/of_device.h>
     13#include <linux/clk-provider.h>
     14#include <linux/regmap.h>
     15
     16#include <dt-bindings/clock/qcom,lcc-msm8960.h>
     17
     18#include "common.h"
     19#include "clk-regmap.h"
     20#include "clk-pll.h"
     21#include "clk-rcg.h"
     22#include "clk-branch.h"
     23#include "clk-regmap-divider.h"
     24#include "clk-regmap-mux.h"
     25
     26static struct clk_pll pll4 = {
     27	.l_reg = 0x4,
     28	.m_reg = 0x8,
     29	.n_reg = 0xc,
     30	.config_reg = 0x14,
     31	.mode_reg = 0x0,
     32	.status_reg = 0x18,
     33	.status_bit = 16,
     34	.clkr.hw.init = &(struct clk_init_data){
     35		.name = "pll4",
     36		.parent_names = (const char *[]){ "pxo" },
     37		.num_parents = 1,
     38		.ops = &clk_pll_ops,
     39	},
     40};
     41
     42enum {
     43	P_PXO,
     44	P_PLL4,
     45};
     46
     47static const struct parent_map lcc_pxo_pll4_map[] = {
     48	{ P_PXO, 0 },
     49	{ P_PLL4, 2 }
     50};
     51
     52static const char * const lcc_pxo_pll4[] = {
     53	"pxo",
     54	"pll4_vote",
     55};
     56
     57static struct freq_tbl clk_tbl_aif_osr_492[] = {
     58	{   512000, P_PLL4, 4, 1, 240 },
     59	{   768000, P_PLL4, 4, 1, 160 },
     60	{  1024000, P_PLL4, 4, 1, 120 },
     61	{  1536000, P_PLL4, 4, 1,  80 },
     62	{  2048000, P_PLL4, 4, 1,  60 },
     63	{  3072000, P_PLL4, 4, 1,  40 },
     64	{  4096000, P_PLL4, 4, 1,  30 },
     65	{  6144000, P_PLL4, 4, 1,  20 },
     66	{  8192000, P_PLL4, 4, 1,  15 },
     67	{ 12288000, P_PLL4, 4, 1,  10 },
     68	{ 24576000, P_PLL4, 4, 1,   5 },
     69	{ 27000000, P_PXO,  1, 0,   0 },
     70	{ }
     71};
     72
     73static struct freq_tbl clk_tbl_aif_osr_393[] = {
     74	{   512000, P_PLL4, 4, 1, 192 },
     75	{   768000, P_PLL4, 4, 1, 128 },
     76	{  1024000, P_PLL4, 4, 1,  96 },
     77	{  1536000, P_PLL4, 4, 1,  64 },
     78	{  2048000, P_PLL4, 4, 1,  48 },
     79	{  3072000, P_PLL4, 4, 1,  32 },
     80	{  4096000, P_PLL4, 4, 1,  24 },
     81	{  6144000, P_PLL4, 4, 1,  16 },
     82	{  8192000, P_PLL4, 4, 1,  12 },
     83	{ 12288000, P_PLL4, 4, 1,   8 },
     84	{ 24576000, P_PLL4, 4, 1,   4 },
     85	{ 27000000, P_PXO,  1, 0,   0 },
     86	{ }
     87};
     88
     89static struct clk_rcg mi2s_osr_src = {
     90	.ns_reg = 0x48,
     91	.md_reg = 0x4c,
     92	.mn = {
     93		.mnctr_en_bit = 8,
     94		.mnctr_reset_bit = 7,
     95		.mnctr_mode_shift = 5,
     96		.n_val_shift = 24,
     97		.m_val_shift = 8,
     98		.width = 8,
     99	},
    100	.p = {
    101		.pre_div_shift = 3,
    102		.pre_div_width = 2,
    103	},
    104	.s = {
    105		.src_sel_shift = 0,
    106		.parent_map = lcc_pxo_pll4_map,
    107	},
    108	.freq_tbl = clk_tbl_aif_osr_393,
    109	.clkr = {
    110		.enable_reg = 0x48,
    111		.enable_mask = BIT(9),
    112		.hw.init = &(struct clk_init_data){
    113			.name = "mi2s_osr_src",
    114			.parent_names = lcc_pxo_pll4,
    115			.num_parents = 2,
    116			.ops = &clk_rcg_ops,
    117			.flags = CLK_SET_RATE_GATE,
    118		},
    119	},
    120};
    121
    122static const char * const lcc_mi2s_parents[] = {
    123	"mi2s_osr_src",
    124};
    125
    126static struct clk_branch mi2s_osr_clk = {
    127	.halt_reg = 0x50,
    128	.halt_bit = 1,
    129	.halt_check = BRANCH_HALT_ENABLE,
    130	.clkr = {
    131		.enable_reg = 0x48,
    132		.enable_mask = BIT(17),
    133		.hw.init = &(struct clk_init_data){
    134			.name = "mi2s_osr_clk",
    135			.parent_names = lcc_mi2s_parents,
    136			.num_parents = 1,
    137			.ops = &clk_branch_ops,
    138			.flags = CLK_SET_RATE_PARENT,
    139		},
    140	},
    141};
    142
    143static struct clk_regmap_div mi2s_div_clk = {
    144	.reg = 0x48,
    145	.shift = 10,
    146	.width = 4,
    147	.clkr = {
    148		.enable_reg = 0x48,
    149		.enable_mask = BIT(15),
    150		.hw.init = &(struct clk_init_data){
    151			.name = "mi2s_div_clk",
    152			.parent_names = lcc_mi2s_parents,
    153			.num_parents = 1,
    154			.ops = &clk_regmap_div_ops,
    155		},
    156	},
    157};
    158
    159static struct clk_branch mi2s_bit_div_clk = {
    160	.halt_reg = 0x50,
    161	.halt_bit = 0,
    162	.halt_check = BRANCH_HALT_ENABLE,
    163	.clkr = {
    164		.enable_reg = 0x48,
    165		.enable_mask = BIT(15),
    166		.hw.init = &(struct clk_init_data){
    167			.name = "mi2s_bit_div_clk",
    168			.parent_names = (const char *[]){ "mi2s_div_clk" },
    169			.num_parents = 1,
    170			.ops = &clk_branch_ops,
    171			.flags = CLK_SET_RATE_PARENT,
    172		},
    173	},
    174};
    175
    176static struct clk_regmap_mux mi2s_bit_clk = {
    177	.reg = 0x48,
    178	.shift = 14,
    179	.width = 1,
    180	.clkr = {
    181		.hw.init = &(struct clk_init_data){
    182			.name = "mi2s_bit_clk",
    183			.parent_names = (const char *[]){
    184				"mi2s_bit_div_clk",
    185				"mi2s_codec_clk",
    186			},
    187			.num_parents = 2,
    188			.ops = &clk_regmap_mux_closest_ops,
    189			.flags = CLK_SET_RATE_PARENT,
    190		},
    191	},
    192};
    193
    194#define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr)			\
    195static struct clk_rcg prefix##_osr_src = {			\
    196	.ns_reg = _ns,						\
    197	.md_reg = _md,						\
    198	.mn = {							\
    199		.mnctr_en_bit = 8,				\
    200		.mnctr_reset_bit = 7,				\
    201		.mnctr_mode_shift = 5,				\
    202		.n_val_shift = 24,				\
    203		.m_val_shift = 8,				\
    204		.width = 8,					\
    205	},							\
    206	.p = {							\
    207		.pre_div_shift = 3,				\
    208		.pre_div_width = 2,				\
    209	},							\
    210	.s = {							\
    211		.src_sel_shift = 0,				\
    212		.parent_map = lcc_pxo_pll4_map,			\
    213	},							\
    214	.freq_tbl = clk_tbl_aif_osr_393,			\
    215	.clkr = {						\
    216		.enable_reg = _ns,				\
    217		.enable_mask = BIT(9),				\
    218		.hw.init = &(struct clk_init_data){		\
    219			.name = #prefix "_osr_src",		\
    220			.parent_names = lcc_pxo_pll4,		\
    221			.num_parents = 2,			\
    222			.ops = &clk_rcg_ops,			\
    223			.flags = CLK_SET_RATE_GATE,		\
    224		},						\
    225	},							\
    226};								\
    227								\
    228static const char * const lcc_##prefix##_parents[] = {		\
    229	#prefix "_osr_src",					\
    230};								\
    231								\
    232static struct clk_branch prefix##_osr_clk = {			\
    233	.halt_reg = hr,						\
    234	.halt_bit = 1,						\
    235	.halt_check = BRANCH_HALT_ENABLE,			\
    236	.clkr = {						\
    237		.enable_reg = _ns,				\
    238		.enable_mask = BIT(21),				\
    239		.hw.init = &(struct clk_init_data){		\
    240			.name = #prefix "_osr_clk",		\
    241			.parent_names = lcc_##prefix##_parents,	\
    242			.num_parents = 1,			\
    243			.ops = &clk_branch_ops,			\
    244			.flags = CLK_SET_RATE_PARENT,		\
    245		},						\
    246	},							\
    247};								\
    248								\
    249static struct clk_regmap_div prefix##_div_clk = {		\
    250	.reg = _ns,						\
    251	.shift = 10,						\
    252	.width = 8,						\
    253	.clkr = {						\
    254		.hw.init = &(struct clk_init_data){		\
    255			.name = #prefix "_div_clk",		\
    256			.parent_names = lcc_##prefix##_parents,	\
    257			.num_parents = 1,			\
    258			.ops = &clk_regmap_div_ops,		\
    259		},						\
    260	},							\
    261};								\
    262								\
    263static struct clk_branch prefix##_bit_div_clk = {		\
    264	.halt_reg = hr,						\
    265	.halt_bit = 0,						\
    266	.halt_check = BRANCH_HALT_ENABLE,			\
    267	.clkr = {						\
    268		.enable_reg = _ns,				\
    269		.enable_mask = BIT(19),				\
    270		.hw.init = &(struct clk_init_data){		\
    271			.name = #prefix "_bit_div_clk",		\
    272			.parent_names = (const char *[]){	\
    273				#prefix "_div_clk"		\
    274			}, 					\
    275			.num_parents = 1,			\
    276			.ops = &clk_branch_ops,			\
    277			.flags = CLK_SET_RATE_PARENT,		\
    278		},						\
    279	},							\
    280};								\
    281								\
    282static struct clk_regmap_mux prefix##_bit_clk = {		\
    283	.reg = _ns,						\
    284	.shift = 18,						\
    285	.width = 1,						\
    286	.clkr = {						\
    287		.hw.init = &(struct clk_init_data){		\
    288			.name = #prefix "_bit_clk",		\
    289			.parent_names = (const char *[]){	\
    290				#prefix "_bit_div_clk",		\
    291				#prefix "_codec_clk",		\
    292			},					\
    293			.num_parents = 2,			\
    294			.ops = &clk_regmap_mux_closest_ops,	\
    295			.flags = CLK_SET_RATE_PARENT,		\
    296		},						\
    297	},							\
    298}
    299
    300CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68);
    301CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80);
    302CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74);
    303CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c);
    304
    305static struct freq_tbl clk_tbl_pcm_492[] = {
    306	{   256000, P_PLL4, 4, 1, 480 },
    307	{   512000, P_PLL4, 4, 1, 240 },
    308	{   768000, P_PLL4, 4, 1, 160 },
    309	{  1024000, P_PLL4, 4, 1, 120 },
    310	{  1536000, P_PLL4, 4, 1,  80 },
    311	{  2048000, P_PLL4, 4, 1,  60 },
    312	{  3072000, P_PLL4, 4, 1,  40 },
    313	{  4096000, P_PLL4, 4, 1,  30 },
    314	{  6144000, P_PLL4, 4, 1,  20 },
    315	{  8192000, P_PLL4, 4, 1,  15 },
    316	{ 12288000, P_PLL4, 4, 1,  10 },
    317	{ 24576000, P_PLL4, 4, 1,   5 },
    318	{ 27000000, P_PXO,  1, 0,   0 },
    319	{ }
    320};
    321
    322static struct freq_tbl clk_tbl_pcm_393[] = {
    323	{   256000, P_PLL4, 4, 1, 384 },
    324	{   512000, P_PLL4, 4, 1, 192 },
    325	{   768000, P_PLL4, 4, 1, 128 },
    326	{  1024000, P_PLL4, 4, 1,  96 },
    327	{  1536000, P_PLL4, 4, 1,  64 },
    328	{  2048000, P_PLL4, 4, 1,  48 },
    329	{  3072000, P_PLL4, 4, 1,  32 },
    330	{  4096000, P_PLL4, 4, 1,  24 },
    331	{  6144000, P_PLL4, 4, 1,  16 },
    332	{  8192000, P_PLL4, 4, 1,  12 },
    333	{ 12288000, P_PLL4, 4, 1,   8 },
    334	{ 24576000, P_PLL4, 4, 1,   4 },
    335	{ 27000000, P_PXO,  1, 0,   0 },
    336	{ }
    337};
    338
    339static struct clk_rcg pcm_src = {
    340	.ns_reg = 0x54,
    341	.md_reg = 0x58,
    342	.mn = {
    343		.mnctr_en_bit = 8,
    344		.mnctr_reset_bit = 7,
    345		.mnctr_mode_shift = 5,
    346		.n_val_shift = 16,
    347		.m_val_shift = 16,
    348		.width = 16,
    349	},
    350	.p = {
    351		.pre_div_shift = 3,
    352		.pre_div_width = 2,
    353	},
    354	.s = {
    355		.src_sel_shift = 0,
    356		.parent_map = lcc_pxo_pll4_map,
    357	},
    358	.freq_tbl = clk_tbl_pcm_393,
    359	.clkr = {
    360		.enable_reg = 0x54,
    361		.enable_mask = BIT(9),
    362		.hw.init = &(struct clk_init_data){
    363			.name = "pcm_src",
    364			.parent_names = lcc_pxo_pll4,
    365			.num_parents = 2,
    366			.ops = &clk_rcg_ops,
    367			.flags = CLK_SET_RATE_GATE,
    368		},
    369	},
    370};
    371
    372static struct clk_branch pcm_clk_out = {
    373	.halt_reg = 0x5c,
    374	.halt_bit = 0,
    375	.halt_check = BRANCH_HALT_ENABLE,
    376	.clkr = {
    377		.enable_reg = 0x54,
    378		.enable_mask = BIT(11),
    379		.hw.init = &(struct clk_init_data){
    380			.name = "pcm_clk_out",
    381			.parent_names = (const char *[]){ "pcm_src" },
    382			.num_parents = 1,
    383			.ops = &clk_branch_ops,
    384			.flags = CLK_SET_RATE_PARENT,
    385		},
    386	},
    387};
    388
    389static struct clk_regmap_mux pcm_clk = {
    390	.reg = 0x54,
    391	.shift = 10,
    392	.width = 1,
    393	.clkr = {
    394		.hw.init = &(struct clk_init_data){
    395			.name = "pcm_clk",
    396			.parent_names = (const char *[]){
    397				"pcm_clk_out",
    398				"pcm_codec_clk",
    399			},
    400			.num_parents = 2,
    401			.ops = &clk_regmap_mux_closest_ops,
    402			.flags = CLK_SET_RATE_PARENT,
    403		},
    404	},
    405};
    406
    407static struct clk_rcg slimbus_src = {
    408	.ns_reg = 0xcc,
    409	.md_reg = 0xd0,
    410	.mn = {
    411		.mnctr_en_bit = 8,
    412		.mnctr_reset_bit = 7,
    413		.mnctr_mode_shift = 5,
    414		.n_val_shift = 24,
    415		.m_val_shift = 8,
    416		.width = 8,
    417	},
    418	.p = {
    419		.pre_div_shift = 3,
    420		.pre_div_width = 2,
    421	},
    422	.s = {
    423		.src_sel_shift = 0,
    424		.parent_map = lcc_pxo_pll4_map,
    425	},
    426	.freq_tbl = clk_tbl_aif_osr_393,
    427	.clkr = {
    428		.enable_reg = 0xcc,
    429		.enable_mask = BIT(9),
    430		.hw.init = &(struct clk_init_data){
    431			.name = "slimbus_src",
    432			.parent_names = lcc_pxo_pll4,
    433			.num_parents = 2,
    434			.ops = &clk_rcg_ops,
    435			.flags = CLK_SET_RATE_GATE,
    436		},
    437	},
    438};
    439
    440static const char * const lcc_slimbus_parents[] = {
    441	"slimbus_src",
    442};
    443
    444static struct clk_branch audio_slimbus_clk = {
    445	.halt_reg = 0xd4,
    446	.halt_bit = 0,
    447	.halt_check = BRANCH_HALT_ENABLE,
    448	.clkr = {
    449		.enable_reg = 0xcc,
    450		.enable_mask = BIT(10),
    451		.hw.init = &(struct clk_init_data){
    452			.name = "audio_slimbus_clk",
    453			.parent_names = lcc_slimbus_parents,
    454			.num_parents = 1,
    455			.ops = &clk_branch_ops,
    456			.flags = CLK_SET_RATE_PARENT,
    457		},
    458	},
    459};
    460
    461static struct clk_branch sps_slimbus_clk = {
    462	.halt_reg = 0xd4,
    463	.halt_bit = 1,
    464	.halt_check = BRANCH_HALT_ENABLE,
    465	.clkr = {
    466		.enable_reg = 0xcc,
    467		.enable_mask = BIT(12),
    468		.hw.init = &(struct clk_init_data){
    469			.name = "sps_slimbus_clk",
    470			.parent_names = lcc_slimbus_parents,
    471			.num_parents = 1,
    472			.ops = &clk_branch_ops,
    473			.flags = CLK_SET_RATE_PARENT,
    474		},
    475	},
    476};
    477
    478static struct clk_regmap *lcc_msm8960_clks[] = {
    479	[PLL4] = &pll4.clkr,
    480	[MI2S_OSR_SRC] = &mi2s_osr_src.clkr,
    481	[MI2S_OSR_CLK] = &mi2s_osr_clk.clkr,
    482	[MI2S_DIV_CLK] = &mi2s_div_clk.clkr,
    483	[MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr,
    484	[MI2S_BIT_CLK] = &mi2s_bit_clk.clkr,
    485	[PCM_SRC] = &pcm_src.clkr,
    486	[PCM_CLK_OUT] = &pcm_clk_out.clkr,
    487	[PCM_CLK] = &pcm_clk.clkr,
    488	[SLIMBUS_SRC] = &slimbus_src.clkr,
    489	[AUDIO_SLIMBUS_CLK] = &audio_slimbus_clk.clkr,
    490	[SPS_SLIMBUS_CLK] = &sps_slimbus_clk.clkr,
    491	[CODEC_I2S_MIC_OSR_SRC] = &codec_i2s_mic_osr_src.clkr,
    492	[CODEC_I2S_MIC_OSR_CLK] = &codec_i2s_mic_osr_clk.clkr,
    493	[CODEC_I2S_MIC_DIV_CLK] = &codec_i2s_mic_div_clk.clkr,
    494	[CODEC_I2S_MIC_BIT_DIV_CLK] = &codec_i2s_mic_bit_div_clk.clkr,
    495	[CODEC_I2S_MIC_BIT_CLK] = &codec_i2s_mic_bit_clk.clkr,
    496	[SPARE_I2S_MIC_OSR_SRC] = &spare_i2s_mic_osr_src.clkr,
    497	[SPARE_I2S_MIC_OSR_CLK] = &spare_i2s_mic_osr_clk.clkr,
    498	[SPARE_I2S_MIC_DIV_CLK] = &spare_i2s_mic_div_clk.clkr,
    499	[SPARE_I2S_MIC_BIT_DIV_CLK] = &spare_i2s_mic_bit_div_clk.clkr,
    500	[SPARE_I2S_MIC_BIT_CLK] = &spare_i2s_mic_bit_clk.clkr,
    501	[CODEC_I2S_SPKR_OSR_SRC] = &codec_i2s_spkr_osr_src.clkr,
    502	[CODEC_I2S_SPKR_OSR_CLK] = &codec_i2s_spkr_osr_clk.clkr,
    503	[CODEC_I2S_SPKR_DIV_CLK] = &codec_i2s_spkr_div_clk.clkr,
    504	[CODEC_I2S_SPKR_BIT_DIV_CLK] = &codec_i2s_spkr_bit_div_clk.clkr,
    505	[CODEC_I2S_SPKR_BIT_CLK] = &codec_i2s_spkr_bit_clk.clkr,
    506	[SPARE_I2S_SPKR_OSR_SRC] = &spare_i2s_spkr_osr_src.clkr,
    507	[SPARE_I2S_SPKR_OSR_CLK] = &spare_i2s_spkr_osr_clk.clkr,
    508	[SPARE_I2S_SPKR_DIV_CLK] = &spare_i2s_spkr_div_clk.clkr,
    509	[SPARE_I2S_SPKR_BIT_DIV_CLK] = &spare_i2s_spkr_bit_div_clk.clkr,
    510	[SPARE_I2S_SPKR_BIT_CLK] = &spare_i2s_spkr_bit_clk.clkr,
    511};
    512
    513static const struct regmap_config lcc_msm8960_regmap_config = {
    514	.reg_bits	= 32,
    515	.reg_stride	= 4,
    516	.val_bits	= 32,
    517	.max_register	= 0xfc,
    518	.fast_io	= true,
    519};
    520
    521static const struct qcom_cc_desc lcc_msm8960_desc = {
    522	.config = &lcc_msm8960_regmap_config,
    523	.clks = lcc_msm8960_clks,
    524	.num_clks = ARRAY_SIZE(lcc_msm8960_clks),
    525};
    526
    527static const struct of_device_id lcc_msm8960_match_table[] = {
    528	{ .compatible = "qcom,lcc-msm8960" },
    529	{ .compatible = "qcom,lcc-apq8064" },
    530	{ }
    531};
    532MODULE_DEVICE_TABLE(of, lcc_msm8960_match_table);
    533
    534static int lcc_msm8960_probe(struct platform_device *pdev)
    535{
    536	u32 val;
    537	struct regmap *regmap;
    538
    539	regmap = qcom_cc_map(pdev, &lcc_msm8960_desc);
    540	if (IS_ERR(regmap))
    541		return PTR_ERR(regmap);
    542
    543	/* Use the correct frequency plan depending on speed of PLL4 */
    544	regmap_read(regmap, 0x4, &val);
    545	if (val == 0x12) {
    546		slimbus_src.freq_tbl = clk_tbl_aif_osr_492;
    547		mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    548		codec_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    549		spare_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    550		codec_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    551		spare_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    552		pcm_src.freq_tbl = clk_tbl_pcm_492;
    553	}
    554	/* Enable PLL4 source on the LPASS Primary PLL Mux */
    555	regmap_write(regmap, 0xc4, 0x1);
    556
    557	return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap);
    558}
    559
    560static struct platform_driver lcc_msm8960_driver = {
    561	.probe		= lcc_msm8960_probe,
    562	.driver		= {
    563		.name	= "lcc-msm8960",
    564		.of_match_table = lcc_msm8960_match_table,
    565	},
    566};
    567module_platform_driver(lcc_msm8960_driver);
    568
    569MODULE_DESCRIPTION("QCOM LCC MSM8960 Driver");
    570MODULE_LICENSE("GPL v2");
    571MODULE_ALIAS("platform:lcc-msm8960");