coresight: add coresight fuse driver

Add support for CoreSight Fuse driver which can be used by other
CoreSight drivers to query the state of the CoreSight fuses to
determine if the Hardware they manage is functionally disabled or
not.

Drivers can then take necessary actions like failing the probe if
the Hardware they manage is functionally disabled.

Change-Id: I2c2a2af064db750539b0ffa33870ddb7a2832e68
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
This commit is contained in:
Pratik Patel 2013-06-13 23:21:40 -07:00 committed by Carter Cooper
parent 3c2d525dfc
commit 9266be3791
5 changed files with 234 additions and 0 deletions

View File

@ -21,6 +21,7 @@ Required properties:
"qcom,coresight-csr" for coresight csr device,
"arm,coresight-cti" for coresight cti devices,
"qcom,coresight-hwevent" for coresight hardware event devices
"arm,coresight-fuse" for coresight fuse device,
- reg : physical base address and length of the register set(s) of the component
- reg-names : names corresponding to each reg property value. The reg-names that
need to be used with corresponding compatible string for a coresight device
@ -68,6 +69,10 @@ Required properties:
"<ss-mux>" - physical base address of hardware event mux
control registers where <ss-mux> is subsystem mux it
represents
- for coresight fuse device:
compatible : should be "arm,coresight-fuse"
reg-names : should be:
"fuse-base" - physical base address of fuse registers
- coresight-id : unique integer identifier for the component
- coresight-name : unique descriptive name of the component
- coresight-nr-inports : number of input ports on the component
@ -236,3 +241,13 @@ Examples:
qcom,hwevent-clks = "core_mmss_clk";
};
fuse: fuse@fc4be024 {
compatible = "arm,coresight-fuse";
reg = <0xfc4be024 0x8>;
reg-names = "fuse-base";
coresight-id = <30>;
coresight-name = "coresight-fuse";
coresight-nr-inports = <0>;
};

View File

@ -24,6 +24,15 @@ if CORESIGHT
config HAVE_CORESIGHT_SINK
bool
config CORESIGHT_FUSE
bool "CoreSight Fuse driver"
help
This driver provides support for CoreSight Fuse state checks that
other CoreSight drivers can query to determine existence of
Hardware functionality they support. Drivers can then take necessary
actions like failing the probe if the Hardware they manage is
functionally disabled.
config CORESIGHT_CTI
bool "CoreSight Cross Trigger Interface driver"
help

View File

@ -2,6 +2,7 @@
# Makefile for CoreSight drivers.
#
obj-$(CONFIG_CORESIGHT) += coresight.o
obj-$(CONFIG_CORESIGHT_FUSE) += coresight-fuse.o
obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
obj-$(CONFIG_CORESIGHT_CSR) += coresight-csr.o
obj-$(CONFIG_CORESIGHT_TMC) += coresight-tmc.o

View File

