linux/drivers/clk/samsung/clk-exynos4.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
 * Copyright (c) 2013 Linaro Ltd.
 * Author: Thomas Abraham <[email protected]>
 *
 * Common Clock Framework support for all Exynos4 SoCs.
*/

#include <dt-bindings/clock/exynos4.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>

#include "clk.h"
#include "clk-cpu.h"

/* Exynos4 clock controller register offsets */
#define SRC_LEFTBUS
#define DIV_LEFTBUS
#define GATE_IP_LEFTBUS
#define E4X12_GATE_IP_IMAGE
#define CLKOUT_CMU_LEFTBUS
#define SRC_RIGHTBUS
#define DIV_RIGHTBUS
#define GATE_IP_RIGHTBUS
#define E4X12_GATE_IP_PERIR
#define CLKOUT_CMU_RIGHTBUS
#define EPLL_LOCK
#define VPLL_LOCK
#define EPLL_CON0
#define EPLL_CON1
#define EPLL_CON2
#define VPLL_CON0
#define VPLL_CON1
#define VPLL_CON2
#define SRC_TOP0
#define SRC_TOP1
#define SRC_CAM
#define SRC_TV
#define SRC_MFC
#define SRC_G3D
#define E4210_SRC_IMAGE
#define SRC_LCD0
#define E4210_SRC_LCD1
#define E4X12_SRC_ISP
#define SRC_MAUDIO
#define SRC_FSYS
#define SRC_PERIL0
#define SRC_PERIL1
#define E4X12_SRC_CAM1
#define SRC_MASK_TOP
#define SRC_MASK_CAM
#define SRC_MASK_TV
#define SRC_MASK_LCD0
#define E4210_SRC_MASK_LCD1
#define E4X12_SRC_MASK_ISP
#define SRC_MASK_MAUDIO
#define SRC_MASK_FSYS
#define SRC_MASK_PERIL0
#define SRC_MASK_PERIL1
#define DIV_TOP
#define DIV_CAM
#define DIV_TV
#define DIV_MFC
#define DIV_G3D
#define DIV_IMAGE
#define DIV_LCD0
#define E4210_DIV_LCD1
#define E4X12_DIV_ISP
#define DIV_MAUDIO
#define DIV_FSYS0
#define DIV_FSYS1
#define DIV_FSYS2
#define DIV_FSYS3
#define DIV_PERIL0
#define DIV_PERIL1
#define DIV_PERIL2
#define DIV_PERIL3
#define DIV_PERIL4
#define DIV_PERIL5
#define E4X12_DIV_CAM1
#define E4X12_GATE_BUS_FSYS1
#define GATE_SCLK_CAM
#define GATE_IP_CAM
#define GATE_IP_TV
#define GATE_IP_MFC
#define GATE_IP_G3D
#define E4210_GATE_IP_IMAGE
#define GATE_IP_LCD0
#define E4210_GATE_IP_LCD1
#define E4X12_GATE_IP_ISP
#define E4X12_GATE_IP_MAUDIO
#define GATE_IP_FSYS
#define GATE_IP_GPS
#define GATE_IP_PERIL
#define E4210_GATE_IP_PERIR
#define GATE_BLOCK
#define CLKOUT_CMU_TOP
#define E4X12_MPLL_LOCK
#define E4X12_MPLL_CON0
#define SRC_DMC
#define SRC_MASK_DMC
#define DIV_DMC0
#define DIV_DMC1
#define GATE_IP_DMC
#define CLKOUT_CMU_DMC
#define APLL_LOCK
#define E4210_MPLL_LOCK
#define APLL_CON0
#define E4210_MPLL_CON0
#define SRC_CPU
#define DIV_CPU0
#define DIV_CPU1
#define GATE_SCLK_CPU
#define GATE_IP_CPU
#define CLKOUT_CMU_CPU
#define PWR_CTRL1
#define E4X12_PWR_CTRL2

