123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- /* Copyright (c) 2017-2018, 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 <asm/arch_timer.h>
- #include <linux/platform_device.h>
- #include "tsens.h"
- #include "tsens-mtc.h"
- /* debug defines */
- #define TSENS_DBG_BUS_ID_0 0
- #define TSENS_DBG_BUS_ID_1 1
- #define TSENS_DBG_BUS_ID_2 2
- #define TSENS_DBG_BUS_ID_15 15
- #define TSENS_DEBUG_LOOP_COUNT_ID_0 2
- #define TSENS_DEBUG_LOOP_COUNT 5
- #define TSENS_DEBUG_STATUS_REG_START 10
- #define TSENS_DEBUG_OFFSET_RANGE 16
- #define TSENS_DEBUG_OFFSET_WORD1 0x4
- #define TSENS_DEBUG_OFFSET_WORD2 0x8
- #define TSENS_DEBUG_OFFSET_WORD3 0xc
- #define TSENS_DEBUG_OFFSET_ROW 0x10
- #define TSENS_DEBUG_DECIDEGC -950
- #define TSENS_DEBUG_CYCLE_MS 64
- #define TSENS_DEBUG_POLL_MS 200
- #define TSENS_DEBUG_BUS_ID2_MIN_CYCLE 50
- #define TSENS_DEBUG_BUS_ID2_MAX_CYCLE 51
- #define TSENS_DEBUG_ID_MASK_1_4 0xffffffe1
- #define DEBUG_SIZE 10
- #define TSENS_DEBUG_CONTROL(n) ((n) + 0x130)
- #define TSENS_DEBUG_DATA(n) ((n) + 0x134)
- struct tsens_dbg_func {
- int (*dbg_func)(struct tsens_device *, u32, u32, int *);
- };
- static ssize_t
- zonemask_show(struct device *dev, struct device_attribute *attr, char *buf)
- {
- struct tsens_device *tmdev = NULL;
- tmdev = tsens_controller_is_present();
- if (!tmdev) {
- pr_err("No TSENS controller present\n");
- return -EPROBE_DEFER;
- }
- return snprintf(buf, PAGE_SIZE,
- "Zone =%d th1=%d th2=%d\n", tmdev->mtcsys.zone_mtc,
- tmdev->mtcsys.th1, tmdev->mtcsys.th2);
- }
- static ssize_t
- zonemask_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
- int ret;
- struct tsens_device *tmdev = NULL;
- tmdev = tsens_controller_is_present();
- if (!tmdev) {
- pr_err("No TSENS controller present\n");
- return -EPROBE_DEFER;
- }
- ret = sscanf(buf, "%d %d %d", &tmdev->mtcsys.zone_mtc,
- &tmdev->mtcsys.th1, &tmdev->mtcsys.th2);
- if (ret != TSENS_ZONEMASK_PARAMS) {
- pr_err("Invalid command line arguments\n");
- count = -EINVAL;
- } else {
- pr_debug("store zone_mtc=%d th1=%d th2=%d\n",
- tmdev->mtcsys.zone_mtc,
- tmdev->mtcsys.th1, tmdev->mtcsys.th2);
- ret = tsens_set_mtc_zone_sw_mask(tmdev->mtcsys.zone_mtc,
- tmdev->mtcsys.th1, tmdev->mtcsys.th2);
- if (ret < 0) {
- pr_err("Invalid command line arguments\n");
- count = -EINVAL;
- }
- }
- return count;
- }
- static ssize_t
- zonelog_show(struct device *dev, struct device_attribute *attr, char *buf)
- {
- int ret, zlog[TSENS_MTC_ZONE_LOG_SIZE];
- struct tsens_device *tmdev = NULL;
- tmdev = tsens_controller_is_present();
- if (!tmdev) {
- pr_err("No TSENS controller present\n");
- return -EPROBE_DEFER;
- }
- ret = tsens_get_mtc_zone_log(tmdev->mtcsys.zone_log, zlog);
- if (ret < 0) {
- pr_err("Invalid command line arguments\n");
- return -EINVAL;
- }
- return snprintf(buf, PAGE_SIZE,
- "Log[0]=%d\nLog[1]=%d\nLog[2]=%d\nLog[3]=%d\nLog[4]=%d\nLog[5]=%d\n",
- zlog[0], zlog[1], zlog[2], zlog[3], zlog[4], zlog[5]);
- }
- static ssize_t
- zonelog_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
- int ret;
- struct tsens_device *tmdev = NULL;
- tmdev = tsens_controller_is_present();
- if (!tmdev) {
- pr_err("No TSENS controller present\n");
- return -EPROBE_DEFER;
- }
- ret = kstrtou32(buf, 0, &tmdev->mtcsys.zone_log);
- if (ret < 0) {
- pr_err("Invalid command line arguments\n");
- return -EINVAL;
- }
- return count;
- }
- static ssize_t
- zonehist_show(struct device *dev, struct device_attribute *attr, char *buf)
- {
- int ret, zhist[TSENS_MTC_ZONE_HISTORY_SIZE];
- struct tsens_device *tmdev = NULL;
- tmdev = tsens_controller_is_present();
- if (!tmdev) {
- pr_err("No TSENS controller present\n");
- return -EPROBE_DEFER;
- }
- ret = tsens_get_mtc_zone_history(tmdev->mtcsys.zone_hist, zhist);
- if (ret < 0) {
- pr_err("Invalid command line arguments\n");
- return -EINVAL;
- }
- return snprintf(buf, PAGE_SIZE,
- "Cool = %d\nYellow = %d\nRed = %d\n",
- zhist[0], zhist[1], zhist[2]);
- }
- static ssize_t
- zonehist_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
- int ret;
- struct tsens_device *tmdev = NULL;
- tmdev = tsens_controller_is_present();
- if (!tmdev) {
- pr_err("No TSENS controller present\n");
- return -EPROBE_DEFER;
- }
- ret = kstrtou32(buf, 0, &tmdev->mtcsys.zone_hist);
- if (ret < 0) {
- pr_err("Invalid command line arguments\n");
- return -EINVAL;
- }
- return count;
- }
- static struct device_attribute tsens_mtc_dev_attr[] = {
- __ATTR(zonemask, 0644, zonemask_show, zonemask_store),
- __ATTR(zonelog, 0644, zonelog_show, zonelog_store),
- __ATTR(zonehist, 0644, zonehist_show, zonehist_store),
- };
- static struct device_attribute tsens_mtc_dev_attr_V14[] = {
- __ATTR(zonemask, 0644, zonemask_show, zonemask_store),
- __ATTR(zonelog, 0644, zonelog_show, zonelog_store),
- };
- static int tsens_dbg_mtc_data(struct tsens_device *data,
- u32 id, u32 dbg_type, int *val)
- {
- int result = 0, i;
- struct tsens_device *tmdev = NULL;
- struct device_attribute *attr_ptr = NULL;
- u32 ver_major;
- u32 ver_minor;
- u32 num_elem;
- tmdev = data;
- ver_major = tmdev->ctrl_data->ver_major;
- ver_minor = tmdev->ctrl_data->ver_minor;
- if (ver_major == 1 && ver_minor == 4) {
- attr_ptr = tsens_mtc_dev_attr_V14;
- num_elem = ARRAY_SIZE(tsens_mtc_dev_attr_V14);
- } else {
- attr_ptr = tsens_mtc_dev_attr;
- num_elem = ARRAY_SIZE(tsens_mtc_dev_attr);
- }
- for (i = 0; i < num_elem; i++) {
- result = device_create_file(&tmdev->pdev->dev, &attr_ptr[i]);
- if (result < 0)
- goto error;
- }
- return result;
- error:
- for (i--; i >= 0; i--)
- device_remove_file(&tmdev->pdev->dev, &attr_ptr[i]);
- return result;
- }
- static int tsens_dbg_log_temp_reads(struct tsens_device *data, u32 id,
- u32 dbg_type, int *temp)
- {
- struct tsens_sensor *sensor;
- struct tsens_device *tmdev = NULL;
- u32 idx = 0;
- if (!data)
- return -EINVAL;
- pr_debug("%d %d\n", id, dbg_type);
- tmdev = data;
- sensor = &tmdev->sensor[id];
- idx = tmdev->tsens_dbg.sensor_dbg_info[sensor->hw_id].idx;
- tmdev->tsens_dbg.sensor_dbg_info[sensor->hw_id].temp[idx%10] = *temp;
- tmdev->tsens_dbg.sensor_dbg_info[sensor->hw_id].time_stmp[idx%10] =
- sched_clock();
- idx++;
- tmdev->tsens_dbg.sensor_dbg_info[sensor->hw_id].idx = idx;
- return 0;
- }
- static int tsens_dbg_log_interrupt_timestamp(struct tsens_device *data,
- u32 id, u32 dbg_type, int *val)
- {
- struct tsens_device *tmdev = NULL;
- u32 idx = 0;
- if (!data)
- return -EINVAL;
- pr_debug("%d %d\n", id, dbg_type);
- tmdev = data;
- /* debug */
- idx = tmdev->tsens_dbg.irq_idx;
- tmdev->tsens_dbg.irq_time_stmp[idx%10] =
- sched_clock();
- tmdev->tsens_dbg.irq_idx++;
- return 0;
- }
- static int tsens_dbg_log_bus_id_data(struct tsens_device *data,
- u32 id, u32 dbg_type, int *val)
- {
- struct tsens_device *tmdev = NULL;
- u32 loop = 0, i = 0;
- uint32_t r1, r2, r3, r4, offset = 0;
- unsigned int debug_dump;
- unsigned int debug_id = 0, cntrl_id = 0;
- void __iomem *srot_addr;
- void __iomem *controller_id_addr;
- void __iomem *debug_id_addr;
- void __iomem *debug_data_addr;
- if (!data)
- return -EINVAL;
- pr_debug("%d %d\n", id, dbg_type);
- tmdev = data;
- controller_id_addr = TSENS_CONTROLLER_ID(tmdev->tsens_tm_addr);
- debug_id_addr = TSENS_DEBUG_CONTROL(tmdev->tsens_tm_addr);
- debug_data_addr = TSENS_DEBUG_DATA(tmdev->tsens_tm_addr);
- srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr);
- cntrl_id = readl_relaxed(controller_id_addr);
- pr_err("Controller_id: 0x%x\n", cntrl_id);
- loop = 0;
- i = 0;
- debug_id = readl_relaxed(debug_id_addr);
- writel_relaxed((debug_id | (i << 1) | 1),
- TSENS_DEBUG_CONTROL(tmdev->tsens_tm_addr));
- while (loop < TSENS_DEBUG_LOOP_COUNT_ID_0) {
- debug_dump = readl_relaxed(debug_data_addr);
- r1 = readl_relaxed(debug_data_addr);
- r2 = readl_relaxed(debug_data_addr);
- r3 = readl_relaxed(debug_data_addr);
- r4 = readl_relaxed(debug_data_addr);
- pr_err("cntrl:%d, bus-id:%d value:0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
- cntrl_id, i, debug_dump, r1, r2, r3, r4);
- loop++;
- }
- for (i = TSENS_DBG_BUS_ID_1; i <= TSENS_DBG_BUS_ID_15; i++) {
- loop = 0;
- debug_id = readl_relaxed(debug_id_addr);
- debug_id = debug_id & TSENS_DEBUG_ID_MASK_1_4;
- writel_relaxed((debug_id | (i << 1) | 1),
- TSENS_DEBUG_CONTROL(tmdev->tsens_tm_addr));
- while (loop < TSENS_DEBUG_LOOP_COUNT) {
- debug_dump = readl_relaxed(debug_data_addr);
- pr_err("cntrl:%d, bus-id:%d with value: 0x%x\n",
- cntrl_id, i, debug_dump);
- if (i == TSENS_DBG_BUS_ID_2)
- usleep_range(
- TSENS_DEBUG_BUS_ID2_MIN_CYCLE,
- TSENS_DEBUG_BUS_ID2_MAX_CYCLE);
- loop++;
- }
- }
- pr_err("Start of TSENS TM dump\n");
- for (i = 0; i < TSENS_DEBUG_OFFSET_RANGE; i++) {
- r1 = readl_relaxed(controller_id_addr + offset);
- r2 = readl_relaxed(controller_id_addr + (offset +
- TSENS_DEBUG_OFFSET_WORD1));
- r3 = readl_relaxed(controller_id_addr + (offset +
- TSENS_DEBUG_OFFSET_WORD2));
- r4 = readl_relaxed(controller_id_addr + (offset +
- TSENS_DEBUG_OFFSET_WORD3));
- pr_err("ctrl:%d:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- cntrl_id, offset, r1, r2, r3, r4);
- offset += TSENS_DEBUG_OFFSET_ROW;
- }
- offset = 0;
- pr_err("Start of TSENS SROT dump\n");
- for (i = 0; i < TSENS_DEBUG_OFFSET_RANGE; i++) {
- r1 = readl_relaxed(srot_addr + offset);
- r2 = readl_relaxed(srot_addr + (offset +
- TSENS_DEBUG_OFFSET_WORD1));
- r3 = readl_relaxed(srot_addr + (offset +
- TSENS_DEBUG_OFFSET_WORD2));
- r4 = readl_relaxed(srot_addr + (offset +
- TSENS_DEBUG_OFFSET_WORD3));
- pr_err("ctrl:%d:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- cntrl_id, offset, r1, r2, r3, r4);
- offset += TSENS_DEBUG_OFFSET_ROW;
- }
- loop = 0;
- while (loop < TSENS_DEBUG_LOOP_COUNT) {
- offset = TSENS_DEBUG_OFFSET_ROW *
- TSENS_DEBUG_STATUS_REG_START;
- pr_err("Start of TSENS TM dump %d\n", loop);
- /* Limited dump of the registers for the temperature */
- for (i = 0; i < TSENS_DEBUG_LOOP_COUNT; i++) {
- r1 = readl_relaxed(controller_id_addr + offset);
- r2 = readl_relaxed(controller_id_addr +
- (offset + TSENS_DEBUG_OFFSET_WORD1));
- r3 = readl_relaxed(controller_id_addr +
- (offset + TSENS_DEBUG_OFFSET_WORD2));
- r4 = readl_relaxed(controller_id_addr +
- (offset + TSENS_DEBUG_OFFSET_WORD3));
- pr_err("ctrl:%d:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- cntrl_id, offset, r1, r2, r3, r4);
- offset += TSENS_DEBUG_OFFSET_ROW;
- }
- loop++;
- }
- return 0;
- }
- static struct tsens_dbg_func dbg_arr[] = {
- [TSENS_DBG_LOG_TEMP_READS] = {tsens_dbg_log_temp_reads},
- [TSENS_DBG_LOG_INTERRUPT_TIMESTAMP] = {
- tsens_dbg_log_interrupt_timestamp},
- [TSENS_DBG_LOG_BUS_ID_DATA] = {tsens_dbg_log_bus_id_data},
- [TSENS_DBG_MTC_DATA] = {tsens_dbg_mtc_data},
- };
- int tsens2xxx_dbg(struct tsens_device *data, u32 id, u32 dbg_type, int *val)
- {
- if (dbg_type >= TSENS_DBG_LOG_MAX)
- return -EINVAL;
- dbg_arr[dbg_type].dbg_func(data, id, dbg_type, val);
- return 0;
- }
- EXPORT_SYMBOL(tsens2xxx_dbg);
|