esoc: mdm-4x: Add coresight support for external modem.
Allow modem debugging using CTI pulses. Change-Id: I092f4e8728aceb1fcb6712425ca930d8bc3fa14b Signed-off-by: Hanumant Singh <hanumant@codeaurora.org>
This commit is contained in:
parent
5830ea788f
commit
658e9de055
|
@ -10,10 +10,13 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/coresight.h>
|
||||
#include <linux/coresight-cti.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -38,6 +41,11 @@
|
|||
#define RD_BUF_SIZE 100
|
||||
#define SFR_MAX_RETRIES 10
|
||||
#define SFR_RETRY_INTERVAL 1000
|
||||
#define MDM_DBG_OFFSET 0x934
|
||||
#define MDM_DBG_MODE 0x53444247
|
||||
#define MDM_CTI_NAME "coresight-cti-rpm-cpu0"
|
||||
#define MDM_CTI_TRIG 0
|
||||
#define MDM_CTI_CH 0
|
||||
|
||||
enum mdm_gpio {
|
||||
AP2MDM_WAKEUP = 0,
|
||||
|
@ -96,6 +104,10 @@ struct mdm_ctrl {
|
|||
bool ready;
|
||||
bool dual_interface;
|
||||
u32 status;
|
||||
void __iomem *dbg_addr;
|
||||
bool dbg_mode;
|
||||
struct coresight_cti *cti;
|
||||
int trig_cnt;
|
||||
};
|
||||
|
||||
struct mdm_ops {
|
||||
|
@ -242,6 +254,18 @@ static void mdm_update_gpio_configs(struct mdm_ctrl *mdm,
|
|||
}
|
||||
}
|
||||
|
||||
static void mdm_trigger_dbg(struct mdm_ctrl *mdm)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (mdm->dbg_mode && !mdm->trig_cnt) {
|
||||
ret = coresight_cti_pulse_trig(mdm->cti, MDM_CTI_CH);
|
||||
mdm->trig_cnt++;
|
||||
if (ret)
|
||||
dev_err(mdm->dev, "unable to trigger cti pulse on\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* This function can be called from atomic context. */
|
||||
static void mdm_toggle_soft_reset(struct mdm_ctrl *mdm)
|
||||
{
|
||||
|
@ -321,6 +345,7 @@ static int mdm_cmd_exe(enum esoc_cmd cmd, struct esoc_clink *esoc)
|
|||
mdm_disable_irqs(mdm);
|
||||
mdm->debug = 0;
|
||||
mdm->ready = false;
|
||||
mdm->trig_cnt = 0;
|
||||
ret = sysmon_send_shutdown(mdm->sysmon_subsys_id);
|
||||
if (ret)
|
||||
dev_err(mdm->dev, "Graceful shutdown fail, ret = %d\n",
|
||||
|
@ -367,6 +392,7 @@ shutdown_cleanup:
|
|||
break;
|
||||
case ESOC_EXE_DEBUG:
|
||||
mdm->debug = 1;
|
||||
mdm->trig_cnt = 0;
|
||||
mdm_toggle_soft_reset(mdm);
|
||||
/*
|
||||
* wait for ramdumps to be collected
|
||||
|
@ -549,6 +575,7 @@ static irqreturn_t mdm_status_change(int irq, void *dev_id)
|
|||
cancel_delayed_work(&mdm->mdm2ap_status_check_work);
|
||||
dev_dbg(dev, "status = 1: mdm is now ready\n");
|
||||
mdm->ready = true;
|
||||
mdm_trigger_dbg(mdm);
|
||||
queue_work(mdm->mdm_queue, &mdm->mdm_status_work);
|
||||
if (mdm->get_restart_reason)
|
||||
queue_work(mdm->mdm_queue, &mdm->restart_reason_work);
|
||||
|
@ -571,6 +598,7 @@ static irqreturn_t mdm_pblrdy_change(int irq, void *dev_id)
|
|||
gpio_get_value(MDM_GPIO(mdm, MDM2AP_PBLRDY)));
|
||||
if (mdm->init) {
|
||||
mdm->init = 0;
|
||||
mdm_trigger_dbg(mdm);
|
||||
esoc_clink_queue_request(ESOC_REQ_IMG, esoc);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -590,6 +618,46 @@ static int mdm_get_status(u32 *status, struct esoc_clink *esoc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mdm_configure_debug(struct mdm_ctrl *mdm)
|
||||
{
|
||||
void __iomem *addr;
|
||||
unsigned val;
|
||||
int ret;
|
||||
struct device_node *node = mdm->dev->of_node;
|
||||
|
||||
addr = of_iomap(node, 0);
|
||||
if (IS_ERR(addr)) {
|
||||
dev_err(mdm->dev, "failed to get debug base addres\n");
|
||||
return;
|
||||
}
|
||||
mdm->dbg_addr = addr + MDM_DBG_OFFSET;
|
||||
val = readl_relaxed(mdm->dbg_addr);
|
||||
if (val == MDM_DBG_MODE) {
|
||||
mdm->dbg_mode = true;
|
||||
mdm->cti = coresight_cti_get(MDM_CTI_NAME);
|
||||
if (IS_ERR(mdm->cti)) {
|
||||
dev_err(mdm->dev, "unable to get cti handle\n");
|
||||
goto cti_get_err;
|
||||
}
|
||||
ret = coresight_cti_map_trigout(mdm->cti, MDM_CTI_TRIG,
|
||||
MDM_CTI_CH);
|
||||
if (ret) {
|
||||
dev_err(mdm->dev, "unable to map trig to channel\n");
|
||||
goto cti_map_err;
|
||||
}
|
||||
mdm->trig_cnt = 0;
|
||||
} else {
|
||||
dev_dbg(mdm->dev, "Not in debug mode. debug mode = %u\n", val);
|
||||
mdm->dbg_mode = false;
|
||||
}
|
||||
return;
|
||||
cti_map_err:
|
||||
coresight_cti_put(mdm->cti);
|
||||
cti_get_err:
|
||||
mdm->dbg_mode = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fail if any of the required gpios is absent. */
|
||||
static int mdm_dt_parse_gpios(struct mdm_ctrl *mdm)
|
||||
{
|
||||
|
@ -786,6 +854,7 @@ static int mdm9x25_setup_hw(struct mdm_ctrl *mdm,
|
|||
ret = mdm_configure_ipc(mdm, pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
mdm_configure_debug(mdm);
|
||||
dev_err(mdm->dev, "ipc configure done\n");
|
||||
esoc->name = MDM9x25_LABEL;
|
||||
esoc->link_name = MDM9x25_HSIC;
|
||||
|
@ -839,6 +908,7 @@ static int mdm9x35_setup_hw(struct mdm_ctrl *mdm,
|
|||
ret = mdm_configure_ipc(mdm, pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
mdm_configure_debug(mdm);
|
||||
dev_dbg(mdm->dev, "ipc configure done\n");
|
||||
esoc->name = MDM9x35_LABEL;
|
||||
mdm->dual_interface = of_property_read_bool(node,
|
||||
|
|
Loading…
Reference in New Issue