162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2014 Marvell Technology Group Ltd. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 662306a36Sopenharmony_ci * Alexandre Belloni <alexandre.belloni@free-electrons.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/clk.h> 1062306a36Sopenharmony_ci#include <linux/clk-provider.h> 1162306a36Sopenharmony_ci#include <linux/io.h> 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/of.h> 1462306a36Sopenharmony_ci#include <linux/of_address.h> 1562306a36Sopenharmony_ci#include <linux/slab.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <dt-bindings/clock/berlin2.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "berlin2-avpll.h" 2062306a36Sopenharmony_ci#include "berlin2-div.h" 2162306a36Sopenharmony_ci#include "berlin2-pll.h" 2262306a36Sopenharmony_ci#include "common.h" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define REG_PINMUX0 0x0000 2562306a36Sopenharmony_ci#define REG_PINMUX1 0x0004 2662306a36Sopenharmony_ci#define REG_SYSPLLCTL0 0x0014 2762306a36Sopenharmony_ci#define REG_SYSPLLCTL4 0x0024 2862306a36Sopenharmony_ci#define REG_MEMPLLCTL0 0x0028 2962306a36Sopenharmony_ci#define REG_MEMPLLCTL4 0x0038 3062306a36Sopenharmony_ci#define REG_CPUPLLCTL0 0x003c 3162306a36Sopenharmony_ci#define REG_CPUPLLCTL4 0x004c 3262306a36Sopenharmony_ci#define REG_AVPLLCTL0 0x0050 3362306a36Sopenharmony_ci#define REG_AVPLLCTL31 0x00cc 3462306a36Sopenharmony_ci#define REG_AVPLLCTL62 0x0148 3562306a36Sopenharmony_ci#define REG_PLLSTATUS 0x014c 3662306a36Sopenharmony_ci#define REG_CLKENABLE 0x0150 3762306a36Sopenharmony_ci#define REG_CLKSELECT0 0x0154 3862306a36Sopenharmony_ci#define REG_CLKSELECT1 0x0158 3962306a36Sopenharmony_ci#define REG_CLKSELECT2 0x015c 4062306a36Sopenharmony_ci#define REG_CLKSELECT3 0x0160 4162306a36Sopenharmony_ci#define REG_CLKSWITCH0 0x0164 4262306a36Sopenharmony_ci#define REG_CLKSWITCH1 0x0168 4362306a36Sopenharmony_ci#define REG_RESET_TRIGGER 0x0178 4462306a36Sopenharmony_ci#define REG_RESET_STATUS0 0x017c 4562306a36Sopenharmony_ci#define REG_RESET_STATUS1 0x0180 4662306a36Sopenharmony_ci#define REG_SW_GENERIC0 0x0184 4762306a36Sopenharmony_ci#define REG_SW_GENERIC3 0x0190 4862306a36Sopenharmony_ci#define REG_PRODUCTID 0x01cc 4962306a36Sopenharmony_ci#define REG_PRODUCTID_EXT 0x01d0 5062306a36Sopenharmony_ci#define REG_GFX3DCORE_CLKCTL 0x022c 5162306a36Sopenharmony_ci#define REG_GFX3DSYS_CLKCTL 0x0230 5262306a36Sopenharmony_ci#define REG_ARC_CLKCTL 0x0234 5362306a36Sopenharmony_ci#define REG_VIP_CLKCTL 0x0238 5462306a36Sopenharmony_ci#define REG_SDIO0XIN_CLKCTL 0x023c 5562306a36Sopenharmony_ci#define REG_SDIO1XIN_CLKCTL 0x0240 5662306a36Sopenharmony_ci#define REG_GFX3DEXTRA_CLKCTL 0x0244 5762306a36Sopenharmony_ci#define REG_GFX3D_RESET 0x0248 5862306a36Sopenharmony_ci#define REG_GC360_CLKCTL 0x024c 5962306a36Sopenharmony_ci#define REG_SDIO_DLLMST_CLKCTL 0x0250 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci/* 6262306a36Sopenharmony_ci * BG2/BG2CD SoCs have the following audio/video I/O units: 6362306a36Sopenharmony_ci * 6462306a36Sopenharmony_ci * audiohd: HDMI TX audio 6562306a36Sopenharmony_ci * audio0: 7.1ch TX 6662306a36Sopenharmony_ci * audio1: 2ch TX 6762306a36Sopenharmony_ci * audio2: 2ch RX 6862306a36Sopenharmony_ci * audio3: SPDIF TX 6962306a36Sopenharmony_ci * video0: HDMI video 7062306a36Sopenharmony_ci * video1: Secondary video 7162306a36Sopenharmony_ci * video2: SD auxiliary video 7262306a36Sopenharmony_ci * 7362306a36Sopenharmony_ci * There are no external audio clocks (ACLKI0, ACLKI1) and 7462306a36Sopenharmony_ci * only one external video clock (VCLKI0). 7562306a36Sopenharmony_ci * 7662306a36Sopenharmony_ci * Currently missing bits and pieces: 7762306a36Sopenharmony_ci * - audio_fast_pll is unknown 7862306a36Sopenharmony_ci * - audiohd_pll is unknown 7962306a36Sopenharmony_ci * - video0_pll is unknown 8062306a36Sopenharmony_ci * - audio[023], audiohd parent pll is assumed to be audio_fast_pll 8162306a36Sopenharmony_ci * 8262306a36Sopenharmony_ci */ 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci#define MAX_CLKS 41 8562306a36Sopenharmony_cistatic struct clk_hw_onecell_data *clk_data; 8662306a36Sopenharmony_cistatic DEFINE_SPINLOCK(lock); 8762306a36Sopenharmony_cistatic void __iomem *gbase; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cienum { 9062306a36Sopenharmony_ci REFCLK, VIDEO_EXT0, 9162306a36Sopenharmony_ci SYSPLL, MEMPLL, CPUPLL, 9262306a36Sopenharmony_ci AVPLL_A1, AVPLL_A2, AVPLL_A3, AVPLL_A4, 9362306a36Sopenharmony_ci AVPLL_A5, AVPLL_A6, AVPLL_A7, AVPLL_A8, 9462306a36Sopenharmony_ci AVPLL_B1, AVPLL_B2, AVPLL_B3, AVPLL_B4, 9562306a36Sopenharmony_ci AVPLL_B5, AVPLL_B6, AVPLL_B7, AVPLL_B8, 9662306a36Sopenharmony_ci AUDIO1_PLL, AUDIO_FAST_PLL, 9762306a36Sopenharmony_ci VIDEO0_PLL, VIDEO0_IN, 9862306a36Sopenharmony_ci VIDEO1_PLL, VIDEO1_IN, 9962306a36Sopenharmony_ci VIDEO2_PLL, VIDEO2_IN, 10062306a36Sopenharmony_ci}; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic const char *clk_names[] = { 10362306a36Sopenharmony_ci [REFCLK] = "refclk", 10462306a36Sopenharmony_ci [VIDEO_EXT0] = "video_ext0", 10562306a36Sopenharmony_ci [SYSPLL] = "syspll", 10662306a36Sopenharmony_ci [MEMPLL] = "mempll", 10762306a36Sopenharmony_ci [CPUPLL] = "cpupll", 10862306a36Sopenharmony_ci [AVPLL_A1] = "avpll_a1", 10962306a36Sopenharmony_ci [AVPLL_A2] = "avpll_a2", 11062306a36Sopenharmony_ci [AVPLL_A3] = "avpll_a3", 11162306a36Sopenharmony_ci [AVPLL_A4] = "avpll_a4", 11262306a36Sopenharmony_ci [AVPLL_A5] = "avpll_a5", 11362306a36Sopenharmony_ci [AVPLL_A6] = "avpll_a6", 11462306a36Sopenharmony_ci [AVPLL_A7] = "avpll_a7", 11562306a36Sopenharmony_ci [AVPLL_A8] = "avpll_a8", 11662306a36Sopenharmony_ci [AVPLL_B1] = "avpll_b1", 11762306a36Sopenharmony_ci [AVPLL_B2] = "avpll_b2", 11862306a36Sopenharmony_ci [AVPLL_B3] = "avpll_b3", 11962306a36Sopenharmony_ci [AVPLL_B4] = "avpll_b4", 12062306a36Sopenharmony_ci [AVPLL_B5] = "avpll_b5", 12162306a36Sopenharmony_ci [AVPLL_B6] = "avpll_b6", 12262306a36Sopenharmony_ci [AVPLL_B7] = "avpll_b7", 12362306a36Sopenharmony_ci [AVPLL_B8] = "avpll_b8", 12462306a36Sopenharmony_ci [AUDIO1_PLL] = "audio1_pll", 12562306a36Sopenharmony_ci [AUDIO_FAST_PLL] = "audio_fast_pll", 12662306a36Sopenharmony_ci [VIDEO0_PLL] = "video0_pll", 12762306a36Sopenharmony_ci [VIDEO0_IN] = "video0_in", 12862306a36Sopenharmony_ci [VIDEO1_PLL] = "video1_pll", 12962306a36Sopenharmony_ci [VIDEO1_IN] = "video1_in", 13062306a36Sopenharmony_ci [VIDEO2_PLL] = "video2_pll", 13162306a36Sopenharmony_ci [VIDEO2_IN] = "video2_in", 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic const struct berlin2_pll_map bg2_pll_map __initconst = { 13562306a36Sopenharmony_ci .vcodiv = {10, 15, 20, 25, 30, 40, 50, 60, 80}, 13662306a36Sopenharmony_ci .mult = 10, 13762306a36Sopenharmony_ci .fbdiv_shift = 6, 13862306a36Sopenharmony_ci .rfdiv_shift = 1, 13962306a36Sopenharmony_ci .divsel_shift = 7, 14062306a36Sopenharmony_ci}; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic const u8 default_parent_ids[] = { 14362306a36Sopenharmony_ci SYSPLL, AVPLL_B4, AVPLL_A5, AVPLL_B6, AVPLL_B7, SYSPLL 14462306a36Sopenharmony_ci}; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistatic const struct berlin2_div_data bg2_divs[] __initconst = { 14762306a36Sopenharmony_ci { 14862306a36Sopenharmony_ci .name = "sys", 14962306a36Sopenharmony_ci .parent_ids = (const u8 []){ 15062306a36Sopenharmony_ci SYSPLL, AVPLL_B4, AVPLL_B5, AVPLL_B6, AVPLL_B7, SYSPLL 15162306a36Sopenharmony_ci }, 15262306a36Sopenharmony_ci .num_parents = 6, 15362306a36Sopenharmony_ci .map = { 15462306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 0), 15562306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT0, 0), 15662306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT0, 3), 15762306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 3), 15862306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 4), 15962306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 5), 16062306a36Sopenharmony_ci }, 16162306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 16262306a36Sopenharmony_ci .flags = CLK_IGNORE_UNUSED, 16362306a36Sopenharmony_ci }, 16462306a36Sopenharmony_ci { 16562306a36Sopenharmony_ci .name = "cpu", 16662306a36Sopenharmony_ci .parent_ids = (const u8 []){ 16762306a36Sopenharmony_ci CPUPLL, MEMPLL, MEMPLL, MEMPLL, MEMPLL 16862306a36Sopenharmony_ci }, 16962306a36Sopenharmony_ci .num_parents = 5, 17062306a36Sopenharmony_ci .map = { 17162306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT0, 6), 17262306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT0, 9), 17362306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 6), 17462306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 7), 17562306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 8), 17662306a36Sopenharmony_ci }, 17762306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_MUX, 17862306a36Sopenharmony_ci .flags = 0, 17962306a36Sopenharmony_ci }, 18062306a36Sopenharmony_ci { 18162306a36Sopenharmony_ci .name = "drmfigo", 18262306a36Sopenharmony_ci .parent_ids = default_parent_ids, 18362306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 18462306a36Sopenharmony_ci .map = { 18562306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 16), 18662306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT0, 17), 18762306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT0, 20), 18862306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 12), 18962306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 13), 19062306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 14), 19162306a36Sopenharmony_ci }, 19262306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 19362306a36Sopenharmony_ci .flags = 0, 19462306a36Sopenharmony_ci }, 19562306a36Sopenharmony_ci { 19662306a36Sopenharmony_ci .name = "cfg", 19762306a36Sopenharmony_ci .parent_ids = default_parent_ids, 19862306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 19962306a36Sopenharmony_ci .map = { 20062306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 1), 20162306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT0, 23), 20262306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT0, 26), 20362306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 15), 20462306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 16), 20562306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 17), 20662306a36Sopenharmony_ci }, 20762306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 20862306a36Sopenharmony_ci .flags = 0, 20962306a36Sopenharmony_ci }, 21062306a36Sopenharmony_ci { 21162306a36Sopenharmony_ci .name = "gfx", 21262306a36Sopenharmony_ci .parent_ids = default_parent_ids, 21362306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 21462306a36Sopenharmony_ci .map = { 21562306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 4), 21662306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT0, 29), 21762306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT1, 0), 21862306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 18), 21962306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 19), 22062306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 20), 22162306a36Sopenharmony_ci }, 22262306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 22362306a36Sopenharmony_ci .flags = 0, 22462306a36Sopenharmony_ci }, 22562306a36Sopenharmony_ci { 22662306a36Sopenharmony_ci .name = "zsp", 22762306a36Sopenharmony_ci .parent_ids = default_parent_ids, 22862306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 22962306a36Sopenharmony_ci .map = { 23062306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 5), 23162306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT1, 3), 23262306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT1, 6), 23362306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 21), 23462306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 22), 23562306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 23), 23662306a36Sopenharmony_ci }, 23762306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 23862306a36Sopenharmony_ci .flags = 0, 23962306a36Sopenharmony_ci }, 24062306a36Sopenharmony_ci { 24162306a36Sopenharmony_ci .name = "perif", 24262306a36Sopenharmony_ci .parent_ids = default_parent_ids, 24362306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 24462306a36Sopenharmony_ci .map = { 24562306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 6), 24662306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT1, 9), 24762306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT1, 12), 24862306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 24), 24962306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 25), 25062306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 26), 25162306a36Sopenharmony_ci }, 25262306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 25362306a36Sopenharmony_ci .flags = CLK_IGNORE_UNUSED, 25462306a36Sopenharmony_ci }, 25562306a36Sopenharmony_ci { 25662306a36Sopenharmony_ci .name = "pcube", 25762306a36Sopenharmony_ci .parent_ids = default_parent_ids, 25862306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 25962306a36Sopenharmony_ci .map = { 26062306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 2), 26162306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT1, 15), 26262306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT1, 18), 26362306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 27), 26462306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 28), 26562306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 29), 26662306a36Sopenharmony_ci }, 26762306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 26862306a36Sopenharmony_ci .flags = 0, 26962306a36Sopenharmony_ci }, 27062306a36Sopenharmony_ci { 27162306a36Sopenharmony_ci .name = "vscope", 27262306a36Sopenharmony_ci .parent_ids = default_parent_ids, 27362306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 27462306a36Sopenharmony_ci .map = { 27562306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 3), 27662306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT1, 21), 27762306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT1, 24), 27862306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 30), 27962306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 31), 28062306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 0), 28162306a36Sopenharmony_ci }, 28262306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 28362306a36Sopenharmony_ci .flags = 0, 28462306a36Sopenharmony_ci }, 28562306a36Sopenharmony_ci { 28662306a36Sopenharmony_ci .name = "nfc_ecc", 28762306a36Sopenharmony_ci .parent_ids = default_parent_ids, 28862306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 28962306a36Sopenharmony_ci .map = { 29062306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 18), 29162306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT1, 27), 29262306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT2, 0), 29362306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 1), 29462306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 2), 29562306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 3), 29662306a36Sopenharmony_ci }, 29762306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 29862306a36Sopenharmony_ci .flags = 0, 29962306a36Sopenharmony_ci }, 30062306a36Sopenharmony_ci { 30162306a36Sopenharmony_ci .name = "vpp", 30262306a36Sopenharmony_ci .parent_ids = default_parent_ids, 30362306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 30462306a36Sopenharmony_ci .map = { 30562306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 21), 30662306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT2, 3), 30762306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT2, 6), 30862306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 4), 30962306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 5), 31062306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 6), 31162306a36Sopenharmony_ci }, 31262306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 31362306a36Sopenharmony_ci .flags = 0, 31462306a36Sopenharmony_ci }, 31562306a36Sopenharmony_ci { 31662306a36Sopenharmony_ci .name = "app", 31762306a36Sopenharmony_ci .parent_ids = default_parent_ids, 31862306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 31962306a36Sopenharmony_ci .map = { 32062306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 20), 32162306a36Sopenharmony_ci BERLIN2_PLL_SELECT(REG_CLKSELECT2, 9), 32262306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT2, 12), 32362306a36Sopenharmony_ci BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 7), 32462306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 8), 32562306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 9), 32662306a36Sopenharmony_ci }, 32762306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 32862306a36Sopenharmony_ci .flags = 0, 32962306a36Sopenharmony_ci }, 33062306a36Sopenharmony_ci { 33162306a36Sopenharmony_ci .name = "audio0", 33262306a36Sopenharmony_ci .parent_ids = (const u8 []){ AUDIO_FAST_PLL }, 33362306a36Sopenharmony_ci .num_parents = 1, 33462306a36Sopenharmony_ci .map = { 33562306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 22), 33662306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT2, 17), 33762306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 10), 33862306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 11), 33962306a36Sopenharmony_ci }, 34062306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE, 34162306a36Sopenharmony_ci .flags = 0, 34262306a36Sopenharmony_ci }, 34362306a36Sopenharmony_ci { 34462306a36Sopenharmony_ci .name = "audio2", 34562306a36Sopenharmony_ci .parent_ids = (const u8 []){ AUDIO_FAST_PLL }, 34662306a36Sopenharmony_ci .num_parents = 1, 34762306a36Sopenharmony_ci .map = { 34862306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 24), 34962306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT2, 20), 35062306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 14), 35162306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 15), 35262306a36Sopenharmony_ci }, 35362306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE, 35462306a36Sopenharmony_ci .flags = 0, 35562306a36Sopenharmony_ci }, 35662306a36Sopenharmony_ci { 35762306a36Sopenharmony_ci .name = "audio3", 35862306a36Sopenharmony_ci .parent_ids = (const u8 []){ AUDIO_FAST_PLL }, 35962306a36Sopenharmony_ci .num_parents = 1, 36062306a36Sopenharmony_ci .map = { 36162306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 25), 36262306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT2, 23), 36362306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 16), 36462306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 17), 36562306a36Sopenharmony_ci }, 36662306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE, 36762306a36Sopenharmony_ci .flags = 0, 36862306a36Sopenharmony_ci }, 36962306a36Sopenharmony_ci { 37062306a36Sopenharmony_ci .name = "audio1", 37162306a36Sopenharmony_ci .parent_ids = (const u8 []){ AUDIO1_PLL }, 37262306a36Sopenharmony_ci .num_parents = 1, 37362306a36Sopenharmony_ci .map = { 37462306a36Sopenharmony_ci BERLIN2_DIV_GATE(REG_CLKENABLE, 23), 37562306a36Sopenharmony_ci BERLIN2_DIV_SELECT(REG_CLKSELECT3, 0), 37662306a36Sopenharmony_ci BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 12), 37762306a36Sopenharmony_ci BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 13), 37862306a36Sopenharmony_ci }, 37962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE, 38062306a36Sopenharmony_ci .flags = 0, 38162306a36Sopenharmony_ci }, 38262306a36Sopenharmony_ci { 38362306a36Sopenharmony_ci .name = "gfx3d_core", 38462306a36Sopenharmony_ci .parent_ids = default_parent_ids, 38562306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 38662306a36Sopenharmony_ci .map = { 38762306a36Sopenharmony_ci BERLIN2_SINGLE_DIV(REG_GFX3DCORE_CLKCTL), 38862306a36Sopenharmony_ci }, 38962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 39062306a36Sopenharmony_ci .flags = 0, 39162306a36Sopenharmony_ci }, 39262306a36Sopenharmony_ci { 39362306a36Sopenharmony_ci .name = "gfx3d_sys", 39462306a36Sopenharmony_ci .parent_ids = default_parent_ids, 39562306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 39662306a36Sopenharmony_ci .map = { 39762306a36Sopenharmony_ci BERLIN2_SINGLE_DIV(REG_GFX3DSYS_CLKCTL), 39862306a36Sopenharmony_ci }, 39962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 40062306a36Sopenharmony_ci .flags = 0, 40162306a36Sopenharmony_ci }, 40262306a36Sopenharmony_ci { 40362306a36Sopenharmony_ci .name = "arc", 40462306a36Sopenharmony_ci .parent_ids = default_parent_ids, 40562306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 40662306a36Sopenharmony_ci .map = { 40762306a36Sopenharmony_ci BERLIN2_SINGLE_DIV(REG_ARC_CLKCTL), 40862306a36Sopenharmony_ci }, 40962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 41062306a36Sopenharmony_ci .flags = 0, 41162306a36Sopenharmony_ci }, 41262306a36Sopenharmony_ci { 41362306a36Sopenharmony_ci .name = "vip", 41462306a36Sopenharmony_ci .parent_ids = default_parent_ids, 41562306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 41662306a36Sopenharmony_ci .map = { 41762306a36Sopenharmony_ci BERLIN2_SINGLE_DIV(REG_VIP_CLKCTL), 41862306a36Sopenharmony_ci }, 41962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 42062306a36Sopenharmony_ci .flags = 0, 42162306a36Sopenharmony_ci }, 42262306a36Sopenharmony_ci { 42362306a36Sopenharmony_ci .name = "sdio0xin", 42462306a36Sopenharmony_ci .parent_ids = default_parent_ids, 42562306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 42662306a36Sopenharmony_ci .map = { 42762306a36Sopenharmony_ci BERLIN2_SINGLE_DIV(REG_SDIO0XIN_CLKCTL), 42862306a36Sopenharmony_ci }, 42962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 43062306a36Sopenharmony_ci .flags = 0, 43162306a36Sopenharmony_ci }, 43262306a36Sopenharmony_ci { 43362306a36Sopenharmony_ci .name = "sdio1xin", 43462306a36Sopenharmony_ci .parent_ids = default_parent_ids, 43562306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 43662306a36Sopenharmony_ci .map = { 43762306a36Sopenharmony_ci BERLIN2_SINGLE_DIV(REG_SDIO1XIN_CLKCTL), 43862306a36Sopenharmony_ci }, 43962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 44062306a36Sopenharmony_ci .flags = 0, 44162306a36Sopenharmony_ci }, 44262306a36Sopenharmony_ci { 44362306a36Sopenharmony_ci .name = "gfx3d_extra", 44462306a36Sopenharmony_ci .parent_ids = default_parent_ids, 44562306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 44662306a36Sopenharmony_ci .map = { 44762306a36Sopenharmony_ci BERLIN2_SINGLE_DIV(REG_GFX3DEXTRA_CLKCTL), 44862306a36Sopenharmony_ci }, 44962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 45062306a36Sopenharmony_ci .flags = 0, 45162306a36Sopenharmony_ci }, 45262306a36Sopenharmony_ci { 45362306a36Sopenharmony_ci .name = "gc360", 45462306a36Sopenharmony_ci .parent_ids = default_parent_ids, 45562306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 45662306a36Sopenharmony_ci .map = { 45762306a36Sopenharmony_ci BERLIN2_SINGLE_DIV(REG_GC360_CLKCTL), 45862306a36Sopenharmony_ci }, 45962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 46062306a36Sopenharmony_ci .flags = 0, 46162306a36Sopenharmony_ci }, 46262306a36Sopenharmony_ci { 46362306a36Sopenharmony_ci .name = "sdio_dllmst", 46462306a36Sopenharmony_ci .parent_ids = default_parent_ids, 46562306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(default_parent_ids), 46662306a36Sopenharmony_ci .map = { 46762306a36Sopenharmony_ci BERLIN2_SINGLE_DIV(REG_SDIO_DLLMST_CLKCTL), 46862306a36Sopenharmony_ci }, 46962306a36Sopenharmony_ci .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 47062306a36Sopenharmony_ci .flags = 0, 47162306a36Sopenharmony_ci }, 47262306a36Sopenharmony_ci}; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_cistatic const struct berlin2_gate_data bg2_gates[] __initconst = { 47562306a36Sopenharmony_ci { "geth0", "perif", 7 }, 47662306a36Sopenharmony_ci { "geth1", "perif", 8 }, 47762306a36Sopenharmony_ci { "sata", "perif", 9 }, 47862306a36Sopenharmony_ci { "ahbapb", "perif", 10, CLK_IGNORE_UNUSED }, 47962306a36Sopenharmony_ci { "usb0", "perif", 11 }, 48062306a36Sopenharmony_ci { "usb1", "perif", 12 }, 48162306a36Sopenharmony_ci { "pbridge", "perif", 13, CLK_IGNORE_UNUSED }, 48262306a36Sopenharmony_ci { "sdio0", "perif", 14 }, 48362306a36Sopenharmony_ci { "sdio1", "perif", 15 }, 48462306a36Sopenharmony_ci { "nfc", "perif", 17 }, 48562306a36Sopenharmony_ci { "smemc", "perif", 19 }, 48662306a36Sopenharmony_ci { "audiohd", "audiohd_pll", 26 }, 48762306a36Sopenharmony_ci { "video0", "video0_in", 27 }, 48862306a36Sopenharmony_ci { "video1", "video1_in", 28 }, 48962306a36Sopenharmony_ci { "video2", "video2_in", 29 }, 49062306a36Sopenharmony_ci}; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_cistatic void __init berlin2_clock_setup(struct device_node *np) 49362306a36Sopenharmony_ci{ 49462306a36Sopenharmony_ci struct device_node *parent_np = of_get_parent(np); 49562306a36Sopenharmony_ci const char *parent_names[9]; 49662306a36Sopenharmony_ci struct clk *clk; 49762306a36Sopenharmony_ci struct clk_hw *hw; 49862306a36Sopenharmony_ci struct clk_hw **hws; 49962306a36Sopenharmony_ci u8 avpll_flags = 0; 50062306a36Sopenharmony_ci int n, ret; 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); 50362306a36Sopenharmony_ci if (!clk_data) { 50462306a36Sopenharmony_ci of_node_put(parent_np); 50562306a36Sopenharmony_ci return; 50662306a36Sopenharmony_ci } 50762306a36Sopenharmony_ci clk_data->num = MAX_CLKS; 50862306a36Sopenharmony_ci hws = clk_data->hws; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci gbase = of_iomap(parent_np, 0); 51162306a36Sopenharmony_ci of_node_put(parent_np); 51262306a36Sopenharmony_ci if (!gbase) 51362306a36Sopenharmony_ci return; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci /* overwrite default clock names with DT provided ones */ 51662306a36Sopenharmony_ci clk = of_clk_get_by_name(np, clk_names[REFCLK]); 51762306a36Sopenharmony_ci if (!IS_ERR(clk)) { 51862306a36Sopenharmony_ci clk_names[REFCLK] = __clk_get_name(clk); 51962306a36Sopenharmony_ci clk_put(clk); 52062306a36Sopenharmony_ci } 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci clk = of_clk_get_by_name(np, clk_names[VIDEO_EXT0]); 52362306a36Sopenharmony_ci if (!IS_ERR(clk)) { 52462306a36Sopenharmony_ci clk_names[VIDEO_EXT0] = __clk_get_name(clk); 52562306a36Sopenharmony_ci clk_put(clk); 52662306a36Sopenharmony_ci } 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci /* simple register PLLs */ 52962306a36Sopenharmony_ci ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0, 53062306a36Sopenharmony_ci clk_names[SYSPLL], clk_names[REFCLK], 0); 53162306a36Sopenharmony_ci if (ret) 53262306a36Sopenharmony_ci goto bg2_fail; 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0, 53562306a36Sopenharmony_ci clk_names[MEMPLL], clk_names[REFCLK], 0); 53662306a36Sopenharmony_ci if (ret) 53762306a36Sopenharmony_ci goto bg2_fail; 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0, 54062306a36Sopenharmony_ci clk_names[CPUPLL], clk_names[REFCLK], 0); 54162306a36Sopenharmony_ci if (ret) 54262306a36Sopenharmony_ci goto bg2_fail; 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci if (of_device_is_compatible(np, "marvell,berlin2-global-register")) 54562306a36Sopenharmony_ci avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK; 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci /* audio/video VCOs */ 54862306a36Sopenharmony_ci ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA", 54962306a36Sopenharmony_ci clk_names[REFCLK], avpll_flags, 0); 55062306a36Sopenharmony_ci if (ret) 55162306a36Sopenharmony_ci goto bg2_fail; 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci for (n = 0; n < 8; n++) { 55462306a36Sopenharmony_ci ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0, 55562306a36Sopenharmony_ci clk_names[AVPLL_A1 + n], n, "avpll_vcoA", 55662306a36Sopenharmony_ci avpll_flags, 0); 55762306a36Sopenharmony_ci if (ret) 55862306a36Sopenharmony_ci goto bg2_fail; 55962306a36Sopenharmony_ci } 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB", 56262306a36Sopenharmony_ci clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK | 56362306a36Sopenharmony_ci avpll_flags, 0); 56462306a36Sopenharmony_ci if (ret) 56562306a36Sopenharmony_ci goto bg2_fail; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci for (n = 0; n < 8; n++) { 56862306a36Sopenharmony_ci ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31, 56962306a36Sopenharmony_ci clk_names[AVPLL_B1 + n], n, "avpll_vcoB", 57062306a36Sopenharmony_ci BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0); 57162306a36Sopenharmony_ci if (ret) 57262306a36Sopenharmony_ci goto bg2_fail; 57362306a36Sopenharmony_ci } 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci /* reference clock bypass switches */ 57662306a36Sopenharmony_ci parent_names[0] = clk_names[SYSPLL]; 57762306a36Sopenharmony_ci parent_names[1] = clk_names[REFCLK]; 57862306a36Sopenharmony_ci hw = clk_hw_register_mux(NULL, "syspll_byp", parent_names, 2, 57962306a36Sopenharmony_ci 0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock); 58062306a36Sopenharmony_ci if (IS_ERR(hw)) 58162306a36Sopenharmony_ci goto bg2_fail; 58262306a36Sopenharmony_ci clk_names[SYSPLL] = clk_hw_get_name(hw); 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci parent_names[0] = clk_names[MEMPLL]; 58562306a36Sopenharmony_ci parent_names[1] = clk_names[REFCLK]; 58662306a36Sopenharmony_ci hw = clk_hw_register_mux(NULL, "mempll_byp", parent_names, 2, 58762306a36Sopenharmony_ci 0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock); 58862306a36Sopenharmony_ci if (IS_ERR(hw)) 58962306a36Sopenharmony_ci goto bg2_fail; 59062306a36Sopenharmony_ci clk_names[MEMPLL] = clk_hw_get_name(hw); 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci parent_names[0] = clk_names[CPUPLL]; 59362306a36Sopenharmony_ci parent_names[1] = clk_names[REFCLK]; 59462306a36Sopenharmony_ci hw = clk_hw_register_mux(NULL, "cpupll_byp", parent_names, 2, 59562306a36Sopenharmony_ci 0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock); 59662306a36Sopenharmony_ci if (IS_ERR(hw)) 59762306a36Sopenharmony_ci goto bg2_fail; 59862306a36Sopenharmony_ci clk_names[CPUPLL] = clk_hw_get_name(hw); 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci /* clock muxes */ 60162306a36Sopenharmony_ci parent_names[0] = clk_names[AVPLL_B3]; 60262306a36Sopenharmony_ci parent_names[1] = clk_names[AVPLL_A3]; 60362306a36Sopenharmony_ci hw = clk_hw_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2, 60462306a36Sopenharmony_ci 0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock); 60562306a36Sopenharmony_ci if (IS_ERR(hw)) 60662306a36Sopenharmony_ci goto bg2_fail; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci parent_names[0] = clk_names[VIDEO0_PLL]; 60962306a36Sopenharmony_ci parent_names[1] = clk_names[VIDEO_EXT0]; 61062306a36Sopenharmony_ci hw = clk_hw_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2, 61162306a36Sopenharmony_ci 0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock); 61262306a36Sopenharmony_ci if (IS_ERR(hw)) 61362306a36Sopenharmony_ci goto bg2_fail; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci parent_names[0] = clk_names[VIDEO1_PLL]; 61662306a36Sopenharmony_ci parent_names[1] = clk_names[VIDEO_EXT0]; 61762306a36Sopenharmony_ci hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2, 61862306a36Sopenharmony_ci 0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock); 61962306a36Sopenharmony_ci if (IS_ERR(hw)) 62062306a36Sopenharmony_ci goto bg2_fail; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci parent_names[0] = clk_names[AVPLL_A2]; 62362306a36Sopenharmony_ci parent_names[1] = clk_names[AVPLL_B2]; 62462306a36Sopenharmony_ci hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2, 62562306a36Sopenharmony_ci 0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock); 62662306a36Sopenharmony_ci if (IS_ERR(hw)) 62762306a36Sopenharmony_ci goto bg2_fail; 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci parent_names[0] = clk_names[VIDEO2_PLL]; 63062306a36Sopenharmony_ci parent_names[1] = clk_names[VIDEO_EXT0]; 63162306a36Sopenharmony_ci hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2, 63262306a36Sopenharmony_ci 0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock); 63362306a36Sopenharmony_ci if (IS_ERR(hw)) 63462306a36Sopenharmony_ci goto bg2_fail; 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ci parent_names[0] = clk_names[AVPLL_B1]; 63762306a36Sopenharmony_ci parent_names[1] = clk_names[AVPLL_A5]; 63862306a36Sopenharmony_ci hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2, 63962306a36Sopenharmony_ci 0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock); 64062306a36Sopenharmony_ci if (IS_ERR(hw)) 64162306a36Sopenharmony_ci goto bg2_fail; 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci /* clock divider cells */ 64462306a36Sopenharmony_ci for (n = 0; n < ARRAY_SIZE(bg2_divs); n++) { 64562306a36Sopenharmony_ci const struct berlin2_div_data *dd = &bg2_divs[n]; 64662306a36Sopenharmony_ci int k; 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci for (k = 0; k < dd->num_parents; k++) 64962306a36Sopenharmony_ci parent_names[k] = clk_names[dd->parent_ids[k]]; 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci hws[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase, 65262306a36Sopenharmony_ci dd->name, dd->div_flags, parent_names, 65362306a36Sopenharmony_ci dd->num_parents, dd->flags, &lock); 65462306a36Sopenharmony_ci } 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci /* clock gate cells */ 65762306a36Sopenharmony_ci for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) { 65862306a36Sopenharmony_ci const struct berlin2_gate_data *gd = &bg2_gates[n]; 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci hws[CLKID_GETH0 + n] = clk_hw_register_gate(NULL, gd->name, 66162306a36Sopenharmony_ci gd->parent_name, gd->flags, gbase + REG_CLKENABLE, 66262306a36Sopenharmony_ci gd->bit_idx, 0, &lock); 66362306a36Sopenharmony_ci } 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci /* twdclk is derived from cpu/3 */ 66662306a36Sopenharmony_ci hws[CLKID_TWD] = 66762306a36Sopenharmony_ci clk_hw_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3); 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci /* check for errors on leaf clocks */ 67062306a36Sopenharmony_ci for (n = 0; n < MAX_CLKS; n++) { 67162306a36Sopenharmony_ci if (!IS_ERR(hws[n])) 67262306a36Sopenharmony_ci continue; 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci pr_err("%pOF: Unable to register leaf clock %d\n", np, n); 67562306a36Sopenharmony_ci goto bg2_fail; 67662306a36Sopenharmony_ci } 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci /* register clk-provider */ 67962306a36Sopenharmony_ci of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci return; 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_cibg2_fail: 68462306a36Sopenharmony_ci iounmap(gbase); 68562306a36Sopenharmony_ci} 68662306a36Sopenharmony_ciCLK_OF_DECLARE(berlin2_clk, "marvell,berlin2-clk", 68762306a36Sopenharmony_ci berlin2_clock_setup); 688