soctherm.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488
  1. /*
  2. * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * Author:
  5. * Mikko Perttunen <mperttunen@nvidia.com>
  6. *
  7. * This software is licensed under the terms of the GNU General Public
  8. * License version 2, as published by the Free Software Foundation, and
  9. * may be copied, distributed, and modified under those terms.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. */
  17. #include <linux/debugfs.h>
  18. #include <linux/bitops.h>
  19. #include <linux/clk.h>
  20. #include <linux/delay.h>
  21. #include <linux/err.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/io.h>
  24. #include <linux/module.h>
  25. #include <linux/of.h>
  26. #include <linux/platform_device.h>
  27. #include <linux/reset.h>
  28. #include <linux/thermal.h>
  29. #include <dt-bindings/thermal/tegra124-soctherm.h>
  30. #include "../thermal_core.h"
  31. #include "soctherm.h"
  32. #define SENSOR_CONFIG0 0
  33. #define SENSOR_CONFIG0_STOP BIT(0)
  34. #define SENSOR_CONFIG0_CPTR_OVER BIT(2)
  35. #define SENSOR_CONFIG0_OVER BIT(3)
  36. #define SENSOR_CONFIG0_TCALC_OVER BIT(4)
  37. #define SENSOR_CONFIG0_TALL_MASK (0xfffff << 8)
  38. #define SENSOR_CONFIG0_TALL_SHIFT 8
  39. #define SENSOR_CONFIG1 4
  40. #define SENSOR_CONFIG1_TSAMPLE_MASK 0x3ff
  41. #define SENSOR_CONFIG1_TSAMPLE_SHIFT 0
  42. #define SENSOR_CONFIG1_TIDDQ_EN_MASK (0x3f << 15)
  43. #define SENSOR_CONFIG1_TIDDQ_EN_SHIFT 15
  44. #define SENSOR_CONFIG1_TEN_COUNT_MASK (0x3f << 24)
  45. #define SENSOR_CONFIG1_TEN_COUNT_SHIFT 24
  46. #define SENSOR_CONFIG1_TEMP_ENABLE BIT(31)
  47. /*
  48. * SENSOR_CONFIG2 is defined in soctherm.h
  49. * because, it will be used by tegra_soctherm_fuse.c
  50. */
  51. #define SENSOR_STATUS0 0xc
  52. #define SENSOR_STATUS0_VALID_MASK BIT(31)
  53. #define SENSOR_STATUS0_CAPTURE_MASK 0xffff
  54. #define SENSOR_STATUS1 0x10
  55. #define SENSOR_STATUS1_TEMP_VALID_MASK BIT(31)
  56. #define SENSOR_STATUS1_TEMP_MASK 0xffff
  57. #define READBACK_VALUE_MASK 0xff00
  58. #define READBACK_VALUE_SHIFT 8
  59. #define READBACK_ADD_HALF BIT(7)
  60. #define READBACK_NEGATE BIT(0)
  61. /*
  62. * THERMCTL_LEVEL0_GROUP_CPU is defined in soctherm.h
  63. * because it will be used by tegraxxx_soctherm.c
  64. */
  65. #define THERMCTL_LVL0_CPU0_EN_MASK BIT(8)
  66. #define THERMCTL_LVL0_CPU0_CPU_THROT_MASK (0x3 << 5)
  67. #define THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT 0x1
  68. #define THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY 0x2
  69. #define THERMCTL_LVL0_CPU0_GPU_THROT_MASK (0x3 << 3)
  70. #define THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT 0x1
  71. #define THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY 0x2
  72. #define THERMCTL_LVL0_CPU0_MEM_THROT_MASK BIT(2)
  73. #define THERMCTL_LVL0_CPU0_STATUS_MASK 0x3
  74. #define THERMCTL_LVL0_UP_STATS 0x10
  75. #define THERMCTL_LVL0_DN_STATS 0x14
  76. #define THERMCTL_STATS_CTL 0x94
  77. #define STATS_CTL_CLR_DN 0x8
  78. #define STATS_CTL_EN_DN 0x4
  79. #define STATS_CTL_CLR_UP 0x2
  80. #define STATS_CTL_EN_UP 0x1
  81. #define THROT_GLOBAL_CFG 0x400
  82. #define THROT_GLOBAL_ENB_MASK BIT(0)
  83. #define CPU_PSKIP_STATUS 0x418
  84. #define XPU_PSKIP_STATUS_M_MASK (0xff << 12)
  85. #define XPU_PSKIP_STATUS_N_MASK (0xff << 4)
  86. #define XPU_PSKIP_STATUS_SW_OVERRIDE_MASK BIT(1)
  87. #define XPU_PSKIP_STATUS_ENABLED_MASK BIT(0)
  88. #define THROT_PRIORITY_LOCK 0x424
  89. #define THROT_PRIORITY_LOCK_PRIORITY_MASK 0xff
  90. #define THROT_STATUS 0x428
  91. #define THROT_STATUS_BREACH_MASK BIT(12)
  92. #define THROT_STATUS_STATE_MASK (0xff << 4)
  93. #define THROT_STATUS_ENABLED_MASK BIT(0)
  94. #define THROT_PSKIP_CTRL_LITE_CPU 0x430
  95. #define THROT_PSKIP_CTRL_ENABLE_MASK BIT(31)
  96. #define THROT_PSKIP_CTRL_DIVIDEND_MASK (0xff << 8)
  97. #define THROT_PSKIP_CTRL_DIVISOR_MASK 0xff
  98. #define THROT_PSKIP_CTRL_VECT_GPU_MASK (0x7 << 16)
  99. #define THROT_PSKIP_CTRL_VECT_CPU_MASK (0x7 << 8)
  100. #define THROT_PSKIP_CTRL_VECT2_CPU_MASK 0x7
  101. #define THROT_VECT_NONE 0x0 /* 3'b000 */
  102. #define THROT_VECT_LOW 0x1 /* 3'b001 */
  103. #define THROT_VECT_MED 0x3 /* 3'b011 */
  104. #define THROT_VECT_HIGH 0x7 /* 3'b111 */
  105. #define THROT_PSKIP_RAMP_LITE_CPU 0x434
  106. #define THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK BIT(31)
  107. #define THROT_PSKIP_RAMP_DURATION_MASK (0xffff << 8)
  108. #define THROT_PSKIP_RAMP_STEP_MASK 0xff
  109. #define THROT_PRIORITY_LITE 0x444
  110. #define THROT_PRIORITY_LITE_PRIO_MASK 0xff
  111. #define THROT_DELAY_LITE 0x448
  112. #define THROT_DELAY_LITE_DELAY_MASK 0xff
  113. /* car register offsets needed for enabling HW throttling */
  114. #define CAR_SUPER_CCLKG_DIVIDER 0x36c
  115. #define CDIVG_USE_THERM_CONTROLS_MASK BIT(30)
  116. /* ccroc register offsets needed for enabling HW throttling for Tegra132 */
  117. #define CCROC_SUPER_CCLKG_DIVIDER 0x024
  118. #define CCROC_GLOBAL_CFG 0x148
  119. #define CCROC_THROT_PSKIP_RAMP_CPU 0x150
  120. #define CCROC_THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK BIT(31)
  121. #define CCROC_THROT_PSKIP_RAMP_DURATION_MASK (0xffff << 8)
  122. #define CCROC_THROT_PSKIP_RAMP_STEP_MASK 0xff
  123. #define CCROC_THROT_PSKIP_CTRL_CPU 0x154
  124. #define CCROC_THROT_PSKIP_CTRL_ENB_MASK BIT(31)
  125. #define CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK (0xff << 8)
  126. #define CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK 0xff
  127. /* get val from register(r) mask bits(m) */
  128. #define REG_GET_MASK(r, m) (((r) & (m)) >> (ffs(m) - 1))
  129. /* set val(v) to mask bits(m) of register(r) */
  130. #define REG_SET_MASK(r, m, v) (((r) & ~(m)) | \
  131. (((v) & (m >> (ffs(m) - 1))) << (ffs(m) - 1)))
  132. /* get dividend from the depth */
  133. #define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
  134. /* get THROT_PSKIP_xxx offset per LIGHT/HEAVY throt and CPU/GPU dev */
  135. #define THROT_OFFSET 0x30
  136. #define THROT_PSKIP_CTRL(throt, dev) (THROT_PSKIP_CTRL_LITE_CPU + \
  137. (THROT_OFFSET * throt) + (8 * dev))
  138. #define THROT_PSKIP_RAMP(throt, dev) (THROT_PSKIP_RAMP_LITE_CPU + \
  139. (THROT_OFFSET * throt) + (8 * dev))
  140. /* get THROT_xxx_CTRL offset per LIGHT/HEAVY throt */
  141. #define THROT_PRIORITY_CTRL(throt) (THROT_PRIORITY_LITE + \
  142. (THROT_OFFSET * throt))
  143. #define THROT_DELAY_CTRL(throt) (THROT_DELAY_LITE + \
  144. (THROT_OFFSET * throt))
  145. /* get CCROC_THROT_PSKIP_xxx offset per HIGH/MED/LOW vect*/
  146. #define CCROC_THROT_OFFSET 0x0c
  147. #define CCROC_THROT_PSKIP_CTRL_CPU_REG(vect) (CCROC_THROT_PSKIP_CTRL_CPU + \
  148. (CCROC_THROT_OFFSET * vect))
  149. #define CCROC_THROT_PSKIP_RAMP_CPU_REG(vect) (CCROC_THROT_PSKIP_RAMP_CPU + \
  150. (CCROC_THROT_OFFSET * vect))
  151. /* get THERMCTL_LEVELx offset per CPU/GPU/MEM/TSENSE rg and LEVEL0~3 lv */
  152. #define THERMCTL_LVL_REGS_SIZE 0x20
  153. #define THERMCTL_LVL_REG(rg, lv) ((rg) + ((lv) * THERMCTL_LVL_REGS_SIZE))
  154. static const int min_low_temp = -127000;
  155. static const int max_high_temp = 127000;
  156. enum soctherm_throttle_id {
  157. THROTTLE_LIGHT = 0,
  158. THROTTLE_HEAVY,
  159. THROTTLE_SIZE,
  160. };
  161. enum soctherm_throttle_dev_id {
  162. THROTTLE_DEV_CPU = 0,
  163. THROTTLE_DEV_GPU,
  164. THROTTLE_DEV_SIZE,
  165. };
  166. static const char *const throt_names[] = {
  167. [THROTTLE_LIGHT] = "light",
  168. [THROTTLE_HEAVY] = "heavy",
  169. };
  170. struct tegra_soctherm;
  171. struct tegra_thermctl_zone {
  172. void __iomem *reg;
  173. struct device *dev;
  174. struct tegra_soctherm *ts;
  175. struct thermal_zone_device *tz;
  176. const struct tegra_tsensor_group *sg;
  177. };
  178. struct soctherm_throt_cfg {
  179. const char *name;
  180. unsigned int id;
  181. u8 priority;
  182. u8 cpu_throt_level;
  183. u32 cpu_throt_depth;
  184. struct thermal_cooling_device *cdev;
  185. bool init;
  186. };
  187. struct tegra_soctherm {
  188. struct reset_control *reset;
  189. struct clk *clock_tsensor;
  190. struct clk *clock_soctherm;
  191. void __iomem *regs;
  192. void __iomem *clk_regs;
  193. void __iomem *ccroc_regs;
  194. u32 *calib;
  195. struct thermal_zone_device **thermctl_tzs;
  196. struct tegra_soctherm_soc *soc;
  197. struct soctherm_throt_cfg throt_cfgs[THROTTLE_SIZE];
  198. struct dentry *debugfs_dir;
  199. };
  200. /**
  201. * clk_writel() - writes a value to a CAR register
  202. * @ts: pointer to a struct tegra_soctherm
  203. * @v: the value to write
  204. * @reg: the register offset
  205. *
  206. * Writes @v to @reg. No return value.
  207. */
  208. static inline void clk_writel(struct tegra_soctherm *ts, u32 value, u32 reg)
  209. {
  210. writel(value, (ts->clk_regs + reg));
  211. }
  212. /**
  213. * clk_readl() - reads specified register from CAR IP block
  214. * @ts: pointer to a struct tegra_soctherm
  215. * @reg: register address to be read
  216. *
  217. * Return: the value of the register
  218. */
  219. static inline u32 clk_readl(struct tegra_soctherm *ts, u32 reg)
  220. {
  221. return readl(ts->clk_regs + reg);
  222. }
  223. /**
  224. * ccroc_writel() - writes a value to a CCROC register
  225. * @ts: pointer to a struct tegra_soctherm
  226. * @v: the value to write
  227. * @reg: the register offset
  228. *
  229. * Writes @v to @reg. No return value.
  230. */
  231. static inline void ccroc_writel(struct tegra_soctherm *ts, u32 value, u32 reg)
  232. {
  233. writel(value, (ts->ccroc_regs + reg));
  234. }
  235. /**
  236. * ccroc_readl() - reads specified register from CCROC IP block
  237. * @ts: pointer to a struct tegra_soctherm
  238. * @reg: register address to be read
  239. *
  240. * Return: the value of the register
  241. */
  242. static inline u32 ccroc_readl(struct tegra_soctherm *ts, u32 reg)
  243. {
  244. return readl(ts->ccroc_regs + reg);
  245. }
  246. static void enable_tsensor(struct tegra_soctherm *tegra, unsigned int i)
  247. {
  248. const struct tegra_tsensor *sensor = &tegra->soc->tsensors[i];
  249. void __iomem *base = tegra->regs + sensor->base;
  250. unsigned int val;
  251. val = sensor->config->tall << SENSOR_CONFIG0_TALL_SHIFT;
  252. writel(val, base + SENSOR_CONFIG0);
  253. val = (sensor->config->tsample - 1) << SENSOR_CONFIG1_TSAMPLE_SHIFT;
  254. val |= sensor->config->tiddq_en << SENSOR_CONFIG1_TIDDQ_EN_SHIFT;
  255. val |= sensor->config->ten_count << SENSOR_CONFIG1_TEN_COUNT_SHIFT;
  256. val |= SENSOR_CONFIG1_TEMP_ENABLE;
  257. writel(val, base + SENSOR_CONFIG1);
  258. writel(tegra->calib[i], base + SENSOR_CONFIG2);
  259. }
  260. /*
  261. * Translate from soctherm readback format to millicelsius.
  262. * The soctherm readback format in bits is as follows:
  263. * TTTTTTTT H______N
  264. * where T's contain the temperature in Celsius,
  265. * H denotes an addition of 0.5 Celsius and N denotes negation
  266. * of the final value.
  267. */
  268. static int translate_temp(u16 val)
  269. {
  270. int t;
  271. t = ((val & READBACK_VALUE_MASK) >> READBACK_VALUE_SHIFT) * 1000;
  272. if (val & READBACK_ADD_HALF)
  273. t += 500;
  274. if (val & READBACK_NEGATE)
  275. t *= -1;
  276. return t;
  277. }
  278. static int tegra_thermctl_get_temp(void *data, int *out_temp)
  279. {
  280. struct tegra_thermctl_zone *zone = data;
  281. u32 val;
  282. val = readl(zone->reg);
  283. val = REG_GET_MASK(val, zone->sg->sensor_temp_mask);
  284. *out_temp = translate_temp(val);
  285. return 0;
  286. }
  287. /**
  288. * enforce_temp_range() - check and enforce temperature range [min, max]
  289. * @trip_temp: the trip temperature to check
  290. *
  291. * Checks and enforces the permitted temperature range that SOC_THERM
  292. * HW can support This is
  293. * done while taking care of precision.
  294. *
  295. * Return: The precision adjusted capped temperature in millicelsius.
  296. */
  297. static int enforce_temp_range(struct device *dev, int trip_temp)
  298. {
  299. int temp;
  300. temp = clamp_val(trip_temp, min_low_temp, max_high_temp);
  301. if (temp != trip_temp)
  302. dev_info(dev, "soctherm: trip temperature %d forced to %d\n",
  303. trip_temp, temp);
  304. return temp;
  305. }
  306. /**
  307. * thermtrip_program() - Configures the hardware to shut down the
  308. * system if a given sensor group reaches a given temperature
  309. * @dev: ptr to the struct device for the SOC_THERM IP block
  310. * @sg: pointer to the sensor group to set the thermtrip temperature for
  311. * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
  312. *
  313. * Sets the thermal trip threshold of the given sensor group to be the
  314. * @trip_temp. If this threshold is crossed, the hardware will shut
  315. * down.
  316. *
  317. * Note that, although @trip_temp is specified in millicelsius, the
  318. * hardware is programmed in degrees Celsius.
  319. *
  320. * Return: 0 upon success, or %-EINVAL upon failure.
  321. */
  322. static int thermtrip_program(struct device *dev,
  323. const struct tegra_tsensor_group *sg,
  324. int trip_temp)
  325. {
  326. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  327. int temp;
  328. u32 r;
  329. if (!sg || !sg->thermtrip_threshold_mask)
  330. return -EINVAL;
  331. temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
  332. r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
  333. r = REG_SET_MASK(r, sg->thermtrip_threshold_mask, temp);
  334. r = REG_SET_MASK(r, sg->thermtrip_enable_mask, 1);
  335. r = REG_SET_MASK(r, sg->thermtrip_any_en_mask, 0);
  336. writel(r, ts->regs + THERMCTL_THERMTRIP_CTL);
  337. return 0;
  338. }
  339. /**
  340. * throttrip_program() - Configures the hardware to throttle the
  341. * pulse if a given sensor group reaches a given temperature
  342. * @dev: ptr to the struct device for the SOC_THERM IP block
  343. * @sg: pointer to the sensor group to set the thermtrip temperature for
  344. * @stc: pointer to the throttle need to be triggered
  345. * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
  346. *
  347. * Sets the thermal trip threshold and throttle event of the given sensor
  348. * group. If this threshold is crossed, the hardware will trigger the
  349. * throttle.
  350. *
  351. * Note that, although @trip_temp is specified in millicelsius, the
  352. * hardware is programmed in degrees Celsius.
  353. *
  354. * Return: 0 upon success, or %-EINVAL upon failure.
  355. */
  356. static int throttrip_program(struct device *dev,
  357. const struct tegra_tsensor_group *sg,
  358. struct soctherm_throt_cfg *stc,
  359. int trip_temp)
  360. {
  361. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  362. int temp, cpu_throt, gpu_throt;
  363. unsigned int throt;
  364. u32 r, reg_off;
  365. if (!sg || !stc || !stc->init)
  366. return -EINVAL;
  367. temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
  368. /* Hardcode LIGHT on LEVEL1 and HEAVY on LEVEL2 */
  369. throt = stc->id;
  370. reg_off = THERMCTL_LVL_REG(sg->thermctl_lvl0_offset, throt + 1);
  371. if (throt == THROTTLE_LIGHT) {
  372. cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT;
  373. gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT;
  374. } else {
  375. cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY;
  376. gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY;
  377. if (throt != THROTTLE_HEAVY)
  378. dev_warn(dev,
  379. "invalid throt id %d - assuming HEAVY",
  380. throt);
  381. }
  382. r = readl(ts->regs + reg_off);
  383. r = REG_SET_MASK(r, sg->thermctl_lvl0_up_thresh_mask, temp);
  384. r = REG_SET_MASK(r, sg->thermctl_lvl0_dn_thresh_mask, temp);
  385. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_CPU_THROT_MASK, cpu_throt);
  386. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_GPU_THROT_MASK, gpu_throt);
  387. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
  388. writel(r, ts->regs + reg_off);
  389. return 0;
  390. }
  391. static struct soctherm_throt_cfg *
  392. find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name)
  393. {
  394. unsigned int i;
  395. for (i = 0; ts->throt_cfgs[i].name; i++)
  396. if (!strcmp(ts->throt_cfgs[i].name, name))
  397. return &ts->throt_cfgs[i];
  398. return NULL;
  399. }
  400. static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
  401. {
  402. struct tegra_thermctl_zone *zone = data;
  403. struct thermal_zone_device *tz = zone->tz;
  404. struct tegra_soctherm *ts = zone->ts;
  405. const struct tegra_tsensor_group *sg = zone->sg;
  406. struct device *dev = zone->dev;
  407. enum thermal_trip_type type;
  408. int ret;
  409. if (!tz)
  410. return -EINVAL;
  411. ret = tz->ops->get_trip_type(tz, trip, &type);
  412. if (ret)
  413. return ret;
  414. if (type == THERMAL_TRIP_CRITICAL) {
  415. return thermtrip_program(dev, sg, temp);
  416. } else if (type == THERMAL_TRIP_HOT) {
  417. int i;
  418. for (i = 0; i < THROTTLE_SIZE; i++) {
  419. struct thermal_cooling_device *cdev;
  420. struct soctherm_throt_cfg *stc;
  421. if (!ts->throt_cfgs[i].init)
  422. continue;
  423. cdev = ts->throt_cfgs[i].cdev;
  424. if (get_thermal_instance(tz, cdev, trip))
  425. stc = find_throttle_cfg_by_name(ts, cdev->type);
  426. else
  427. continue;
  428. return throttrip_program(dev, sg, stc, temp);
  429. }
  430. }
  431. return 0;
  432. }
  433. static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
  434. .get_temp = tegra_thermctl_get_temp,
  435. .set_trip_temp = tegra_thermctl_set_trip_temp,
  436. };
  437. static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
  438. {
  439. int ntrips, i, ret;
  440. enum thermal_trip_type type;
  441. ntrips = of_thermal_get_ntrips(tz);
  442. if (ntrips <= 0)
  443. return -EINVAL;
  444. for (i = 0; i < ntrips; i++) {
  445. ret = tz->ops->get_trip_type(tz, i, &type);
  446. if (ret)
  447. return -EINVAL;
  448. if (type == THERMAL_TRIP_HOT) {
  449. ret = tz->ops->get_trip_temp(tz, i, temp);
  450. if (!ret)
  451. *trip = i;
  452. return ret;
  453. }
  454. }
  455. return -EINVAL;
  456. }
  457. /**
  458. * tegra_soctherm_set_hwtrips() - set HW trip point from DT data
  459. * @dev: struct device * of the SOC_THERM instance
  460. *
  461. * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
  462. * "THROTTLE" trip points , using "critical" or "hot" type trip_temp
  463. * from thermal zone.
  464. * After they have been configured, THERMTRIP or THROTTLE will take
  465. * action when the configured SoC thermal sensor group reaches a
  466. * certain temperature.
  467. *
  468. * Return: 0 upon success, or a negative error code on failure.
  469. * "Success" does not mean that trips was enabled; it could also
  470. * mean that no node was found in DT.
  471. * THERMTRIP has been enabled successfully when a message similar to
  472. * this one appears on the serial console:
  473. * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC"
  474. * THROTTLE has been enabled successfully when a message similar to
  475. * this one appears on the serial console:
  476. * ""throttrip: will throttle when sensor group XXX reaches YYYYYY mC"
  477. */
  478. static int tegra_soctherm_set_hwtrips(struct device *dev,
  479. const struct tegra_tsensor_group *sg,
  480. struct thermal_zone_device *tz)
  481. {
  482. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  483. struct soctherm_throt_cfg *stc;
  484. int i, trip, temperature;
  485. int ret;
  486. ret = tz->ops->get_crit_temp(tz, &temperature);
  487. if (ret) {
  488. dev_warn(dev, "thermtrip: %s: missing critical temperature\n",
  489. sg->name);
  490. goto set_throttle;
  491. }
  492. ret = thermtrip_program(dev, sg, temperature);
  493. if (ret) {
  494. dev_err(dev, "thermtrip: %s: error during enable\n",
  495. sg->name);
  496. return ret;
  497. }
  498. dev_info(dev,
  499. "thermtrip: will shut down when %s reaches %d mC\n",
  500. sg->name, temperature);
  501. set_throttle:
  502. ret = get_hot_temp(tz, &trip, &temperature);
  503. if (ret) {
  504. dev_warn(dev, "throttrip: %s: missing hot temperature\n",
  505. sg->name);
  506. return 0;
  507. }
  508. for (i = 0; i < THROTTLE_SIZE; i++) {
  509. struct thermal_cooling_device *cdev;
  510. if (!ts->throt_cfgs[i].init)
  511. continue;
  512. cdev = ts->throt_cfgs[i].cdev;
  513. if (get_thermal_instance(tz, cdev, trip))
  514. stc = find_throttle_cfg_by_name(ts, cdev->type);
  515. else
  516. continue;
  517. ret = throttrip_program(dev, sg, stc, temperature);
  518. if (ret) {
  519. dev_err(dev, "throttrip: %s: error during enable\n",
  520. sg->name);
  521. return ret;
  522. }
  523. dev_info(dev,
  524. "throttrip: will throttle when %s reaches %d mC\n",
  525. sg->name, temperature);
  526. break;
  527. }
  528. if (i == THROTTLE_SIZE)
  529. dev_warn(dev, "throttrip: %s: missing throttle cdev\n",
  530. sg->name);
  531. return 0;
  532. }
  533. #ifdef CONFIG_DEBUG_FS
  534. static int regs_show(struct seq_file *s, void *data)
  535. {
  536. struct platform_device *pdev = s->private;
  537. struct tegra_soctherm *ts = platform_get_drvdata(pdev);
  538. const struct tegra_tsensor *tsensors = ts->soc->tsensors;
  539. const struct tegra_tsensor_group **ttgs = ts->soc->ttgs;
  540. u32 r, state;
  541. int i, level;
  542. seq_puts(s, "-----TSENSE (convert HW)-----\n");
  543. for (i = 0; i < ts->soc->num_tsensors; i++) {
  544. r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG1);
  545. state = REG_GET_MASK(r, SENSOR_CONFIG1_TEMP_ENABLE);
  546. seq_printf(s, "%s: ", tsensors[i].name);
  547. seq_printf(s, "En(%d) ", state);
  548. if (!state) {
  549. seq_puts(s, "\n");
  550. continue;
  551. }
  552. state = REG_GET_MASK(r, SENSOR_CONFIG1_TIDDQ_EN_MASK);
  553. seq_printf(s, "tiddq(%d) ", state);
  554. state = REG_GET_MASK(r, SENSOR_CONFIG1_TEN_COUNT_MASK);
  555. seq_printf(s, "ten_count(%d) ", state);
  556. state = REG_GET_MASK(r, SENSOR_CONFIG1_TSAMPLE_MASK);
  557. seq_printf(s, "tsample(%d) ", state + 1);
  558. r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS1);
  559. state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_VALID_MASK);
  560. seq_printf(s, "Temp(%d/", state);
  561. state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_MASK);
  562. seq_printf(s, "%d) ", translate_temp(state));
  563. r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS0);
  564. state = REG_GET_MASK(r, SENSOR_STATUS0_VALID_MASK);
  565. seq_printf(s, "Capture(%d/", state);
  566. state = REG_GET_MASK(r, SENSOR_STATUS0_CAPTURE_MASK);
  567. seq_printf(s, "%d) ", state);
  568. r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG0);
  569. state = REG_GET_MASK(r, SENSOR_CONFIG0_STOP);
  570. seq_printf(s, "Stop(%d) ", state);
  571. state = REG_GET_MASK(r, SENSOR_CONFIG0_TALL_MASK);
  572. seq_printf(s, "Tall(%d) ", state);
  573. state = REG_GET_MASK(r, SENSOR_CONFIG0_TCALC_OVER);
  574. seq_printf(s, "Over(%d/", state);
  575. state = REG_GET_MASK(r, SENSOR_CONFIG0_OVER);
  576. seq_printf(s, "%d/", state);
  577. state = REG_GET_MASK(r, SENSOR_CONFIG0_CPTR_OVER);
  578. seq_printf(s, "%d) ", state);
  579. r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG2);
  580. state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMA_MASK);
  581. seq_printf(s, "Therm_A/B(%d/", state);
  582. state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMB_MASK);
  583. seq_printf(s, "%d)\n", (s16)state);
  584. }
  585. r = readl(ts->regs + SENSOR_PDIV);
  586. seq_printf(s, "PDIV: 0x%x\n", r);
  587. r = readl(ts->regs + SENSOR_HOTSPOT_OFF);
  588. seq_printf(s, "HOTSPOT: 0x%x\n", r);
  589. seq_puts(s, "\n");
  590. seq_puts(s, "-----SOC_THERM-----\n");
  591. r = readl(ts->regs + SENSOR_TEMP1);
  592. state = REG_GET_MASK(r, SENSOR_TEMP1_CPU_TEMP_MASK);
  593. seq_printf(s, "Temperatures: CPU(%d) ", translate_temp(state));
  594. state = REG_GET_MASK(r, SENSOR_TEMP1_GPU_TEMP_MASK);
  595. seq_printf(s, " GPU(%d) ", translate_temp(state));
  596. r = readl(ts->regs + SENSOR_TEMP2);
  597. state = REG_GET_MASK(r, SENSOR_TEMP2_PLLX_TEMP_MASK);
  598. seq_printf(s, " PLLX(%d) ", translate_temp(state));
  599. state = REG_GET_MASK(r, SENSOR_TEMP2_MEM_TEMP_MASK);
  600. seq_printf(s, " MEM(%d)\n", translate_temp(state));
  601. for (i = 0; i < ts->soc->num_ttgs; i++) {
  602. seq_printf(s, "%s:\n", ttgs[i]->name);
  603. for (level = 0; level < 4; level++) {
  604. s32 v;
  605. u32 mask;
  606. u16 off = ttgs[i]->thermctl_lvl0_offset;
  607. r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
  608. mask = ttgs[i]->thermctl_lvl0_up_thresh_mask;
  609. state = REG_GET_MASK(r, mask);
  610. v = sign_extend32(state, ts->soc->bptt - 1);
  611. v *= ts->soc->thresh_grain;
  612. seq_printf(s, " %d: Up/Dn(%d /", level, v);
  613. mask = ttgs[i]->thermctl_lvl0_dn_thresh_mask;
  614. state = REG_GET_MASK(r, mask);
  615. v = sign_extend32(state, ts->soc->bptt - 1);
  616. v *= ts->soc->thresh_grain;
  617. seq_printf(s, "%d ) ", v);
  618. mask = THERMCTL_LVL0_CPU0_EN_MASK;
  619. state = REG_GET_MASK(r, mask);
  620. seq_printf(s, "En(%d) ", state);
  621. mask = THERMCTL_LVL0_CPU0_CPU_THROT_MASK;
  622. state = REG_GET_MASK(r, mask);
  623. seq_puts(s, "CPU Throt");
  624. if (!state)
  625. seq_printf(s, "(%s) ", "none");
  626. else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT)
  627. seq_printf(s, "(%s) ", "L");
  628. else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY)
  629. seq_printf(s, "(%s) ", "H");
  630. else
  631. seq_printf(s, "(%s) ", "H+L");
  632. mask = THERMCTL_LVL0_CPU0_GPU_THROT_MASK;
  633. state = REG_GET_MASK(r, mask);
  634. seq_puts(s, "GPU Throt");
  635. if (!state)
  636. seq_printf(s, "(%s) ", "none");
  637. else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT)
  638. seq_printf(s, "(%s) ", "L");
  639. else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY)
  640. seq_printf(s, "(%s) ", "H");
  641. else
  642. seq_printf(s, "(%s) ", "H+L");
  643. mask = THERMCTL_LVL0_CPU0_STATUS_MASK;
  644. state = REG_GET_MASK(r, mask);
  645. seq_printf(s, "Status(%s)\n",
  646. state == 0 ? "LO" :
  647. state == 1 ? "In" :
  648. state == 2 ? "Res" : "HI");
  649. }
  650. }
  651. r = readl(ts->regs + THERMCTL_STATS_CTL);
  652. seq_printf(s, "STATS: Up(%s) Dn(%s)\n",
  653. r & STATS_CTL_EN_UP ? "En" : "--",
  654. r & STATS_CTL_EN_DN ? "En" : "--");
  655. for (level = 0; level < 4; level++) {
  656. u16 off;
  657. off = THERMCTL_LVL0_UP_STATS;
  658. r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
  659. seq_printf(s, " Level_%d Up(%d) ", level, r);
  660. off = THERMCTL_LVL0_DN_STATS;
  661. r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
  662. seq_printf(s, "Dn(%d)\n", r);
  663. }
  664. r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
  665. state = REG_GET_MASK(r, ttgs[0]->thermtrip_any_en_mask);
  666. seq_printf(s, "Thermtrip Any En(%d)\n", state);
  667. for (i = 0; i < ts->soc->num_ttgs; i++) {
  668. state = REG_GET_MASK(r, ttgs[i]->thermtrip_enable_mask);
  669. seq_printf(s, " %s En(%d) ", ttgs[i]->name, state);
  670. state = REG_GET_MASK(r, ttgs[i]->thermtrip_threshold_mask);
  671. state *= ts->soc->thresh_grain;
  672. seq_printf(s, "Thresh(%d)\n", state);
  673. }
  674. r = readl(ts->regs + THROT_GLOBAL_CFG);
  675. seq_puts(s, "\n");
  676. seq_printf(s, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r);
  677. seq_puts(s, "---------------------------------------------------\n");
  678. r = readl(ts->regs + THROT_STATUS);
  679. state = REG_GET_MASK(r, THROT_STATUS_BREACH_MASK);
  680. seq_printf(s, "THROT STATUS: breach(%d) ", state);
  681. state = REG_GET_MASK(r, THROT_STATUS_STATE_MASK);
  682. seq_printf(s, "state(%d) ", state);
  683. state = REG_GET_MASK(r, THROT_STATUS_ENABLED_MASK);
  684. seq_printf(s, "enabled(%d)\n", state);
  685. r = readl(ts->regs + CPU_PSKIP_STATUS);
  686. if (ts->soc->use_ccroc) {
  687. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
  688. seq_printf(s, "CPU PSKIP STATUS: enabled(%d)\n", state);
  689. } else {
  690. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_M_MASK);
  691. seq_printf(s, "CPU PSKIP STATUS: M(%d) ", state);
  692. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_N_MASK);
  693. seq_printf(s, "N(%d) ", state);
  694. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
  695. seq_printf(s, "enabled(%d)\n", state);
  696. }
  697. return 0;
  698. }
  699. static int regs_open(struct inode *inode, struct file *file)
  700. {
  701. return single_open(file, regs_show, inode->i_private);
  702. }
  703. static const struct file_operations regs_fops = {
  704. .open = regs_open,
  705. .read = seq_read,
  706. .llseek = seq_lseek,
  707. .release = single_release,
  708. };
  709. static void soctherm_debug_init(struct platform_device *pdev)
  710. {
  711. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  712. struct dentry *root, *file;
  713. root = debugfs_create_dir("soctherm", NULL);
  714. if (!root) {
  715. dev_err(&pdev->dev, "failed to create debugfs directory\n");
  716. return;
  717. }
  718. tegra->debugfs_dir = root;
  719. file = debugfs_create_file("reg_contents", 0644, root,
  720. pdev, &regs_fops);
  721. if (!file) {
  722. dev_err(&pdev->dev, "failed to create debugfs file\n");
  723. debugfs_remove_recursive(tegra->debugfs_dir);
  724. tegra->debugfs_dir = NULL;
  725. }
  726. }
  727. #else
  728. static inline void soctherm_debug_init(struct platform_device *pdev) {}
  729. #endif
  730. static int soctherm_clk_enable(struct platform_device *pdev, bool enable)
  731. {
  732. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  733. int err;
  734. if (!tegra->clock_soctherm || !tegra->clock_tsensor)
  735. return -EINVAL;
  736. reset_control_assert(tegra->reset);
  737. if (enable) {
  738. err = clk_prepare_enable(tegra->clock_soctherm);
  739. if (err) {
  740. reset_control_deassert(tegra->reset);
  741. return err;
  742. }
  743. err = clk_prepare_enable(tegra->clock_tsensor);
  744. if (err) {
  745. clk_disable_unprepare(tegra->clock_soctherm);
  746. reset_control_deassert(tegra->reset);
  747. return err;
  748. }
  749. } else {
  750. clk_disable_unprepare(tegra->clock_tsensor);
  751. clk_disable_unprepare(tegra->clock_soctherm);
  752. }
  753. reset_control_deassert(tegra->reset);
  754. return 0;
  755. }
  756. static int throt_get_cdev_max_state(struct thermal_cooling_device *cdev,
  757. unsigned long *max_state)
  758. {
  759. *max_state = 1;
  760. return 0;
  761. }
  762. static int throt_get_cdev_cur_state(struct thermal_cooling_device *cdev,
  763. unsigned long *cur_state)
  764. {
  765. struct tegra_soctherm *ts = cdev->devdata;
  766. u32 r;
  767. r = readl(ts->regs + THROT_STATUS);
  768. if (REG_GET_MASK(r, THROT_STATUS_STATE_MASK))
  769. *cur_state = 1;
  770. else
  771. *cur_state = 0;
  772. return 0;
  773. }
  774. static int throt_set_cdev_state(struct thermal_cooling_device *cdev,
  775. unsigned long cur_state)
  776. {
  777. return 0;
  778. }
  779. static struct thermal_cooling_device_ops throt_cooling_ops = {
  780. .get_max_state = throt_get_cdev_max_state,
  781. .get_cur_state = throt_get_cdev_cur_state,
  782. .set_cur_state = throt_set_cdev_state,
  783. };
  784. /**
  785. * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
  786. * and register them as cooling devices.
  787. */
  788. static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
  789. {
  790. struct device *dev = &pdev->dev;
  791. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  792. struct device_node *np_stc, *np_stcc;
  793. const char *name;
  794. u32 val;
  795. int i, r;
  796. for (i = 0; i < THROTTLE_SIZE; i++) {
  797. ts->throt_cfgs[i].name = throt_names[i];
  798. ts->throt_cfgs[i].id = i;
  799. ts->throt_cfgs[i].init = false;
  800. }
  801. np_stc = of_get_child_by_name(dev->of_node, "throttle-cfgs");
  802. if (!np_stc) {
  803. dev_info(dev,
  804. "throttle-cfg: no throttle-cfgs - not enabling\n");
  805. return;
  806. }
  807. for_each_child_of_node(np_stc, np_stcc) {
  808. struct soctherm_throt_cfg *stc;
  809. struct thermal_cooling_device *tcd;
  810. name = np_stcc->name;
  811. stc = find_throttle_cfg_by_name(ts, name);
  812. if (!stc) {
  813. dev_err(dev,
  814. "throttle-cfg: could not find %s\n", name);
  815. continue;
  816. }
  817. r = of_property_read_u32(np_stcc, "nvidia,priority", &val);
  818. if (r) {
  819. dev_info(dev,
  820. "throttle-cfg: %s: missing priority\n", name);
  821. continue;
  822. }
  823. stc->priority = val;
  824. if (ts->soc->use_ccroc) {
  825. r = of_property_read_u32(np_stcc,
  826. "nvidia,cpu-throt-level",
  827. &val);
  828. if (r) {
  829. dev_info(dev,
  830. "throttle-cfg: %s: missing cpu-throt-level\n",
  831. name);
  832. continue;
  833. }
  834. stc->cpu_throt_level = val;
  835. } else {
  836. r = of_property_read_u32(np_stcc,
  837. "nvidia,cpu-throt-percent",
  838. &val);
  839. if (r) {
  840. dev_info(dev,
  841. "throttle-cfg: %s: missing cpu-throt-percent\n",
  842. name);
  843. continue;
  844. }
  845. stc->cpu_throt_depth = val;
  846. }
  847. tcd = thermal_of_cooling_device_register(np_stcc,
  848. (char *)name, ts,
  849. &throt_cooling_ops);
  850. of_node_put(np_stcc);
  851. if (IS_ERR_OR_NULL(tcd)) {
  852. dev_err(dev,
  853. "throttle-cfg: %s: failed to register cooling device\n",
  854. name);
  855. continue;
  856. }
  857. stc->cdev = tcd;
  858. stc->init = true;
  859. }
  860. of_node_put(np_stc);
  861. }
  862. /**
  863. * throttlectl_cpu_level_cfg() - programs CCROC NV_THERM level config
  864. * @level: describing the level LOW/MED/HIGH of throttling
  865. *
  866. * It's necessary to set up the CPU-local CCROC NV_THERM instance with
  867. * the M/N values desired for each level. This function does this.
  868. *
  869. * This function pre-programs the CCROC NV_THERM levels in terms of
  870. * pre-configured "Low", "Medium" or "Heavy" throttle levels which are
  871. * mapped to THROT_LEVEL_LOW, THROT_LEVEL_MED and THROT_LEVEL_HVY.
  872. */
  873. static void throttlectl_cpu_level_cfg(struct tegra_soctherm *ts, int level)
  874. {
  875. u8 depth, dividend;
  876. u32 r;
  877. switch (level) {
  878. case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
  879. depth = 50;
  880. break;
  881. case TEGRA_SOCTHERM_THROT_LEVEL_MED:
  882. depth = 75;
  883. break;
  884. case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
  885. depth = 80;
  886. break;
  887. case TEGRA_SOCTHERM_THROT_LEVEL_NONE:
  888. return;
  889. default:
  890. return;
  891. }
  892. dividend = THROT_DEPTH_DIVIDEND(depth);
  893. /* setup PSKIP in ccroc nv_therm registers */
  894. r = ccroc_readl(ts, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
  895. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
  896. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_STEP_MASK, 0xf);
  897. ccroc_writel(ts, r, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
  898. r = ccroc_readl(ts, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
  899. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_ENB_MASK, 1);
  900. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
  901. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
  902. ccroc_writel(ts, r, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
  903. }
  904. /**
  905. * throttlectl_cpu_level_select() - program CPU pulse skipper config
  906. * @throt: the LIGHT/HEAVY of throttle event id
  907. *
  908. * Pulse skippers are used to throttle clock frequencies. This
  909. * function programs the pulse skippers based on @throt and platform
  910. * data. This function is used on SoCs which have CPU-local pulse
  911. * skipper control, such as T13x. It programs soctherm's interface to
  912. * Denver:CCROC NV_THERM in terms of Low, Medium and HIGH throttling
  913. * vectors. PSKIP_BYPASS mode is set as required per HW spec.
  914. */
  915. static void throttlectl_cpu_level_select(struct tegra_soctherm *ts,
  916. enum soctherm_throttle_id throt)
  917. {
  918. u32 r, throt_vect;
  919. /* Denver:CCROC NV_THERM interface N:3 Mapping */
  920. switch (ts->throt_cfgs[throt].cpu_throt_level) {
  921. case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
  922. throt_vect = THROT_VECT_LOW;
  923. break;
  924. case TEGRA_SOCTHERM_THROT_LEVEL_MED:
  925. throt_vect = THROT_VECT_MED;
  926. break;
  927. case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
  928. throt_vect = THROT_VECT_HIGH;
  929. break;
  930. default:
  931. throt_vect = THROT_VECT_NONE;
  932. break;
  933. }
  934. r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  935. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
  936. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT_CPU_MASK, throt_vect);
  937. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT2_CPU_MASK, throt_vect);
  938. writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  939. /* bypass sequencer in soc_therm as it is programmed in ccroc */
  940. r = REG_SET_MASK(0, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK, 1);
  941. writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
  942. }
  943. /**
  944. * throttlectl_cpu_mn() - program CPU pulse skipper configuration
  945. * @throt: the LIGHT/HEAVY of throttle event id
  946. *
  947. * Pulse skippers are used to throttle clock frequencies. This
  948. * function programs the pulse skippers based on @throt and platform
  949. * data. This function is used for CPUs that have "remote" pulse
  950. * skipper control, e.g., the CPU pulse skipper is controlled by the
  951. * SOC_THERM IP block. (SOC_THERM is located outside the CPU
  952. * complex.)
  953. */
  954. static void throttlectl_cpu_mn(struct tegra_soctherm *ts,
  955. enum soctherm_throttle_id throt)
  956. {
  957. u32 r;
  958. int depth;
  959. u8 dividend;
  960. depth = ts->throt_cfgs[throt].cpu_throt_depth;
  961. dividend = THROT_DEPTH_DIVIDEND(depth);
  962. r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  963. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
  964. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
  965. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
  966. writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  967. r = readl(ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
  968. r = REG_SET_MASK(r, THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
  969. r = REG_SET_MASK(r, THROT_PSKIP_RAMP_STEP_MASK, 0xf);
  970. writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
  971. }
  972. /**
  973. * soctherm_throttle_program() - programs pulse skippers' configuration
  974. * @throt: the LIGHT/HEAVY of the throttle event id.
  975. *
  976. * Pulse skippers are used to throttle clock frequencies.
  977. * This function programs the pulse skippers.
  978. */
  979. static void soctherm_throttle_program(struct tegra_soctherm *ts,
  980. enum soctherm_throttle_id throt)
  981. {
  982. u32 r;
  983. struct soctherm_throt_cfg stc = ts->throt_cfgs[throt];
  984. if (!stc.init)
  985. return;
  986. /* Setup PSKIP parameters */
  987. if (ts->soc->use_ccroc)
  988. throttlectl_cpu_level_select(ts, throt);
  989. else
  990. throttlectl_cpu_mn(ts, throt);
  991. r = REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK, stc.priority);
  992. writel(r, ts->regs + THROT_PRIORITY_CTRL(throt));
  993. r = REG_SET_MASK(0, THROT_DELAY_LITE_DELAY_MASK, 0);
  994. writel(r, ts->regs + THROT_DELAY_CTRL(throt));
  995. r = readl(ts->regs + THROT_PRIORITY_LOCK);
  996. r = REG_GET_MASK(r, THROT_PRIORITY_LOCK_PRIORITY_MASK);
  997. if (r >= stc.priority)
  998. return;
  999. r = REG_SET_MASK(0, THROT_PRIORITY_LOCK_PRIORITY_MASK,
  1000. stc.priority);
  1001. writel(r, ts->regs + THROT_PRIORITY_LOCK);
  1002. }
  1003. static void tegra_soctherm_throttle(struct device *dev)
  1004. {
  1005. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  1006. u32 v;
  1007. int i;
  1008. /* configure LOW, MED and HIGH levels for CCROC NV_THERM */
  1009. if (ts->soc->use_ccroc) {
  1010. throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_LOW);
  1011. throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_MED);
  1012. throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_HIGH);
  1013. }
  1014. /* Thermal HW throttle programming */
  1015. for (i = 0; i < THROTTLE_SIZE; i++)
  1016. soctherm_throttle_program(ts, i);
  1017. v = REG_SET_MASK(0, THROT_GLOBAL_ENB_MASK, 1);
  1018. if (ts->soc->use_ccroc) {
  1019. ccroc_writel(ts, v, CCROC_GLOBAL_CFG);
  1020. v = ccroc_readl(ts, CCROC_SUPER_CCLKG_DIVIDER);
  1021. v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
  1022. ccroc_writel(ts, v, CCROC_SUPER_CCLKG_DIVIDER);
  1023. } else {
  1024. writel(v, ts->regs + THROT_GLOBAL_CFG);
  1025. v = clk_readl(ts, CAR_SUPER_CCLKG_DIVIDER);
  1026. v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
  1027. clk_writel(ts, v, CAR_SUPER_CCLKG_DIVIDER);
  1028. }
  1029. /* initialize stats collection */
  1030. v = STATS_CTL_CLR_DN | STATS_CTL_EN_DN |
  1031. STATS_CTL_CLR_UP | STATS_CTL_EN_UP;
  1032. writel(v, ts->regs + THERMCTL_STATS_CTL);
  1033. }
  1034. static void soctherm_init(struct platform_device *pdev)
  1035. {
  1036. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1037. const struct tegra_tsensor_group **ttgs = tegra->soc->ttgs;
  1038. int i;
  1039. u32 pdiv, hotspot;
  1040. /* Initialize raw sensors */
  1041. for (i = 0; i < tegra->soc->num_tsensors; ++i)
  1042. enable_tsensor(tegra, i);
  1043. /* program pdiv and hotspot offsets per THERM */
  1044. pdiv = readl(tegra->regs + SENSOR_PDIV);
  1045. hotspot = readl(tegra->regs + SENSOR_HOTSPOT_OFF);
  1046. for (i = 0; i < tegra->soc->num_ttgs; ++i) {
  1047. pdiv = REG_SET_MASK(pdiv, ttgs[i]->pdiv_mask,
  1048. ttgs[i]->pdiv);
  1049. /* hotspot offset from PLLX, doesn't need to configure PLLX */
  1050. if (ttgs[i]->id == TEGRA124_SOCTHERM_SENSOR_PLLX)
  1051. continue;
  1052. hotspot = REG_SET_MASK(hotspot,
  1053. ttgs[i]->pllx_hotspot_mask,
  1054. ttgs[i]->pllx_hotspot_diff);
  1055. }
  1056. writel(pdiv, tegra->regs + SENSOR_PDIV);
  1057. writel(hotspot, tegra->regs + SENSOR_HOTSPOT_OFF);
  1058. /* Configure hw throttle */
  1059. tegra_soctherm_throttle(&pdev->dev);
  1060. }
  1061. static const struct of_device_id tegra_soctherm_of_match[] = {
  1062. #ifdef CONFIG_ARCH_TEGRA_124_SOC
  1063. {
  1064. .compatible = "nvidia,tegra124-soctherm",
  1065. .data = &tegra124_soctherm,
  1066. },
  1067. #endif
  1068. #ifdef CONFIG_ARCH_TEGRA_132_SOC
  1069. {
  1070. .compatible = "nvidia,tegra132-soctherm",
  1071. .data = &tegra132_soctherm,
  1072. },
  1073. #endif
  1074. #ifdef CONFIG_ARCH_TEGRA_210_SOC
  1075. {
  1076. .compatible = "nvidia,tegra210-soctherm",
  1077. .data = &tegra210_soctherm,
  1078. },
  1079. #endif
  1080. { },
  1081. };
  1082. MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
  1083. static int tegra_soctherm_probe(struct platform_device *pdev)
  1084. {
  1085. const struct of_device_id *match;
  1086. struct tegra_soctherm *tegra;
  1087. struct thermal_zone_device *z;
  1088. struct tsensor_shared_calib shared_calib;
  1089. struct resource *res;
  1090. struct tegra_soctherm_soc *soc;
  1091. unsigned int i;
  1092. int err;
  1093. match = of_match_node(tegra_soctherm_of_match, pdev->dev.of_node);
  1094. if (!match)
  1095. return -ENODEV;
  1096. soc = (struct tegra_soctherm_soc *)match->data;
  1097. if (soc->num_ttgs > TEGRA124_SOCTHERM_SENSOR_NUM)
  1098. return -EINVAL;
  1099. tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
  1100. if (!tegra)
  1101. return -ENOMEM;
  1102. dev_set_drvdata(&pdev->dev, tegra);
  1103. tegra->soc = soc;
  1104. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  1105. "soctherm-reg");
  1106. tegra->regs = devm_ioremap_resource(&pdev->dev, res);
  1107. if (IS_ERR(tegra->regs)) {
  1108. dev_err(&pdev->dev, "can't get soctherm registers");
  1109. return PTR_ERR(tegra->regs);
  1110. }
  1111. if (!tegra->soc->use_ccroc) {
  1112. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  1113. "car-reg");
  1114. tegra->clk_regs = devm_ioremap_resource(&pdev->dev, res);
  1115. if (IS_ERR(tegra->clk_regs)) {
  1116. dev_err(&pdev->dev, "can't get car clk registers");
  1117. return PTR_ERR(tegra->clk_regs);
  1118. }
  1119. } else {
  1120. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  1121. "ccroc-reg");
  1122. tegra->ccroc_regs = devm_ioremap_resource(&pdev->dev, res);
  1123. if (IS_ERR(tegra->ccroc_regs)) {
  1124. dev_err(&pdev->dev, "can't get ccroc registers");
  1125. return PTR_ERR(tegra->ccroc_regs);
  1126. }
  1127. }
  1128. tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm");
  1129. if (IS_ERR(tegra->reset)) {
  1130. dev_err(&pdev->dev, "can't get soctherm reset\n");
  1131. return PTR_ERR(tegra->reset);
  1132. }
  1133. tegra->clock_tsensor = devm_clk_get(&pdev->dev, "tsensor");
  1134. if (IS_ERR(tegra->clock_tsensor)) {
  1135. dev_err(&pdev->dev, "can't get tsensor clock\n");
  1136. return PTR_ERR(tegra->clock_tsensor);
  1137. }
  1138. tegra->clock_soctherm = devm_clk_get(&pdev->dev, "soctherm");
  1139. if (IS_ERR(tegra->clock_soctherm)) {
  1140. dev_err(&pdev->dev, "can't get soctherm clock\n");
  1141. return PTR_ERR(tegra->clock_soctherm);
  1142. }
  1143. tegra->calib = devm_kzalloc(&pdev->dev,
  1144. sizeof(u32) * soc->num_tsensors,
  1145. GFP_KERNEL);
  1146. if (!tegra->calib)
  1147. return -ENOMEM;
  1148. /* calculate shared calibration data */
  1149. err = tegra_calc_shared_calib(soc->tfuse, &shared_calib);
  1150. if (err)
  1151. return err;
  1152. /* calculate tsensor calibaration data */
  1153. for (i = 0; i < soc->num_tsensors; ++i) {
  1154. err = tegra_calc_tsensor_calib(&soc->tsensors[i],
  1155. &shared_calib,
  1156. &tegra->calib[i]);
  1157. if (err)
  1158. return err;
  1159. }
  1160. tegra->thermctl_tzs = devm_kzalloc(&pdev->dev,
  1161. sizeof(*z) * soc->num_ttgs,
  1162. GFP_KERNEL);
  1163. if (!tegra->thermctl_tzs)
  1164. return -ENOMEM;
  1165. err = soctherm_clk_enable(pdev, true);
  1166. if (err)
  1167. return err;
  1168. soctherm_init_hw_throt_cdev(pdev);
  1169. soctherm_init(pdev);
  1170. for (i = 0; i < soc->num_ttgs; ++i) {
  1171. struct tegra_thermctl_zone *zone =
  1172. devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL);
  1173. if (!zone) {
  1174. err = -ENOMEM;
  1175. goto disable_clocks;
  1176. }
  1177. zone->reg = tegra->regs + soc->ttgs[i]->sensor_temp_offset;
  1178. zone->dev = &pdev->dev;
  1179. zone->sg = soc->ttgs[i];
  1180. zone->ts = tegra;
  1181. z = devm_thermal_zone_of_sensor_register(&pdev->dev,
  1182. soc->ttgs[i]->id, zone,
  1183. &tegra_of_thermal_ops);
  1184. if (IS_ERR(z)) {
  1185. err = PTR_ERR(z);
  1186. dev_err(&pdev->dev, "failed to register sensor: %d\n",
  1187. err);
  1188. goto disable_clocks;
  1189. }
  1190. zone->tz = z;
  1191. tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
  1192. /* Configure hw trip points */
  1193. err = tegra_soctherm_set_hwtrips(&pdev->dev, soc->ttgs[i], z);
  1194. if (err)
  1195. goto disable_clocks;
  1196. }
  1197. soctherm_debug_init(pdev);
  1198. return 0;
  1199. disable_clocks:
  1200. soctherm_clk_enable(pdev, false);
  1201. return err;
  1202. }
  1203. static int tegra_soctherm_remove(struct platform_device *pdev)
  1204. {
  1205. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1206. debugfs_remove_recursive(tegra->debugfs_dir);
  1207. soctherm_clk_enable(pdev, false);
  1208. return 0;
  1209. }
  1210. static int __maybe_unused soctherm_suspend(struct device *dev)
  1211. {
  1212. struct platform_device *pdev = to_platform_device(dev);
  1213. soctherm_clk_enable(pdev, false);
  1214. return 0;
  1215. }
  1216. static int __maybe_unused soctherm_resume(struct device *dev)
  1217. {
  1218. struct platform_device *pdev = to_platform_device(dev);
  1219. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1220. struct tegra_soctherm_soc *soc = tegra->soc;
  1221. int err, i;
  1222. err = soctherm_clk_enable(pdev, true);
  1223. if (err) {
  1224. dev_err(&pdev->dev,
  1225. "Resume failed: enable clocks failed\n");
  1226. return err;
  1227. }
  1228. soctherm_init(pdev);
  1229. for (i = 0; i < soc->num_ttgs; ++i) {
  1230. struct thermal_zone_device *tz;
  1231. tz = tegra->thermctl_tzs[soc->ttgs[i]->id];
  1232. err = tegra_soctherm_set_hwtrips(dev, soc->ttgs[i], tz);
  1233. if (err) {
  1234. dev_err(&pdev->dev,
  1235. "Resume failed: set hwtrips failed\n");
  1236. return err;
  1237. }
  1238. }
  1239. return 0;
  1240. }
  1241. static SIMPLE_DEV_PM_OPS(tegra_soctherm_pm, soctherm_suspend, soctherm_resume);
  1242. static struct platform_driver tegra_soctherm_driver = {
  1243. .probe = tegra_soctherm_probe,
  1244. .remove = tegra_soctherm_remove,
  1245. .driver = {
  1246. .name = "tegra_soctherm",
  1247. .pm = &tegra_soctherm_pm,
  1248. .of_match_table = tegra_soctherm_of_match,
  1249. },
  1250. };
  1251. module_platform_driver(tegra_soctherm_driver);
  1252. MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
  1253. MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver");
  1254. MODULE_LICENSE("GPL v2");