Loading drivers/esoc/esoc-mdm-4x.c +70 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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, Loading Loading @@ -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 { Loading Loading @@ -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) { Loading Loading @@ -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", Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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 Loading
drivers/esoc/esoc-mdm-4x.c +70 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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, Loading Loading @@ -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 { Loading Loading @@ -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) { Loading Loading @@ -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", Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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