--- /dev/null
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Clock support
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/pm.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/sysmmu.h>
+
+#include "common.h"
+#include "clock-exynos4.h"
+
+#ifdef CONFIG_PM_SLEEP
+static struct sleep_save exynos4_clock_save[] = {
+ SAVE_ITEM(EXYNOS4_CLKDIV_LEFTBUS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_LEFTBUS),
+ SAVE_ITEM(EXYNOS4_CLKDIV_RIGHTBUS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_RIGHTBUS),
+ SAVE_ITEM(EXYNOS4_CLKSRC_TOP0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_TOP1),
+ SAVE_ITEM(EXYNOS4_CLKSRC_CAM),
+ SAVE_ITEM(EXYNOS4_CLKSRC_TV),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MFC),
+ SAVE_ITEM(EXYNOS4_CLKSRC_G3D),
+ SAVE_ITEM(EXYNOS4_CLKSRC_LCD0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MAUDIO),
+ SAVE_ITEM(EXYNOS4_CLKSRC_FSYS),
+ SAVE_ITEM(EXYNOS4_CLKSRC_PERIL0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_PERIL1),
+ SAVE_ITEM(EXYNOS4_CLKDIV_CAM),
+ SAVE_ITEM(EXYNOS4_CLKDIV_TV),
+ SAVE_ITEM(EXYNOS4_CLKDIV_MFC),
+ SAVE_ITEM(EXYNOS4_CLKDIV_G3D),
+ SAVE_ITEM(EXYNOS4_CLKDIV_LCD0),
+ SAVE_ITEM(EXYNOS4_CLKDIV_MAUDIO),
+ SAVE_ITEM(EXYNOS4_CLKDIV_FSYS0),
+ SAVE_ITEM(EXYNOS4_CLKDIV_FSYS1),
+ SAVE_ITEM(EXYNOS4_CLKDIV_FSYS2),
+ SAVE_ITEM(EXYNOS4_CLKDIV_FSYS3),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL0),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL1),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL2),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL3),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL4),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL5),
+ SAVE_ITEM(EXYNOS4_CLKDIV_TOP),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TOP),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_CAM),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TV),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_MAUDIO),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_FSYS),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL1),
+ SAVE_ITEM(EXYNOS4_CLKDIV2_RATIO),
+ SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCAM),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_CAM),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_TV),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_MFC),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_G3D),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_LCD0),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_FSYS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_GPS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIL),
+ SAVE_ITEM(EXYNOS4_CLKGATE_BLOCK),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_DMC),
+ SAVE_ITEM(EXYNOS4_CLKSRC_DMC),
+ SAVE_ITEM(EXYNOS4_CLKDIV_DMC0),
+ SAVE_ITEM(EXYNOS4_CLKDIV_DMC1),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_DMC),
+ SAVE_ITEM(EXYNOS4_CLKSRC_CPU),
+ SAVE_ITEM(EXYNOS4_CLKDIV_CPU),
+ SAVE_ITEM(EXYNOS4_CLKDIV_CPU + 0x4),
+ SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCPU),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_CPU),
+};
+#endif
+
+static struct clk exynos4_clk_sclk_hdmi27m = {
+ .name = "sclk_hdmi27m",
+ .rate = 27000000,
+};
+
+static struct clk exynos4_clk_sclk_hdmiphy = {
+ .name = "sclk_hdmiphy",
+};
+
+static struct clk exynos4_clk_sclk_usbphy0 = {
+ .name = "sclk_usbphy0",
+ .rate = 27000000,
+};
+
+static struct clk exynos4_clk_sclk_usbphy1 = {
+ .name = "sclk_usbphy1",
+};
+
+static struct clk dummy_apb_pclk = {
+ .name = "apb_pclk",
+ .id = -1,
+};
+
+static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TOP, clk, enable);
+}
+
+static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_CAM, clk, enable);
+}
+
+static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_LCD0, clk, enable);
+}
+
+int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_FSYS, clk, enable);
+}
+
+static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL0, clk, enable);
+}
+
+static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL1, clk, enable);
+}
+
+static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_MFC, clk, enable);
+}
+
+static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TV, clk, enable);
+}
+
+static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_CAM, clk, enable);
+}
+
+static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable);
+}
+
+static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable);
+}
+
+static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LCD0, clk, enable);
+}
+
+int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4210_CLKGATE_IP_LCD1, clk, enable);
+}
+
+int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_FSYS, clk, enable);
+}
+
+static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIL, clk, enable);
+}
+
+static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable);
+}
+
+static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
+}
+
+static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
+}
+
+/* Core list of CMU_CPU side */
+
+static struct clksrc_clk exynos4_clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_apll = {
+ .clk = {
+ .name = "sclk_apll",
+ .parent = &exynos4_clk_mout_apll.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 24, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 4, .size = 1 },
+};
+
+struct clksrc_clk exynos4_clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ },
+ .sources = &clk_src_mpll,
+
+ /* reg_src will be added in each SoCs' clock */
+};
+
+static struct clk *exynos4_clkset_moutcore_list[] = {
+ [0] = &exynos4_clk_mout_apll.clk,
+ [1] = &exynos4_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_moutcore = {
+ .sources = exynos4_clkset_moutcore_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_moutcore_list),
+};
+
+static struct clksrc_clk exynos4_clk_moutcore = {
+ .clk = {
+ .name = "moutcore",
+ },
+ .sources = &exynos4_clkset_moutcore,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_coreclk = {
+ .clk = {
+ .name = "core_clk",
+ .parent = &exynos4_clk_moutcore.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_armclk = {
+ .clk = {
+ .name = "armclk",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_corem0 = {
+ .clk = {
+ .name = "aclk_corem0",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_cores = {
+ .clk = {
+ .name = "aclk_cores",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_corem1 = {
+ .clk = {
+ .name = "aclk_corem1",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_periphclk = {
+ .clk = {
+ .name = "periphclk",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 12, .size = 3 },
+};
+
+/* Core list of CMU_CORE side */
+
+static struct clk *exynos4_clkset_corebus_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+struct clksrc_sources exynos4_clkset_mout_corebus = {
+ .sources = exynos4_clkset_corebus_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_corebus_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_corebus = {
+ .clk = {
+ .name = "mout_corebus",
+ },
+ .sources = &exynos4_clkset_mout_corebus,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_dmc = {
+ .clk = {
+ .name = "sclk_dmc",
+ .parent = &exynos4_clk_mout_corebus.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_cored = {
+ .clk = {
+ .name = "aclk_cored",
+ .parent = &exynos4_clk_sclk_dmc.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_corep = {
+ .clk = {
+ .name = "aclk_corep",
+ .parent = &exynos4_clk_aclk_cored.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 20, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_acp = {
+ .clk = {
+ .name = "aclk_acp",
+ .parent = &exynos4_clk_mout_corebus.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_pclk_acp = {
+ .clk = {
+ .name = "pclk_acp",
+ .parent = &exynos4_clk_aclk_acp.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 4, .size = 3 },
+};
+
+/* Core list of CMU_TOP side */
+
+struct clk *exynos4_clkset_aclk_top_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_aclk = {
+ .sources = exynos4_clkset_aclk_top_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_aclk_top_list),
+};
+
+static struct clksrc_clk exynos4_clk_aclk_200 = {
+ .clk = {
+ .name = "aclk_200",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 12, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_100 = {
+ .clk = {
+ .name = "aclk_100",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 16, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_160 = {
+ .clk = {
+ .name = "aclk_160",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 20, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 8, .size = 3 },
+};
+
+struct clksrc_clk exynos4_clk_aclk_133 = {
+ .clk = {
+ .name = "aclk_133",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 24, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 12, .size = 3 },
+};
+
+static struct clk *exynos4_clkset_vpllsrc_list[] = {
+ [0] = &clk_fin_vpll,
+ [1] = &exynos4_clk_sclk_hdmi27m,
+};
+
+static struct clksrc_sources exynos4_clkset_vpllsrc = {
+ .sources = exynos4_clkset_vpllsrc_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_vpllsrc_list),
+};
+
+static struct clksrc_clk exynos4_clk_vpllsrc = {
+ .clk = {
+ .name = "vpll_src",
+ .enable = exynos4_clksrc_mask_top_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_vpllsrc,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_sclk_vpll_list[] = {
+ [0] = &exynos4_clk_vpllsrc.clk,
+ [1] = &clk_fout_vpll,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_vpll = {
+ .sources = exynos4_clkset_sclk_vpll_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_vpll = {
+ .clk = {
+ .name = "sclk_vpll",
+ },
+ .sources = &exynos4_clkset_sclk_vpll,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 },
+};
+
+static struct clk exynos4_init_clocks_off[] = {
+ {
+ .name = "timers",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1<<24),
+ }, {
+ .name = "csis",
+ .devname = "s5p-mipi-csis.0",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "csis",
+ .devname = "s5p-mipi-csis.1",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 5),
++ }, {
++ .name = "jpeg",
++ .id = 0,
++ .enable = exynos4_clk_ip_cam_ctrl,
++ .ctrlbit = (1 << 6),
+ }, {
+ .name = "fimc",
+ .devname = "exynos4-fimc.0",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "fimc",
+ .devname = "exynos4-fimc.1",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "fimc",
+ .devname = "exynos4-fimc.2",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "fimc",
+ .devname = "exynos4-fimc.3",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.0",
+ .parent = &exynos4_clk_aclk_133.clk,
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.1",
+ .parent = &exynos4_clk_aclk_133.clk,
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.2",
+ .parent = &exynos4_clk_aclk_133.clk,
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.3",
+ .parent = &exynos4_clk_aclk_133.clk,
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "dwmmc",
+ .parent = &exynos4_clk_aclk_133.clk,
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "dac",
+ .devname = "s5p-sdo",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "mixer",
+ .devname = "s5p-mixer",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "vp",
+ .devname = "s5p-mixer",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "hdmi",
+ .devname = "exynos4-hdmi",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "hdmiphy",
+ .devname = "exynos4-hdmi",
+ .enable = exynos4_clk_hdmiphy_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "dacphy",
+ .devname = "s5p-sdo",
+ .enable = exynos4_clk_dac_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "adc",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "keypad",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "rtc",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "watchdog",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "usbhost",
+ .enable = exynos4_clk_ip_fsys_ctrl ,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "otg",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "spi",
+ .devname = "s3c64xx-spi.0",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "spi",
+ .devname = "s3c64xx-spi.1",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "spi",
+ .devname = "s3c64xx-spi.2",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "iis",
+ .devname = "samsung-i2s.0",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "iis",
+ .devname = "samsung-i2s.1",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 20),
+ }, {
+ .name = "iis",
+ .devname = "samsung-i2s.2",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "ac97",
+ .devname = "samsung-ac97",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
+ .name = "fimg2d",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "mfc",
+ .devname = "s5p-mfc",
+ .enable = exynos4_clk_ip_mfc_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.0",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.1",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.2",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.3",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.4",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.5",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.6",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.7",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-hdmiphy-i2c",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "SYSMMU_MDMA",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "SYSMMU_FIMC0",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "SYSMMU_FIMC1",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "SYSMMU_FIMC2",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "SYSMMU_FIMC3",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "SYSMMU_JPEG",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "SYSMMU_FIMD0",
+ .enable = exynos4_clk_ip_lcd0_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "SYSMMU_FIMD1",
+ .enable = exynos4_clk_ip_lcd1_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "SYSMMU_PCIe",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "SYSMMU_G2D",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "SYSMMU_ROTATOR",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "SYSMMU_TV",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "SYSMMU_MFC_L",
+ .enable = exynos4_clk_ip_mfc_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "SYSMMU_MFC_R",
+ .enable = exynos4_clk_ip_mfc_ctrl,
+ .ctrlbit = (1 << 2),
+ }
+};
+
+static struct clk exynos4_init_clocks_on[] = {
+ {
+ .name = "uart",
+ .devname = "s5pv210-uart.0",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.1",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.2",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.3",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.4",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.5",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 5),
+ }
+};
+
+static struct clk exynos4_clk_pdma0 = {
+ .name = "dma",
+ .devname = "dma-pl330.0",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 0),
+};
+
+static struct clk exynos4_clk_pdma1 = {
+ .name = "dma",
+ .devname = "dma-pl330.1",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 1),
+};
+
+static struct clk exynos4_clk_mdma1 = {
+ .name = "dma",
+ .devname = "dma-pl330.2",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = ((1 << 8) | (1 << 5) | (1 << 2)),
+};
+
+static struct clk exynos4_clk_fimd0 = {
+ .name = "fimd",
+ .devname = "exynos4-fb.0",
+ .enable = exynos4_clk_ip_lcd0_ctrl,
+ .ctrlbit = (1 << 0),
+};
+
+struct clk *exynos4_clkset_group_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &clk_xusbxti,
+ [2] = &exynos4_clk_sclk_hdmi27m,
+ [3] = &exynos4_clk_sclk_usbphy0,
+ [4] = &exynos4_clk_sclk_usbphy1,
+ [5] = &exynos4_clk_sclk_hdmiphy,
+ [6] = &exynos4_clk_mout_mpll.clk,
+ [7] = &exynos4_clk_mout_epll.clk,
+ [8] = &exynos4_clk_sclk_vpll.clk,
+};
+
+struct clksrc_sources exynos4_clkset_group = {
+ .sources = exynos4_clkset_group_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_group_list),
+};
+
+static struct clk *exynos4_clkset_mout_g2d0_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g2d0 = {
+ .sources = exynos4_clkset_mout_g2d0_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_g2d0 = {
+ .clk = {
+ .name = "mout_g2d0",
+ },
+ .sources = &exynos4_clkset_mout_g2d0,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_g2d1_list[] = {
+ [0] = &exynos4_clk_mout_epll.clk,
+ [1] = &exynos4_clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g2d1 = {
+ .sources = exynos4_clkset_mout_g2d1_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_g2d1 = {
+ .clk = {
+ .name = "mout_g2d1",
+ },
+ .sources = &exynos4_clkset_mout_g2d1,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_g2d_list[] = {
+ [0] = &exynos4_clk_mout_g2d0.clk,
+ [1] = &exynos4_clk_mout_g2d1.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g2d = {
+ .sources = exynos4_clkset_mout_g2d_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d_list),
+};
+
+static struct clk *exynos4_clkset_mout_mfc0_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_mfc0 = {
+ .sources = exynos4_clkset_mout_mfc0_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc0_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_mfc0 = {
+ .clk = {
+ .name = "mout_mfc0",
+ },
+ .sources = &exynos4_clkset_mout_mfc0,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_mfc1_list[] = {
+ [0] = &exynos4_clk_mout_epll.clk,
+ [1] = &exynos4_clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_mfc1 = {
+ .sources = exynos4_clkset_mout_mfc1_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc1_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_mfc1 = {
+ .clk = {
+ .name = "mout_mfc1",
+ },
+ .sources = &exynos4_clkset_mout_mfc1,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_mfc_list[] = {
+ [0] = &exynos4_clk_mout_mfc0.clk,
+ [1] = &exynos4_clk_mout_mfc1.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_mfc = {
+ .sources = exynos4_clkset_mout_mfc_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc_list),
+};
+
+static struct clk *exynos4_clkset_sclk_dac_list[] = {
+ [0] = &exynos4_clk_sclk_vpll.clk,
+ [1] = &exynos4_clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_dac = {
+ .sources = exynos4_clkset_sclk_dac_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_dac_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_dac = {
+ .clk = {
+ .name = "sclk_dac",
+ .enable = exynos4_clksrc_mask_tv_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &exynos4_clkset_sclk_dac,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_pixel = {
+ .clk = {
+ .name = "sclk_pixel",
+ .parent = &exynos4_clk_sclk_vpll.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TV, .shift = 0, .size = 4 },
+};
+
+static struct clk *exynos4_clkset_sclk_hdmi_list[] = {
+ [0] = &exynos4_clk_sclk_pixel.clk,
+ [1] = &exynos4_clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_hdmi = {
+ .sources = exynos4_clkset_sclk_hdmi_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_hdmi_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_hdmi = {
+ .clk = {
+ .name = "sclk_hdmi",
+ .enable = exynos4_clksrc_mask_tv_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_sclk_hdmi,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_sclk_mixer_list[] = {
+ [0] = &exynos4_clk_sclk_dac.clk,
+ [1] = &exynos4_clk_sclk_hdmi.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_mixer = {
+ .sources = exynos4_clkset_sclk_mixer_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_mixer_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mixer = {
+ .clk = {
+ .name = "sclk_mixer",
+ .enable = exynos4_clksrc_mask_tv_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos4_clkset_sclk_mixer,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk *exynos4_sclk_tv[] = {
+ &exynos4_clk_sclk_dac,
+ &exynos4_clk_sclk_pixel,
+ &exynos4_clk_sclk_hdmi,
+ &exynos4_clk_sclk_mixer,
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc0 = {
+ .clk = {
+ .name = "dout_mmc0",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc1 = {
+ .clk = {
+ .name = "dout_mmc1",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc2 = {
+ .clk = {
+ .name = "dout_mmc2",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc3 = {
+ .clk = {
+ .name = "dout_mmc3",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc4 = {
+ .clk = {
+ .name = "dout_mmc4",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clksrcs[] = {
+ {
+ .clk = {
+ .name = "sclk_pwm",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 24, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL3, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_csis",
+ .devname = "s5p-mipi-csis.0",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 24, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_csis",
+ .devname = "s5p-mipi-csis.1",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 28),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 28, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 28, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam0",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam1",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 20, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .devname = "exynos4-fimc.0",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .devname = "exynos4-fimc.1",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .devname = "exynos4-fimc.2",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .devname = "exynos4-fimc.3",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimd",
+ .devname = "exynos4-fb.0",
+ .enable = exynos4_clksrc_mask_lcd0_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimg2d",
+ },
+ .sources = &exynos4_clkset_mout_g2d,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mfc",
+ .devname = "s5p-mfc",
+ },
+ .sources = &exynos4_clkset_mout_mfc,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_dwmmc",
+ .parent = &exynos4_clk_dout_mmc4.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 },
+ }
+};
+
+static struct clksrc_clk exynos4_clk_sclk_uart0 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "exynos4210-uart.0",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_uart1 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "exynos4210-uart.1",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_uart2 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "exynos4210-uart.2",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_uart3 = {
+ .clk = {
+ .name = "uclk1",
+ .devname = "exynos4210-uart.3",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 12, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mmc0 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.0",
+ .parent = &exynos4_clk_dout_mmc0.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 8, .size = 8 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mmc1 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.1",
+ .parent = &exynos4_clk_dout_mmc1.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 24, .size = 8 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mmc2 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.2",
+ .parent = &exynos4_clk_dout_mmc2.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 8, .size = 8 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mmc3 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.3",
+ .parent = &exynos4_clk_dout_mmc3.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_spi0 = {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.0",
+ .enable = exynos4_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_spi1 = {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.1",
+ .enable = exynos4_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_spi2 = {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.2",
+ .enable = exynos4_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *exynos4_sysclks[] = {
+ &exynos4_clk_mout_apll,
+ &exynos4_clk_sclk_apll,
+ &exynos4_clk_mout_epll,
+ &exynos4_clk_mout_mpll,
+ &exynos4_clk_moutcore,
+ &exynos4_clk_coreclk,
+ &exynos4_clk_armclk,
+ &exynos4_clk_aclk_corem0,
+ &exynos4_clk_aclk_cores,
+ &exynos4_clk_aclk_corem1,
+ &exynos4_clk_periphclk,
+ &exynos4_clk_mout_corebus,
+ &exynos4_clk_sclk_dmc,
+ &exynos4_clk_aclk_cored,
+ &exynos4_clk_aclk_corep,
+ &exynos4_clk_aclk_acp,
+ &exynos4_clk_pclk_acp,
+ &exynos4_clk_vpllsrc,
+ &exynos4_clk_sclk_vpll,
+ &exynos4_clk_aclk_200,
+ &exynos4_clk_aclk_100,
+ &exynos4_clk_aclk_160,
+ &exynos4_clk_aclk_133,
+ &exynos4_clk_dout_mmc0,
+ &exynos4_clk_dout_mmc1,
+ &exynos4_clk_dout_mmc2,
+ &exynos4_clk_dout_mmc3,
+ &exynos4_clk_dout_mmc4,
+ &exynos4_clk_mout_mfc0,
+ &exynos4_clk_mout_mfc1,
+};
+
+static struct clk *exynos4_clk_cdev[] = {
+ &exynos4_clk_pdma0,
+ &exynos4_clk_pdma1,
+ &exynos4_clk_mdma1,
+ &exynos4_clk_fimd0,
+};
+
+static struct clksrc_clk *exynos4_clksrc_cdev[] = {
+ &exynos4_clk_sclk_uart0,
+ &exynos4_clk_sclk_uart1,
+ &exynos4_clk_sclk_uart2,
+ &exynos4_clk_sclk_uart3,
+ &exynos4_clk_sclk_mmc0,
+ &exynos4_clk_sclk_mmc1,
+ &exynos4_clk_sclk_mmc2,
+ &exynos4_clk_sclk_mmc3,
+ &exynos4_clk_sclk_spi0,
+ &exynos4_clk_sclk_spi1,
+ &exynos4_clk_sclk_spi2,
+
+};
+
+static struct clk_lookup exynos4_clk_lookup[] = {
+ CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos4_clk_sclk_uart0.clk),
+ CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk),
+ CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk),
+ CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk),
+ CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk),
+ CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk),
+ CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk),
+ CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk),
+ CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0),
+ CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0),
+ CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1),
+ CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos4_clk_mdma1),
+ CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &exynos4_clk_sclk_spi0.clk),
+ CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk0", &exynos4_clk_sclk_spi1.clk),
+ CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk0", &exynos4_clk_sclk_spi2.clk),
+};
+
+static int xtal_rate;
+
+static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
+{
+ if (soc_is_exynos4210())
+ return s5p_get_pll45xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0),
+ pll_4508);
+ else if (soc_is_exynos4212() || soc_is_exynos4412())
+ return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0));
+ else
+ return 0;
+}
+
+static struct clk_ops exynos4_fout_apll_ops = {
+ .get_rate = exynos4_fout_apll_get_rate,
+};
+
+static u32 exynos4_vpll_div[][8] = {
+ { 54000000, 3, 53, 3, 1024, 0, 17, 0 },
+ { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
+};
+
+static unsigned long exynos4_vpll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int vpll_con0, vpll_con1 = 0;
+ unsigned int i;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0);
+ vpll_con0 &= ~(0x1 << 27 | \
+ PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
+ PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
+ PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+ vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1);
+ vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT | \
+ PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \
+ PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT);
+
+ for (i = 0; i < ARRAY_SIZE(exynos4_vpll_div); i++) {
+ if (exynos4_vpll_div[i][0] == rate) {
+ vpll_con0 |= exynos4_vpll_div[i][1] << PLL46XX_PDIV_SHIFT;
+ vpll_con0 |= exynos4_vpll_div[i][2] << PLL46XX_MDIV_SHIFT;
+ vpll_con0 |= exynos4_vpll_div[i][3] << PLL46XX_SDIV_SHIFT;
+ vpll_con1 |= exynos4_vpll_div[i][4] << PLL46XX_KDIV_SHIFT;
+ vpll_con1 |= exynos4_vpll_div[i][5] << PLL46XX_MFR_SHIFT;
+ vpll_con1 |= exynos4_vpll_div[i][6] << PLL46XX_MRR_SHIFT;
+ vpll_con0 |= exynos4_vpll_div[i][7] << 27;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(exynos4_vpll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(vpll_con0, EXYNOS4_VPLL_CON0);
+ __raw_writel(vpll_con1, EXYNOS4_VPLL_CON1);
+
+ /* Wait for VPLL lock */
+ while (!(__raw_readl(EXYNOS4_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT)))
+ continue;
+
+ clk->rate = rate;
+ return 0;
+}
+
+static struct clk_ops exynos4_vpll_ops = {
+ .get_rate = exynos4_vpll_get_rate,
+ .set_rate = exynos4_vpll_set_rate,
+};
+
+void __init_or_cpufreq exynos4_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long apll = 0;
+ unsigned long mpll = 0;
+ unsigned long epll = 0;
+ unsigned long vpll = 0;
+ unsigned long vpllsrc;
+ unsigned long xtal;
+ unsigned long armclk;
+ unsigned long sclk_dmc;
+ unsigned long aclk_200;
+ unsigned long aclk_100;
+ unsigned long aclk_160;
+ unsigned long aclk_133;
+ unsigned int ptr;
+
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+ xtal_clk = clk_get(NULL, "xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+
+ xtal_rate = xtal;
+
+ clk_put(xtal_clk);
+
+ printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+ if (soc_is_exynos4210()) {
+ apll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_APLL_CON0),
+ pll_4508);
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0),
+ pll_4508);
+ epll = s5p_get_pll46xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
+ __raw_readl(EXYNOS4_EPLL_CON1), pll_4600);
+
+ vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
+ vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
+ __raw_readl(EXYNOS4_VPLL_CON1), pll_4650c);
+ } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_APLL_CON0));
+ mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0));
+ epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
+ __raw_readl(EXYNOS4_EPLL_CON1));
+
+ vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
+ vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
+ __raw_readl(EXYNOS4_VPLL_CON1));
+ } else {
+ /* nothing */
+ }
+
+ clk_fout_apll.ops = &exynos4_fout_apll_ops;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+ clk_fout_vpll.ops = &exynos4_vpll_ops;
+ clk_fout_vpll.rate = vpll;
+
+ printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
+ apll, mpll, epll, vpll);
+
+ armclk = clk_get_rate(&exynos4_clk_armclk.clk);
+ sclk_dmc = clk_get_rate(&exynos4_clk_sclk_dmc.clk);
+
+ aclk_200 = clk_get_rate(&exynos4_clk_aclk_200.clk);
+ aclk_100 = clk_get_rate(&exynos4_clk_aclk_100.clk);
+ aclk_160 = clk_get_rate(&exynos4_clk_aclk_160.clk);
+ aclk_133 = clk_get_rate(&exynos4_clk_aclk_133.clk);
+
+ printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
+ "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
+ armclk, sclk_dmc, aclk_200,
+ aclk_100, aclk_160, aclk_133);
+
+ clk_f.rate = armclk;
+ clk_h.rate = sclk_dmc;
+ clk_p.rate = aclk_100;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++)
+ s3c_set_clksrc(&exynos4_clksrcs[ptr], true);
+}
+
+static struct clk *exynos4_clks[] __initdata = {
+ &exynos4_clk_sclk_hdmi27m,
+ &exynos4_clk_sclk_hdmiphy,
+ &exynos4_clk_sclk_usbphy0,
+ &exynos4_clk_sclk_usbphy1,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos4_clock_suspend(void)
+{
+ s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+ return 0;
+}
+
+static void exynos4_clock_resume(void)
+{
+ s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+}
+
+#else
+#define exynos4_clock_suspend NULL
+#define exynos4_clock_resume NULL
+#endif
+
+static struct syscore_ops exynos4_clock_syscore_ops = {
+ .suspend = exynos4_clock_suspend,
+ .resume = exynos4_clock_resume,
+};
+
+void __init exynos4_register_clocks(void)
+{
+ int ptr;
+
+ s3c24xx_register_clocks(exynos4_clks, ARRAY_SIZE(exynos4_clks));
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sysclks); ptr++)
+ s3c_register_clksrc(exynos4_sysclks[ptr], 1);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sclk_tv); ptr++)
+ s3c_register_clksrc(exynos4_sclk_tv[ptr], 1);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrc_cdev); ptr++)
+ s3c_register_clksrc(exynos4_clksrc_cdev[ptr], 1);
+
+ s3c_register_clksrc(exynos4_clksrcs, ARRAY_SIZE(exynos4_clksrcs));
+ s3c_register_clocks(exynos4_init_clocks_on, ARRAY_SIZE(exynos4_init_clocks_on));
+
+ s3c24xx_register_clocks(exynos4_clk_cdev, ARRAY_SIZE(exynos4_clk_cdev));
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clk_cdev); ptr++)
+ s3c_disable_clocks(exynos4_clk_cdev[ptr], 1);
+
+ s3c_register_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
+ s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
+ clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
+
+ register_syscore_ops(&exynos4_clock_syscore_ops);
+ s3c24xx_register_clock(&dummy_apb_pclk);
+
+ s3c_pwmclk_init();
+}
#include <asm/hardware/gic.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+ #include <asm/cacheflush.h>
#include <mach/regs-irq.h>
#include <mach/regs-pmu.h>
#include <mach/regs-gpio.h>
+ #include <mach/pmu.h>
#include <plat/cpu.h>
#include <plat/clock.h>
#include <plat/regs-serial.h>
#include "common.h"
+ #define L2_AUX_VAL 0x7C470001
+ #define L2_AUX_MASK 0xC200ffff
static const char name_exynos4210[] = "EXYNOS4210";
static const char name_exynos4212[] = "EXYNOS4212";
static const char name_exynos4412[] = "EXYNOS4412";
+static const char name_exynos5250[] = "EXYNOS5250";
+
+static void exynos4_map_io(void);
+static void exynos5_map_io(void);
+static void exynos4_init_clocks(int xtal);
+static void exynos5_init_clocks(int xtal);
+static void exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+static int exynos_init(void);
static struct cpu_table cpu_ids[] __initdata = {
{
.idmask = EXYNOS4_CPU_MASK,
.map_io = exynos4_map_io,
.init_clocks = exynos4_init_clocks,
- .init_uarts = exynos4_init_uarts,
+ .init_uarts = exynos_init_uarts,
.init = exynos_init,
.name = name_exynos4210,
}, {
.idmask = EXYNOS4_CPU_MASK,
.map_io = exynos4_map_io,
.init_clocks = exynos4_init_clocks,
- .init_uarts = exynos4_init_uarts,
+ .init_uarts = exynos_init_uarts,
.init = exynos_init,
.name = name_exynos4212,
}, {
.idmask = EXYNOS4_CPU_MASK,
.map_io = exynos4_map_io,
.init_clocks = exynos4_init_clocks,
- .init_uarts = exynos4_init_uarts,
+ .init_uarts = exynos_init_uarts,
.init = exynos_init,
.name = name_exynos4412,
+ }, {
+ .idcode = EXYNOS5250_SOC_ID,
+ .idmask = EXYNOS5_SOC_MASK,
+ .map_io = exynos5_map_io,
+ .init_clocks = exynos5_init_clocks,
+ .init_uarts = exynos_init_uarts,
+ .init = exynos_init,
+ .name = name_exynos5250,
},
};
static struct map_desc exynos_iodesc[] __initdata = {
{
.virtual = (unsigned long)S5P_VA_CHIPID,
- .pfn = __phys_to_pfn(EXYNOS4_PA_CHIPID),
+ .pfn = __phys_to_pfn(EXYNOS_PA_CHIPID),
.length = SZ_4K,
.type = MT_DEVICE,
- }, {
+ },
+};
+
+static struct map_desc exynos4_iodesc[] __initdata = {
+ {
.virtual = (unsigned long)S3C_VA_SYS,
.pfn = __phys_to_pfn(EXYNOS4_PA_SYSCON),
.length = SZ_64K,
.pfn = __phys_to_pfn(EXYNOS4_PA_UART),
.length = SZ_512K,
.type = MT_DEVICE,
- },
-};
-
-static struct map_desc exynos4_iodesc[] __initdata = {
- {
+ }, {
.virtual = (unsigned long)S5P_VA_CMU,
.pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
.length = SZ_128K,
}, {
.virtual = (unsigned long)S5P_VA_DMC0,
.pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
- .length = SZ_4K,
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC1,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
+ .length = SZ_64K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_USB_HSPHY,
},
};
-static void exynos_idle(void)
-{
- if (!need_resched())
- cpu_do_idle();
-
- local_irq_enable();
-}
+static struct map_desc exynos5_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_SYS,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_SYSCON),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_TIMER,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_TIMER),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_WATCHDOG,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_WATCHDOG),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SROMC,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_SROMC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SYSTIMER,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_SYSTIMER),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SYSRAM,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_CMU,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_CMU),
+ .length = 144 * SZ_1K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PMU,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_PMU),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_COMBINER),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_UART),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GIC_CPU,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_CPU),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GIC_DIST,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_DIST),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ },
+};
void exynos4_restart(char mode, const char *cmd)
{
__raw_writel(0x1, S5P_SWRESET);
}
+void exynos5_restart(char mode, const char *cmd)
+{
+ __raw_writel(0x1, EXYNOS_SWRESET);
+}
+
/*
* exynos_map_io
*
s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
}
-void __init exynos4_map_io(void)
+static void __init exynos4_map_io(void)
{
iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
s5p_hdmi_setname("exynos4-hdmi");
}
-void __init exynos4_init_clocks(int xtal)
+static void __init exynos5_map_io(void)
+{
+ iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
+
+ s3c_device_i2c0.resource[0].start = EXYNOS5_PA_IIC(0);
+ s3c_device_i2c0.resource[0].end = EXYNOS5_PA_IIC(0) + SZ_4K - 1;
+ s3c_device_i2c0.resource[1].start = EXYNOS5_IRQ_IIC;
+ s3c_device_i2c0.resource[1].end = EXYNOS5_IRQ_IIC;
+
+ /* The I2C bus controllers are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+ s3c_i2c2_setname("s3c2440-i2c");
+}
+
+static void __init exynos4_init_clocks(int xtal)
{
printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
exynos4_setup_clocks();
}
+static void __init exynos5_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+
+ exynos5_register_clocks();
+ exynos5_setup_clocks();
+}
+
#define COMBINER_ENABLE_SET 0x0
#define COMBINER_ENABLE_CLEAR 0x4
#define COMBINER_INT_STATUS 0xC
static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
{
- if (combiner_nr >= MAX_COMBINER_NR)
+ unsigned int max_nr;
+
+ if (soc_is_exynos5250())
+ max_nr = EXYNOS5_MAX_COMBINER_NR;
+ else
+ max_nr = EXYNOS4_MAX_COMBINER_NR;
+
+ if (combiner_nr >= max_nr)
BUG();
if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
BUG();
unsigned int irq_start)
{
unsigned int i;
+ unsigned int max_nr;
- if (combiner_nr >= MAX_COMBINER_NR)
+ if (soc_is_exynos5250())
+ max_nr = EXYNOS5_MAX_COMBINER_NR;
+ else
+ max_nr = EXYNOS4_MAX_COMBINER_NR;
+
+ if (combiner_nr >= max_nr)
BUG();
combiner_data[combiner_nr].base = base;
of_irq_init(exynos4_dt_irq_match);
#endif
- for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
+ for (irq = 0; irq < EXYNOS4_MAX_COMBINER_NR; irq++) {
combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
COMBINER_IRQ(irq, 0));
s5p_init_irq(NULL, 0);
}
+void __init exynos5_init_irq(void)
+{
+ int irq;
+
+ gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
+
+ for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) {
+ combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
+ COMBINER_IRQ(irq, 0));
+ combiner_cascade_irq(irq, IRQ_SPI(irq));
+ }
+
+ /*
+ * The parameters of s5p_init_irq() are for VIC init.
+ * Theses parameters should be NULL and 0 because EXYNOS4
+ * uses GIC instead of VIC.
+ */
+ s5p_init_irq(NULL, 0);
+}
+
struct bus_type exynos4_subsys = {
.name = "exynos4-core",
.dev_name = "exynos4-core",
};
+struct bus_type exynos5_subsys = {
+ .name = "exynos5-core",
+ .dev_name = "exynos5-core",
+};
+
static struct device exynos4_dev = {
.bus = &exynos4_subsys,
};
-static int __init exynos4_core_init(void)
+static struct device exynos5_dev = {
+ .bus = &exynos5_subsys,
+};
+
+static int __init exynos_core_init(void)
{
- return subsys_system_register(&exynos4_subsys, NULL);
+ if (soc_is_exynos5250())
+ return subsys_system_register(&exynos5_subsys, NULL);
+ else
+ return subsys_system_register(&exynos4_subsys, NULL);
}
-core_initcall(exynos4_core_init);
+core_initcall(exynos_core_init);
#ifdef CONFIG_CACHE_L2X0
static int __init exynos4_l2x0_cache_init(void)
{
- /* TAG, Data Latency Control: 2cycle */
- __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
+ if (soc_is_exynos5250())
+ return 0;
+
+ int ret;
+ ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
+ if (!ret) {
+ l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
+ clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
+ return 0;
+ }
+
+ if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) {
+ l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC;
+ /* TAG, Data Latency Control: 2 cycles */
+ l2x0_saved_regs.tag_latency = 0x110;
- if (soc_is_exynos4210())
- __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
- else if (soc_is_exynos4212() || soc_is_exynos4412())
- __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
+ if (soc_is_exynos4212() || soc_is_exynos4412())
+ l2x0_saved_regs.data_latency = 0x120;
+ else
+ l2x0_saved_regs.data_latency = 0x110;
+
+ l2x0_saved_regs.prefetch_ctrl = 0x30000007;
+ l2x0_saved_regs.pwr_ctrl =
+ (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN);
- /* L2X0 Prefetch Control */
- __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
+ l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
- /* L2X0 Power Control */
- __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
- S5P_VA_L2CC + L2X0_POWER_CTRL);
+ __raw_writel(l2x0_saved_regs.tag_latency,
+ S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
+ __raw_writel(l2x0_saved_regs.data_latency,
+ S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
- l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
+ /* L2X0 Prefetch Control */
+ __raw_writel(l2x0_saved_regs.prefetch_ctrl,
+ S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
+
+ /* L2X0 Power Control */
+ __raw_writel(l2x0_saved_regs.pwr_ctrl,
+ S5P_VA_L2CC + L2X0_POWER_CTRL);
+
+ clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
+ clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs));
+ }
+ l2x0_init(S5P_VA_L2CC, L2_AUX_VAL, L2_AUX_MASK);
return 0;
}
-
early_initcall(exynos4_l2x0_cache_init);
#endif
-int __init exynos_init(void)
+static int __init exynos5_l2_cache_init(void)
{
- printk(KERN_INFO "EXYNOS: Initializing architecture\n");
+ unsigned int val;
- /* set idle function */
- pm_idle = exynos_idle;
+ if (!soc_is_exynos5250())
+ return 0;
+
+ asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
+ "bic %0, %0, #(1 << 2)\n" /* cache disable */
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ "mrc p15, 1, %0, c9, c0, 2\n"
+ : "=r"(val));
+
+ val |= (1 << 9) | (1 << 5) | (2 << 6) | (2 << 0);
- return device_register(&exynos4_dev);
+ asm volatile("mcr p15, 1, %0, c9, c0, 2\n" : : "r"(val));
+ asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
+ "orr %0, %0, #(1 << 2)\n" /* cache enable */
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ : : "r"(val));
+
+ return 0;
+}
+early_initcall(exynos5_l2_cache_init);
+
+static int __init exynos_init(void)
+{
+ printk(KERN_INFO "EXYNOS: Initializing architecture\n");
+
+ if (soc_is_exynos5250())
+ return device_register(&exynos5_dev);
+ else
+ return device_register(&exynos4_dev);
}
/* uart registration process */
-void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+static void __init exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
struct s3c2410_uartcfg *tcfg = cfg;
u32 ucnt;
for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
tcfg->has_fracval = 1;
- s3c24xx_init_uartdevs("exynos4210-uart", s5p_uart_resources, cfg, no);
+ if (soc_is_exynos5250())
+ s3c24xx_init_uartdevs("exynos4210-uart", exynos5_uart_resources, cfg, no);
+ else
+ s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no);
}
+static void __iomem *exynos_eint_base;
+
static DEFINE_SPINLOCK(eint_lock);
static unsigned int eint0_15_data[16];
-static unsigned int exynos4_get_irq_nr(unsigned int number)
+static inline int exynos4_irq_to_gpio(unsigned int irq)
{
- u32 ret = 0;
+ if (irq < IRQ_EINT(0))
+ return -EINVAL;
- switch (number) {
- case 0 ... 3:
- ret = (number + IRQ_EINT0);
- break;
- case 4 ... 7:
- ret = (number + (IRQ_EINT4 - 4));
- break;
- case 8 ... 15:
- ret = (number + (IRQ_EINT8 - 8));
- break;
- default:
- printk(KERN_ERR "number available : %d\n", number);
- }
+ irq -= IRQ_EINT(0);
+ if (irq < 8)
+ return EXYNOS4_GPX0(irq);
+
+ irq -= 8;
+ if (irq < 8)
+ return EXYNOS4_GPX1(irq);
+
+ irq -= 8;
+ if (irq < 8)
+ return EXYNOS4_GPX2(irq);
+
+ irq -= 8;
+ if (irq < 8)
+ return EXYNOS4_GPX3(irq);
+
+ return -EINVAL;
+}
+
+static inline int exynos5_irq_to_gpio(unsigned int irq)
+{
+ if (irq < IRQ_EINT(0))
+ return -EINVAL;
+
+ irq -= IRQ_EINT(0);
+ if (irq < 8)
+ return EXYNOS5_GPX0(irq);
+
+ irq -= 8;
+ if (irq < 8)
+ return EXYNOS5_GPX1(irq);
+
+ irq -= 8;
+ if (irq < 8)
+ return EXYNOS5_GPX2(irq);
- return ret;
+ irq -= 8;
+ if (irq < 8)
+ return EXYNOS5_GPX3(irq);
+
+ return -EINVAL;
}
-static inline void exynos4_irq_eint_mask(struct irq_data *data)
+static unsigned int exynos4_eint0_15_src_int[16] = {
+ EXYNOS4_IRQ_EINT0,
+ EXYNOS4_IRQ_EINT1,
+ EXYNOS4_IRQ_EINT2,
+ EXYNOS4_IRQ_EINT3,
+ EXYNOS4_IRQ_EINT4,
+ EXYNOS4_IRQ_EINT5,
+ EXYNOS4_IRQ_EINT6,
+ EXYNOS4_IRQ_EINT7,
+ EXYNOS4_IRQ_EINT8,
+ EXYNOS4_IRQ_EINT9,
+ EXYNOS4_IRQ_EINT10,
+ EXYNOS4_IRQ_EINT11,
+ EXYNOS4_IRQ_EINT12,
+ EXYNOS4_IRQ_EINT13,
+ EXYNOS4_IRQ_EINT14,
+ EXYNOS4_IRQ_EINT15,
+};
+
+static unsigned int exynos5_eint0_15_src_int[16] = {
+ EXYNOS5_IRQ_EINT0,
+ EXYNOS5_IRQ_EINT1,
+ EXYNOS5_IRQ_EINT2,
+ EXYNOS5_IRQ_EINT3,
+ EXYNOS5_IRQ_EINT4,
+ EXYNOS5_IRQ_EINT5,
+ EXYNOS5_IRQ_EINT6,
+ EXYNOS5_IRQ_EINT7,
+ EXYNOS5_IRQ_EINT8,
+ EXYNOS5_IRQ_EINT9,
+ EXYNOS5_IRQ_EINT10,
+ EXYNOS5_IRQ_EINT11,
+ EXYNOS5_IRQ_EINT12,
+ EXYNOS5_IRQ_EINT13,
+ EXYNOS5_IRQ_EINT14,
+ EXYNOS5_IRQ_EINT15,
+};
+static inline void exynos_irq_eint_mask(struct irq_data *data)
{
u32 mask;
spin_lock(&eint_lock);
- mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
- mask |= eint_irq_to_bit(data->irq);
- __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq));
+ mask |= EINT_OFFSET_BIT(data->irq);
+ __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq));
spin_unlock(&eint_lock);
}
-static void exynos4_irq_eint_unmask(struct irq_data *data)
+static void exynos_irq_eint_unmask(struct irq_data *data)
{
u32 mask;
spin_lock(&eint_lock);
- mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
- mask &= ~(eint_irq_to_bit(data->irq));
- __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq));
+ mask &= ~(EINT_OFFSET_BIT(data->irq));
+ __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq));
spin_unlock(&eint_lock);
}
-static inline void exynos4_irq_eint_ack(struct irq_data *data)
+static inline void exynos_irq_eint_ack(struct irq_data *data)
{
- __raw_writel(eint_irq_to_bit(data->irq),
- S5P_EINT_PEND(EINT_REG_NR(data->irq)));
+ __raw_writel(EINT_OFFSET_BIT(data->irq),
+ EINT_PEND(exynos_eint_base, data->irq));
}
-static void exynos4_irq_eint_maskack(struct irq_data *data)
+static void exynos_irq_eint_maskack(struct irq_data *data)
{
- exynos4_irq_eint_mask(data);
- exynos4_irq_eint_ack(data);
+ exynos_irq_eint_mask(data);
+ exynos_irq_eint_ack(data);
}
-static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type)
+static int exynos_irq_eint_set_type(struct irq_data *data, unsigned int type)
{
int offs = EINT_OFFSET(data->irq);
int shift;
mask = 0x7 << shift;
spin_lock(&eint_lock);
- ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
+ ctrl = __raw_readl(EINT_CON(exynos_eint_base, data->irq));
ctrl &= ~mask;
ctrl |= newvalue << shift;
- __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
+ __raw_writel(ctrl, EINT_CON(exynos_eint_base, data->irq));
spin_unlock(&eint_lock);
- switch (offs) {
- case 0 ... 7:
- s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
- break;
- case 8 ... 15:
- s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
- break;
- case 16 ... 23:
- s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
- break;
- case 24 ... 31:
- s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
- break;
- default:
- printk(KERN_ERR "No such irq number %d", offs);
- }
+ if (soc_is_exynos5250())
+ s3c_gpio_cfgpin(exynos5_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf));
+ else
+ s3c_gpio_cfgpin(exynos4_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf));
return 0;
}
-static struct irq_chip exynos4_irq_eint = {
- .name = "exynos4-eint",
- .irq_mask = exynos4_irq_eint_mask,
- .irq_unmask = exynos4_irq_eint_unmask,
- .irq_mask_ack = exynos4_irq_eint_maskack,
- .irq_ack = exynos4_irq_eint_ack,
- .irq_set_type = exynos4_irq_eint_set_type,
+static struct irq_chip exynos_irq_eint = {
+ .name = "exynos-eint",
+ .irq_mask = exynos_irq_eint_mask,
+ .irq_unmask = exynos_irq_eint_unmask,
+ .irq_mask_ack = exynos_irq_eint_maskack,
+ .irq_ack = exynos_irq_eint_ack,
+ .irq_set_type = exynos_irq_eint_set_type,
#ifdef CONFIG_PM
.irq_set_wake = s3c_irqext_wake,
#endif
*
* Each EINT pend/mask registers handle eight of them.
*/
-static inline void exynos4_irq_demux_eint(unsigned int start)
+static inline void exynos_irq_demux_eint(unsigned int start)
{
unsigned int irq;
- u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
- u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
+ u32 status = __raw_readl(EINT_PEND(exynos_eint_base, start));
+ u32 mask = __raw_readl(EINT_MASK(exynos_eint_base, start));
status &= ~mask;
status &= 0xff;
}
}
-static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = irq_get_chip(irq);
chained_irq_enter(chip, desc);
- exynos4_irq_demux_eint(IRQ_EINT(16));
- exynos4_irq_demux_eint(IRQ_EINT(24));
+ exynos_irq_demux_eint(IRQ_EINT(16));
+ exynos_irq_demux_eint(IRQ_EINT(24));
chained_irq_exit(chip, desc);
}
-static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
+static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
{
u32 *irq_data = irq_get_handler_data(irq);
struct irq_chip *chip = irq_get_chip(irq);
chained_irq_exit(chip, desc);
}
-int __init exynos4_init_irq_eint(void)
+static int __init exynos_init_irq_eint(void)
{
int irq;
+ if (soc_is_exynos5250())
+ exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
+ else
+ exynos_eint_base = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
+
+ if (exynos_eint_base == NULL) {
+ pr_err("unable to ioremap for EINT base address\n");
+ return -ENOMEM;
+ }
+
for (irq = 0 ; irq <= 31 ; irq++) {
- irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint,
+ irq_set_chip_and_handler(IRQ_EINT(irq), &exynos_irq_eint,
handle_level_irq);
set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
}
- irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31);
+ irq_set_chained_handler(EXYNOS_IRQ_EINT16_31, exynos_irq_demux_eint16_31);
for (irq = 0 ; irq <= 15 ; irq++) {
eint0_15_data[irq] = IRQ_EINT(irq);
- irq_set_handler_data(exynos4_get_irq_nr(irq),
- &eint0_15_data[irq]);
- irq_set_chained_handler(exynos4_get_irq_nr(irq),
- exynos4_irq_eint0_15);
+ if (soc_is_exynos5250()) {
+ irq_set_handler_data(exynos5_eint0_15_src_int[irq],
+ &eint0_15_data[irq]);
+ irq_set_chained_handler(exynos5_eint0_15_src_int[irq],
+ exynos_irq_eint0_15);
+ } else {
+ irq_set_handler_data(exynos4_eint0_15_src_int[irq],
+ &eint0_15_data[irq]);
+ irq_set_chained_handler(exynos4_eint0_15_src_int[irq],
+ exynos_irq_eint0_15);
+ }
}
return 0;
}
-arch_initcall(exynos4_init_irq_eint);
+arch_initcall(exynos_init_irq_eint);