summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/configs/imx6_defconfig3
-rw-r--r--arch/arm/mach-mx6/Kconfig1
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.c3
-rw-r--r--arch/arm/mach-mx6/clock.c30
-rw-r--r--arch/arm/mach-mx6/devices-imx6q.h5
-rw-r--r--arch/arm/mach-mx6/system.c1
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-perfmon.c88
7 files changed, 129 insertions, 2 deletions
diff --git a/arch/arm/configs/imx6_defconfig b/arch/arm/configs/imx6_defconfig
index 06ee86f5e0b7..c1c36838eb91 100644
--- a/arch/arm/configs/imx6_defconfig
+++ b/arch/arm/configs/imx6_defconfig
@@ -768,7 +768,8 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MG_DISK is not set
# CONFIG_BLK_DEV_RBD is not set
-# CONFIG_MISC_DEVICES is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_MXS_PERFMON=m
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
index 6a1a99dd7d17..c277f8b828fd 100644
--- a/arch/arm/mach-mx6/Kconfig
+++ b/arch/arm/mach-mx6/Kconfig
@@ -54,6 +54,7 @@ config MACH_MX6Q_ARM2
select IMX_HAVE_PLATFORM_IMX_MIPI_DSI
select IMX_HAVE_PLATFORM_FLEXCAN
select IMX_HAVE_PLATFORM_IMX_MIPI_CSI2
+ select IMX_HAVE_PLATFORM_PERFMON
help
Include support for i.MX 6Quad Armadillo2 platform. This includes specific
configurations for the board and its peripherals.
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c
index 4b73fb2d98aa..f1f9600fb674 100644
--- a/arch/arm/mach-mx6/board-mx6q_arm2.c
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.c
@@ -1527,6 +1527,9 @@ static void __init mx6_board_init(void)
imx6q_add_hdmi_soc();
imx6q_add_hdmi_soc_dai();
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
}
extern void __iomem *twd_base;
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index c5545153ffad..37912ca23c0f 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -4630,6 +4630,33 @@ static struct clk clko_clk = {
.round_rate = _clk_clko_round_rate,
};
+static struct clk perfmon0_clk = {
+ __INIT_CLK_DEBUG(perfmon0_clk)
+ .parent = &mmdc_ch0_axi_clk[0],
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk perfmon1_clk = {
+ __INIT_CLK_DEBUG(perfmon1_clk)
+ .parent = &ipu1_clk,
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk perfmon2_clk = {
+ __INIT_CLK_DEBUG(perfmon2_clk)
+ .parent = &mmdc_ch0_axi_clk[0],
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable1,
+};
+
static struct clk dummy_clk = {
.id = 0,
};
@@ -4755,6 +4782,9 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, NULL, aips_tz2_clk),
_REGISTER_CLOCK(NULL, NULL, aips_tz1_clk),
_REGISTER_CLOCK(NULL, "clko_clk", clko_clk),
+ _REGISTER_CLOCK("mxs-perfmon.0", "perfmon", perfmon0_clk),
+ _REGISTER_CLOCK("mxs-perfmon.1", "perfmon", perfmon1_clk),
+ _REGISTER_CLOCK("mxs-perfmon.2", "perfmon", perfmon2_clk),
};
diff --git a/arch/arm/mach-mx6/devices-imx6q.h b/arch/arm/mach-mx6/devices-imx6q.h
index e46c97ef927c..e87f9c0d7e7f 100644
--- a/arch/arm/mach-mx6/devices-imx6q.h
+++ b/arch/arm/mach-mx6/devices-imx6q.h
@@ -189,3 +189,8 @@ extern const struct imx_flexcan_data imx6q_flexcan_data[] __initconst;
extern const struct imx_mipi_csi2_data imx6q_mipi_csi2_data __initconst;
#define imx6q_add_mipi_csi2(pdata) \
imx_add_mipi_csi2(&imx6q_mipi_csi2_data, pdata)
+
+extern const struct imx_perfmon_data imx6q_perfmon_data[] __initconst;
+#define imx6q_add_perfmon(id) \
+ imx_add_perfmon(&imx6q_perfmon_data[id])
+
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c
index de15c2a1f791..16a6531abf5f 100644
--- a/arch/arm/mach-mx6/system.c
+++ b/arch/arm/mach-mx6/system.c
@@ -243,3 +243,4 @@ int mxs_reset_block(void __iomem *hwreg, int just_enable)
}
return r;
}
+EXPORT_SYMBOL(mxs_reset_block);
diff --git a/arch/arm/plat-mxc/devices/platform-imx-perfmon.c b/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
index faec9b0e1111..25d1bf582de2 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
@@ -21,6 +21,7 @@
#include <mach/hardware.h>
#include <mach/devices-common.h>
#include <linux/fsl_devices.h>
+#include <mach/iomux-v3.h>
#ifdef CONFIG_SOC_IMX50
static struct mxs_perfmon_bit_config
@@ -51,10 +52,95 @@ const struct imx_perfmon_data imx50_perfmon_data = {
};
#endif
+#ifdef CONFIG_SOC_IMX6Q
+static struct mxs_perfmon_bit_config
+mx6q_perfmon1_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-GPU_3D" },
+ {.field = (1 << 1), .name = "MID1-GPU_2D" },
+ {.field = (1 << 2), .name = "MID2-VDOA" },
+ {.field = (1 << 3), .name = "MID3-Unused" },
+ {.field = (1 << 4), .name = "MID4-OPENVG" }
+};
+
+static struct mxs_perfmon_bit_config
+mx6q_perfmon2_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-IPU1.ld00" },
+ {.field = (1 << 1), .name = "MID1-IPU1.ld01" },
+ {.field = (1 << 2), .name = "MID2-IPU1.ld10" },
+ {.field = (1 << 3), .name = "MID3-IPU1.ld11" }
+};
+
+static struct mxs_perfmon_bit_config
+mx6q_perfmon3_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-CORES" },
+ {.field = (1 << 1), .name = "MID1-L2-BUF" },
+ {.field = (1 << 2), .name = "MID2-Unused" },
+ {.field = (1 << 3), .name = "MID3-L2-EVIC" },
+ {.field = (1 << 4), .name = "MID4-Unused" }
+};
+
+static int init;
+
+static void platform_perfmon_init(void)
+{
+ if (init)
+ return;
+
+ /* GPR11 bit[16] is the clock enable bit for perfmon */
+ mxc_iomux_set_gpr_register(11, 16, 1, 1);
+ init = true;
+}
+
+static void platform_perfmon_exit(void)
+{
+ if (!init)
+ return;
+
+ /* GPR11 bit[16] is the clock enable bit for perfmon */
+ mxc_iomux_set_gpr_register(11, 16, 1, 0);
+ init = false;
+}
+
+struct mxs_platform_perfmon_data mxc_perfmon_data1 = {
+ .bit_config_tab = mx6q_perfmon1_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx6q_perfmon1_bit_config),
+ .plt_init = platform_perfmon_init,
+ .plt_exit = platform_perfmon_exit,
+};
+
+struct mxs_platform_perfmon_data mxc_perfmon_data2 = {
+ .bit_config_tab = mx6q_perfmon2_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx6q_perfmon2_bit_config),
+ .plt_init = platform_perfmon_init,
+};
+
+struct mxs_platform_perfmon_data mxc_perfmon_data3 = {
+ .bit_config_tab = mx6q_perfmon3_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx6q_perfmon3_bit_config),
+ .plt_init = platform_perfmon_init,
+};
+
+const struct imx_perfmon_data imx6q_perfmon_data[3] = {
+ {
+ .iobase = IP2APB_PERFMON1_BASE_ADDR,
+ .pdata = &mxc_perfmon_data1,
+ },
+ {
+ .iobase = IP2APB_PERFMON2_BASE_ADDR,
+ .pdata = &mxc_perfmon_data2,
+ },
+ {
+ .iobase = IP2APB_PERFMON3_BASE_ADDR,
+ .pdata = &mxc_perfmon_data3,
+ }
+};
+#endif
struct platform_device *__init imx_add_perfmon(
const struct imx_perfmon_data *data)
{
+ static int id;
+
struct resource res[] = {
{
.start = data->iobase,
@@ -63,7 +149,7 @@ struct platform_device *__init imx_add_perfmon(
}
};
- return imx_add_platform_device("mxs-perfmon", 0,
+ return imx_add_platform_device("mxs-perfmon", id++,
res, ARRAY_SIZE(res), data->pdata,
sizeof(struct mxs_platform_perfmon_data));
}