summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Lin <tony.lin@freescale.com>2011-01-11 18:01:03 +0800
committerTony Lin <tony.lin@freescale.com>2011-01-18 11:20:44 +0800
commita98eb1a5b4b24cda8a3153c241e910f8ef611834 (patch)
treeab791aa1890137fe878eb8852554740bf73d7c27
parent5a1274b80bad3c126bb79bcd8e2df641cbc1cb41 (diff)
ENGR00137979-3 add performance monitor driver
add performance monitor driver. sample: cd /sys/devices/platform/mxs-perfmon.0/ 'echo 1 > MIDn-xxx' to enable monitor this channel n: channel number; xxx: name of channel (PXP, LCD...) you can enable the multiple channels you want to monitor respectively using this command. use following command to check the channel is enabled 'cat MIDn-xxx' 1: enable; 0: disable 'echo read > Monitor' to monitor all read activities 'echo start > Monitor' to start monitoring 'echo fetch > Monitor' to get a snapshot of monitor statistics. 'cat xxx_Count' to show the statistics. xxx: name of statistics, (Data, Transfer, Latency...) 'echo clear > Monitor' to clear snapshot of monitor statistics. 'echo stop > Monitor' to stop monitoring Signed-off-by: Tony Lin <tony.lin@freescale.com>
-rw-r--r--drivers/misc/Kconfig5
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/mxs-perfmon.c395
-rw-r--r--drivers/misc/regs-perfmon.h189
-rw-r--r--include/linux/fsl_devices.h11
5 files changed, 601 insertions, 0 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 2ffffd42ec3c..c13aa6fe558a 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -358,6 +358,11 @@ config MXS_PERSISTENT
depends on ARCH_MXS
default y
+config MXS_PERFMON
+ tristate "i.MX Performance Monitor"
+ depends on ARCH_MX28 || ARCH_MX50
+ default y
+
config ANDROID_PMEM
bool "Android pmem allocator"
default n
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 347d953a4bd4..281eb2e73e1f 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
obj-$(CONFIG_C2PORT) += c2port/
obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/
obj-$(CONFIG_MXS_PERSISTENT) += mxs-persistent.o
+obj-$(CONFIG_MXS_PERFMON) += mxs-perfmon.o
obj-y += eeprom/
obj-y += cb710/
obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o
diff --git a/drivers/misc/mxs-perfmon.c b/drivers/misc/mxs-perfmon.c
new file mode 100644
index 000000000000..51228ec3bf89
--- /dev/null
+++ b/drivers/misc/mxs-perfmon.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sysdev.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/sysfs.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <linux/fsl_devices.h>
+#include <mach/system.h>
+#include "regs-perfmon.h"
+
+#define MONITOR "Monitor"
+
+struct mxs_perfmon_cmd_config {
+ int field;
+ int val;
+ const char *cmd;
+};
+
+static struct mxs_perfmon_cmd_config
+common_perfmon_cmd_config[] = {
+ {.val = 1, .cmd = "start", .field = BM_PERFMON_CTRL_RUN },
+ {.val = 0, .cmd = "stop", .field = BM_PERFMON_CTRL_RUN },
+ {.val = 1, .cmd = "fetch", .field = BM_PERFMON_CTRL_SNAP },
+ {.val = 1, .cmd = "clear", .field = BM_PERFMON_CTRL_CLR },
+ {.val = 1, .cmd = "read", .field = BM_PERFMON_CTRL_READ_EN },
+ {.val = 0, .cmd = "write", .field = BM_PERFMON_CTRL_READ_EN }
+};
+
+static struct mxs_perfmon_bit_config
+common_perfmon_bit_config[] = {
+ {.reg = HW_PERFMON_CTRL, .name = MONITOR,
+ .field = ~0 },
+ {.reg = HW_PERFMON_CTRL, .name = "Trap-En",
+ .field = BM_PERFMON_CTRL_TRAP_ENABLE },
+ {.reg = HW_PERFMON_CTRL, .name = "Trap-In-Range",
+ .field = BM_PERFMON_CTRL_TRAP_IN_RANGE },
+ {.reg = HW_PERFMON_CTRL, .name = "Latency-En",
+ .field = BM_PERFMON_CTRL_LATENCY_ENABLE },
+ {.reg = HW_PERFMON_CTRL, .name = "Trap-IRQ",
+ .field = BM_PERFMON_CTRL_TRAP_IRQ },
+ {.reg = HW_PERFMON_CTRL, .name = "Latency-IRQ",
+ .field = BM_PERFMON_CTRL_LATENCY_IRQ },
+ {.reg = HW_PERFMON_TRAP_ADDR_LOW, .name = "Trap-Low",
+ .field = BM_PERFMON_TRAP_ADDR_LOW_ADDR },
+ {.reg = HW_PERFMON_TRAP_ADDR_HIGH, .name = "Trap-High",
+ .field = BM_PERFMON_TRAP_ADDR_HIGH_ADDR },
+ {.reg = HW_PERFMON_LAT_THRESHOLD, .name = "Latency-Threshold",
+ .field = BM_PERFMON_LAT_THRESHOLD_VALUE },
+ {.reg = HW_PERFMON_ACTIVE_CYCLE, .name = "Active-Cycle",
+ .field = BM_PERFMON_ACTIVE_CYCLE_COUNT },
+ {.reg = HW_PERFMON_TRANSFER_COUNT, .name = "Transfer-count",
+ .field = BM_PERFMON_TRANSFER_COUNT_VALUE },
+ {.reg = HW_PERFMON_TOTAL_LATENCY, .name = "Latency-count",
+ .field = BM_PERFMON_TOTAL_LATENCY_COUNT },
+ {.reg = HW_PERFMON_DATA_COUNT, .name = "Data-count",
+ .field = BM_PERFMON_DATA_COUNT_COUNT },
+ {.reg = HW_PERFMON_MAX_LATENCY, .name = "ABurst",
+ .field = BM_PERFMON_MAX_LATENCY_ABURST },
+ {.reg = HW_PERFMON_MAX_LATENCY, .name = "ALen",
+ .field = BM_PERFMON_MAX_LATENCY_ALEN },
+ {.reg = HW_PERFMON_MAX_LATENCY, .name = "ASize",
+ .field = BM_PERFMON_MAX_LATENCY_ASIZE },
+ {.reg = HW_PERFMON_MAX_LATENCY, .name = "TAGID",
+ .field = BM_PERFMON_MAX_LATENCY_TAGID },
+ {.reg = HW_PERFMON_MAX_LATENCY, .name = "Max-Count",
+ .field = BM_PERFMON_MAX_LATENCY_COUNT }
+};
+
+static struct mxs_platform_perfmon_data common_perfmon_data = {
+ .bit_config_tab = common_perfmon_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(common_perfmon_bit_config),
+};
+
+struct mxs_perfmon_data {
+ struct device *dev;
+ struct mxs_platform_perfmon_data *pdata;
+ struct mxs_platform_perfmon_data *pdata_common;
+ int count;
+ struct attribute_group attr_group;
+ unsigned int base;
+ unsigned int initial;
+ /* attribute ** follow */
+ /* device_attribute follow */
+};
+
+#define pd_attribute_ptr(x) \
+ ((struct attribute **)((x) + 1))
+#define pd_device_attribute_ptr(x) \
+ ((struct device_attribute *)(pd_attribute_ptr(x) + (x)->count + 1))
+
+static inline u32 perfmon_reg_read(struct mxs_perfmon_data *pdata,
+ int reg)
+{
+ return __raw_readl(pdata->base + reg);
+}
+
+static inline void perfmon_reg_write(struct mxs_perfmon_data *pdata,
+ u32 val, int reg)
+{
+ __raw_writel(val, pdata->base + reg);
+}
+
+static int get_offset_form_field(int field)
+{
+ int offset = 0;
+
+ if (!field)
+ return offset;
+
+ while (!(field & 0x1)) {
+ field >>= 1;
+ offset++;
+ }
+
+ return offset;
+}
+
+static ssize_t
+perfmon_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mxs_perfmon_data *pd = platform_get_drvdata(pdev);
+ struct device_attribute *devattr = pd_device_attribute_ptr(pd);
+ struct mxs_perfmon_bit_config *pb;
+ int idx;
+ u32 val;
+ ssize_t result = 0;
+
+ idx = attr - devattr;
+ if ((unsigned int)idx >= pd->count)
+ return -EINVAL;
+
+ if (idx < pd->pdata->bit_config_cnt) {
+ pb = &pd->pdata->bit_config_tab[idx];
+ pb->reg = HW_PERFMON_MASTER_EN;
+ } else
+ pb = &pd->pdata_common->bit_config_tab \
+ [idx - pd->pdata->bit_config_cnt];
+
+ if (!pd->initial) {
+ mxs_reset_block((void *)pd->base, true);
+ pd->initial = true;
+ }
+
+ if (!memcmp(pb->name, MONITOR, sizeof(MONITOR))) {
+ /* cat monitor command, we return monitor status */
+ val = perfmon_reg_read(pd, pb->reg);
+
+ if (val & BV_PERFMON_CTRL_RUN__RUN)
+ result += sprintf(buf, "Run mode\r\n");
+ else
+ result += sprintf(buf, "Stop mode\r\n");
+
+ if (val & BM_PERFMON_CTRL_READ_EN)
+ result += \
+ sprintf(buf + result, "PM Read Activities\r\n");
+ else
+ result += \
+ sprintf(buf + result, "PM Write Activities\r\n");
+
+ return result;
+ }
+
+ /* read value and shift */
+ val = perfmon_reg_read(pd, pb->reg);
+ val &= pb->field;
+ val >>= get_offset_form_field(pb->field);
+
+ return sprintf(buf, "0x%x\n", val);
+}
+
+static ssize_t
+perfmon_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mxs_perfmon_data *pd = platform_get_drvdata(pdev);
+ struct device_attribute *devattr = pd_device_attribute_ptr(pd);
+ struct mxs_perfmon_bit_config *pb;
+ int idx, r;
+ unsigned long val, newval;
+
+ idx = attr - devattr;
+ if ((unsigned int)idx >= pd->count)
+ return -EINVAL;
+
+ if (!buf)
+ return -EINVAL;
+
+ if (idx < pd->pdata->bit_config_cnt) {
+ pb = &pd->pdata->bit_config_tab[idx];
+ pb->reg = HW_PERFMON_MASTER_EN;
+ } else
+ pb = &pd->pdata_common->bit_config_tab \
+ [idx - pd->pdata->bit_config_cnt];
+
+ if (!pd->initial) {
+ mxs_reset_block((void *)pd->base, true);
+ pd->initial = true;
+ }
+
+ if (!memcmp(pb->name, MONITOR, sizeof(MONITOR))) {
+ /* it's a cmd */
+ int scan, size;
+ const struct mxs_perfmon_cmd_config *pcfg;
+
+ size = ARRAY_SIZE(common_perfmon_cmd_config);
+ for (scan = 0; scan < size; scan++) {
+ pcfg = &common_perfmon_cmd_config[scan];
+ if (!memcmp(buf, pcfg->cmd, strlen(pcfg->cmd))) {
+ val = perfmon_reg_read(pd, HW_PERFMON_CTRL);
+ val &= ~pcfg->field;
+ val |= \
+ pcfg->val << get_offset_form_field(pcfg->field);
+ perfmon_reg_write(pd, val, HW_PERFMON_CTRL);
+
+ return count;
+ }
+ }
+ if (scan == ARRAY_SIZE(common_perfmon_cmd_config))
+ return -EINVAL;
+ }
+ /* get value to write */
+ if (buf && (count >= 2) && buf[0] == '0' && buf[1] == 'x')
+ r = strict_strtoul(buf, 16, &val);
+ else
+ r = strict_strtoul(buf, 10, &val);
+
+ if (r != 0)
+ return r;
+
+ /* verify it fits */
+ if ((unsigned int)val > (pb->field >> get_offset_form_field(pb->field)))
+ return -EINVAL;
+
+ newval = perfmon_reg_read(pd, pb->reg);
+ newval &= ~pb->field;
+ newval |= val << get_offset_form_field(pb->field);
+ perfmon_reg_write(pd, newval, pb->reg);
+
+ return count;
+}
+
+
+static int __devinit mxs_perfmon_probe(struct platform_device *pdev)
+{
+ struct mxs_perfmon_data *pd;
+ struct mxs_platform_perfmon_data *pdata;
+ struct mxs_platform_perfmon_data *pdata_common;
+ struct resource *res;
+ struct mxs_perfmon_bit_config *pb;
+ struct attribute **attr;
+ struct device_attribute *devattr;
+ int i, cnt, size;
+ int err;
+
+ pdata = pdev->dev.platform_data;
+ if (pdata == NULL)
+ return -ENODEV;
+
+ pdata_common = &common_perfmon_data;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL)
+ return -ENODEV;
+
+ cnt = pdata->bit_config_cnt + pdata_common->bit_config_cnt;
+ size = sizeof(*pd) +
+ (cnt + 1) * sizeof(struct atrribute *) +
+ cnt * sizeof(struct device_attribute);
+ pd = kzalloc(size, GFP_KERNEL);
+ if (pd == NULL)
+ return -ENOMEM;
+ pd->dev = &pdev->dev;
+ pd->pdata = pdata;
+ pd->pdata_common = pdata_common;
+ pd->base = (unsigned int)ioremap(res->start, res->end - res->start);
+ pd->initial = false;
+
+ platform_set_drvdata(pdev, pd);
+ pd->count = cnt;
+ attr = pd_attribute_ptr(pd);
+ devattr = pd_device_attribute_ptr(pd);
+
+ /* build the attributes structures */
+ pd->attr_group.attrs = attr;
+ pb = pdata->bit_config_tab;
+ for (i = 0; i < pdata->bit_config_cnt; i++) {
+ devattr[i].attr.name = pb[i].name;
+ devattr[i].attr.mode = S_IWUSR | S_IRUGO;
+ devattr[i].show = perfmon_show;
+ devattr[i].store = perfmon_store;
+ attr[i] = &devattr[i].attr;
+ }
+ pb = pdata_common->bit_config_tab;
+ for (i = 0; i < pdata_common->bit_config_cnt; i++) {
+ devattr[i + pdata->bit_config_cnt].attr.name = pb[i].name;
+ devattr[i + pdata->bit_config_cnt].attr.mode = \
+ S_IWUSR | S_IRUGO;
+ devattr[i + pdata->bit_config_cnt].show = perfmon_show;
+ devattr[i + pdata->bit_config_cnt].store = perfmon_store;
+ attr[i + pdata->bit_config_cnt] = \
+ &devattr[i + pdata->bit_config_cnt].attr;
+ }
+
+ err = sysfs_create_group(&pdev->dev.kobj, &pd->attr_group);
+ if (err != 0) {
+ platform_set_drvdata(pdev, NULL);
+ kfree(pd);
+ return err;
+ }
+
+ return 0;
+}
+
+static int __devexit mxs_perfmon_remove(struct platform_device *pdev)
+{
+ struct mxs_perfmon_data *pd;
+
+ pd = platform_get_drvdata(pdev);
+ sysfs_remove_group(&pdev->dev.kobj, &pd->attr_group);
+ platform_set_drvdata(pdev, NULL);
+ kfree(pd);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int
+mxs_perfmon_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ return 0;
+}
+
+static int mxs_perfmon_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+#else
+#define mxs_perfmon_suspend NULL
+#define mxs_perfmon_resume NULL
+#endif
+
+static struct platform_driver mxs_perfmon_driver = {
+ .probe = mxs_perfmon_probe,
+ .remove = __exit_p(mxs_perfmon_remove),
+ .suspend = mxs_perfmon_suspend,
+ .resume = mxs_perfmon_resume,
+ .driver = {
+ .name = "mxs-perfmon",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mxs_perfmon_init(void)
+{
+ return platform_driver_register(&mxs_perfmon_driver);
+}
+
+static void __exit mxs_perfmon_exit(void)
+{
+ platform_driver_unregister(&mxs_perfmon_driver);
+}
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Performance Monitor user-access driver");
+MODULE_LICENSE("GPL");
+
+module_init(mxs_perfmon_init);
+module_exit(mxs_perfmon_exit);
diff --git a/drivers/misc/regs-perfmon.h b/drivers/misc/regs-perfmon.h
new file mode 100644
index 000000000000..2f12885b3baf
--- /dev/null
+++ b/drivers/misc/regs-perfmon.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.36
+ * Template revision: 26195
+ */
+
+#ifndef __ARCH_ARM___PERFMON_H
+#define __ARCH_ARM___PERFMON_H
+
+
+#define HW_PERFMON_CTRL (0x00000000)
+#define HW_PERFMON_CTRL_SET (0x00000004)
+#define HW_PERFMON_CTRL_CLR (0x00000008)
+#define HW_PERFMON_CTRL_TOG (0x0000000c)
+
+#define BM_PERFMON_CTRL_SFTRST 0x80000000
+#define BV_PERFMON_CTRL_SFTRST__RUN 0x0
+#define BV_PERFMON_CTRL_SFTRST__RESET 0x1
+#define BM_PERFMON_CTRL_CLKGATE 0x40000000
+#define BV_PERFMON_CTRL_CLKGATE__RUN 0x0
+#define BV_PERFMON_CTRL_CLKGATE__NO_CLKS 0x1
+#define BP_PERFMON_CTRL_RSVD2 24
+#define BM_PERFMON_CTRL_RSVD2 0x3F000000
+#define BF_PERFMON_CTRL_RSVD2(v) \
+ (((v) << 24) & BM_PERFMON_CTRL_RSVD2)
+#define BP_PERFMON_CTRL_IRQ_MID 16
+#define BM_PERFMON_CTRL_IRQ_MID 0x00FF0000
+#define BF_PERFMON_CTRL_IRQ_MID(v) \
+ (((v) << 16) & BM_PERFMON_CTRL_IRQ_MID)
+#define BP_PERFMON_CTRL_RSVD1 13
+#define BM_PERFMON_CTRL_RSVD1 0x0000E000
+#define BF_PERFMON_CTRL_RSVD1(v) \
+ (((v) << 13) & BM_PERFMON_CTRL_RSVD1)
+#define BM_PERFMON_CTRL_BUS_ERR_IRQ 0x00001000
+#define BM_PERFMON_CTRL_LATENCY_IRQ 0x00000800
+#define BM_PERFMON_CTRL_TRAP_IRQ 0x00000400
+#define BM_PERFMON_CTRL_BUS_ERR_IRQ_EN 0x00000200
+#define BM_PERFMON_CTRL_LATENCY_IRQ_EN 0x00000100
+#define BM_PERFMON_CTRL_TRAP_IRQ_EN 0x00000080
+#define BM_PERFMON_CTRL_LATENCY_ENABLE 0x00000040
+#define BM_PERFMON_CTRL_TRAP_IN_RANGE 0x00000020
+#define BM_PERFMON_CTRL_TRAP_ENABLE 0x00000010
+#define BM_PERFMON_CTRL_READ_EN 0x00000008
+#define BM_PERFMON_CTRL_CLR 0x00000004
+#define BM_PERFMON_CTRL_SNAP 0x00000002
+#define BM_PERFMON_CTRL_RUN 0x00000001
+#define BV_PERFMON_CTRL_RUN__HALT 0x0
+#define BV_PERFMON_CTRL_RUN__RUN 0x1
+
+#define HW_PERFMON_MASTER_EN (0x00000010)
+
+#define BP_PERFMON_MASTER_EN_RSVD0 16
+#define BM_PERFMON_MASTER_EN_RSVD0 0xFFFF0000
+#define BF_PERFMON_MASTER_EN_RSVD0(v) \
+ (((v) << 16) & BM_PERFMON_MASTER_EN_RSVD0)
+#define BM_PERFMON_MASTER_EN_MID15 0x00008000
+#define BM_PERFMON_MASTER_EN_MID14 0x00004000
+#define BM_PERFMON_MASTER_EN_MID13 0x00002000
+#define BM_PERFMON_MASTER_EN_MID12 0x00001000
+#define BM_PERFMON_MASTER_EN_MID11 0x00000800
+#define BM_PERFMON_MASTER_EN_MID10 0x00000400
+#define BM_PERFMON_MASTER_EN_MID9 0x00000200
+#define BM_PERFMON_MASTER_EN_MID8 0x00000100
+#define BM_PERFMON_MASTER_EN_MID7 0x00000080
+#define BM_PERFMON_MASTER_EN_MID6 0x00000040
+#define BM_PERFMON_MASTER_EN_MID5 0x00000020
+#define BM_PERFMON_MASTER_EN_MID4 0x00000010
+#define BM_PERFMON_MASTER_EN_MID3 0x00000008
+#define BM_PERFMON_MASTER_EN_MID2 0x00000004
+#define BM_PERFMON_MASTER_EN_MID1 0x00000002
+#define BM_PERFMON_MASTER_EN_MID0 0x00000001
+
+#define HW_PERFMON_TRAP_ADDR_LOW (0x00000020)
+
+#define BP_PERFMON_TRAP_ADDR_LOW_ADDR 0
+#define BM_PERFMON_TRAP_ADDR_LOW_ADDR 0xFFFFFFFF
+#define BF_PERFMON_TRAP_ADDR_LOW_ADDR(v) (v)
+
+#define HW_PERFMON_TRAP_ADDR_HIGH (0x00000030)
+
+#define BP_PERFMON_TRAP_ADDR_HIGH_ADDR 0
+#define BM_PERFMON_TRAP_ADDR_HIGH_ADDR 0xFFFFFFFF
+#define BF_PERFMON_TRAP_ADDR_HIGH_ADDR(v) (v)
+
+#define HW_PERFMON_LAT_THRESHOLD (0x00000040)
+
+#define BP_PERFMON_LAT_THRESHOLD_RSVD0 12
+#define BM_PERFMON_LAT_THRESHOLD_RSVD0 0xFFFFF000
+#define BF_PERFMON_LAT_THRESHOLD_RSVD0(v) \
+ (((v) << 12) & BM_PERFMON_LAT_THRESHOLD_RSVD0)
+#define BP_PERFMON_LAT_THRESHOLD_VALUE 0
+#define BM_PERFMON_LAT_THRESHOLD_VALUE 0x00000FFF
+#define BF_PERFMON_LAT_THRESHOLD_VALUE(v) \
+ (((v) << 0) & BM_PERFMON_LAT_THRESHOLD_VALUE)
+
+#define HW_PERFMON_ACTIVE_CYCLE (0x00000050)
+
+#define BP_PERFMON_ACTIVE_CYCLE_COUNT 0
+#define BM_PERFMON_ACTIVE_CYCLE_COUNT 0xFFFFFFFF
+#define BF_PERFMON_ACTIVE_CYCLE_COUNT(v) (v)
+
+#define HW_PERFMON_TRANSFER_COUNT (0x00000060)
+
+#define BP_PERFMON_TRANSFER_COUNT_VALUE 0
+#define BM_PERFMON_TRANSFER_COUNT_VALUE 0xFFFFFFFF
+#define BF_PERFMON_TRANSFER_COUNT_VALUE(v) (v)
+
+#define HW_PERFMON_TOTAL_LATENCY (0x00000070)
+
+#define BP_PERFMON_TOTAL_LATENCY_COUNT 0
+#define BM_PERFMON_TOTAL_LATENCY_COUNT 0xFFFFFFFF
+#define BF_PERFMON_TOTAL_LATENCY_COUNT(v) (v)
+
+#define HW_PERFMON_DATA_COUNT (0x00000080)
+
+#define BP_PERFMON_DATA_COUNT_COUNT 0
+#define BM_PERFMON_DATA_COUNT_COUNT 0xFFFFFFFF
+#define BF_PERFMON_DATA_COUNT_COUNT(v) (v)
+
+#define HW_PERFMON_MAX_LATENCY (0x00000090)
+
+#define BP_PERFMON_MAX_LATENCY_ABURST 30
+#define BM_PERFMON_MAX_LATENCY_ABURST 0xC0000000
+#define BF_PERFMON_MAX_LATENCY_ABURST(v) \
+ (((v) << 30) & BM_PERFMON_MAX_LATENCY_ABURST)
+#define BP_PERFMON_MAX_LATENCY_ALEN 26
+#define BM_PERFMON_MAX_LATENCY_ALEN 0x3C000000
+#define BF_PERFMON_MAX_LATENCY_ALEN(v) \
+ (((v) << 26) & BM_PERFMON_MAX_LATENCY_ALEN)
+#define BP_PERFMON_MAX_LATENCY_ASIZE 23
+#define BM_PERFMON_MAX_LATENCY_ASIZE 0x03800000
+#define BF_PERFMON_MAX_LATENCY_ASIZE(v) \
+ (((v) << 23) & BM_PERFMON_MAX_LATENCY_ASIZE)
+#define BP_PERFMON_MAX_LATENCY_TAGID 15
+#define BM_PERFMON_MAX_LATENCY_TAGID 0x007F8000
+#define BF_PERFMON_MAX_LATENCY_TAGID(v) \
+ (((v) << 15) & BM_PERFMON_MAX_LATENCY_TAGID)
+#define BP_PERFMON_MAX_LATENCY_RSVD0 12
+#define BM_PERFMON_MAX_LATENCY_RSVD0 0x00007000
+#define BF_PERFMON_MAX_LATENCY_RSVD0(v) \
+ (((v) << 12) & BM_PERFMON_MAX_LATENCY_RSVD0)
+#define BP_PERFMON_MAX_LATENCY_COUNT 0
+#define BM_PERFMON_MAX_LATENCY_COUNT 0x00000FFF
+#define BF_PERFMON_MAX_LATENCY_COUNT(v) \
+ (((v) << 0) & BM_PERFMON_MAX_LATENCY_COUNT)
+
+#define HW_PERFMON_DEBUG (0x000000a0)
+
+#define BP_PERFMON_DEBUG_RSVD 2
+#define BM_PERFMON_DEBUG_RSVD 0xFFFFFFFC
+#define BF_PERFMON_DEBUG_RSVD(v) \
+ (((v) << 2) & BM_PERFMON_DEBUG_RSVD)
+#define BM_PERFMON_DEBUG_TOTAL_CYCLE_CLR_EN 0x00000002
+#define BM_PERFMON_DEBUG_ERR_MID 0x00000001
+
+#define HW_PERFMON_VERSION (0x000000b0)
+
+#define BP_PERFMON_VERSION_MAJOR 24
+#define BM_PERFMON_VERSION_MAJOR 0xFF000000
+#define BF_PERFMON_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_PERFMON_VERSION_MAJOR)
+#define BP_PERFMON_VERSION_MINOR 16
+#define BM_PERFMON_VERSION_MINOR 0x00FF0000
+#define BF_PERFMON_VERSION_MINOR(v) \
+ (((v) << 16) & BM_PERFMON_VERSION_MINOR)
+#define BP_PERFMON_VERSION_STEP 0
+#define BM_PERFMON_VERSION_STEP 0x0000FFFF
+#define BF_PERFMON_VERSION_STEP(v) \
+ (((v) << 0) & BM_PERFMON_VERSION_STEP)
+#endif /* __ARCH_ARM___PERFMON_H */
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 91d4d427d727..0e6e744f828c 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -630,4 +630,15 @@ int fsl_deep_sleep(void);
static inline int fsl_deep_sleep(void) { return 0; }
#endif
+struct mxs_perfmon_bit_config {
+ int reg;
+ int field;
+ const char *name;
+};
+
+struct mxs_platform_perfmon_data {
+ struct mxs_perfmon_bit_config *bit_config_tab;
+ int bit_config_cnt;
+};
+
#endif /* _FSL_DEVICE_H_ */