1 /*
2  * Renesas SCP/MCP Software
3  * Copyright (c) 2020-2021, Renesas Electronics Corporation. All rights
4  * reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef MOD_RCAR_REG_SENSOR_H
10 #define MOD_RCAR_REG_SENSOR_H
11 
12 #include <utils_def.h>
13 
14 #include <mod_sensor.h>
15 
16 #include <stdint.h>
17 
18 /*!
19  * \addtogroup GroupRCARModule RCAR Product Modules
20  * @{
21  */
22 
23 /*!
24  * \defgroup GroupRCARRegSensor Register Sensor Driver
25  *
26  * \brief Driver for simple, register-based sensors.
27  * @{
28  */
29 
30 /*! \brief Element configuration */
31 struct mod_reg_sensor_dev_config {
32     /*! Address of the sensor register */
33     uintptr_t reg;
34 
35     /*! Auxiliary sensor information */
36     struct mod_sensor_info *info;
37 };
38 
39 /*!
40  * @cond
41  */
42 
43 /*!
44  * \brief APIs provided by the driver.
45  */
46 enum mod_rcar_reg_sensor_api_type {
47     MOD_RCAR_REG_SENSOR_API_TYPE_PUBLIC,
48     MOD_RCAR_REG_SENSOR_API_TYPE_SYSTEM,
49     MOD_RCAR_REG_SENSOR_API_COUNT,
50 };
51 
52 /* Register base */
53 #define GEN3_THERMAL_BASE (PERIPHERAL_BASE + 0x198000)
54 #define GEN3_THERMAL_OFFSET (0x8000)
55 /* Register offsets */
56 #define REG_GEN3_IRQSTR (0x04)
57 #define REG_GEN3_IRQMSK (0x08)
58 #define REG_GEN3_IRQCTL (0x0C)
59 #define REG_GEN3_IRQEN (0x10)
60 #define REG_GEN3_IRQTEMP1 (0x14)
61 #define REG_GEN3_IRQTEMP2 (0x18)
62 #define REG_GEN3_IRQTEMP3 (0x1C)
63 #define REG_GEN3_CTSR (0x20)
64 #define REG_GEN3_THCTR (0x20)
65 #define REG_GEN3_TEMP (0x28)
66 #define REG_GEN3_THCODE1 (0x50)
67 #define REG_GEN3_THCODE2 (0x54)
68 #define REG_GEN3_THCODE3 (0x58)
69 #define REG_GEN3_PTAT1 (0x5C)
70 #define REG_GEN3_PTAT2 (0x60)
71 #define REG_GEN3_PTAT3 (0x64)
72 #define REG_GEN3_THSCP (0x68)
73 #define NEXT_REG_OFFSET (4)
74 
75 /* THCTR bits */
76 #define THCTR_PONM BIT(6)
77 #define THCTR_THSST BIT(0)
78 
79 #define CTEMP_MASK (0xFFF)
80 #define MCELSIUS(temp) ((temp)*1000)
81 
82 #define AVAILABLE_HARDWARE_PARAM \
83     (mmio_read_32(GEN3_THERMAL_BASE + REG_GEN3_THSCP) == (0x03 << 14))
84 
85 /* Structure for thermal temperature calculation */
86 struct equation_coefs {
87     int a1;
88     int b1;
89     int a2;
90     int b2;
91 };
92 
93 struct rcar_gen3_thermal_tsc {
94     uintptr_t base;
95     struct thermal_zone_device *zone;
96     struct equation_coefs coef;
97     int low;
98     int high;
99     int tj_t;
100     int id; /* thermal channel id */
101 };
102 
103 /*
104  * Linear approximation for temperature
105  *
106  * [reg] = [temp] * a + b => [temp] = ([reg] - b) / a
107  *
108  * The constants a and b are calculated using two triplets of int values PTAT
109  * and THCODE. PTAT and THCODE can either be read from hardware or use hard
110  * coded values from driver. The formula to calculate a and b are taken from
111  * BSP and sparsely documented and understood.
112  *
113  * Examining the linear formula and the formula used to calculate constants a
114  * and b while knowing that the span for PTAT and THCODE values are between
115  * 0x000 and 0xfff the largest integer possible is 0xfff * 0xfff == 0xffe001.
116  * Integer also needs to be signed so that leaves 7 bits for binary
117  * fixed point scaling.
118  */
119 #define DIV_ROUND_CLOSEST(x, divisor) \
120     ({ \
121         __typeof(x) __x = x; \
122         __typeof(divisor) __d = divisor; \
123         (((__typeof(x)) - 1) > 0 || ((__typeof(divisor)) - 1) > 0 || \
124          (__x) > 0) ? \
125             (((__x) + ((__d) / 2)) / (__d)) : \
126             (((__x) - ((__d) / 2)) / (__d)); \
127     })
128 #define FIXPT_SHIFT (7)
129 #define FIXPT_INT(_x) ((_x) * (1 << FIXPT_SHIFT))
130 #define INT_FIXPT(_x) ((_x) >> FIXPT_SHIFT)
131 #define FIXPT_DIV(_a, _b) DIV_ROUND_CLOSEST(((_a) * (1 << FIXPT_SHIFT)), (_b))
132 #define FIXPT_TO_MCELSIUS(_x) ((_x)*1000 >> FIXPT_SHIFT)
133 
134 #define RCAR3_THERMAL_GRAN (500) /* mili Celsius */
135 
136 #define TSC_MAX_NUM (3)
137 #define TSC_PARAM_NUM (3)
138 #define TEMP_UPPER_LIMIT (125)
139 #define TEMP_LOWER_LIMIT (-40)
140 
141 /* no idea where these constants come from */
142 #define TJ_1 (116)
143 #define TJ_3 (-41)
144 
145 #define SENSOR_ADR_BASE (SENSOR_SOC_TEMP1 & SENSOR_SOC_TEMP2 & SENSOR_SOC_TEMP3)
146 #define SENSOR_ADR_MASK \
147     ((SENSOR_SOC_TEMP1 | SENSOR_SOC_TEMP2 | SENSOR_SOC_TEMP3) - SENSOR_ADR_BASE)
148 #define IS_SENSOR_ADR(adr) ((adr & ~SENSOR_ADR_MASK) == SENSOR_ADR_BASE)
149 #define CV_ADR2INDEX(adr) (int)(((adr & SENSOR_ADR_MASK) >> 15) - 3)
150 #define ADR2INDEX(adr) (IS_SENSOR_ADR(adr) ? CV_ADR2INDEX(adr) : (-1))
151 
152 /*!
153  * @endcond
154  */
155 
156 /*!
157  * @}
158  */
159 
160 /*!
161  * @}
162  */
163 
164 #endif /* MOD_RCAR_REG_SENSOR_H */
165