/* Below definitions are used for PWR_CTRL settings */
#define PWR_CTRL1_CORE2_DOWN_RATIO(x)
#define PWR_CTRL1_CORE1_DOWN_RATIO(x)
#define PWR_CTRL1_DIV2_DOWN_EN
#define PWR_CTRL1_DIV1_DOWN_EN
#define PWR_CTRL1_USE_CORE3_WFE
#define PWR_CTRL1_USE_CORE2_WFE
#define PWR_CTRL1_USE_CORE1_WFE
#define PWR_CTRL1_USE_CORE0_WFE
#define PWR_CTRL1_USE_CORE3_WFI
#define PWR_CTRL1_USE_CORE2_WFI
#define PWR_CTRL1_USE_CORE1_WFI
#define PWR_CTRL1_USE_CORE0_WFI

/* NOTE: Must be equal to the last clock ID increased by one */
#define CLKS_NR

/* the exynos4 soc type */
enum exynos4_soc {};

/* list of PLLs to be registered */
enum exynos4_plls {};

static void __iomem *reg_base;
static enum exynos4_soc exynos4_soc;

/*
 * list of controller registers to be saved and restored during a
 * suspend/resume cycle.
 */
static const unsigned long exynos4210_clk_save[] __initconst =;

static const unsigned long exynos4x12_clk_save[] __initconst =;

static const unsigned long exynos4_clk_regs[] __initconst =;

static const struct samsung_clk_reg_dump src_mask_suspend[] =;

static const struct samsung_clk_reg_dump src_mask_suspend_e4210[] =;

/* list of all parent clock list */
PNAME(mout_apll_p)	=;
PNAME(mout_mpll_p)	=;
PNAME(mout_epll_p)	=;
PNAME(mout_vpllsrc_p)	=;
PNAME(mout_vpll_p)	=;
PNAME(sclk_evpll_p)	=;
PNAME(mout_mfc_p)	=;
PNAME(mout_g3d_p)	=;
PNAME(mout_g2d_p)	=;
PNAME(mout_hdmi_p)	=;
PNAME(mout_jpeg_p)	=;
PNAME(mout_spdif_p)	=;
PNAME(mout_onenand_p)  =;
PNAME(mout_onenand1_p) =;

/* Exynos 4210-specific parent groups */
PNAME(sclk_vpll_p4210)	=;
PNAME(mout_core_p4210)	=;
PNAME(sclk_ampll_p4210)	=;
PNAME(group1_p4210)	=;
PNAME(mout_audio0_p4210) =;
PNAME(mout_audio1_p4210) =;
PNAME(mout_audio2_p4210) =;
PNAME(mout_mixer_p4210)	=;
PNAME(mout_dac_p4210)	=;
PNAME(mout_pwi_p4210) =;
PNAME(clkout_left_p4210) =;
PNAME(clkout_right_p4210) =;
PNAME(clkout_top_p4210) =;
PNAME(clkout_dmc_p4210) =;
PNAME(clkout_cpu_p4210) =;

/* Exynos 4x12-specific parent groups */
PNAME(mout_mpll_user_p4x12) =;
PNAME(mout_core_p4x12)	=;
PNAME(mout_gdl_p4x12)	=;
PNAME(mout_gdr_p4x12)	=;
PNAME(sclk_ampll_p4x12)	=;
PNAME(group1_p4x12)	=;
PNAME(mout_audio0_p4x12) =;
PNAME(mout_audio1_p4x12) =;
PNAME(mout_audio2_p4x12) =;
PNAME(aclk_p4412)	=;
PNAME(mout_user_aclk400_mcuisp_p4x12) =;
PNAME(mout_user_aclk200_p4x12) =;
PNAME(mout_user_aclk266_gps_p4x12) =;
PNAME(mout_pwi_p4x12) =;
PNAME(clkout_left_p4x12) =;
PNAME(clkout_right_p4x12) =;
PNAME(clkout_top_p4x12) =;
PNAME(clkout_dmc_p4x12) =;
PNAME(clkout_cpu_p4x12) =;

/* fixed rate clocks generated outside the soc */
static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata =;

