soctherm.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497
  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. static int
  288. thermtrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
  289. int trip_temp);
  290. static int
  291. throttrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
  292. struct soctherm_throt_cfg *stc, int trip_temp);
  293. static struct soctherm_throt_cfg *
  294. find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name);
  295. static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
  296. {
  297. struct tegra_thermctl_zone *zone = data;
  298. struct thermal_zone_device *tz = zone->tz;
  299. struct tegra_soctherm *ts = zone->ts;
  300. const struct tegra_tsensor_group *sg = zone->sg;
  301. struct device *dev = zone->dev;
  302. enum thermal_trip_type type;
  303. int ret;
  304. if (!tz)
  305. return -EINVAL;
  306. ret = tz->ops->get_trip_type(tz, trip, &type);
  307. if (ret)
  308. return ret;
  309. if (type == THERMAL_TRIP_CRITICAL) {
  310. return thermtrip_program(dev, sg, temp);
  311. } else if (type == THERMAL_TRIP_HOT) {
  312. int i;
  313. for (i = 0; i < THROTTLE_SIZE; i++) {
  314. struct thermal_cooling_device *cdev;
  315. struct soctherm_throt_cfg *stc;
  316. if (!ts->throt_cfgs[i].init)
  317. continue;
  318. cdev = ts->throt_cfgs[i].cdev;
  319. if (get_thermal_instance(tz, cdev, trip))
  320. stc = find_throttle_cfg_by_name(ts, cdev->type);
  321. else
  322. continue;
  323. return throttrip_program(dev, sg, stc, temp);
  324. }
  325. }
  326. return 0;
  327. }
  328. static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
  329. .get_temp = tegra_thermctl_get_temp,
  330. .set_trip_temp = tegra_thermctl_set_trip_temp,
  331. };
  332. /**
  333. * enforce_temp_range() - check and enforce temperature range [min, max]
  334. * @trip_temp: the trip temperature to check
  335. *
  336. * Checks and enforces the permitted temperature range that SOC_THERM
  337. * HW can support This is
  338. * done while taking care of precision.
  339. *
  340. * Return: The precision adjusted capped temperature in millicelsius.
  341. */
  342. static int enforce_temp_range(struct device *dev, int trip_temp)
  343. {
  344. int temp;
  345. temp = clamp_val(trip_temp, min_low_temp, max_high_temp);
  346. if (temp != trip_temp)
  347. dev_info(dev, "soctherm: trip temperature %d forced to %d\n",
  348. trip_temp, temp);
  349. return temp;
  350. }
  351. /**
  352. * thermtrip_program() - Configures the hardware to shut down the
  353. * system if a given sensor group reaches a given temperature
  354. * @dev: ptr to the struct device for the SOC_THERM IP block
  355. * @sg: pointer to the sensor group to set the thermtrip temperature for
  356. * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
  357. *
  358. * Sets the thermal trip threshold of the given sensor group to be the
  359. * @trip_temp. If this threshold is crossed, the hardware will shut
  360. * down.
  361. *
  362. * Note that, although @trip_temp is specified in millicelsius, the
  363. * hardware is programmed in degrees Celsius.
  364. *
  365. * Return: 0 upon success, or %-EINVAL upon failure.
  366. */
  367. static int thermtrip_program(struct device *dev,
  368. const struct tegra_tsensor_group *sg,
  369. int trip_temp)
  370. {
  371. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  372. int temp;
  373. u32 r;
  374. if (!sg || !sg->thermtrip_threshold_mask)
  375. return -EINVAL;
  376. temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
  377. r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
  378. r = REG_SET_MASK(r, sg->thermtrip_threshold_mask, temp);
  379. r = REG_SET_MASK(r, sg->thermtrip_enable_mask, 1);
  380. r = REG_SET_MASK(r, sg->thermtrip_any_en_mask, 0);
  381. writel(r, ts->regs + THERMCTL_THERMTRIP_CTL);
  382. return 0;
  383. }
  384. /**
  385. * throttrip_program() - Configures the hardware to throttle the
  386. * pulse if a given sensor group reaches a given temperature
  387. * @dev: ptr to the struct device for the SOC_THERM IP block
  388. * @sg: pointer to the sensor group to set the thermtrip temperature for
  389. * @stc: pointer to the throttle need to be triggered
  390. * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
  391. *
  392. * Sets the thermal trip threshold and throttle event of the given sensor
  393. * group. If this threshold is crossed, the hardware will trigger the
  394. * throttle.
  395. *
  396. * Note that, although @trip_temp is specified in millicelsius, the
  397. * hardware is programmed in degrees Celsius.
  398. *
  399. * Return: 0 upon success, or %-EINVAL upon failure.
  400. */
  401. static int throttrip_program(struct device *dev,
  402. const struct tegra_tsensor_group *sg,
  403. struct soctherm_throt_cfg *stc,
  404. int trip_temp)
  405. {
  406. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  407. int temp, cpu_throt, gpu_throt;
  408. unsigned int throt;
  409. u32 r, reg_off;
  410. if (!dev || !sg || !stc || !stc->init)
  411. return -EINVAL;
  412. temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
  413. /* Hardcode LIGHT on LEVEL1 and HEAVY on LEVEL2 */
  414. throt = stc->id;
  415. reg_off = THERMCTL_LVL_REG(sg->thermctl_lvl0_offset, throt + 1);
  416. if (throt == THROTTLE_LIGHT) {
  417. cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT;
  418. gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT;
  419. } else {
  420. cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY;
  421. gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY;
  422. if (throt != THROTTLE_HEAVY)
  423. dev_warn(dev,
  424. "invalid throt id %d - assuming HEAVY",
  425. throt);
  426. }
  427. r = readl(ts->regs + reg_off);
  428. r = REG_SET_MASK(r, sg->thermctl_lvl0_up_thresh_mask, temp);
  429. r = REG_SET_MASK(r, sg->thermctl_lvl0_dn_thresh_mask, temp);
  430. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_CPU_THROT_MASK, cpu_throt);
  431. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_GPU_THROT_MASK, gpu_throt);
  432. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
  433. writel(r, ts->regs + reg_off);
  434. return 0;
  435. }
  436. static struct soctherm_throt_cfg *
  437. find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name)
  438. {
  439. unsigned int i;
  440. for (i = 0; ts->throt_cfgs[i].name; i++)
  441. if (!strcmp(ts->throt_cfgs[i].name, name))
  442. return &ts->throt_cfgs[i];
  443. return NULL;
  444. }
  445. static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
  446. {
  447. int ntrips, i, ret;
  448. enum thermal_trip_type type;
  449. ntrips = of_thermal_get_ntrips(tz);
  450. if (ntrips <= 0)
  451. return -EINVAL;
  452. for (i = 0; i < ntrips; i++) {
  453. ret = tz->ops->get_trip_type(tz, i, &type);
  454. if (ret)
  455. return -EINVAL;
  456. if (type == THERMAL_TRIP_HOT) {
  457. ret = tz->ops->get_trip_temp(tz, i, temp);
  458. if (!ret)
  459. *trip = i;
  460. return ret;
  461. }
  462. }
  463. return -EINVAL;
  464. }
  465. /**
  466. * tegra_soctherm_set_hwtrips() - set HW trip point from DT data
  467. * @dev: struct device * of the SOC_THERM instance
  468. *
  469. * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
  470. * "THROTTLE" trip points , using "critical" or "hot" type trip_temp
  471. * from thermal zone.
  472. * After they have been configured, THERMTRIP or THROTTLE will take
  473. * action when the configured SoC thermal sensor group reaches a
  474. * certain temperature.
  475. *
  476. * Return: 0 upon success, or a negative error code on failure.
  477. * "Success" does not mean that trips was enabled; it could also
  478. * mean that no node was found in DT.
  479. * THERMTRIP has been enabled successfully when a message similar to
  480. * this one appears on the serial console:
  481. * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC"
  482. * THROTTLE has been enabled successfully when a message similar to
  483. * this one appears on the serial console:
  484. * ""throttrip: will throttle when sensor group XXX reaches YYYYYY mC"
  485. */
  486. static int tegra_soctherm_set_hwtrips(struct device *dev,
  487. const struct tegra_tsensor_group *sg,
  488. struct thermal_zone_device *tz)
  489. {
  490. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  491. struct soctherm_throt_cfg *stc;
  492. int i, trip, temperature;
  493. int ret;
  494. ret = tz->ops->get_crit_temp(tz, &temperature);
  495. if (ret) {
  496. dev_warn(dev, "thermtrip: %s: missing critical temperature\n",
  497. sg->name);
  498. goto set_throttle;
  499. }
  500. ret = thermtrip_program(dev, sg, temperature);
  501. if (ret) {
  502. dev_err(dev, "thermtrip: %s: error during enable\n",
  503. sg->name);
  504. return ret;
  505. }
  506. dev_info(dev,
  507. "thermtrip: will shut down when %s reaches %d mC\n",
  508. sg->name, temperature);
  509. set_throttle:
  510. ret = get_hot_temp(tz, &trip, &temperature);
  511. if (ret) {
  512. dev_warn(dev, "throttrip: %s: missing hot temperature\n",
  513. sg->name);
  514. return 0;
  515. }
  516. for (i = 0; i < THROTTLE_SIZE; i++) {
  517. struct thermal_cooling_device *cdev;
  518. if (!ts->throt_cfgs[i].init)
  519. continue;
  520. cdev = ts->throt_cfgs[i].cdev;
  521. if (get_thermal_instance(tz, cdev, trip))
  522. stc = find_throttle_cfg_by_name(ts, cdev->type);
  523. else
  524. continue;
  525. ret = throttrip_program(dev, sg, stc, temperature);
  526. if (ret) {
  527. dev_err(dev, "throttrip: %s: error during enable\n",
  528. sg->name);
  529. return ret;
  530. }
  531. dev_info(dev,
  532. "throttrip: will throttle when %s reaches %d mC\n",
  533. sg->name, temperature);
  534. break;
  535. }
  536. if (i == THROTTLE_SIZE)
  537. dev_warn(dev, "throttrip: %s: missing throttle cdev\n",
  538. sg->name);
  539. return 0;
  540. }
  541. #ifdef CONFIG_DEBUG_FS
  542. static int regs_show(struct seq_file *s, void *data)
  543. {
  544. struct platform_device *pdev = s->private;
  545. struct tegra_soctherm *ts = platform_get_drvdata(pdev);
  546. const struct tegra_tsensor *tsensors = ts->soc->tsensors;
  547. const struct tegra_tsensor_group **ttgs = ts->soc->ttgs;
  548. u32 r, state;
  549. int i, level;
  550. seq_puts(s, "-----TSENSE (convert HW)-----\n");
  551. for (i = 0; i < ts->soc->num_tsensors; i++) {
  552. r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG1);
  553. state = REG_GET_MASK(r, SENSOR_CONFIG1_TEMP_ENABLE);
  554. seq_printf(s, "%s: ", tsensors[i].name);
  555. seq_printf(s, "En(%d) ", state);
  556. if (!state) {
  557. seq_puts(s, "\n");
  558. continue;
  559. }
  560. state = REG_GET_MASK(r, SENSOR_CONFIG1_TIDDQ_EN_MASK);
  561. seq_printf(s, "tiddq(%d) ", state);
  562. state = REG_GET_MASK(r, SENSOR_CONFIG1_TEN_COUNT_MASK);
  563. seq_printf(s, "ten_count(%d) ", state);
  564. state = REG_GET_MASK(r, SENSOR_CONFIG1_TSAMPLE_MASK);
  565. seq_printf(s, "tsample(%d) ", state + 1);
  566. r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS1);
  567. state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_VALID_MASK);
  568. seq_printf(s, "Temp(%d/", state);
  569. state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_MASK);
  570. seq_printf(s, "%d) ", translate_temp(state));
  571. r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS0);
  572. state = REG_GET_MASK(r, SENSOR_STATUS0_VALID_MASK);
  573. seq_printf(s, "Capture(%d/", state);
  574. state = REG_GET_MASK(r, SENSOR_STATUS0_CAPTURE_MASK);
  575. seq_printf(s, "%d) ", state);
  576. r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG0);
  577. state = REG_GET_MASK(r, SENSOR_CONFIG0_STOP);
  578. seq_printf(s, "Stop(%d) ", state);
  579. state = REG_GET_MASK(r, SENSOR_CONFIG0_TALL_MASK);
  580. seq_printf(s, "Tall(%d) ", state);
  581. state = REG_GET_MASK(r, SENSOR_CONFIG0_TCALC_OVER);
  582. seq_printf(s, "Over(%d/", state);
  583. state = REG_GET_MASK(r, SENSOR_CONFIG0_OVER);
  584. seq_printf(s, "%d/", state);
  585. state = REG_GET_MASK(r, SENSOR_CONFIG0_CPTR_OVER);
  586. seq_printf(s, "%d) ", state);
  587. r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG2);
  588. state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMA_MASK);
  589. seq_printf(s, "Therm_A/B(%d/", state);
  590. state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMB_MASK);
  591. seq_printf(s, "%d)\n", (s16)state);
  592. }
  593. r = readl(ts->regs + SENSOR_PDIV);
  594. seq_printf(s, "PDIV: 0x%x\n", r);
  595. r = readl(ts->regs + SENSOR_HOTSPOT_OFF);
  596. seq_printf(s, "HOTSPOT: 0x%x\n", r);
  597. seq_puts(s, "\n");
  598. seq_puts(s, "-----SOC_THERM-----\n");
  599. r = readl(ts->regs + SENSOR_TEMP1);
  600. state = REG_GET_MASK(r, SENSOR_TEMP1_CPU_TEMP_MASK);
  601. seq_printf(s, "Temperatures: CPU(%d) ", translate_temp(state));
  602. state = REG_GET_MASK(r, SENSOR_TEMP1_GPU_TEMP_MASK);
  603. seq_printf(s, " GPU(%d) ", translate_temp(state));
  604. r = readl(ts->regs + SENSOR_TEMP2);
  605. state = REG_GET_MASK(r, SENSOR_TEMP2_PLLX_TEMP_MASK);
  606. seq_printf(s, " PLLX(%d) ", translate_temp(state));
  607. state = REG_GET_MASK(r, SENSOR_TEMP2_MEM_TEMP_MASK);
  608. seq_printf(s, " MEM(%d)\n", translate_temp(state));
  609. for (i = 0; i < ts->soc->num_ttgs; i++) {
  610. seq_printf(s, "%s:\n", ttgs[i]->name);
  611. for (level = 0; level < 4; level++) {
  612. s32 v;
  613. u32 mask;
  614. u16 off = ttgs[i]->thermctl_lvl0_offset;
  615. r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
  616. mask = ttgs[i]->thermctl_lvl0_up_thresh_mask;
  617. state = REG_GET_MASK(r, mask);
  618. v = sign_extend32(state, ts->soc->bptt - 1);
  619. v *= ts->soc->thresh_grain;
  620. seq_printf(s, " %d: Up/Dn(%d /", level, v);
  621. mask = ttgs[i]->thermctl_lvl0_dn_thresh_mask;
  622. state = REG_GET_MASK(r, mask);
  623. v = sign_extend32(state, ts->soc->bptt - 1);
  624. v *= ts->soc->thresh_grain;
  625. seq_printf(s, "%d ) ", v);
  626. mask = THERMCTL_LVL0_CPU0_EN_MASK;
  627. state = REG_GET_MASK(r, mask);
  628. seq_printf(s, "En(%d) ", state);
  629. mask = THERMCTL_LVL0_CPU0_CPU_THROT_MASK;
  630. state = REG_GET_MASK(r, mask);
  631. seq_puts(s, "CPU Throt");
  632. if (!state)
  633. seq_printf(s, "(%s) ", "none");
  634. else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT)
  635. seq_printf(s, "(%s) ", "L");
  636. else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY)
  637. seq_printf(s, "(%s) ", "H");
  638. else
  639. seq_printf(s, "(%s) ", "H+L");
  640. mask = THERMCTL_LVL0_CPU0_GPU_THROT_MASK;
  641. state = REG_GET_MASK(r, mask);
  642. seq_puts(s, "GPU Throt");
  643. if (!state)
  644. seq_printf(s, "(%s) ", "none");
  645. else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT)
  646. seq_printf(s, "(%s) ", "L");
  647. else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY)
  648. seq_printf(s, "(%s) ", "H");
  649. else
  650. seq_printf(s, "(%s) ", "H+L");
  651. mask = THERMCTL_LVL0_CPU0_STATUS_MASK;
  652. state = REG_GET_MASK(r, mask);
  653. seq_printf(s, "Status(%s)\n",
  654. state == 0 ? "LO" :
  655. state == 1 ? "In" :
  656. state == 2 ? "Res" : "HI");
  657. }
  658. }
  659. r = readl(ts->regs + THERMCTL_STATS_CTL);
  660. seq_printf(s, "STATS: Up(%s) Dn(%s)\n",
  661. r & STATS_CTL_EN_UP ? "En" : "--",
  662. r & STATS_CTL_EN_DN ? "En" : "--");
  663. for (level = 0; level < 4; level++) {
  664. u16 off;
  665. off = THERMCTL_LVL0_UP_STATS;
  666. r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
  667. seq_printf(s, " Level_%d Up(%d) ", level, r);
  668. off = THERMCTL_LVL0_DN_STATS;
  669. r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
  670. seq_printf(s, "Dn(%d)\n", r);
  671. }
  672. r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
  673. state = REG_GET_MASK(r, ttgs[0]->thermtrip_any_en_mask);
  674. seq_printf(s, "Thermtrip Any En(%d)\n", state);
  675. for (i = 0; i < ts->soc->num_ttgs; i++) {
  676. state = REG_GET_MASK(r, ttgs[i]->thermtrip_enable_mask);
  677. seq_printf(s, " %s En(%d) ", ttgs[i]->name, state);
  678. state = REG_GET_MASK(r, ttgs[i]->thermtrip_threshold_mask);
  679. state *= ts->soc->thresh_grain;
  680. seq_printf(s, "Thresh(%d)\n", state);
  681. }
  682. r = readl(ts->regs + THROT_GLOBAL_CFG);
  683. seq_puts(s, "\n");
  684. seq_printf(s, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r);
  685. seq_puts(s, "---------------------------------------------------\n");
  686. r = readl(ts->regs + THROT_STATUS);
  687. state = REG_GET_MASK(r, THROT_STATUS_BREACH_MASK);
  688. seq_printf(s, "THROT STATUS: breach(%d) ", state);
  689. state = REG_GET_MASK(r, THROT_STATUS_STATE_MASK);
  690. seq_printf(s, "state(%d) ", state);
  691. state = REG_GET_MASK(r, THROT_STATUS_ENABLED_MASK);
  692. seq_printf(s, "enabled(%d)\n", state);
  693. r = readl(ts->regs + CPU_PSKIP_STATUS);
  694. if (ts->soc->use_ccroc) {
  695. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
  696. seq_printf(s, "CPU PSKIP STATUS: enabled(%d)\n", state);
  697. } else {
  698. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_M_MASK);
  699. seq_printf(s, "CPU PSKIP STATUS: M(%d) ", state);
  700. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_N_MASK);
  701. seq_printf(s, "N(%d) ", state);
  702. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
  703. seq_printf(s, "enabled(%d)\n", state);
  704. }
  705. return 0;
  706. }
  707. static int regs_open(struct inode *inode, struct file *file)
  708. {
  709. return single_open(file, regs_show, inode->i_private);
  710. }
  711. static const struct file_operations regs_fops = {
  712. .open = regs_open,
  713. .read = seq_read,
  714. .llseek = seq_lseek,
  715. .release = single_release,
  716. };
  717. static void soctherm_debug_init(struct platform_device *pdev)
  718. {
  719. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  720. struct dentry *root, *file;
  721. root = debugfs_create_dir("soctherm", NULL);
  722. if (!root) {
  723. dev_err(&pdev->dev, "failed to create debugfs directory\n");
  724. return;
  725. }
  726. tegra->debugfs_dir = root;
  727. file = debugfs_create_file("reg_contents", 0644, root,
  728. pdev, &regs_fops);
  729. if (!file) {
  730. dev_err(&pdev->dev, "failed to create debugfs file\n");
  731. debugfs_remove_recursive(tegra->debugfs_dir);
  732. tegra->debugfs_dir = NULL;
  733. }
  734. }
  735. #else
  736. static inline void soctherm_debug_init(struct platform_device *pdev) {}
  737. #endif
  738. static int soctherm_clk_enable(struct platform_device *pdev, bool enable)
  739. {
  740. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  741. int err;
  742. if (!tegra->clock_soctherm || !tegra->clock_tsensor)
  743. return -EINVAL;
  744. reset_control_assert(tegra->reset);
  745. if (enable) {
  746. err = clk_prepare_enable(tegra->clock_soctherm);
  747. if (err) {
  748. reset_control_deassert(tegra->reset);
  749. return err;
  750. }
  751. err = clk_prepare_enable(tegra->clock_tsensor);
  752. if (err) {
  753. clk_disable_unprepare(tegra->clock_soctherm);
  754. reset_control_deassert(tegra->reset);
  755. return err;
  756. }
  757. } else {
  758. clk_disable_unprepare(tegra->clock_tsensor);
  759. clk_disable_unprepare(tegra->clock_soctherm);
  760. }
  761. reset_control_deassert(tegra->reset);
  762. return 0;
  763. }
  764. static int throt_get_cdev_max_state(struct thermal_cooling_device *cdev,
  765. unsigned long *max_state)
  766. {
  767. *max_state = 1;
  768. return 0;
  769. }
  770. static int throt_get_cdev_cur_state(struct thermal_cooling_device *cdev,
  771. unsigned long *cur_state)
  772. {
  773. struct tegra_soctherm *ts = cdev->devdata;
  774. u32 r;
  775. r = readl(ts->regs + THROT_STATUS);
  776. if (REG_GET_MASK(r, THROT_STATUS_STATE_MASK))
  777. *cur_state = 1;
  778. else
  779. *cur_state = 0;
  780. return 0;
  781. }
  782. static int throt_set_cdev_state(struct thermal_cooling_device *cdev,
  783. unsigned long cur_state)
  784. {
  785. return 0;
  786. }
  787. static struct thermal_cooling_device_ops throt_cooling_ops = {
  788. .get_max_state = throt_get_cdev_max_state,
  789. .get_cur_state = throt_get_cdev_cur_state,
  790. .set_cur_state = throt_set_cdev_state,
  791. };
  792. /**
  793. * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
  794. * and register them as cooling devices.
  795. */
  796. static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
  797. {
  798. struct device *dev = &pdev->dev;
  799. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  800. struct device_node *np_stc, *np_stcc;
  801. const char *name;
  802. u32 val;
  803. int i, r;
  804. for (i = 0; i < THROTTLE_SIZE; i++) {
  805. ts->throt_cfgs[i].name = throt_names[i];
  806. ts->throt_cfgs[i].id = i;
  807. ts->throt_cfgs[i].init = false;
  808. }
  809. np_stc = of_get_child_by_name(dev->of_node, "throttle-cfgs");
  810. if (!np_stc) {
  811. dev_info(dev,
  812. "throttle-cfg: no throttle-cfgs - not enabling\n");
  813. return;
  814. }
  815. for_each_child_of_node(np_stc, np_stcc) {
  816. struct soctherm_throt_cfg *stc;
  817. struct thermal_cooling_device *tcd;
  818. name = np_stcc->name;
  819. stc = find_throttle_cfg_by_name(ts, name);
  820. if (!stc) {
  821. dev_err(dev,
  822. "throttle-cfg: could not find %s\n", name);
  823. continue;
  824. }
  825. r = of_property_read_u32(np_stcc, "nvidia,priority", &val);
  826. if (r) {
  827. dev_info(dev,
  828. "throttle-cfg: %s: missing priority\n", name);
  829. continue;
  830. }
  831. stc->priority = val;
  832. if (ts->soc->use_ccroc) {
  833. r = of_property_read_u32(np_stcc,
  834. "nvidia,cpu-throt-level",
  835. &val);
  836. if (r) {
  837. dev_info(dev,
  838. "throttle-cfg: %s: missing cpu-throt-level\n",
  839. name);
  840. continue;
  841. }
  842. stc->cpu_throt_level = val;
  843. } else {
  844. r = of_property_read_u32(np_stcc,
  845. "nvidia,cpu-throt-percent",
  846. &val);
  847. if (r) {
  848. dev_info(dev,
  849. "throttle-cfg: %s: missing cpu-throt-percent\n",
  850. name);
  851. continue;
  852. }
  853. stc->cpu_throt_depth = val;
  854. }
  855. tcd = thermal_of_cooling_device_register(np_stcc,
  856. (char *)name, ts,
  857. &throt_cooling_ops);
  858. of_node_put(np_stcc);
  859. if (IS_ERR_OR_NULL(tcd)) {
  860. dev_err(dev,
  861. "throttle-cfg: %s: failed to register cooling device\n",
  862. name);
  863. continue;
  864. }
  865. stc->cdev = tcd;
  866. stc->init = true;
  867. }
  868. of_node_put(np_stc);
  869. }
  870. /**
  871. * throttlectl_cpu_level_cfg() - programs CCROC NV_THERM level config
  872. * @level: describing the level LOW/MED/HIGH of throttling
  873. *
  874. * It's necessary to set up the CPU-local CCROC NV_THERM instance with
  875. * the M/N values desired for each level. This function does this.
  876. *
  877. * This function pre-programs the CCROC NV_THERM levels in terms of
  878. * pre-configured "Low", "Medium" or "Heavy" throttle levels which are
  879. * mapped to THROT_LEVEL_LOW, THROT_LEVEL_MED and THROT_LEVEL_HVY.
  880. */
  881. static void throttlectl_cpu_level_cfg(struct tegra_soctherm *ts, int level)
  882. {
  883. u8 depth, dividend;
  884. u32 r;
  885. switch (level) {
  886. case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
  887. depth = 50;
  888. break;
  889. case TEGRA_SOCTHERM_THROT_LEVEL_MED:
  890. depth = 75;
  891. break;
  892. case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
  893. depth = 80;
  894. break;
  895. case TEGRA_SOCTHERM_THROT_LEVEL_NONE:
  896. return;
  897. default:
  898. return;
  899. }
  900. dividend = THROT_DEPTH_DIVIDEND(depth);
  901. /* setup PSKIP in ccroc nv_therm registers */
  902. r = ccroc_readl(ts, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
  903. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
  904. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_STEP_MASK, 0xf);
  905. ccroc_writel(ts, r, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
  906. r = ccroc_readl(ts, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
  907. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_ENB_MASK, 1);
  908. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
  909. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
  910. ccroc_writel(ts, r, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
  911. }
  912. /**
  913. * throttlectl_cpu_level_select() - program CPU pulse skipper config
  914. * @throt: the LIGHT/HEAVY of throttle event id
  915. *
  916. * Pulse skippers are used to throttle clock frequencies. This
  917. * function programs the pulse skippers based on @throt and platform
  918. * data. This function is used on SoCs which have CPU-local pulse
  919. * skipper control, such as T13x. It programs soctherm's interface to
  920. * Denver:CCROC NV_THERM in terms of Low, Medium and HIGH throttling
  921. * vectors. PSKIP_BYPASS mode is set as required per HW spec.
  922. */
  923. static void throttlectl_cpu_level_select(struct tegra_soctherm *ts,
  924. enum soctherm_throttle_id throt)
  925. {
  926. u32 r, throt_vect;
  927. /* Denver:CCROC NV_THERM interface N:3 Mapping */
  928. switch (ts->throt_cfgs[throt].cpu_throt_level) {
  929. case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
  930. throt_vect = THROT_VECT_LOW;
  931. break;
  932. case TEGRA_SOCTHERM_THROT_LEVEL_MED:
  933. throt_vect = THROT_VECT_MED;
  934. break;
  935. case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
  936. throt_vect = THROT_VECT_HIGH;
  937. break;
  938. default:
  939. throt_vect = THROT_VECT_NONE;
  940. break;
  941. }
  942. r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  943. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
  944. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT_CPU_MASK, throt_vect);
  945. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT2_CPU_MASK, throt_vect);
  946. writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  947. /* bypass sequencer in soc_therm as it is programmed in ccroc */
  948. r = REG_SET_MASK(0, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK, 1);
  949. writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
  950. }
  951. /**
  952. * throttlectl_cpu_mn() - program CPU pulse skipper configuration
  953. * @throt: the LIGHT/HEAVY of throttle event id
  954. *
  955. * Pulse skippers are used to throttle clock frequencies. This
  956. * function programs the pulse skippers based on @throt and platform
  957. * data. This function is used for CPUs that have "remote" pulse
  958. * skipper control, e.g., the CPU pulse skipper is controlled by the
  959. * SOC_THERM IP block. (SOC_THERM is located outside the CPU
  960. * complex.)
  961. */
  962. static void throttlectl_cpu_mn(struct tegra_soctherm *ts,
  963. enum soctherm_throttle_id throt)
  964. {
  965. u32 r;
  966. int depth;
  967. u8 dividend;
  968. depth = ts->throt_cfgs[throt].cpu_throt_depth;
  969. dividend = THROT_DEPTH_DIVIDEND(depth);
  970. r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  971. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
  972. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
  973. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
  974. writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  975. r = readl(ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
  976. r = REG_SET_MASK(r, THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
  977. r = REG_SET_MASK(r, THROT_PSKIP_RAMP_STEP_MASK, 0xf);
  978. writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
  979. }
  980. /**
  981. * soctherm_throttle_program() - programs pulse skippers' configuration
  982. * @throt: the LIGHT/HEAVY of the throttle event id.
  983. *
  984. * Pulse skippers are used to throttle clock frequencies.
  985. * This function programs the pulse skippers.
  986. */
  987. static void soctherm_throttle_program(struct tegra_soctherm *ts,
  988. enum soctherm_throttle_id throt)
  989. {
  990. u32 r;
  991. struct soctherm_throt_cfg stc = ts->throt_cfgs[throt];
  992. if (!stc.init)
  993. return;
  994. /* Setup PSKIP parameters */
  995. if (ts->soc->use_ccroc)
  996. throttlectl_cpu_level_select(ts, throt);
  997. else
  998. throttlectl_cpu_mn(ts, throt);
  999. r = REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK, stc.priority);
  1000. writel(r, ts->regs + THROT_PRIORITY_CTRL(throt));
  1001. r = REG_SET_MASK(0, THROT_DELAY_LITE_DELAY_MASK, 0);
  1002. writel(r, ts->regs + THROT_DELAY_CTRL(throt));
  1003. r = readl(ts->regs + THROT_PRIORITY_LOCK);
  1004. r = REG_GET_MASK(r, THROT_PRIORITY_LOCK_PRIORITY_MASK);
  1005. if (r >= stc.priority)
  1006. return;
  1007. r = REG_SET_MASK(0, THROT_PRIORITY_LOCK_PRIORITY_MASK,
  1008. stc.priority);
  1009. writel(r, ts->regs + THROT_PRIORITY_LOCK);
  1010. }
  1011. static void tegra_soctherm_throttle(struct device *dev)
  1012. {
  1013. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  1014. u32 v;
  1015. int i;
  1016. /* configure LOW, MED and HIGH levels for CCROC NV_THERM */
  1017. if (ts->soc->use_ccroc) {
  1018. throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_LOW);
  1019. throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_MED);
  1020. throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_HIGH);
  1021. }
  1022. /* Thermal HW throttle programming */
  1023. for (i = 0; i < THROTTLE_SIZE; i++)
  1024. soctherm_throttle_program(ts, i);
  1025. v = REG_SET_MASK(0, THROT_GLOBAL_ENB_MASK, 1);
  1026. if (ts->soc->use_ccroc) {
  1027. ccroc_writel(ts, v, CCROC_GLOBAL_CFG);
  1028. v = ccroc_readl(ts, CCROC_SUPER_CCLKG_DIVIDER);
  1029. v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
  1030. ccroc_writel(ts, v, CCROC_SUPER_CCLKG_DIVIDER);
  1031. } else {
  1032. writel(v, ts->regs + THROT_GLOBAL_CFG);
  1033. v = clk_readl(ts, CAR_SUPER_CCLKG_DIVIDER);
  1034. v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
  1035. clk_writel(ts, v, CAR_SUPER_CCLKG_DIVIDER);
  1036. }
  1037. /* initialize stats collection */
  1038. v = STATS_CTL_CLR_DN | STATS_CTL_EN_DN |
  1039. STATS_CTL_CLR_UP | STATS_CTL_EN_UP;
  1040. writel(v, ts->regs + THERMCTL_STATS_CTL);
  1041. }
  1042. static void soctherm_init(struct platform_device *pdev)
  1043. {
  1044. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1045. const struct tegra_tsensor_group **ttgs = tegra->soc->ttgs;
  1046. int i;
  1047. u32 pdiv, hotspot;
  1048. /* Initialize raw sensors */
  1049. for (i = 0; i < tegra->soc->num_tsensors; ++i)
  1050. enable_tsensor(tegra, i);
  1051. /* program pdiv and hotspot offsets per THERM */
  1052. pdiv = readl(tegra->regs + SENSOR_PDIV);
  1053. hotspot = readl(tegra->regs + SENSOR_HOTSPOT_OFF);
  1054. for (i = 0; i < tegra->soc->num_ttgs; ++i) {
  1055. pdiv = REG_SET_MASK(pdiv, ttgs[i]->pdiv_mask,
  1056. ttgs[i]->pdiv);
  1057. /* hotspot offset from PLLX, doesn't need to configure PLLX */
  1058. if (ttgs[i]->id == TEGRA124_SOCTHERM_SENSOR_PLLX)
  1059. continue;
  1060. hotspot = REG_SET_MASK(hotspot,
  1061. ttgs[i]->pllx_hotspot_mask,
  1062. ttgs[i]->pllx_hotspot_diff);
  1063. }
  1064. writel(pdiv, tegra->regs + SENSOR_PDIV);
  1065. writel(hotspot, tegra->regs + SENSOR_HOTSPOT_OFF);
  1066. /* Configure hw throttle */
  1067. tegra_soctherm_throttle(&pdev->dev);
  1068. }
  1069. static const struct of_device_id tegra_soctherm_of_match[] = {
  1070. #ifdef CONFIG_ARCH_TEGRA_124_SOC
  1071. {
  1072. .compatible = "nvidia,tegra124-soctherm",
  1073. .data = &tegra124_soctherm,
  1074. },
  1075. #endif
  1076. #ifdef CONFIG_ARCH_TEGRA_132_SOC
  1077. {
  1078. .compatible = "nvidia,tegra132-soctherm",
  1079. .data = &tegra132_soctherm,
  1080. },
  1081. #endif
  1082. #ifdef CONFIG_ARCH_TEGRA_210_SOC
  1083. {
  1084. .compatible = "nvidia,tegra210-soctherm",
  1085. .data = &tegra210_soctherm,
  1086. },
  1087. #endif
  1088. { },
  1089. };
  1090. MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
  1091. static int tegra_soctherm_probe(struct platform_device *pdev)
  1092. {
  1093. const struct of_device_id *match;
  1094. struct tegra_soctherm *tegra;
  1095. struct thermal_zone_device *z;
  1096. struct tsensor_shared_calib shared_calib;
  1097. struct resource *res;
  1098. struct tegra_soctherm_soc *soc;
  1099. unsigned int i;
  1100. int err;
  1101. match = of_match_node(tegra_soctherm_of_match, pdev->dev.of_node);
  1102. if (!match)
  1103. return -ENODEV;
  1104. soc = (struct tegra_soctherm_soc *)match->data;
  1105. if (soc->num_ttgs > TEGRA124_SOCTHERM_SENSOR_NUM)
  1106. return -EINVAL;
  1107. tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
  1108. if (!tegra)
  1109. return -ENOMEM;
  1110. dev_set_drvdata(&pdev->dev, tegra);
  1111. tegra->soc = soc;
  1112. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  1113. "soctherm-reg");
  1114. tegra->regs = devm_ioremap_resource(&pdev->dev, res);
  1115. if (IS_ERR(tegra->regs)) {
  1116. dev_err(&pdev->dev, "can't get soctherm registers");
  1117. return PTR_ERR(tegra->regs);
  1118. }
  1119. if (!tegra->soc->use_ccroc) {
  1120. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  1121. "car-reg");
  1122. tegra->clk_regs = devm_ioremap_resource(&pdev->dev, res);
  1123. if (IS_ERR(tegra->clk_regs)) {
  1124. dev_err(&pdev->dev, "can't get car clk registers");
  1125. return PTR_ERR(tegra->clk_regs);
  1126. }
  1127. } else {
  1128. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  1129. "ccroc-reg");
  1130. tegra->ccroc_regs = devm_ioremap_resource(&pdev->dev, res);
  1131. if (IS_ERR(tegra->ccroc_regs)) {
  1132. dev_err(&pdev->dev, "can't get ccroc registers");
  1133. return PTR_ERR(tegra->ccroc_regs);
  1134. }
  1135. }
  1136. tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm");
  1137. if (IS_ERR(tegra->reset)) {
  1138. dev_err(&pdev->dev, "can't get soctherm reset\n");
  1139. return PTR_ERR(tegra->reset);
  1140. }
  1141. tegra->clock_tsensor = devm_clk_get(&pdev->dev, "tsensor");
  1142. if (IS_ERR(tegra->clock_tsensor)) {
  1143. dev_err(&pdev->dev, "can't get tsensor clock\n");
  1144. return PTR_ERR(tegra->clock_tsensor);
  1145. }
  1146. tegra->clock_soctherm = devm_clk_get(&pdev->dev, "soctherm");
  1147. if (IS_ERR(tegra->clock_soctherm)) {
  1148. dev_err(&pdev->dev, "can't get soctherm clock\n");
  1149. return PTR_ERR(tegra->clock_soctherm);
  1150. }
  1151. tegra->calib = devm_kzalloc(&pdev->dev,
  1152. sizeof(u32) * soc->num_tsensors,
  1153. GFP_KERNEL);
  1154. if (!tegra->calib)
  1155. return -ENOMEM;
  1156. /* calculate shared calibration data */
  1157. err = tegra_calc_shared_calib(soc->tfuse, &shared_calib);
  1158. if (err)
  1159. return err;
  1160. /* calculate tsensor calibaration data */
  1161. for (i = 0; i < soc->num_tsensors; ++i) {
  1162. err = tegra_calc_tsensor_calib(&soc->tsensors[i],
  1163. &shared_calib,
  1164. &tegra->calib[i]);
  1165. if (err)
  1166. return err;
  1167. }
  1168. tegra->thermctl_tzs = devm_kzalloc(&pdev->dev,
  1169. sizeof(*z) * soc->num_ttgs,
  1170. GFP_KERNEL);
  1171. if (!tegra->thermctl_tzs)
  1172. return -ENOMEM;
  1173. err = soctherm_clk_enable(pdev, true);
  1174. if (err)
  1175. return err;
  1176. soctherm_init_hw_throt_cdev(pdev);
  1177. soctherm_init(pdev);
  1178. for (i = 0; i < soc->num_ttgs; ++i) {
  1179. struct tegra_thermctl_zone *zone =
  1180. devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL);
  1181. if (!zone) {
  1182. err = -ENOMEM;
  1183. goto disable_clocks;
  1184. }
  1185. zone->reg = tegra->regs + soc->ttgs[i]->sensor_temp_offset;
  1186. zone->dev = &pdev->dev;
  1187. zone->sg = soc->ttgs[i];
  1188. zone->ts = tegra;
  1189. z = devm_thermal_zone_of_sensor_register(&pdev->dev,
  1190. soc->ttgs[i]->id, zone,
  1191. &tegra_of_thermal_ops);
  1192. if (IS_ERR(z)) {
  1193. err = PTR_ERR(z);
  1194. dev_err(&pdev->dev, "failed to register sensor: %d\n",
  1195. err);
  1196. goto disable_clocks;
  1197. }
  1198. zone->tz = z;
  1199. tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
  1200. /* Configure hw trip points */
  1201. err = tegra_soctherm_set_hwtrips(&pdev->dev, soc->ttgs[i], z);
  1202. if (err)
  1203. goto disable_clocks;
  1204. }
  1205. soctherm_debug_init(pdev);
  1206. return 0;
  1207. disable_clocks:
  1208. soctherm_clk_enable(pdev, false);
  1209. return err;
  1210. }
  1211. static int tegra_soctherm_remove(struct platform_device *pdev)
  1212. {
  1213. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1214. debugfs_remove_recursive(tegra->debugfs_dir);
  1215. soctherm_clk_enable(pdev, false);
  1216. return 0;
  1217. }
  1218. static int __maybe_unused soctherm_suspend(struct device *dev)
  1219. {
  1220. struct platform_device *pdev = to_platform_device(dev);
  1221. soctherm_clk_enable(pdev, false);
  1222. return 0;
  1223. }
  1224. static int __maybe_unused soctherm_resume(struct device *dev)
  1225. {
  1226. struct platform_device *pdev = to_platform_device(dev);
  1227. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1228. struct tegra_soctherm_soc *soc = tegra->soc;
  1229. int err, i;
  1230. err = soctherm_clk_enable(pdev, true);
  1231. if (err) {
  1232. dev_err(&pdev->dev,
  1233. "Resume failed: enable clocks failed\n");
  1234. return err;
  1235. }
  1236. soctherm_init(pdev);
  1237. for (i = 0; i < soc->num_ttgs; ++i) {
  1238. struct thermal_zone_device *tz;
  1239. tz = tegra->thermctl_tzs[soc->ttgs[i]->id];
  1240. err = tegra_soctherm_set_hwtrips(dev, soc->ttgs[i], tz);
  1241. if (err) {
  1242. dev_err(&pdev->dev,
  1243. "Resume failed: set hwtrips failed\n");
  1244. return err;
  1245. }
  1246. }
  1247. return 0;
  1248. }
  1249. static SIMPLE_DEV_PM_OPS(tegra_soctherm_pm, soctherm_suspend, soctherm_resume);
  1250. static struct platform_driver tegra_soctherm_driver = {
  1251. .probe = tegra_soctherm_probe,
  1252. .remove = tegra_soctherm_remove,
  1253. .driver = {
  1254. .name = "tegra_soctherm",
  1255. .pm = &tegra_soctherm_pm,
  1256. .of_match_table = tegra_soctherm_of_match,
  1257. },
  1258. };
  1259. module_platform_driver(tegra_soctherm_driver);
  1260. MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
  1261. MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver");
  1262. MODULE_LICENSE("GPL v2");