From b2e3b21407074603963c4dc1c860f1abaefd66c7 Mon Sep 17 00:00:00 2001 From: Gopala Krishna Nuthaki Date: Mon, 21 Sep 2020 14:33:47 +0530 Subject: [PATCH 1/2] drivers: thermal: call TSENS re-init only when register is ready to update If TSENS controller reset pin is held asserted for long duration and the same time if TSENS software detects TSENS reset and tries to re-initialize TSENS controller, TSENS initialization may not reflect in TSENS register due to reset pin is held asserted. Invoke TSENS re-init routine only if software is able to write TSENS register successfully. It makes sure that TSENS re-init routine is able to re-initialize TSENS controller. Add a check whether TSENS is re-enabled or not on post TSENS re-init. If it is not re-enabled, re-try TSENS re-init routine. Change-Id: I1b0500b4d08b28c200d6b818d91650e272be709d Signed-off-by: Gopala Krishna Nuthaki --- drivers/thermal/msm-tsens.c | 6 +- drivers/thermal/tsens2xxx.c | 212 +++++++++++++++++++++++------------- 2 files changed, 138 insertions(+), 80 deletions(-) diff --git a/drivers/thermal/msm-tsens.c b/drivers/thermal/msm-tsens.c index aa5c12d480f8..c660a05761af 100644 --- a/drivers/thermal/msm-tsens.c +++ b/drivers/thermal/msm-tsens.c @@ -271,8 +271,7 @@ static void tsens_therm_fwk_notify(struct work_struct *work) } TSENS_DBG(tmdev, "Calling trip_temp for sensor %d\n", i); - of_thermal_handle_trip_temp(tmdev->dev, - tmdev->sensor[i].tzd, temp); + of_thermal_handle_trip(tmdev->dev, tmdev->sensor[i].tzd); } } if (tmdev->zeroc_sensor_id != MIN_TEMP_DEF_OFFSET) { @@ -283,8 +282,7 @@ static void tsens_therm_fwk_notify(struct work_struct *work) return; } TSENS_DBG(tmdev, "Calling trip_temp for sensor %d\n", i); - of_thermal_handle_trip_temp(tmdev->dev, - tmdev->zeroc.tzd, temp); + of_thermal_handle_trip(tmdev->dev, tmdev->zeroc.tzd); } } diff --git a/drivers/thermal/tsens2xxx.c b/drivers/thermal/tsens2xxx.c index f2e6084a661f..10dbabfc5c64 100644 --- a/drivers/thermal/tsens2xxx.c +++ b/drivers/thermal/tsens2xxx.c @@ -65,7 +65,6 @@ #define TSENS_INIT_ID 0x5 #define TSENS_RECOVERY_LOOP_COUNT 5 -#define TSENS_RE_INIT_MAX_COUNT 5 static void msm_tsens_convert_temp(int last_temp, int *temp) { @@ -79,12 +78,70 @@ static void msm_tsens_convert_temp(int last_temp, int *temp) *temp = last_temp * TSENS_TM_SCALE_DECI_MILLIDEG; } +static int __tsens2xxx_hw_init(struct tsens_device *tmdev) +{ + void __iomem *srot_addr; + void __iomem *sensor_int_mask_addr; + unsigned int srot_val, crit_mask, crit_val; + void __iomem *int_mask_addr; + + srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4); + srot_val = readl_relaxed(srot_addr); + if (!(srot_val & TSENS_EN)) { + pr_err("TSENS device is not enabled\n"); + return -ENODEV; + } + + if (tmdev->ctrl_data->cycle_monitor) { + sensor_int_mask_addr = + TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr); + crit_mask = readl_relaxed(sensor_int_mask_addr); + crit_val = TSENS_TM_CRITICAL_CYCLE_MONITOR; + if (tmdev->ctrl_data->cycle_compltn_monitor_mask) + writel_relaxed((crit_mask | crit_val), + (TSENS_TM_CRITICAL_INT_MASK + (tmdev->tsens_tm_addr))); + else + writel_relaxed((crit_mask & ~crit_val), + (TSENS_TM_CRITICAL_INT_MASK + (tmdev->tsens_tm_addr))); + /*Update critical cycle monitoring*/ + mb(); + } + + if (tmdev->ctrl_data->wd_bark) { + sensor_int_mask_addr = + TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr); + crit_mask = readl_relaxed(sensor_int_mask_addr); + crit_val = TSENS_TM_CRITICAL_WD_BARK; + if (tmdev->ctrl_data->wd_bark_mask) + writel_relaxed((crit_mask | crit_val), + (TSENS_TM_CRITICAL_INT_MASK + (tmdev->tsens_tm_addr))); + else + writel_relaxed((crit_mask & ~crit_val), + (TSENS_TM_CRITICAL_INT_MASK + (tmdev->tsens_tm_addr))); + /*Update watchdog monitoring*/ + mb(); + } + + int_mask_addr = TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_tm_addr); + writel_relaxed(TSENS_TM_UPPER_LOWER_INT_DISABLE, int_mask_addr); + + writel_relaxed(TSENS_TM_CRITICAL_INT_EN | + TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN, + TSENS_TM_INT_EN(tmdev->tsens_tm_addr)); + + return 0; +} + static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp) { struct tsens_device *tmdev = NULL, *tmdev_itr; unsigned int code, ret; void __iomem *sensor_addr, *trdy; - int last_temp = 0, last_temp2 = 0, last_temp3 = 0, count = 0; + int rc = 0, last_temp = 0, last_temp2 = 0, last_temp3 = 0, count = 0; int tsens_ret; static atomic_t in_tsens_reinit; @@ -123,6 +180,8 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp) * proceed with SCM call to re-init it */ if (tmdev->tsens_reinit_wa) { + int scm_cnt = 0, reg_write_cnt = 0; + if (atomic_read(&in_tsens_reinit)) { pr_err("%s: tsens re-init is in progress\n", __func__); @@ -135,30 +194,79 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp) tmdev->ops->dbg(tmdev, 0, TSENS_DBG_LOG_BUS_ID_DATA, NULL); - if (tmdev->tsens_reinit_cnt >= - TSENS_RE_INIT_MAX_COUNT) { - pr_err( - "%s: TSENS not recovered after %d re-init\n", - __func__, tmdev->tsens_reinit_cnt); - BUG(); + while (1) { + /* + * Invoke scm call only if SW register write is + * reflecting in controller. If not, wait for + * 2 ms and then retry. + */ + if (reg_write_cnt >= 100) { + msleep(100); + pr_err( + "%s: Tsens write is failed. cnt:%d\n", + __func__, reg_write_cnt); + BUG(); + } + writel_relaxed(BIT(2), + TSENS_TM_INT_EN(tmdev->tsens_tm_addr)); + code = readl_relaxed( + TSENS_TM_INT_EN(tmdev->tsens_tm_addr)); + if (!(code & BIT(2))) { + udelay(2000); + TSENS_DBG(tmdev, "%s cnt:%d\n", + "Re-try TSENS write prior to scm", + reg_write_cnt++); + continue; + } + reg_write_cnt = 0; + + /* Make an scm call to re-init TSENS */ + TSENS_DBG(tmdev, "%s", + "Calling TZ to re-init TSENS\n"); + ret = qcom_scm_tsens_reinit(&tsens_ret); + TSENS_DBG(tmdev, "%s", + "return from scm call\n"); + if (ret) { + msleep(100); + pr_err("%s: scm call failed, ret:%d\n", + __func__, ret); + BUG(); + } + if (tsens_ret) { + msleep(100); + pr_err("%s: scm call failed to init tsens, ret:%d\n", + __func__, tsens_ret); + BUG(); + } + + scm_cnt++; + rc = 0; + list_for_each_entry(tmdev_itr, + &tsens_device_list, list) { + rc = __tsens2xxx_hw_init(tmdev_itr); + if (rc) { + pr_err( + "%s: TSENS hw_init error\n", + __func__); + break; + } + } + + if (!rc) + break; + + if (scm_cnt >= 100) { + msleep(100); + pr_err( + "%s: Tsens is not up after %d scm\n", + __func__, scm_cnt); + BUG(); + } + udelay(2000); + TSENS_DBG(tmdev, "%s cnt:%d\n", + "Re-try TSENS scm call", scm_cnt); } - /*Make an scm call to re-init TSENS */ - TSENS_DBG(tmdev, "%s", - "Calling TZ to re-init TSENS\n"); - ret = qcom_scm_tsens_reinit(&tsens_ret); - TSENS_DBG(tmdev, "%s", - "return from scm call\n"); - if (ret) { - pr_err("%s: scm call failed %d\n", - __func__, ret); - BUG(); - } - if (tsens_ret) { - pr_err("%s: scm call failed to init tsens %d\n", - __func__, tsens_ret); - BUG(); - } tmdev->tsens_reinit_cnt++; atomic_set(&in_tsens_reinit, 0); @@ -179,7 +287,6 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp) sensor_read: tmdev->trdy_fail_ctr = 0; - tmdev->tsens_reinit_cnt = 0; code = readl_relaxed_no_log(sensor_addr + (sensor->hw_id << TSENS_STATUS_ADDR_OFFSET)); @@ -653,58 +760,11 @@ static int tsens2xxx_hw_sensor_en(struct tsens_device *tmdev, static int tsens2xxx_hw_init(struct tsens_device *tmdev) { - void __iomem *srot_addr; - void __iomem *sensor_int_mask_addr; - unsigned int srot_val, crit_mask, crit_val; - void __iomem *int_mask_addr; + int rc = 0; - srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4); - srot_val = readl_relaxed(srot_addr); - if (!(srot_val & TSENS_EN)) { - pr_err("TSENS device is not enabled\n"); - return -ENODEV; - } - - if (tmdev->ctrl_data->cycle_monitor) { - sensor_int_mask_addr = - TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr); - crit_mask = readl_relaxed(sensor_int_mask_addr); - crit_val = TSENS_TM_CRITICAL_CYCLE_MONITOR; - if (tmdev->ctrl_data->cycle_compltn_monitor_mask) - writel_relaxed((crit_mask | crit_val), - (TSENS_TM_CRITICAL_INT_MASK - (tmdev->tsens_tm_addr))); - else - writel_relaxed((crit_mask & ~crit_val), - (TSENS_TM_CRITICAL_INT_MASK - (tmdev->tsens_tm_addr))); - /*Update critical cycle monitoring*/ - mb(); - } - - if (tmdev->ctrl_data->wd_bark) { - sensor_int_mask_addr = - TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr); - crit_mask = readl_relaxed(sensor_int_mask_addr); - crit_val = TSENS_TM_CRITICAL_WD_BARK; - if (tmdev->ctrl_data->wd_bark_mask) - writel_relaxed((crit_mask | crit_val), - (TSENS_TM_CRITICAL_INT_MASK - (tmdev->tsens_tm_addr))); - else - writel_relaxed((crit_mask & ~crit_val), - (TSENS_TM_CRITICAL_INT_MASK - (tmdev->tsens_tm_addr))); - /*Update watchdog monitoring*/ - mb(); - } - - int_mask_addr = TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_tm_addr); - writel_relaxed(TSENS_TM_UPPER_LOWER_INT_DISABLE, int_mask_addr); - - writel_relaxed(TSENS_TM_CRITICAL_INT_EN | - TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN, - TSENS_TM_INT_EN(tmdev->tsens_tm_addr)); + rc = __tsens2xxx_hw_init(tmdev); + if (rc) + return rc; spin_lock_init(&tmdev->tsens_crit_lock); spin_lock_init(&tmdev->tsens_upp_low_lock); From b8cf9019b677fd3ea0afe5da827480e4623880e2 Mon Sep 17 00:00:00 2001 From: Gopala Krishna Nuthaki Date: Mon, 21 Sep 2020 15:06:50 +0530 Subject: [PATCH 2/2] dt-bindings: thermal: Add support for modem skin sensor via QMI Add support to expose msm_skin_therm sensor via QMI. Change-Id: I7837c924456fc36867a9d6633c58d6c1e0aacda1 Signed-off-by: Gopala Krishna Nuthaki --- include/dt-bindings/thermal/thermal_qti.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/thermal/thermal_qti.h b/include/dt-bindings/thermal/thermal_qti.h index f38bcd5f1e38..4c0d31afbd0a 100644 --- a/include/dt-bindings/thermal/thermal_qti.h +++ b/include/dt-bindings/thermal/thermal_qti.h @@ -41,6 +41,7 @@ #define QMI_MMW_PA2 27 #define QMI_MMW_PA3 28 #define QMI_SDR_MMW 29 +#define QMI_MSM_SKIN 30 #define QMI_MODEM_INST_ID 0x0 #define QMI_ADSP_INST_ID 0x1