/* fixed rate clocks generated inside the soc */
static const struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initconst =;

static const struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initconst =;

static const struct samsung_fixed_factor_clock exynos4_fixed_factor_clks[] __initconst =;

static const struct samsung_fixed_factor_clock exynos4210_fixed_factor_clks[] __initconst =;

static const struct samsung_fixed_factor_clock exynos4x12_fixed_factor_clks[] __initconst =;

/* list of mux clocks supported in all exynos4 soc's */
static const struct samsung_mux_clock exynos4_mux_clks[] __initconst =;

/* list of mux clocks supported in exynos4210 soc */
static const struct samsung_mux_clock exynos4210_mux_early[] __initconst =;

static const struct samsung_mux_clock exynos4210_mux_clks[] __initconst =;

/* list of mux clocks supported in exynos4x12 soc */
static const struct samsung_mux_clock exynos4x12_mux_clks[] __initconst =;

/* list of divider clocks supported in all exynos4 soc's */
static const struct samsung_div_clock exynos4_div_clks[] __initconst =;

/* list of divider clocks supported in exynos4210 soc */
static const struct samsung_div_clock exynos4210_div_clks[] __initconst =;

/* list of divider clocks supported in exynos4x12 soc */
static const struct samsung_div_clock exynos4x12_div_clks[] __initconst =;

/* list of gate clocks supported in all exynos4 soc's */
static const struct samsung_gate_clock exynos4_gate_clks[] __initconst =;

/* list of gate clocks supported in exynos4210 soc */
static const struct samsung_gate_clock exynos4210_gate_clks[] __initconst =;

/* list of gate clocks supported in exynos4x12 soc */
static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst =;

/*
 * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit
 * resides in chipid register space, outside of the clock controller memory
 * mapped space. So to determine the parent of fin_pll clock, the chipid
 * controller is first remapped and the value of XOM[0] bit is read to
 * determine the parent clock.
 */
static unsigned long __init exynos4_get_xom(void)
{}

static void __init exynos4_clk_register_finpll(struct samsung_clk_provider *ctx)
{}

static const struct of_device_id ext_clk_match[] __initconst =;

/* PLLs PMS values */
static const struct samsung_pll_rate_table exynos4210_apll_rates[] __initconst =;

static const struct samsung_pll_rate_table exynos4210_epll_rates[] __initconst =;

static const struct samsung_pll_rate_table exynos4210_vpll_rates[] __initconst =;

static const struct samsung_pll_rate_table exynos4x12_apll_rates[] __initconst =;

static const struct samsung_pll_rate_table exynos4x12_epll_rates[] __initconst =;

static const struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initconst =;

static struct samsung_pll_clock exynos4210_plls[nr_plls] __initdata =;

static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata =;

static void __init exynos4x12_core_down_clock(void)
{}

#define E4210_CPU_DIV0(apll, pclk_dbg, atb, periph, corem1, corem0)
#define E4210_CPU_DIV1(hpm, copy)

static const struct exynos_cpuclk_cfg_data e4210_armclk_d[] __initconst =;

static const struct exynos_cpuclk_cfg_data e4212_armclk_d[] __initconst =;

#define E4412_CPU_DIV1(cores, hpm, copy)

static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst =;

static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst =;

static const struct samsung_cpu_clock exynos4212_cpu_clks[] __initconst =;

static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst =;

/* register exynos4 clocks */
static void __init exynos4_clk_init(struct device_node *np,
				    enum exynos4_soc soc)
{}


static void __init exynos4210_clk_init(struct device_node *np)
{}
CLK_OF_DECLARE(exynos4210_clk, "samsung,exynos4210-clock", exynos4210_clk_init);

static void __init exynos4212_clk_init(struct device_node *np)
{}
CLK_OF_DECLARE(exynos4212_clk, "samsung,exynos4212-clock", exynos4212_clk_init);

static void __init exynos4412_clk_init(struct device_node *np)
{}
CLK_OF_DECLARE(exynos4412_clk, "samsung,exynos4412-clock", exynos4412_clk_init);