@ -0,0 +1,202 @@
/* Copyright (c) 2013, The Linux Foundation. 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 version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_coresight.h>
#include <linux/coresight.h>
#include "coresight-priv.h"
#define fuse_writel(drvdata, val, off) __raw_writel((val), drvdata->base + off)
#define fuse_readl(drvdata, off) __raw_readl(drvdata->base + off)
#define OEM_CONFIG0 (0x000)
#define OEM_CONFIG1 (0x004)
#define ALL_DEBUG_DISABLE BIT(21)
#define APPS_DBGEN_DISABLE BIT(0)
#define APPS_NIDEN_DISABLE BIT(1)
#define APPS_SPIDEN_DISABLE BIT(2)
#define APPS_SPNIDEN_DISABLE BIT(3)
#define DAP_DBGEN_DISABLE BIT(4)
#define DAP_NIDEN_DISABLE BIT(5)
#define DAP_SPIDEN_DISABLE BIT(6)
#define DAP_SPNIDEN_DISABLE BIT(7)
#define DAP_DEVICEEN_DISABLE BIT(8)
struct fuse_drvdata {
void __iomem *base;
struct device *dev;
struct coresight_device *csdev;
};
static struct fuse_drvdata *fusedrvdata;
bool coresight_fuse_access_disabled(void)
{
struct fuse_drvdata *drvdata = fusedrvdata;
uint32_t config0, config1;
bool ret;
config0 = fuse_readl(drvdata, OEM_CONFIG0);
config1 = fuse_readl(drvdata, OEM_CONFIG1);
dev_dbg(drvdata->dev, "config0: %lx\n", (unsigned long)config0);
dev_dbg(drvdata->dev, "config1: %lx\n", (unsigned long)config1);
if (config0 & ALL_DEBUG_DISABLE)
ret = true;
else if (config1 & DAP_DBGEN_DISABLE)
ret = true;
else if (config1 & DAP_NIDEN_DISABLE)
ret = true;
else if (config1 & DAP_SPIDEN_DISABLE)
ret = true;
else if (config1 & DAP_SPNIDEN_DISABLE)
ret = true;
else if (config1 & DAP_DEVICEEN_DISABLE)
ret = true;
else
ret = false;
if (ret)
dev_dbg(drvdata->dev, "coresight fuse disabled\n");
return ret;
}
EXPORT_SYMBOL(coresight_fuse_access_disabled);
bool coresight_fuse_apps_access_disabled(void)
{
struct fuse_drvdata *drvdata = fusedrvdata;
uint32_t config0, config1;
bool ret;
config0 = fuse_readl(drvdata, OEM_CONFIG0);
config1 = fuse_readl(drvdata, OEM_CONFIG1);
dev_dbg(drvdata->dev, "apps config0: %lx\n", (unsigned long)config0);
dev_dbg(drvdata->dev, "apps config1: %lx\n", (unsigned long)config1);
if (config0 & ALL_DEBUG_DISABLE)
ret = true;
else if (config1 & APPS_DBGEN_DISABLE)
ret = true;
else if (config1 & APPS_NIDEN_DISABLE)
ret = true;
else if (config1 & APPS_SPIDEN_DISABLE)
ret = true;
else if (config1 & APPS_SPNIDEN_DISABLE)
ret = true;
else if (config1 & DAP_DEVICEEN_DISABLE)
ret = true;
else
ret = false;
if (ret)
dev_dbg(drvdata->dev, "apps fuse disabled\n");
return ret;
}
EXPORT_SYMBOL(coresight_fuse_apps_access_disabled);
static int __devinit fuse_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct coresight_platform_data *pdata;
struct fuse_drvdata *drvdata;
struct resource *res;
struct coresight_desc *desc;
if (pdev->dev.of_node) {
pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
pdev->dev.platform_data = pdata;
}
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
/* Store the driver data pointer for use in exported functions */
fusedrvdata = drvdata;
drvdata->dev = &pdev->dev;
platform_set_drvdata(pdev, drvdata);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fuse-base");
if (!res)
return -ENODEV;
drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
if (!drvdata->base)
return -ENOMEM;
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
if (!desc)
return -ENOMEM;
desc->type = CORESIGHT_DEV_TYPE_NONE;
desc->pdata = pdev->dev.platform_data;
desc->dev = &pdev->dev;
desc->owner = THIS_MODULE;
drvdata->csdev = coresight_register(desc);
if (IS_ERR(drvdata->csdev))
return PTR_ERR(drvdata->csdev);
dev_info(dev, "Fuse initialized\n");
return 0;
}
static int __devexit fuse_remove(struct platform_device *pdev)
{
struct fuse_drvdata *drvdata = platform_get_drvdata(pdev);
coresight_unregister(drvdata->csdev);
return 0;
}
static struct of_device_id fuse_match[] = {
{.compatible = "arm,coresight-fuse"},
{}
};
static struct platform_driver fuse_driver = {
.probe = fuse_probe,
.remove = __devexit_p(fuse_remove),
.driver = {
.name = "coresight-fuse",
.owner = THIS_MODULE,
.of_match_table = fuse_match,
},
};
static int __init fuse_init(void)
{
return platform_driver_register(&fuse_driver);
}
module_init(fuse_init);
static void __exit fuse_exit(void)
{
platform_driver_unregister(&fuse_driver);
}
module_exit(fuse_exit);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("CoreSight Fuse driver");

View File

@ -36,6 +36,13 @@
#define BMVAL(val, lsb, msb) ((val & BM(lsb, msb)) >> lsb)
#define BVAL(val, n) ((val & BIT(n)) >> n)
#ifdef CONFIG_CORESIGHT_FUSE
extern bool coresight_fuse_access_disabled(void);
extern bool coresight_fuse_apps_access_disabled(void);
#else
static inline bool coresight_fuse_access_disabled(void) { return false; }
static inline bool coresight_fuse_apps_access_disabled(void) { return false; }
#endif
#ifdef CONFIG_CORESIGHT_CSR
extern void msm_qdss_csr_enable_bam_to_usb(void);
extern void msm_qdss_csr_disable_bam_to_usb(void);