/*
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Common Clock Framework support for Exynos3250 SoC.
*/
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>
#include <dt-bindings/clock/exynos3250.h>
#include "clk.h"
#include "clk-cpu.h"
#include "clk-pll.h"
#define SRC_LEFTBUS 0x4200
#define DIV_LEFTBUS 0x4500
#define GATE_IP_LEFTBUS 0x4800
#define SRC_RIGHTBUS 0x8200
#define DIV_RIGHTBUS 0x8500
#define GATE_IP_RIGHTBUS 0x8800
#define GATE_IP_PERIR 0x8960
#define MPLL_LOCK 0xc010
#define MPLL_CON0 0xc110
#define VPLL_LOCK 0xc020
#define VPLL_CON0 0xc120
#define UPLL_LOCK 0xc030
#define UPLL_CON0 0xc130
#define SRC_TOP0 0xc210
#define SRC_TOP1 0xc214
#define SRC_CAM 0xc220
#define SRC_MFC 0xc228
#define SRC_G3D 0xc22c
#define SRC_LCD 0xc234
#define SRC_ISP 0xc238
#define SRC_FSYS 0xc240
#define SRC_PERIL0 0xc250
#define SRC_PERIL1 0xc254
#define SRC_MASK_TOP 0xc310
#define SRC_MASK_CAM 0xc320
#define SRC_MASK_LCD 0xc334
#define SRC_MASK_ISP 0xc338
#define SRC_MASK_FSYS 0xc340
#define SRC_MASK_PERIL0 0xc350
#define SRC_MASK_PERIL1 0xc354
#define DIV_TOP 0xc510
#define DIV_CAM 0xc520
#define DIV_MFC 0xc528
#define DIV_G3D 0xc52c
#define DIV_LCD 0xc534
#define DIV_ISP 0xc538
#define DIV_FSYS0 0xc540
#define DIV_FSYS1 0xc544
#define DIV_FSYS2 0xc548
#define DIV_PERIL0 0xc550
#define DIV_PERIL1 0xc554
#define DIV_PERIL3 0xc55c
#define DIV_PERIL4 0xc560
#define DIV_PERIL5 0xc564
#define DIV_CAM1 0xc568
#define CLKDIV2_RATIO 0xc580
#define GATE_SCLK_CAM 0xc820
#define GATE_SCLK_MFC 0xc828
#define GATE_SCLK_G3D 0xc82c
#define GATE_SCLK_LCD 0xc834
#define GATE_SCLK_ISP_TOP 0xc838
#define GATE_SCLK_FSYS 0xc840
#define GATE_SCLK_PERIL 0xc850
#define GATE_IP_CAM 0xc920
#define GATE_IP_MFC 0xc928
#define GATE_IP_G3D 0xc92c
#define GATE_IP_LCD 0xc934
#define GATE_IP_ISP 0xc938
#define GATE_IP_FSYS 0xc940
#define GATE_IP_PERIL 0xc950
#define GATE_BLOCK 0xc970
#define APLL_LOCK 0x14000
#define APLL_CON0 0x14100
#define SRC_CPU 0x14200
#define DIV_CPU0 0x14500
#define DIV_CPU1 0x14504
#define PWR_CTRL1 0x15020
#define PWR_CTRL2 0x15024
/* Below definitions are used for PWR_CTRL settings */
#define PWR_CTRL1_CORE2_DOWN_RATIO(x) (((x) & 0x7) << 28)
#define PWR_CTRL1_CORE1_DOWN_RATIO(x) (((x) & 0x7) << 16)
#define PWR_CTRL1_DIV2_DOWN_EN (1 << 9)
#define PWR_CTRL1_DIV1_DOWN_EN (1 << 8)
#define PWR_CTRL1_USE_CORE3_WFE (1 << 7)
#define PWR_CTRL1_USE_CORE2_WFE (1 << 6)
#define PWR_CTRL1_USE_CORE1_WFE (1 << 5)
#define PWR_CTRL1_USE_CORE0_WFE (1 << 4)
#define PWR_CTRL1_USE_CORE3_WFI (1 << 3)
#define PWR_CTRL1_USE_CORE2_WFI (1 << 2)
#define PWR_CTRL1_USE_CORE1_WFI (1 << 1)
#define PWR_CTRL1_USE_CORE0_WFI (1 << 0)
static const unsigned long exynos3250_cmu_clk_regs[] __initconst = {
SRC_LEFTBUS,
DIV_LEFTBUS,
GATE_IP_LEFTBUS,
SRC_RIGHTBUS,
DIV_RIGHTBUS,
GATE_IP_RIGHTBUS,
GATE_IP_PERIR,
MPLL_LOCK,
MPLL_CON0,
VPLL_LOCK,
VPLL_CON0,
UPLL_LOCK,
UPLL_CON0,
SRC_TOP0,
SRC_TOP1,
SRC_CAM,
SRC_MFC,
SRC_G3D,
SRC_LCD,
SRC_ISP,
SRC_FSYS,
SRC_PERIL0,
SRC_PERIL1,
SRC_MASK_TOP,
SRC_MASK_CAM,
SRC_MASK_LCD,
SRC_MASK_ISP,
SRC_MASK_FSYS,
SRC_MASK_PERIL0,
SRC_MASK_PERIL1,
DIV_TOP,
DIV_CAM,
DIV_MFC,
DIV_G3D,
DIV_LCD,
DIV_ISP,
DIV_FSYS0,
DIV_FSYS1,
DIV_FSYS2,
DIV_PERIL0,
DIV_PERIL1,
DIV_PERIL3,
DIV_PERIL4,
DIV_PERIL5,
DIV_CAM1,
CLKDIV2_RATIO,
GATE_SCLK_CAM,
GATE_SCLK_MFC,
GATE_SCLK_G3D,
GATE_SCLK_LCD,
GATE_SCLK_ISP_TOP,
GATE_SCLK_FSYS,
GATE_SCLK_PERIL,
GATE_IP_CAM,
GATE_IP_MFC,
GATE_IP_G3D,
GATE_IP_LCD,
GATE_IP_ISP,
GATE_IP_FSYS,
GATE_IP_PERIL,
GATE_BLOCK,
APLL_LOCK,
SRC_CPU,
DIV_CPU0,
DIV_CPU1,
PWR_CTRL1,
PWR_CTRL2,
};
/* list of all parent clock list */
PNAME(mout_vpllsrc_p) = { "fin_pll", };
PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", };
PNAME(mout_upll_p) = { "fin_pll", "fout_upll", };
PNAME(mout_mpll_user_p) = { "fin_pll", "div_mpll_pre", };
PNAME(mout_epll_user_p) = { "fin_pll", "mout_epll", };
PNAME(mout_core_p) = { "mout_apll", "mout_mpll_user_c", };
PNAME(mout_hpm_p) = { "mout_apll", "mout_mpll_user_c", };
PNAME(mout_ebi_p) = { "div_aclk_200", "div_aclk_160", };
PNAME(mout_ebi_1_p) = { "mout_ebi", "mout_vpll", };
PNAME(mout_gdl_p) = { "mout_mpll_user_l", };
PNAME(mout_gdr_p) = { "mout_mpll_user_r", };
PNAME(mout_aclk_400_mcuisp_sub_p)
= { "fin_pll", "div_aclk_400_mcuisp", };
PNAME(mout_aclk_266_0_p) = { "div_mpll_pre", "mout_vpll", };
PNAME(mout_aclk_266_1_p) = { "mout_epll_user", };
PNAME(mout_aclk_266_p) = { "mout_aclk_266_0"