soctherm.c 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2014 - 2018, NVIDIA CORPORATION. All rights reserved.
  4. *
  5. * Author:
  6. * Mikko Perttunen <mperttunen@nvidia.com>
  7. *
  8. * This software is licensed under the terms of the GNU General Public
  9. * License version 2, as published by the Free Software Foundation, and
  10. * may be copied, distributed, and modified under those terms.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. */
  18. #include <linux/debugfs.h>
  19. #include <linux/bitops.h>
  20. #include <linux/clk.h>
  21. #include <linux/delay.h>
  22. #include <linux/err.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/io.h>
  25. #include <linux/irq.h>
  26. #include <linux/irqdomain.h>
  27. #include <linux/module.h>
  28. #include <linux/of.h>
  29. #include <linux/platform_device.h>
  30. #include <linux/reset.h>
  31. #include <linux/thermal.h>
  32. #include <dt-bindings/thermal/tegra124-soctherm.h>
  33. #include "../thermal_core.h"
  34. #include "soctherm.h"
  35. #define SENSOR_CONFIG0 0
  36. #define SENSOR_CONFIG0_STOP BIT(0)
  37. #define SENSOR_CONFIG0_CPTR_OVER BIT(2)
  38. #define SENSOR_CONFIG0_OVER BIT(3)
  39. #define SENSOR_CONFIG0_TCALC_OVER BIT(4)
  40. #define SENSOR_CONFIG0_TALL_MASK (0xfffff << 8)
  41. #define SENSOR_CONFIG0_TALL_SHIFT 8
  42. #define SENSOR_CONFIG1 4
  43. #define SENSOR_CONFIG1_TSAMPLE_MASK 0x3ff
  44. #define SENSOR_CONFIG1_TSAMPLE_SHIFT 0
  45. #define SENSOR_CONFIG1_TIDDQ_EN_MASK (0x3f << 15)
  46. #define SENSOR_CONFIG1_TIDDQ_EN_SHIFT 15
  47. #define SENSOR_CONFIG1_TEN_COUNT_MASK (0x3f << 24)
  48. #define SENSOR_CONFIG1_TEN_COUNT_SHIFT 24
  49. #define SENSOR_CONFIG1_TEMP_ENABLE BIT(31)
  50. /*
  51. * SENSOR_CONFIG2 is defined in soctherm.h
  52. * because, it will be used by tegra_soctherm_fuse.c
  53. */
  54. #define SENSOR_STATUS0 0xc
  55. #define SENSOR_STATUS0_VALID_MASK BIT(31)
  56. #define SENSOR_STATUS0_CAPTURE_MASK 0xffff
  57. #define SENSOR_STATUS1 0x10
  58. #define SENSOR_STATUS1_TEMP_VALID_MASK BIT(31)
  59. #define SENSOR_STATUS1_TEMP_MASK 0xffff
  60. #define READBACK_VALUE_MASK 0xff00
  61. #define READBACK_VALUE_SHIFT 8
  62. #define READBACK_ADD_HALF BIT(7)
  63. #define READBACK_NEGATE BIT(0)
  64. /*
  65. * THERMCTL_LEVEL0_GROUP_CPU is defined in soctherm.h
  66. * because it will be used by tegraxxx_soctherm.c
  67. */
  68. #define THERMCTL_LVL0_CPU0_EN_MASK BIT(8)
  69. #define THERMCTL_LVL0_CPU0_CPU_THROT_MASK (0x3 << 5)
  70. #define THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT 0x1
  71. #define THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY 0x2
  72. #define THERMCTL_LVL0_CPU0_GPU_THROT_MASK (0x3 << 3)
  73. #define THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT 0x1
  74. #define THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY 0x2
  75. #define THERMCTL_LVL0_CPU0_MEM_THROT_MASK BIT(2)
  76. #define THERMCTL_LVL0_CPU0_STATUS_MASK 0x3
  77. #define THERMCTL_LVL0_UP_STATS 0x10
  78. #define THERMCTL_LVL0_DN_STATS 0x14
  79. #define THERMCTL_INTR_STATUS 0x84
  80. #define TH_INTR_MD0_MASK BIT(25)
  81. #define TH_INTR_MU0_MASK BIT(24)
  82. #define TH_INTR_GD0_MASK BIT(17)
  83. #define TH_INTR_GU0_MASK BIT(16)
  84. #define TH_INTR_CD0_MASK BIT(9)
  85. #define TH_INTR_CU0_MASK BIT(8)
  86. #define TH_INTR_PD0_MASK BIT(1)
  87. #define TH_INTR_PU0_MASK BIT(0)
  88. #define TH_INTR_IGNORE_MASK 0xFCFCFCFC
  89. #define THERMCTL_STATS_CTL 0x94
  90. #define STATS_CTL_CLR_DN 0x8
  91. #define STATS_CTL_EN_DN 0x4
  92. #define STATS_CTL_CLR_UP 0x2
  93. #define STATS_CTL_EN_UP 0x1
  94. #define OC1_CFG 0x310
  95. #define OC1_CFG_LONG_LATENCY_MASK BIT(6)
  96. #define OC1_CFG_HW_RESTORE_MASK BIT(5)
  97. #define OC1_CFG_PWR_GOOD_MASK_MASK BIT(4)
  98. #define OC1_CFG_THROTTLE_MODE_MASK (0x3 << 2)
  99. #define OC1_CFG_ALARM_POLARITY_MASK BIT(1)
  100. #define OC1_CFG_EN_THROTTLE_MASK BIT(0)
  101. #define OC1_CNT_THRESHOLD 0x314
  102. #define OC1_THROTTLE_PERIOD 0x318
  103. #define OC1_ALARM_COUNT 0x31c
  104. #define OC1_FILTER 0x320
  105. #define OC1_STATS 0x3a8
  106. #define OC_INTR_STATUS 0x39c
  107. #define OC_INTR_ENABLE 0x3a0
  108. #define OC_INTR_DISABLE 0x3a4
  109. #define OC_STATS_CTL 0x3c4
  110. #define OC_STATS_CTL_CLR_ALL 0x2
  111. #define OC_STATS_CTL_EN_ALL 0x1
  112. #define OC_INTR_OC1_MASK BIT(0)
  113. #define OC_INTR_OC2_MASK BIT(1)
  114. #define OC_INTR_OC3_MASK BIT(2)
  115. #define OC_INTR_OC4_MASK BIT(3)
  116. #define OC_INTR_OC5_MASK BIT(4)
  117. #define THROT_GLOBAL_CFG 0x400
  118. #define THROT_GLOBAL_ENB_MASK BIT(0)
  119. #define CPU_PSKIP_STATUS 0x418
  120. #define XPU_PSKIP_STATUS_M_MASK (0xff << 12)
  121. #define XPU_PSKIP_STATUS_N_MASK (0xff << 4)
  122. #define XPU_PSKIP_STATUS_SW_OVERRIDE_MASK BIT(1)
  123. #define XPU_PSKIP_STATUS_ENABLED_MASK BIT(0)
  124. #define THROT_PRIORITY_LOCK 0x424
  125. #define THROT_PRIORITY_LOCK_PRIORITY_MASK 0xff
  126. #define THROT_STATUS 0x428
  127. #define THROT_STATUS_BREACH_MASK BIT(12)
  128. #define THROT_STATUS_STATE_MASK (0xff << 4)
  129. #define THROT_STATUS_ENABLED_MASK BIT(0)
  130. #define THROT_PSKIP_CTRL_LITE_CPU 0x430
  131. #define THROT_PSKIP_CTRL_ENABLE_MASK BIT(31)
  132. #define THROT_PSKIP_CTRL_DIVIDEND_MASK (0xff << 8)
  133. #define THROT_PSKIP_CTRL_DIVISOR_MASK 0xff
  134. #define THROT_PSKIP_CTRL_VECT_GPU_MASK (0x7 << 16)
  135. #define THROT_PSKIP_CTRL_VECT_CPU_MASK (0x7 << 8)
  136. #define THROT_PSKIP_CTRL_VECT2_CPU_MASK 0x7
  137. #define THROT_VECT_NONE 0x0 /* 3'b000 */
  138. #define THROT_VECT_LOW 0x1 /* 3'b001 */
  139. #define THROT_VECT_MED 0x3 /* 3'b011 */
  140. #define THROT_VECT_HIGH 0x7 /* 3'b111 */
  141. #define THROT_PSKIP_RAMP_LITE_CPU 0x434
  142. #define THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK BIT(31)
  143. #define THROT_PSKIP_RAMP_DURATION_MASK (0xffff << 8)
  144. #define THROT_PSKIP_RAMP_STEP_MASK 0xff
  145. #define THROT_PRIORITY_LITE 0x444
  146. #define THROT_PRIORITY_LITE_PRIO_MASK 0xff
  147. #define THROT_DELAY_LITE 0x448
  148. #define THROT_DELAY_LITE_DELAY_MASK 0xff
  149. /* car register offsets needed for enabling HW throttling */
  150. #define CAR_SUPER_CCLKG_DIVIDER 0x36c
  151. #define CDIVG_USE_THERM_CONTROLS_MASK BIT(30)
  152. /* ccroc register offsets needed for enabling HW throttling for Tegra132 */
  153. #define CCROC_SUPER_CCLKG_DIVIDER 0x024
  154. #define CCROC_GLOBAL_CFG 0x148
  155. #define CCROC_THROT_PSKIP_RAMP_CPU 0x150
  156. #define CCROC_THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK BIT(31)
  157. #define CCROC_THROT_PSKIP_RAMP_DURATION_MASK (0xffff << 8)
  158. #define CCROC_THROT_PSKIP_RAMP_STEP_MASK 0xff
  159. #define CCROC_THROT_PSKIP_CTRL_CPU 0x154
  160. #define CCROC_THROT_PSKIP_CTRL_ENB_MASK BIT(31)
  161. #define CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK (0xff << 8)
  162. #define CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK 0xff
  163. /* get val from register(r) mask bits(m) */
  164. #define REG_GET_MASK(r, m) (((r) & (m)) >> (ffs(m) - 1))
  165. /* set val(v) to mask bits(m) of register(r) */
  166. #define REG_SET_MASK(r, m, v) (((r) & ~(m)) | \
  167. (((v) & (m >> (ffs(m) - 1))) << (ffs(m) - 1)))
  168. /* get dividend from the depth */
  169. #define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
  170. /* gk20a nv_therm interface N:3 Mapping. Levels defined in tegra124-soctherm.h
  171. * level vector
  172. * NONE 3'b000
  173. * LOW 3'b001
  174. * MED 3'b011
  175. * HIGH 3'b111
  176. */
  177. #define THROT_LEVEL_TO_DEPTH(level) ((0x1 << (level)) - 1)
  178. /* get THROT_PSKIP_xxx offset per LIGHT/HEAVY throt and CPU/GPU dev */
  179. #define THROT_OFFSET 0x30
  180. #define THROT_PSKIP_CTRL(throt, dev) (THROT_PSKIP_CTRL_LITE_CPU + \
  181. (THROT_OFFSET * throt) + (8 * dev))
  182. #define THROT_PSKIP_RAMP(throt, dev) (THROT_PSKIP_RAMP_LITE_CPU + \
  183. (THROT_OFFSET * throt) + (8 * dev))
  184. /* get THROT_xxx_CTRL offset per LIGHT/HEAVY throt */
  185. #define THROT_PRIORITY_CTRL(throt) (THROT_PRIORITY_LITE + \
  186. (THROT_OFFSET * throt))
  187. #define THROT_DELAY_CTRL(throt) (THROT_DELAY_LITE + \
  188. (THROT_OFFSET * throt))
  189. #define ALARM_OFFSET 0x14
  190. #define ALARM_CFG(throt) (OC1_CFG + \
  191. (ALARM_OFFSET * (throt - THROTTLE_OC1)))
  192. #define ALARM_CNT_THRESHOLD(throt) (OC1_CNT_THRESHOLD + \
  193. (ALARM_OFFSET * (throt - THROTTLE_OC1)))
  194. #define ALARM_THROTTLE_PERIOD(throt) (OC1_THROTTLE_PERIOD + \
  195. (ALARM_OFFSET * (throt - THROTTLE_OC1)))
  196. #define ALARM_ALARM_COUNT(throt) (OC1_ALARM_COUNT + \
  197. (ALARM_OFFSET * (throt - THROTTLE_OC1)))
  198. #define ALARM_FILTER(throt) (OC1_FILTER + \
  199. (ALARM_OFFSET * (throt - THROTTLE_OC1)))
  200. #define ALARM_STATS(throt) (OC1_STATS + \
  201. (4 * (throt - THROTTLE_OC1)))
  202. /* get CCROC_THROT_PSKIP_xxx offset per HIGH/MED/LOW vect*/
  203. #define CCROC_THROT_OFFSET 0x0c
  204. #define CCROC_THROT_PSKIP_CTRL_CPU_REG(vect) (CCROC_THROT_PSKIP_CTRL_CPU + \
  205. (CCROC_THROT_OFFSET * vect))
  206. #define CCROC_THROT_PSKIP_RAMP_CPU_REG(vect) (CCROC_THROT_PSKIP_RAMP_CPU + \
  207. (CCROC_THROT_OFFSET * vect))
  208. /* get THERMCTL_LEVELx offset per CPU/GPU/MEM/TSENSE rg and LEVEL0~3 lv */
  209. #define THERMCTL_LVL_REGS_SIZE 0x20
  210. #define THERMCTL_LVL_REG(rg, lv) ((rg) + ((lv) * THERMCTL_LVL_REGS_SIZE))
  211. #define OC_THROTTLE_MODE_DISABLED 0
  212. #define OC_THROTTLE_MODE_BRIEF 2
  213. static const int min_low_temp = -127000;
  214. static const int max_high_temp = 127000;
  215. enum soctherm_throttle_id {
  216. THROTTLE_LIGHT = 0,
  217. THROTTLE_HEAVY,
  218. THROTTLE_OC1,
  219. THROTTLE_OC2,
  220. THROTTLE_OC3,
  221. THROTTLE_OC4,
  222. THROTTLE_OC5, /* OC5 is reserved */
  223. THROTTLE_SIZE,
  224. };
  225. enum soctherm_oc_irq_id {
  226. TEGRA_SOC_OC_IRQ_1,
  227. TEGRA_SOC_OC_IRQ_2,
  228. TEGRA_SOC_OC_IRQ_3,
  229. TEGRA_SOC_OC_IRQ_4,
  230. TEGRA_SOC_OC_IRQ_5,
  231. TEGRA_SOC_OC_IRQ_MAX,
  232. };
  233. enum soctherm_throttle_dev_id {
  234. THROTTLE_DEV_CPU = 0,
  235. THROTTLE_DEV_GPU,
  236. THROTTLE_DEV_SIZE,
  237. };
  238. static const char *const throt_names[] = {
  239. [THROTTLE_LIGHT] = "light",
  240. [THROTTLE_HEAVY] = "heavy",
  241. [THROTTLE_OC1] = "oc1",
  242. [THROTTLE_OC2] = "oc2",
  243. [THROTTLE_OC3] = "oc3",
  244. [THROTTLE_OC4] = "oc4",
  245. [THROTTLE_OC5] = "oc5",
  246. };
  247. struct tegra_soctherm;
  248. struct tegra_thermctl_zone {
  249. void __iomem *reg;
  250. struct device *dev;
  251. struct tegra_soctherm *ts;
  252. struct thermal_zone_device *tz;
  253. const struct tegra_tsensor_group *sg;
  254. };
  255. struct soctherm_oc_cfg {
  256. u32 active_low;
  257. u32 throt_period;
  258. u32 alarm_cnt_thresh;
  259. u32 alarm_filter;
  260. u32 mode;
  261. bool intr_en;
  262. };
  263. struct soctherm_throt_cfg {
  264. const char *name;
  265. unsigned int id;
  266. u8 priority;
  267. u8 cpu_throt_level;
  268. u32 cpu_throt_depth;
  269. u32 gpu_throt_level;
  270. struct soctherm_oc_cfg oc_cfg;
  271. struct thermal_cooling_device *cdev;
  272. bool init;
  273. };
  274. struct tegra_soctherm {
  275. struct reset_control *reset;
  276. struct clk *clock_tsensor;
  277. struct clk *clock_soctherm;
  278. void __iomem *regs;
  279. void __iomem *clk_regs;
  280. void __iomem *ccroc_regs;
  281. int thermal_irq;
  282. int edp_irq;
  283. u32 *calib;
  284. struct thermal_zone_device **thermctl_tzs;
  285. struct tegra_soctherm_soc *soc;
  286. struct soctherm_throt_cfg throt_cfgs[THROTTLE_SIZE];
  287. struct dentry *debugfs_dir;
  288. struct mutex thermctl_lock;
  289. };
  290. struct soctherm_oc_irq_chip_data {
  291. struct mutex irq_lock; /* serialize OC IRQs */
  292. struct irq_chip irq_chip;
  293. struct irq_domain *domain;
  294. int irq_enable;
  295. };
  296. static struct soctherm_oc_irq_chip_data soc_irq_cdata;
  297. /**
  298. * ccroc_writel() - writes a value to a CCROC register
  299. * @ts: pointer to a struct tegra_soctherm
  300. * @value: the value to write
  301. * @reg: the register offset
  302. *
  303. * Writes @v to @reg. No return value.
  304. */
  305. static inline void ccroc_writel(struct tegra_soctherm *ts, u32 value, u32 reg)
  306. {
  307. writel(value, (ts->ccroc_regs + reg));
  308. }
  309. /**
  310. * ccroc_readl() - reads specified register from CCROC IP block
  311. * @ts: pointer to a struct tegra_soctherm
  312. * @reg: register address to be read
  313. *
  314. * Return: the value of the register
  315. */
  316. static inline u32 ccroc_readl(struct tegra_soctherm *ts, u32 reg)
  317. {
  318. return readl(ts->ccroc_regs + reg);
  319. }
  320. static void enable_tsensor(struct tegra_soctherm *tegra, unsigned int i)
  321. {
  322. const struct tegra_tsensor *sensor = &tegra->soc->tsensors[i];
  323. void __iomem *base = tegra->regs + sensor->base;
  324. unsigned int val;
  325. val = sensor->config->tall << SENSOR_CONFIG0_TALL_SHIFT;
  326. writel(val, base + SENSOR_CONFIG0);
  327. val = (sensor->config->tsample - 1) << SENSOR_CONFIG1_TSAMPLE_SHIFT;
  328. val |= sensor->config->tiddq_en << SENSOR_CONFIG1_TIDDQ_EN_SHIFT;
  329. val |= sensor->config->ten_count << SENSOR_CONFIG1_TEN_COUNT_SHIFT;
  330. val |= SENSOR_CONFIG1_TEMP_ENABLE;
  331. writel(val, base + SENSOR_CONFIG1);
  332. writel(tegra->calib[i], base + SENSOR_CONFIG2);
  333. }
  334. /*
  335. * Translate from soctherm readback format to millicelsius.
  336. * The soctherm readback format in bits is as follows:
  337. * TTTTTTTT H______N
  338. * where T's contain the temperature in Celsius,
  339. * H denotes an addition of 0.5 Celsius and N denotes negation
  340. * of the final value.
  341. */
  342. static int translate_temp(u16 val)
  343. {
  344. int t;
  345. t = ((val & READBACK_VALUE_MASK) >> READBACK_VALUE_SHIFT) * 1000;
  346. if (val & READBACK_ADD_HALF)
  347. t += 500;
  348. if (val & READBACK_NEGATE)
  349. t *= -1;
  350. return t;
  351. }
  352. static int tegra_thermctl_get_temp(struct thermal_zone_device *tz, int *out_temp)
  353. {
  354. struct tegra_thermctl_zone *zone = thermal_zone_device_priv(tz);
  355. u32 val;
  356. val = readl(zone->reg);
  357. val = REG_GET_MASK(val, zone->sg->sensor_temp_mask);
  358. *out_temp = translate_temp(val);
  359. return 0;
  360. }
  361. /**
  362. * enforce_temp_range() - check and enforce temperature range [min, max]
  363. * @dev: struct device * of the SOC_THERM instance
  364. * @trip_temp: the trip temperature to check
  365. *
  366. * Checks and enforces the permitted temperature range that SOC_THERM
  367. * HW can support This is
  368. * done while taking care of precision.
  369. *
  370. * Return: The precision adjusted capped temperature in millicelsius.
  371. */
  372. static int enforce_temp_range(struct device *dev, int trip_temp)
  373. {
  374. int temp;
  375. temp = clamp_val(trip_temp, min_low_temp, max_high_temp);
  376. if (temp != trip_temp)
  377. dev_dbg(dev, "soctherm: trip temperature %d forced to %d\n",
  378. trip_temp, temp);
  379. return temp;
  380. }
  381. /**
  382. * thermtrip_program() - Configures the hardware to shut down the
  383. * system if a given sensor group reaches a given temperature
  384. * @dev: ptr to the struct device for the SOC_THERM IP block
  385. * @sg: pointer to the sensor group to set the thermtrip temperature for
  386. * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
  387. *
  388. * Sets the thermal trip threshold of the given sensor group to be the
  389. * @trip_temp. If this threshold is crossed, the hardware will shut
  390. * down.
  391. *
  392. * Note that, although @trip_temp is specified in millicelsius, the
  393. * hardware is programmed in degrees Celsius.
  394. *
  395. * Return: 0 upon success, or %-EINVAL upon failure.
  396. */
  397. static int thermtrip_program(struct device *dev,
  398. const struct tegra_tsensor_group *sg,
  399. int trip_temp)
  400. {
  401. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  402. int temp;
  403. u32 r;
  404. if (!sg || !sg->thermtrip_threshold_mask)
  405. return -EINVAL;
  406. temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
  407. r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
  408. r = REG_SET_MASK(r, sg->thermtrip_threshold_mask, temp);
  409. r = REG_SET_MASK(r, sg->thermtrip_enable_mask, 1);
  410. r = REG_SET_MASK(r, sg->thermtrip_any_en_mask, 0);
  411. writel(r, ts->regs + THERMCTL_THERMTRIP_CTL);
  412. return 0;
  413. }
  414. /**
  415. * throttrip_program() - Configures the hardware to throttle the
  416. * pulse if a given sensor group reaches a given temperature
  417. * @dev: ptr to the struct device for the SOC_THERM IP block
  418. * @sg: pointer to the sensor group to set the thermtrip temperature for
  419. * @stc: pointer to the throttle need to be triggered
  420. * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
  421. *
  422. * Sets the thermal trip threshold and throttle event of the given sensor
  423. * group. If this threshold is crossed, the hardware will trigger the
  424. * throttle.
  425. *
  426. * Note that, although @trip_temp is specified in millicelsius, the
  427. * hardware is programmed in degrees Celsius.
  428. *
  429. * Return: 0 upon success, or %-EINVAL upon failure.
  430. */
  431. static int throttrip_program(struct device *dev,
  432. const struct tegra_tsensor_group *sg,
  433. struct soctherm_throt_cfg *stc,
  434. int trip_temp)
  435. {
  436. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  437. int temp, cpu_throt, gpu_throt;
  438. unsigned int throt;
  439. u32 r, reg_off;
  440. if (!sg || !stc || !stc->init)
  441. return -EINVAL;
  442. temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
  443. /* Hardcode LIGHT on LEVEL1 and HEAVY on LEVEL2 */
  444. throt = stc->id;
  445. reg_off = THERMCTL_LVL_REG(sg->thermctl_lvl0_offset, throt + 1);
  446. if (throt == THROTTLE_LIGHT) {
  447. cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT;
  448. gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT;
  449. } else {
  450. cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY;
  451. gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY;
  452. if (throt != THROTTLE_HEAVY)
  453. dev_warn(dev,
  454. "invalid throt id %d - assuming HEAVY",
  455. throt);
  456. }
  457. r = readl(ts->regs + reg_off);
  458. r = REG_SET_MASK(r, sg->thermctl_lvl0_up_thresh_mask, temp);
  459. r = REG_SET_MASK(r, sg->thermctl_lvl0_dn_thresh_mask, temp);
  460. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_CPU_THROT_MASK, cpu_throt);
  461. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_GPU_THROT_MASK, gpu_throt);
  462. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
  463. writel(r, ts->regs + reg_off);
  464. return 0;
  465. }
  466. static struct soctherm_throt_cfg *
  467. find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name)
  468. {
  469. unsigned int i;
  470. for (i = 0; ts->throt_cfgs[i].name; i++)
  471. if (!strcmp(ts->throt_cfgs[i].name, name))
  472. return &ts->throt_cfgs[i];
  473. return NULL;
  474. }
  475. static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id)
  476. {
  477. int i, temp = min_low_temp;
  478. struct tsensor_group_thermtrips *tt = ts->soc->thermtrips;
  479. if (id >= TEGRA124_SOCTHERM_SENSOR_NUM)
  480. return temp;
  481. if (tt) {
  482. for (i = 0; i < ts->soc->num_ttgs; i++) {
  483. if (tt[i].id == id)
  484. return tt[i].temp;
  485. }
  486. }
  487. return temp;
  488. }
  489. static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz,
  490. const struct thermal_trip *trip, int temp)
  491. {
  492. struct tegra_thermctl_zone *zone = thermal_zone_device_priv(tz);
  493. struct tegra_soctherm *ts = zone->ts;
  494. const struct tegra_tsensor_group *sg = zone->sg;
  495. struct device *dev = zone->dev;
  496. if (!tz)
  497. return -EINVAL;
  498. if (trip->type == THERMAL_TRIP_CRITICAL) {
  499. /*
  500. * If thermtrips property is set in DT,
  501. * doesn't need to program critical type trip to HW,
  502. * if not, program critical trip to HW.
  503. */
  504. if (min_low_temp == tsensor_group_thermtrip_get(ts, sg->id))
  505. return thermtrip_program(dev, sg, temp);
  506. else
  507. return 0;
  508. } else if (trip->type == THERMAL_TRIP_HOT) {
  509. int i;
  510. for (i = 0; i < THROTTLE_SIZE; i++) {
  511. struct thermal_cooling_device *cdev;
  512. struct soctherm_throt_cfg *stc;
  513. if (!ts->throt_cfgs[i].init)
  514. continue;
  515. cdev = ts->throt_cfgs[i].cdev;
  516. if (thermal_trip_is_bound_to_cdev(tz, trip, cdev))
  517. stc = find_throttle_cfg_by_name(ts, cdev->type);
  518. else
  519. continue;
  520. return throttrip_program(dev, sg, stc, temp);
  521. }
  522. }
  523. return 0;
  524. }
  525. static void thermal_irq_enable(struct tegra_thermctl_zone *zn)
  526. {
  527. u32 r;
  528. /* multiple zones could be handling and setting trips at once */
  529. mutex_lock(&zn->ts->thermctl_lock);
  530. r = readl(zn->ts->regs + THERMCTL_INTR_ENABLE);
  531. r = REG_SET_MASK(r, zn->sg->thermctl_isr_mask, TH_INTR_UP_DN_EN);
  532. writel(r, zn->ts->regs + THERMCTL_INTR_ENABLE);
  533. mutex_unlock(&zn->ts->thermctl_lock);
  534. }
  535. static void thermal_irq_disable(struct tegra_thermctl_zone *zn)
  536. {
  537. u32 r;
  538. /* multiple zones could be handling and setting trips at once */
  539. mutex_lock(&zn->ts->thermctl_lock);
  540. r = readl(zn->ts->regs + THERMCTL_INTR_DISABLE);
  541. r = REG_SET_MASK(r, zn->sg->thermctl_isr_mask, 0);
  542. writel(r, zn->ts->regs + THERMCTL_INTR_DISABLE);
  543. mutex_unlock(&zn->ts->thermctl_lock);
  544. }
  545. static int tegra_thermctl_set_trips(struct thermal_zone_device *tz, int lo, int hi)
  546. {
  547. struct tegra_thermctl_zone *zone = thermal_zone_device_priv(tz);
  548. u32 r;
  549. thermal_irq_disable(zone);
  550. r = readl(zone->ts->regs + zone->sg->thermctl_lvl0_offset);
  551. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 0);
  552. writel(r, zone->ts->regs + zone->sg->thermctl_lvl0_offset);
  553. lo = enforce_temp_range(zone->dev, lo) / zone->ts->soc->thresh_grain;
  554. hi = enforce_temp_range(zone->dev, hi) / zone->ts->soc->thresh_grain;
  555. dev_dbg(zone->dev, "%s hi:%d, lo:%d\n", __func__, hi, lo);
  556. r = REG_SET_MASK(r, zone->sg->thermctl_lvl0_up_thresh_mask, hi);
  557. r = REG_SET_MASK(r, zone->sg->thermctl_lvl0_dn_thresh_mask, lo);
  558. r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
  559. writel(r, zone->ts->regs + zone->sg->thermctl_lvl0_offset);
  560. thermal_irq_enable(zone);
  561. return 0;
  562. }
  563. static const struct thermal_zone_device_ops tegra_of_thermal_ops = {
  564. .get_temp = tegra_thermctl_get_temp,
  565. .set_trip_temp = tegra_thermctl_set_trip_temp,
  566. .set_trips = tegra_thermctl_set_trips,
  567. };
  568. static int get_hot_trip_cb(struct thermal_trip *trip, void *arg)
  569. {
  570. const struct thermal_trip **trip_ret = arg;
  571. if (trip->type != THERMAL_TRIP_HOT)
  572. return 0;
  573. *trip_ret = trip;
  574. /* Return nonzero to terminate the search. */
  575. return 1;
  576. }
  577. static const struct thermal_trip *get_hot_trip(struct thermal_zone_device *tz)
  578. {
  579. const struct thermal_trip *trip = NULL;
  580. thermal_zone_for_each_trip(tz, get_hot_trip_cb, &trip);
  581. return trip;
  582. }
  583. /**
  584. * tegra_soctherm_set_hwtrips() - set HW trip point from DT data
  585. * @dev: struct device * of the SOC_THERM instance
  586. * @sg: pointer to the sensor group to set the thermtrip temperature for
  587. * @tz: struct thermal_zone_device *
  588. *
  589. * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
  590. * "THROTTLE" trip points , using "thermtrips", "critical" or "hot"
  591. * type trip_temp
  592. * from thermal zone.
  593. * After they have been configured, THERMTRIP or THROTTLE will take
  594. * action when the configured SoC thermal sensor group reaches a
  595. * certain temperature.
  596. *
  597. * Return: 0 upon success, or a negative error code on failure.
  598. * "Success" does not mean that trips was enabled; it could also
  599. * mean that no node was found in DT.
  600. * THERMTRIP has been enabled successfully when a message similar to
  601. * this one appears on the serial console:
  602. * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC"
  603. * THROTTLE has been enabled successfully when a message similar to
  604. * this one appears on the serial console:
  605. * ""throttrip: will throttle when sensor group XXX reaches YYYYYY mC"
  606. */
  607. static int tegra_soctherm_set_hwtrips(struct device *dev,
  608. const struct tegra_tsensor_group *sg,
  609. struct thermal_zone_device *tz)
  610. {
  611. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  612. const struct thermal_trip *hot_trip;
  613. struct soctherm_throt_cfg *stc;
  614. int i, temperature, ret;
  615. /* Get thermtrips. If missing, try to get critical trips. */
  616. temperature = tsensor_group_thermtrip_get(ts, sg->id);
  617. if (min_low_temp == temperature)
  618. if (thermal_zone_get_crit_temp(tz, &temperature))
  619. temperature = max_high_temp;
  620. ret = thermtrip_program(dev, sg, temperature);
  621. if (ret) {
  622. dev_err(dev, "thermtrip: %s: error during enable\n", sg->name);
  623. return ret;
  624. }
  625. dev_info(dev, "thermtrip: will shut down when %s reaches %d mC\n",
  626. sg->name, temperature);
  627. hot_trip = get_hot_trip(tz);
  628. if (!hot_trip) {
  629. dev_info(dev, "throttrip: %s: missing hot temperature\n",
  630. sg->name);
  631. return 0;
  632. }
  633. for (i = 0; i < THROTTLE_OC1; i++) {
  634. struct thermal_cooling_device *cdev;
  635. if (!ts->throt_cfgs[i].init)
  636. continue;
  637. cdev = ts->throt_cfgs[i].cdev;
  638. if (thermal_trip_is_bound_to_cdev(tz, hot_trip, cdev))
  639. stc = find_throttle_cfg_by_name(ts, cdev->type);
  640. else
  641. continue;
  642. ret = throttrip_program(dev, sg, stc, temperature);
  643. if (ret) {
  644. dev_err(dev, "throttrip: %s: error during enable\n",
  645. sg->name);
  646. return ret;
  647. }
  648. dev_info(dev,
  649. "throttrip: will throttle when %s reaches %d mC\n",
  650. sg->name, temperature);
  651. break;
  652. }
  653. if (i == THROTTLE_SIZE)
  654. dev_info(dev, "throttrip: %s: missing throttle cdev\n",
  655. sg->name);
  656. return 0;
  657. }
  658. static irqreturn_t soctherm_thermal_isr(int irq, void *dev_id)
  659. {
  660. struct tegra_soctherm *ts = dev_id;
  661. u32 r;
  662. /* Case for no lock:
  663. * Although interrupts are enabled in set_trips, there is still no need
  664. * to lock here because the interrupts are disabled before programming
  665. * new trip points. Hence there cant be a interrupt on the same sensor.
  666. * An interrupt can however occur on a sensor while trips are being
  667. * programmed on a different one. This beign a LEVEL interrupt won't
  668. * cause a new interrupt but this is taken care of by the re-reading of
  669. * the STATUS register in the thread function.
  670. */
  671. r = readl(ts->regs + THERMCTL_INTR_STATUS);
  672. writel(r, ts->regs + THERMCTL_INTR_DISABLE);
  673. return IRQ_WAKE_THREAD;
  674. }
  675. /**
  676. * soctherm_thermal_isr_thread() - Handles a thermal interrupt request
  677. * @irq: The interrupt number being requested; not used
  678. * @dev_id: Opaque pointer to tegra_soctherm;
  679. *
  680. * Clears the interrupt status register if there are expected
  681. * interrupt bits set.
  682. * The interrupt(s) are then handled by updating the corresponding
  683. * thermal zones.
  684. *
  685. * An error is logged if any unexpected interrupt bits are set.
  686. *
  687. * Disabled interrupts are re-enabled.
  688. *
  689. * Return: %IRQ_HANDLED. Interrupt was handled and no further processing
  690. * is needed.
  691. */
  692. static irqreturn_t soctherm_thermal_isr_thread(int irq, void *dev_id)
  693. {
  694. struct tegra_soctherm *ts = dev_id;
  695. struct thermal_zone_device *tz;
  696. u32 st, ex = 0, cp = 0, gp = 0, pl = 0, me = 0;
  697. st = readl(ts->regs + THERMCTL_INTR_STATUS);
  698. /* deliberately clear expected interrupts handled in SW */
  699. cp |= st & TH_INTR_CD0_MASK;
  700. cp |= st & TH_INTR_CU0_MASK;
  701. gp |= st & TH_INTR_GD0_MASK;
  702. gp |= st & TH_INTR_GU0_MASK;
  703. pl |= st & TH_INTR_PD0_MASK;
  704. pl |= st & TH_INTR_PU0_MASK;
  705. me |= st & TH_INTR_MD0_MASK;
  706. me |= st & TH_INTR_MU0_MASK;
  707. ex |= cp | gp | pl | me;
  708. if (ex) {
  709. writel(ex, ts->regs + THERMCTL_INTR_STATUS);
  710. st &= ~ex;
  711. if (cp) {
  712. tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_CPU];
  713. thermal_zone_device_update(tz,
  714. THERMAL_EVENT_UNSPECIFIED);
  715. }
  716. if (gp) {
  717. tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_GPU];
  718. thermal_zone_device_update(tz,
  719. THERMAL_EVENT_UNSPECIFIED);
  720. }
  721. if (pl) {
  722. tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_PLLX];
  723. thermal_zone_device_update(tz,
  724. THERMAL_EVENT_UNSPECIFIED);
  725. }
  726. if (me) {
  727. tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_MEM];
  728. thermal_zone_device_update(tz,
  729. THERMAL_EVENT_UNSPECIFIED);
  730. }
  731. }
  732. /* deliberately ignore expected interrupts NOT handled in SW */
  733. ex |= TH_INTR_IGNORE_MASK;
  734. st &= ~ex;
  735. if (st) {
  736. /* Whine about any other unexpected INTR bits still set */
  737. pr_err("soctherm: Ignored unexpected INTRs 0x%08x\n", st);
  738. writel(st, ts->regs + THERMCTL_INTR_STATUS);
  739. }
  740. return IRQ_HANDLED;
  741. }
  742. /**
  743. * soctherm_oc_intr_enable() - Enables the soctherm over-current interrupt
  744. * @ts: pointer to a struct tegra_soctherm
  745. * @alarm: The soctherm throttle id
  746. * @enable: Flag indicating enable the soctherm over-current
  747. * interrupt or disable it
  748. *
  749. * Enables a specific over-current pins @alarm to raise an interrupt if the flag
  750. * is set and the alarm corresponds to OC1, OC2, OC3, or OC4.
  751. */
  752. static void soctherm_oc_intr_enable(struct tegra_soctherm *ts,
  753. enum soctherm_throttle_id alarm,
  754. bool enable)
  755. {
  756. u32 r;
  757. if (!enable)
  758. return;
  759. r = readl(ts->regs + OC_INTR_ENABLE);
  760. switch (alarm) {
  761. case THROTTLE_OC1:
  762. r = REG_SET_MASK(r, OC_INTR_OC1_MASK, 1);
  763. break;
  764. case THROTTLE_OC2:
  765. r = REG_SET_MASK(r, OC_INTR_OC2_MASK, 1);
  766. break;
  767. case THROTTLE_OC3:
  768. r = REG_SET_MASK(r, OC_INTR_OC3_MASK, 1);
  769. break;
  770. case THROTTLE_OC4:
  771. r = REG_SET_MASK(r, OC_INTR_OC4_MASK, 1);
  772. break;
  773. default:
  774. r = 0;
  775. break;
  776. }
  777. writel(r, ts->regs + OC_INTR_ENABLE);
  778. }
  779. /**
  780. * soctherm_handle_alarm() - Handles soctherm alarms
  781. * @alarm: The soctherm throttle id
  782. *
  783. * "Handles" over-current alarms (OC1, OC2, OC3, and OC4) by printing
  784. * a warning or informative message.
  785. *
  786. * Return: -EINVAL for @alarm = THROTTLE_OC3, otherwise 0 (success).
  787. */
  788. static int soctherm_handle_alarm(enum soctherm_throttle_id alarm)
  789. {
  790. int rv = -EINVAL;
  791. switch (alarm) {
  792. case THROTTLE_OC1:
  793. pr_debug("soctherm: Successfully handled OC1 alarm\n");
  794. rv = 0;
  795. break;
  796. case THROTTLE_OC2:
  797. pr_debug("soctherm: Successfully handled OC2 alarm\n");
  798. rv = 0;
  799. break;
  800. case THROTTLE_OC3:
  801. pr_debug("soctherm: Successfully handled OC3 alarm\n");
  802. rv = 0;
  803. break;
  804. case THROTTLE_OC4:
  805. pr_debug("soctherm: Successfully handled OC4 alarm\n");
  806. rv = 0;
  807. break;
  808. default:
  809. break;
  810. }
  811. if (rv)
  812. pr_err("soctherm: ERROR in handling %s alarm\n",
  813. throt_names[alarm]);
  814. return rv;
  815. }
  816. /**
  817. * soctherm_edp_isr_thread() - log an over-current interrupt request
  818. * @irq: OC irq number. Currently not being used. See description
  819. * @arg: a void pointer for callback, currently not being used
  820. *
  821. * Over-current events are handled in hardware. This function is called to log
  822. * and handle any OC events that happened. Additionally, it checks every
  823. * over-current interrupt registers for registers are set but
  824. * was not expected (i.e. any discrepancy in interrupt status) by the function,
  825. * the discrepancy will logged.
  826. *
  827. * Return: %IRQ_HANDLED
  828. */
  829. static irqreturn_t soctherm_edp_isr_thread(int irq, void *arg)
  830. {
  831. struct tegra_soctherm *ts = arg;
  832. u32 st, ex, oc1, oc2, oc3, oc4;
  833. st = readl(ts->regs + OC_INTR_STATUS);
  834. /* deliberately clear expected interrupts handled in SW */
  835. oc1 = st & OC_INTR_OC1_MASK;
  836. oc2 = st & OC_INTR_OC2_MASK;
  837. oc3 = st & OC_INTR_OC3_MASK;
  838. oc4 = st & OC_INTR_OC4_MASK;
  839. ex = oc1 | oc2 | oc3 | oc4;
  840. pr_err("soctherm: OC ALARM 0x%08x\n", ex);
  841. if (ex) {
  842. writel(st, ts->regs + OC_INTR_STATUS);
  843. st &= ~ex;
  844. if (oc1 && !soctherm_handle_alarm(THROTTLE_OC1))
  845. soctherm_oc_intr_enable(ts, THROTTLE_OC1, true);
  846. if (oc2 && !soctherm_handle_alarm(THROTTLE_OC2))
  847. soctherm_oc_intr_enable(ts, THROTTLE_OC2, true);
  848. if (oc3 && !soctherm_handle_alarm(THROTTLE_OC3))
  849. soctherm_oc_intr_enable(ts, THROTTLE_OC3, true);
  850. if (oc4 && !soctherm_handle_alarm(THROTTLE_OC4))
  851. soctherm_oc_intr_enable(ts, THROTTLE_OC4, true);
  852. if (oc1 && soc_irq_cdata.irq_enable & BIT(0))
  853. handle_nested_irq(
  854. irq_find_mapping(soc_irq_cdata.domain, 0));
  855. if (oc2 && soc_irq_cdata.irq_enable & BIT(1))
  856. handle_nested_irq(
  857. irq_find_mapping(soc_irq_cdata.domain, 1));
  858. if (oc3 && soc_irq_cdata.irq_enable & BIT(2))
  859. handle_nested_irq(
  860. irq_find_mapping(soc_irq_cdata.domain, 2));
  861. if (oc4 && soc_irq_cdata.irq_enable & BIT(3))
  862. handle_nested_irq(
  863. irq_find_mapping(soc_irq_cdata.domain, 3));
  864. }
  865. if (st) {
  866. pr_err("soctherm: Ignored unexpected OC ALARM 0x%08x\n", st);
  867. writel(st, ts->regs + OC_INTR_STATUS);
  868. }
  869. return IRQ_HANDLED;
  870. }
  871. /**
  872. * soctherm_edp_isr() - Disables any active interrupts
  873. * @irq: The interrupt request number
  874. * @arg: Opaque pointer to an argument
  875. *
  876. * Writes to the OC_INTR_DISABLE register the over current interrupt status,
  877. * masking any asserted interrupts. Doing this prevents the same interrupts
  878. * from triggering this isr repeatedly. The thread woken by this isr will
  879. * handle asserted interrupts and subsequently unmask/re-enable them.
  880. *
  881. * The OC_INTR_DISABLE register indicates which OC interrupts
  882. * have been disabled.
  883. *
  884. * Return: %IRQ_WAKE_THREAD, handler requests to wake the handler thread
  885. */
  886. static irqreturn_t soctherm_edp_isr(int irq, void *arg)
  887. {
  888. struct tegra_soctherm *ts = arg;
  889. u32 r;
  890. if (!ts)
  891. return IRQ_NONE;
  892. r = readl(ts->regs + OC_INTR_STATUS);
  893. writel(r, ts->regs + OC_INTR_DISABLE);
  894. return IRQ_WAKE_THREAD;
  895. }
  896. /**
  897. * soctherm_oc_irq_lock() - locks the over-current interrupt request
  898. * @data: Interrupt request data
  899. *
  900. * Looks up the chip data from @data and locks the mutex associated with
  901. * a particular over-current interrupt request.
  902. */
  903. static void soctherm_oc_irq_lock(struct irq_data *data)
  904. {
  905. struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
  906. mutex_lock(&d->irq_lock);
  907. }
  908. /**
  909. * soctherm_oc_irq_sync_unlock() - Unlocks the OC interrupt request
  910. * @data: Interrupt request data
  911. *
  912. * Looks up the interrupt request data @data and unlocks the mutex associated
  913. * with a particular over-current interrupt request.
  914. */
  915. static void soctherm_oc_irq_sync_unlock(struct irq_data *data)
  916. {
  917. struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
  918. mutex_unlock(&d->irq_lock);
  919. }
  920. /**
  921. * soctherm_oc_irq_enable() - Enables the SOC_THERM over-current interrupt queue
  922. * @data: irq_data structure of the chip
  923. *
  924. * Sets the irq_enable bit of SOC_THERM allowing SOC_THERM
  925. * to respond to over-current interrupts.
  926. *
  927. */
  928. static void soctherm_oc_irq_enable(struct irq_data *data)
  929. {
  930. struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
  931. d->irq_enable |= BIT(data->hwirq);
  932. }
  933. /**
  934. * soctherm_oc_irq_disable() - Disables overcurrent interrupt requests
  935. * @data: The interrupt request information
  936. *
  937. * Clears the interrupt request enable bit of the overcurrent
  938. * interrupt request chip data.
  939. *
  940. * Return: Nothing is returned (void)
  941. */
  942. static void soctherm_oc_irq_disable(struct irq_data *data)
  943. {
  944. struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
  945. d->irq_enable &= ~BIT(data->hwirq);
  946. }
  947. static int soctherm_oc_irq_set_type(struct irq_data *data, unsigned int type)
  948. {
  949. return 0;
  950. }
  951. /**
  952. * soctherm_oc_irq_map() - SOC_THERM interrupt request domain mapper
  953. * @h: Interrupt request domain
  954. * @virq: Virtual interrupt request number
  955. * @hw: Hardware interrupt request number
  956. *
  957. * Mapping callback function for SOC_THERM's irq_domain. When a SOC_THERM
  958. * interrupt request is called, the irq_domain takes the request's virtual
  959. * request number (much like a virtual memory address) and maps it to a
  960. * physical hardware request number.
  961. *
  962. * When a mapping doesn't already exist for a virtual request number, the
  963. * irq_domain calls this function to associate the virtual request number with
  964. * a hardware request number.
  965. *
  966. * Return: 0
  967. */
  968. static int soctherm_oc_irq_map(struct irq_domain *h, unsigned int virq,
  969. irq_hw_number_t hw)
  970. {
  971. struct soctherm_oc_irq_chip_data *data = h->host_data;
  972. irq_set_chip_data(virq, data);
  973. irq_set_chip(virq, &data->irq_chip);
  974. irq_set_nested_thread(virq, 1);
  975. return 0;
  976. }
  977. /**
  978. * soctherm_irq_domain_xlate_twocell() - xlate for soctherm interrupts
  979. * @d: Interrupt request domain
  980. * @ctrlr: Controller device tree node
  981. * @intspec: Array of u32s from DTs "interrupt" property
  982. * @intsize: Number of values inside the intspec array
  983. * @out_hwirq: HW IRQ value associated with this interrupt
  984. * @out_type: The IRQ SENSE type for this interrupt.
  985. *
  986. * This Device Tree IRQ specifier translation function will translate a
  987. * specific "interrupt" as defined by 2 DT values where the cell values map
  988. * the hwirq number + 1 and linux irq flags. Since the output is the hwirq
  989. * number, this function will subtract 1 from the value listed in DT.
  990. *
  991. * Return: 0
  992. */
  993. static int soctherm_irq_domain_xlate_twocell(struct irq_domain *d,
  994. struct device_node *ctrlr, const u32 *intspec, unsigned int intsize,
  995. irq_hw_number_t *out_hwirq, unsigned int *out_type)
  996. {
  997. if (WARN_ON(intsize < 2))
  998. return -EINVAL;
  999. /*
  1000. * The HW value is 1 index less than the DT IRQ values.
  1001. * i.e. OC4 goes to HW index 3.
  1002. */
  1003. *out_hwirq = intspec[0] - 1;
  1004. *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
  1005. return 0;
  1006. }
  1007. static const struct irq_domain_ops soctherm_oc_domain_ops = {
  1008. .map = soctherm_oc_irq_map,
  1009. .xlate = soctherm_irq_domain_xlate_twocell,
  1010. };
  1011. /**
  1012. * soctherm_oc_int_init() - Initial enabling of the over
  1013. * current interrupts
  1014. * @np: The devicetree node for soctherm
  1015. * @num_irqs: The number of new interrupt requests
  1016. *
  1017. * Sets the over current interrupt request chip data
  1018. *
  1019. * Return: 0 on success or if overcurrent interrupts are not enabled,
  1020. * -ENOMEM (out of memory), or irq_base if the function failed to
  1021. * allocate the irqs
  1022. */
  1023. static int soctherm_oc_int_init(struct device_node *np, int num_irqs)
  1024. {
  1025. if (!num_irqs) {
  1026. pr_info("%s(): OC interrupts are not enabled\n", __func__);
  1027. return 0;
  1028. }
  1029. mutex_init(&soc_irq_cdata.irq_lock);
  1030. soc_irq_cdata.irq_enable = 0;
  1031. soc_irq_cdata.irq_chip.name = "soc_therm_oc";
  1032. soc_irq_cdata.irq_chip.irq_bus_lock = soctherm_oc_irq_lock;
  1033. soc_irq_cdata.irq_chip.irq_bus_sync_unlock =
  1034. soctherm_oc_irq_sync_unlock;
  1035. soc_irq_cdata.irq_chip.irq_disable = soctherm_oc_irq_disable;
  1036. soc_irq_cdata.irq_chip.irq_enable = soctherm_oc_irq_enable;
  1037. soc_irq_cdata.irq_chip.irq_set_type = soctherm_oc_irq_set_type;
  1038. soc_irq_cdata.irq_chip.irq_set_wake = NULL;
  1039. soc_irq_cdata.domain = irq_domain_add_linear(np, num_irqs,
  1040. &soctherm_oc_domain_ops,
  1041. &soc_irq_cdata);
  1042. if (!soc_irq_cdata.domain) {
  1043. pr_err("%s: Failed to create IRQ domain\n", __func__);
  1044. return -ENOMEM;
  1045. }
  1046. pr_debug("%s(): OC interrupts enabled successful\n", __func__);
  1047. return 0;
  1048. }
  1049. #ifdef CONFIG_DEBUG_FS
  1050. static int regs_show(struct seq_file *s, void *data)
  1051. {
  1052. struct platform_device *pdev = s->private;
  1053. struct tegra_soctherm *ts = platform_get_drvdata(pdev);
  1054. const struct tegra_tsensor *tsensors = ts->soc->tsensors;
  1055. const struct tegra_tsensor_group **ttgs = ts->soc->ttgs;
  1056. u32 r, state;
  1057. int i, level;
  1058. seq_puts(s, "-----TSENSE (convert HW)-----\n");
  1059. for (i = 0; i < ts->soc->num_tsensors; i++) {
  1060. r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG1);
  1061. state = REG_GET_MASK(r, SENSOR_CONFIG1_TEMP_ENABLE);
  1062. seq_printf(s, "%s: ", tsensors[i].name);
  1063. seq_printf(s, "En(%d) ", state);
  1064. if (!state) {
  1065. seq_puts(s, "\n");
  1066. continue;
  1067. }
  1068. state = REG_GET_MASK(r, SENSOR_CONFIG1_TIDDQ_EN_MASK);
  1069. seq_printf(s, "tiddq(%d) ", state);
  1070. state = REG_GET_MASK(r, SENSOR_CONFIG1_TEN_COUNT_MASK);
  1071. seq_printf(s, "ten_count(%d) ", state);
  1072. state = REG_GET_MASK(r, SENSOR_CONFIG1_TSAMPLE_MASK);
  1073. seq_printf(s, "tsample(%d) ", state + 1);
  1074. r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS1);
  1075. state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_VALID_MASK);
  1076. seq_printf(s, "Temp(%d/", state);
  1077. state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_MASK);
  1078. seq_printf(s, "%d) ", translate_temp(state));
  1079. r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS0);
  1080. state = REG_GET_MASK(r, SENSOR_STATUS0_VALID_MASK);
  1081. seq_printf(s, "Capture(%d/", state);
  1082. state = REG_GET_MASK(r, SENSOR_STATUS0_CAPTURE_MASK);
  1083. seq_printf(s, "%d) ", state);
  1084. r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG0);
  1085. state = REG_GET_MASK(r, SENSOR_CONFIG0_STOP);
  1086. seq_printf(s, "Stop(%d) ", state);
  1087. state = REG_GET_MASK(r, SENSOR_CONFIG0_TALL_MASK);
  1088. seq_printf(s, "Tall(%d) ", state);
  1089. state = REG_GET_MASK(r, SENSOR_CONFIG0_TCALC_OVER);
  1090. seq_printf(s, "Over(%d/", state);
  1091. state = REG_GET_MASK(r, SENSOR_CONFIG0_OVER);
  1092. seq_printf(s, "%d/", state);
  1093. state = REG_GET_MASK(r, SENSOR_CONFIG0_CPTR_OVER);
  1094. seq_printf(s, "%d) ", state);
  1095. r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG2);
  1096. state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMA_MASK);
  1097. seq_printf(s, "Therm_A/B(%d/", state);
  1098. state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMB_MASK);
  1099. seq_printf(s, "%d)\n", (s16)state);
  1100. }
  1101. r = readl(ts->regs + SENSOR_PDIV);
  1102. seq_printf(s, "PDIV: 0x%x\n", r);
  1103. r = readl(ts->regs + SENSOR_HOTSPOT_OFF);
  1104. seq_printf(s, "HOTSPOT: 0x%x\n", r);
  1105. seq_puts(s, "\n");
  1106. seq_puts(s, "-----SOC_THERM-----\n");
  1107. r = readl(ts->regs + SENSOR_TEMP1);
  1108. state = REG_GET_MASK(r, SENSOR_TEMP1_CPU_TEMP_MASK);
  1109. seq_printf(s, "Temperatures: CPU(%d) ", translate_temp(state));
  1110. state = REG_GET_MASK(r, SENSOR_TEMP1_GPU_TEMP_MASK);
  1111. seq_printf(s, " GPU(%d) ", translate_temp(state));
  1112. r = readl(ts->regs + SENSOR_TEMP2);
  1113. state = REG_GET_MASK(r, SENSOR_TEMP2_PLLX_TEMP_MASK);
  1114. seq_printf(s, " PLLX(%d) ", translate_temp(state));
  1115. state = REG_GET_MASK(r, SENSOR_TEMP2_MEM_TEMP_MASK);
  1116. seq_printf(s, " MEM(%d)\n", translate_temp(state));
  1117. for (i = 0; i < ts->soc->num_ttgs; i++) {
  1118. seq_printf(s, "%s:\n", ttgs[i]->name);
  1119. for (level = 0; level < 4; level++) {
  1120. s32 v;
  1121. u32 mask;
  1122. u16 off = ttgs[i]->thermctl_lvl0_offset;
  1123. r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
  1124. mask = ttgs[i]->thermctl_lvl0_up_thresh_mask;
  1125. state = REG_GET_MASK(r, mask);
  1126. v = sign_extend32(state, ts->soc->bptt - 1);
  1127. v *= ts->soc->thresh_grain;
  1128. seq_printf(s, " %d: Up/Dn(%d /", level, v);
  1129. mask = ttgs[i]->thermctl_lvl0_dn_thresh_mask;
  1130. state = REG_GET_MASK(r, mask);
  1131. v = sign_extend32(state, ts->soc->bptt - 1);
  1132. v *= ts->soc->thresh_grain;
  1133. seq_printf(s, "%d ) ", v);
  1134. mask = THERMCTL_LVL0_CPU0_EN_MASK;
  1135. state = REG_GET_MASK(r, mask);
  1136. seq_printf(s, "En(%d) ", state);
  1137. mask = THERMCTL_LVL0_CPU0_CPU_THROT_MASK;
  1138. state = REG_GET_MASK(r, mask);
  1139. seq_puts(s, "CPU Throt");
  1140. if (!state)
  1141. seq_printf(s, "(%s) ", "none");
  1142. else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT)
  1143. seq_printf(s, "(%s) ", "L");
  1144. else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY)
  1145. seq_printf(s, "(%s) ", "H");
  1146. else
  1147. seq_printf(s, "(%s) ", "H+L");
  1148. mask = THERMCTL_LVL0_CPU0_GPU_THROT_MASK;
  1149. state = REG_GET_MASK(r, mask);
  1150. seq_puts(s, "GPU Throt");
  1151. if (!state)
  1152. seq_printf(s, "(%s) ", "none");
  1153. else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT)
  1154. seq_printf(s, "(%s) ", "L");
  1155. else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY)
  1156. seq_printf(s, "(%s) ", "H");
  1157. else
  1158. seq_printf(s, "(%s) ", "H+L");
  1159. mask = THERMCTL_LVL0_CPU0_STATUS_MASK;
  1160. state = REG_GET_MASK(r, mask);
  1161. seq_printf(s, "Status(%s)\n",
  1162. state == 0 ? "LO" :
  1163. state == 1 ? "In" :
  1164. state == 2 ? "Res" : "HI");
  1165. }
  1166. }
  1167. r = readl(ts->regs + THERMCTL_STATS_CTL);
  1168. seq_printf(s, "STATS: Up(%s) Dn(%s)\n",
  1169. r & STATS_CTL_EN_UP ? "En" : "--",
  1170. r & STATS_CTL_EN_DN ? "En" : "--");
  1171. for (level = 0; level < 4; level++) {
  1172. u16 off;
  1173. off = THERMCTL_LVL0_UP_STATS;
  1174. r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
  1175. seq_printf(s, " Level_%d Up(%d) ", level, r);
  1176. off = THERMCTL_LVL0_DN_STATS;
  1177. r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
  1178. seq_printf(s, "Dn(%d)\n", r);
  1179. }
  1180. r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
  1181. state = REG_GET_MASK(r, ttgs[0]->thermtrip_any_en_mask);
  1182. seq_printf(s, "Thermtrip Any En(%d)\n", state);
  1183. for (i = 0; i < ts->soc->num_ttgs; i++) {
  1184. state = REG_GET_MASK(r, ttgs[i]->thermtrip_enable_mask);
  1185. seq_printf(s, " %s En(%d) ", ttgs[i]->name, state);
  1186. state = REG_GET_MASK(r, ttgs[i]->thermtrip_threshold_mask);
  1187. state *= ts->soc->thresh_grain;
  1188. seq_printf(s, "Thresh(%d)\n", state);
  1189. }
  1190. r = readl(ts->regs + THROT_GLOBAL_CFG);
  1191. seq_puts(s, "\n");
  1192. seq_printf(s, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r);
  1193. seq_puts(s, "---------------------------------------------------\n");
  1194. r = readl(ts->regs + THROT_STATUS);
  1195. state = REG_GET_MASK(r, THROT_STATUS_BREACH_MASK);
  1196. seq_printf(s, "THROT STATUS: breach(%d) ", state);
  1197. state = REG_GET_MASK(r, THROT_STATUS_STATE_MASK);
  1198. seq_printf(s, "state(%d) ", state);
  1199. state = REG_GET_MASK(r, THROT_STATUS_ENABLED_MASK);
  1200. seq_printf(s, "enabled(%d)\n", state);
  1201. r = readl(ts->regs + CPU_PSKIP_STATUS);
  1202. if (ts->soc->use_ccroc) {
  1203. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
  1204. seq_printf(s, "CPU PSKIP STATUS: enabled(%d)\n", state);
  1205. } else {
  1206. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_M_MASK);
  1207. seq_printf(s, "CPU PSKIP STATUS: M(%d) ", state);
  1208. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_N_MASK);
  1209. seq_printf(s, "N(%d) ", state);
  1210. state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
  1211. seq_printf(s, "enabled(%d)\n", state);
  1212. }
  1213. return 0;
  1214. }
  1215. DEFINE_SHOW_ATTRIBUTE(regs);
  1216. static void soctherm_debug_init(struct platform_device *pdev)
  1217. {
  1218. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1219. struct dentry *root;
  1220. root = debugfs_create_dir("soctherm", NULL);
  1221. tegra->debugfs_dir = root;
  1222. debugfs_create_file("reg_contents", 0644, root, pdev, &regs_fops);
  1223. }
  1224. #else
  1225. static inline void soctherm_debug_init(struct platform_device *pdev) {}
  1226. #endif
  1227. static int soctherm_clk_enable(struct platform_device *pdev, bool enable)
  1228. {
  1229. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1230. int err;
  1231. if (!tegra->clock_soctherm || !tegra->clock_tsensor)
  1232. return -EINVAL;
  1233. reset_control_assert(tegra->reset);
  1234. if (enable) {
  1235. err = clk_prepare_enable(tegra->clock_soctherm);
  1236. if (err) {
  1237. reset_control_deassert(tegra->reset);
  1238. return err;
  1239. }
  1240. err = clk_prepare_enable(tegra->clock_tsensor);
  1241. if (err) {
  1242. clk_disable_unprepare(tegra->clock_soctherm);
  1243. reset_control_deassert(tegra->reset);
  1244. return err;
  1245. }
  1246. } else {
  1247. clk_disable_unprepare(tegra->clock_tsensor);
  1248. clk_disable_unprepare(tegra->clock_soctherm);
  1249. }
  1250. reset_control_deassert(tegra->reset);
  1251. return 0;
  1252. }
  1253. static int throt_get_cdev_max_state(struct thermal_cooling_device *cdev,
  1254. unsigned long *max_state)
  1255. {
  1256. *max_state = 1;
  1257. return 0;
  1258. }
  1259. static int throt_get_cdev_cur_state(struct thermal_cooling_device *cdev,
  1260. unsigned long *cur_state)
  1261. {
  1262. struct tegra_soctherm *ts = cdev->devdata;
  1263. u32 r;
  1264. r = readl(ts->regs + THROT_STATUS);
  1265. if (REG_GET_MASK(r, THROT_STATUS_STATE_MASK))
  1266. *cur_state = 1;
  1267. else
  1268. *cur_state = 0;
  1269. return 0;
  1270. }
  1271. static int throt_set_cdev_state(struct thermal_cooling_device *cdev,
  1272. unsigned long cur_state)
  1273. {
  1274. return 0;
  1275. }
  1276. static const struct thermal_cooling_device_ops throt_cooling_ops = {
  1277. .get_max_state = throt_get_cdev_max_state,
  1278. .get_cur_state = throt_get_cdev_cur_state,
  1279. .set_cur_state = throt_set_cdev_state,
  1280. };
  1281. static int soctherm_thermtrips_parse(struct platform_device *pdev)
  1282. {
  1283. struct device *dev = &pdev->dev;
  1284. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  1285. struct tsensor_group_thermtrips *tt = ts->soc->thermtrips;
  1286. const int max_num_prop = ts->soc->num_ttgs * 2;
  1287. u32 *tlb;
  1288. int i, j, n, ret;
  1289. if (!tt)
  1290. return -ENOMEM;
  1291. n = of_property_count_u32_elems(dev->of_node, "nvidia,thermtrips");
  1292. if (n <= 0) {
  1293. dev_info(dev,
  1294. "missing thermtrips, will use critical trips as shut down temp\n");
  1295. return n;
  1296. }
  1297. n = min(max_num_prop, n);
  1298. tlb = devm_kcalloc(&pdev->dev, max_num_prop, sizeof(u32), GFP_KERNEL);
  1299. if (!tlb)
  1300. return -ENOMEM;
  1301. ret = of_property_read_u32_array(dev->of_node, "nvidia,thermtrips",
  1302. tlb, n);
  1303. if (ret) {
  1304. dev_err(dev, "invalid num ele: thermtrips:%d\n", ret);
  1305. return ret;
  1306. }
  1307. i = 0;
  1308. for (j = 0; j < n; j = j + 2) {
  1309. if (tlb[j] >= TEGRA124_SOCTHERM_SENSOR_NUM)
  1310. continue;
  1311. tt[i].id = tlb[j];
  1312. tt[i].temp = tlb[j + 1];
  1313. i++;
  1314. }
  1315. return 0;
  1316. }
  1317. static void soctherm_oc_cfg_parse(struct device *dev,
  1318. struct device_node *np_oc,
  1319. struct soctherm_throt_cfg *stc)
  1320. {
  1321. u32 val;
  1322. if (of_property_read_bool(np_oc, "nvidia,polarity-active-low"))
  1323. stc->oc_cfg.active_low = 1;
  1324. else
  1325. stc->oc_cfg.active_low = 0;
  1326. if (!of_property_read_u32(np_oc, "nvidia,count-threshold", &val)) {
  1327. stc->oc_cfg.intr_en = 1;
  1328. stc->oc_cfg.alarm_cnt_thresh = val;
  1329. }
  1330. if (!of_property_read_u32(np_oc, "nvidia,throttle-period-us", &val))
  1331. stc->oc_cfg.throt_period = val;
  1332. if (!of_property_read_u32(np_oc, "nvidia,alarm-filter", &val))
  1333. stc->oc_cfg.alarm_filter = val;
  1334. /* BRIEF throttling by default, do not support STICKY */
  1335. stc->oc_cfg.mode = OC_THROTTLE_MODE_BRIEF;
  1336. }
  1337. static int soctherm_throt_cfg_parse(struct device *dev,
  1338. struct device_node *np,
  1339. struct soctherm_throt_cfg *stc)
  1340. {
  1341. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  1342. int ret;
  1343. u32 val;
  1344. ret = of_property_read_u32(np, "nvidia,priority", &val);
  1345. if (ret) {
  1346. dev_err(dev, "throttle-cfg: %s: invalid priority\n", stc->name);
  1347. return -EINVAL;
  1348. }
  1349. stc->priority = val;
  1350. ret = of_property_read_u32(np, ts->soc->use_ccroc ?
  1351. "nvidia,cpu-throt-level" :
  1352. "nvidia,cpu-throt-percent", &val);
  1353. if (!ret) {
  1354. if (ts->soc->use_ccroc &&
  1355. val <= TEGRA_SOCTHERM_THROT_LEVEL_HIGH)
  1356. stc->cpu_throt_level = val;
  1357. else if (!ts->soc->use_ccroc && val <= 100)
  1358. stc->cpu_throt_depth = val;
  1359. else
  1360. goto err;
  1361. } else {
  1362. goto err;
  1363. }
  1364. ret = of_property_read_u32(np, "nvidia,gpu-throt-level", &val);
  1365. if (!ret && val <= TEGRA_SOCTHERM_THROT_LEVEL_HIGH)
  1366. stc->gpu_throt_level = val;
  1367. else
  1368. goto err;
  1369. return 0;
  1370. err:
  1371. dev_err(dev, "throttle-cfg: %s: no throt prop or invalid prop\n",
  1372. stc->name);
  1373. return -EINVAL;
  1374. }
  1375. /**
  1376. * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
  1377. * and register them as cooling devices.
  1378. * @pdev: Pointer to platform_device struct
  1379. */
  1380. static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
  1381. {
  1382. struct device *dev = &pdev->dev;
  1383. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  1384. struct device_node *np_stc, *np_stcc;
  1385. const char *name;
  1386. int i;
  1387. for (i = 0; i < THROTTLE_SIZE; i++) {
  1388. ts->throt_cfgs[i].name = throt_names[i];
  1389. ts->throt_cfgs[i].id = i;
  1390. ts->throt_cfgs[i].init = false;
  1391. }
  1392. np_stc = of_get_child_by_name(dev->of_node, "throttle-cfgs");
  1393. if (!np_stc) {
  1394. dev_info(dev,
  1395. "throttle-cfg: no throttle-cfgs - not enabling\n");
  1396. return;
  1397. }
  1398. for_each_child_of_node(np_stc, np_stcc) {
  1399. struct soctherm_throt_cfg *stc;
  1400. struct thermal_cooling_device *tcd;
  1401. int err;
  1402. name = np_stcc->name;
  1403. stc = find_throttle_cfg_by_name(ts, name);
  1404. if (!stc) {
  1405. dev_err(dev,
  1406. "throttle-cfg: could not find %s\n", name);
  1407. continue;
  1408. }
  1409. if (stc->init) {
  1410. dev_err(dev, "throttle-cfg: %s: redefined!\n", name);
  1411. of_node_put(np_stcc);
  1412. break;
  1413. }
  1414. err = soctherm_throt_cfg_parse(dev, np_stcc, stc);
  1415. if (err)
  1416. continue;
  1417. if (stc->id >= THROTTLE_OC1) {
  1418. soctherm_oc_cfg_parse(dev, np_stcc, stc);
  1419. stc->init = true;
  1420. } else {
  1421. tcd = thermal_of_cooling_device_register(np_stcc,
  1422. (char *)name, ts,
  1423. &throt_cooling_ops);
  1424. if (IS_ERR_OR_NULL(tcd)) {
  1425. dev_err(dev,
  1426. "throttle-cfg: %s: failed to register cooling device\n",
  1427. name);
  1428. continue;
  1429. }
  1430. stc->cdev = tcd;
  1431. stc->init = true;
  1432. }
  1433. }
  1434. of_node_put(np_stc);
  1435. }
  1436. /**
  1437. * throttlectl_cpu_level_cfg() - programs CCROC NV_THERM level config
  1438. * @ts: pointer to a struct tegra_soctherm
  1439. * @level: describing the level LOW/MED/HIGH of throttling
  1440. *
  1441. * It's necessary to set up the CPU-local CCROC NV_THERM instance with
  1442. * the M/N values desired for each level. This function does this.
  1443. *
  1444. * This function pre-programs the CCROC NV_THERM levels in terms of
  1445. * pre-configured "Low", "Medium" or "Heavy" throttle levels which are
  1446. * mapped to THROT_LEVEL_LOW, THROT_LEVEL_MED and THROT_LEVEL_HVY.
  1447. */
  1448. static void throttlectl_cpu_level_cfg(struct tegra_soctherm *ts, int level)
  1449. {
  1450. u8 depth, dividend;
  1451. u32 r;
  1452. switch (level) {
  1453. case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
  1454. depth = 50;
  1455. break;
  1456. case TEGRA_SOCTHERM_THROT_LEVEL_MED:
  1457. depth = 75;
  1458. break;
  1459. case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
  1460. depth = 80;
  1461. break;
  1462. case TEGRA_SOCTHERM_THROT_LEVEL_NONE:
  1463. return;
  1464. default:
  1465. return;
  1466. }
  1467. dividend = THROT_DEPTH_DIVIDEND(depth);
  1468. /* setup PSKIP in ccroc nv_therm registers */
  1469. r = ccroc_readl(ts, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
  1470. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
  1471. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_STEP_MASK, 0xf);
  1472. ccroc_writel(ts, r, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
  1473. r = ccroc_readl(ts, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
  1474. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_ENB_MASK, 1);
  1475. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
  1476. r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
  1477. ccroc_writel(ts, r, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
  1478. }
  1479. /**
  1480. * throttlectl_cpu_level_select() - program CPU pulse skipper config
  1481. * @ts: pointer to a struct tegra_soctherm
  1482. * @throt: the LIGHT/HEAVY of throttle event id
  1483. *
  1484. * Pulse skippers are used to throttle clock frequencies. This
  1485. * function programs the pulse skippers based on @throt and platform
  1486. * data. This function is used on SoCs which have CPU-local pulse
  1487. * skipper control, such as T13x. It programs soctherm's interface to
  1488. * Denver:CCROC NV_THERM in terms of Low, Medium and HIGH throttling
  1489. * vectors. PSKIP_BYPASS mode is set as required per HW spec.
  1490. */
  1491. static void throttlectl_cpu_level_select(struct tegra_soctherm *ts,
  1492. enum soctherm_throttle_id throt)
  1493. {
  1494. u32 r, throt_vect;
  1495. /* Denver:CCROC NV_THERM interface N:3 Mapping */
  1496. switch (ts->throt_cfgs[throt].cpu_throt_level) {
  1497. case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
  1498. throt_vect = THROT_VECT_LOW;
  1499. break;
  1500. case TEGRA_SOCTHERM_THROT_LEVEL_MED:
  1501. throt_vect = THROT_VECT_MED;
  1502. break;
  1503. case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
  1504. throt_vect = THROT_VECT_HIGH;
  1505. break;
  1506. default:
  1507. throt_vect = THROT_VECT_NONE;
  1508. break;
  1509. }
  1510. r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  1511. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
  1512. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT_CPU_MASK, throt_vect);
  1513. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT2_CPU_MASK, throt_vect);
  1514. writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  1515. /* bypass sequencer in soc_therm as it is programmed in ccroc */
  1516. r = REG_SET_MASK(0, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK, 1);
  1517. writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
  1518. }
  1519. /**
  1520. * throttlectl_cpu_mn() - program CPU pulse skipper configuration
  1521. * @ts: pointer to a struct tegra_soctherm
  1522. * @throt: the LIGHT/HEAVY of throttle event id
  1523. *
  1524. * Pulse skippers are used to throttle clock frequencies. This
  1525. * function programs the pulse skippers based on @throt and platform
  1526. * data. This function is used for CPUs that have "remote" pulse
  1527. * skipper control, e.g., the CPU pulse skipper is controlled by the
  1528. * SOC_THERM IP block. (SOC_THERM is located outside the CPU
  1529. * complex.)
  1530. */
  1531. static void throttlectl_cpu_mn(struct tegra_soctherm *ts,
  1532. enum soctherm_throttle_id throt)
  1533. {
  1534. u32 r;
  1535. int depth;
  1536. u8 dividend;
  1537. depth = ts->throt_cfgs[throt].cpu_throt_depth;
  1538. dividend = THROT_DEPTH_DIVIDEND(depth);
  1539. r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  1540. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
  1541. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
  1542. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
  1543. writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
  1544. r = readl(ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
  1545. r = REG_SET_MASK(r, THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
  1546. r = REG_SET_MASK(r, THROT_PSKIP_RAMP_STEP_MASK, 0xf);
  1547. writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
  1548. }
  1549. /**
  1550. * throttlectl_gpu_level_select() - selects throttling level for GPU
  1551. * @ts: pointer to a struct tegra_soctherm
  1552. * @throt: the LIGHT/HEAVY of throttle event id
  1553. *
  1554. * This function programs soctherm's interface to GK20a NV_THERM to select
  1555. * pre-configured "Low", "Medium" or "Heavy" throttle levels.
  1556. *
  1557. * Return: boolean true if HW was programmed
  1558. */
  1559. static void throttlectl_gpu_level_select(struct tegra_soctherm *ts,
  1560. enum soctherm_throttle_id throt)
  1561. {
  1562. u32 r, level, throt_vect;
  1563. level = ts->throt_cfgs[throt].gpu_throt_level;
  1564. throt_vect = THROT_LEVEL_TO_DEPTH(level);
  1565. r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
  1566. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
  1567. r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT_GPU_MASK, throt_vect);
  1568. writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
  1569. }
  1570. static int soctherm_oc_cfg_program(struct tegra_soctherm *ts,
  1571. enum soctherm_throttle_id throt)
  1572. {
  1573. u32 r;
  1574. struct soctherm_oc_cfg *oc = &ts->throt_cfgs[throt].oc_cfg;
  1575. if (oc->mode == OC_THROTTLE_MODE_DISABLED)
  1576. return -EINVAL;
  1577. r = REG_SET_MASK(0, OC1_CFG_HW_RESTORE_MASK, 1);
  1578. r = REG_SET_MASK(r, OC1_CFG_THROTTLE_MODE_MASK, oc->mode);
  1579. r = REG_SET_MASK(r, OC1_CFG_ALARM_POLARITY_MASK, oc->active_low);
  1580. r = REG_SET_MASK(r, OC1_CFG_EN_THROTTLE_MASK, 1);
  1581. writel(r, ts->regs + ALARM_CFG(throt));
  1582. writel(oc->throt_period, ts->regs + ALARM_THROTTLE_PERIOD(throt));
  1583. writel(oc->alarm_cnt_thresh, ts->regs + ALARM_CNT_THRESHOLD(throt));
  1584. writel(oc->alarm_filter, ts->regs + ALARM_FILTER(throt));
  1585. soctherm_oc_intr_enable(ts, throt, oc->intr_en);
  1586. return 0;
  1587. }
  1588. /**
  1589. * soctherm_throttle_program() - programs pulse skippers' configuration
  1590. * @ts: pointer to a struct tegra_soctherm
  1591. * @throt: the LIGHT/HEAVY of the throttle event id.
  1592. *
  1593. * Pulse skippers are used to throttle clock frequencies.
  1594. * This function programs the pulse skippers.
  1595. */
  1596. static void soctherm_throttle_program(struct tegra_soctherm *ts,
  1597. enum soctherm_throttle_id throt)
  1598. {
  1599. u32 r;
  1600. struct soctherm_throt_cfg stc = ts->throt_cfgs[throt];
  1601. if (!stc.init)
  1602. return;
  1603. if ((throt >= THROTTLE_OC1) && (soctherm_oc_cfg_program(ts, throt)))
  1604. return;
  1605. /* Setup PSKIP parameters */
  1606. if (ts->soc->use_ccroc)
  1607. throttlectl_cpu_level_select(ts, throt);
  1608. else
  1609. throttlectl_cpu_mn(ts, throt);
  1610. throttlectl_gpu_level_select(ts, throt);
  1611. r = REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK, stc.priority);
  1612. writel(r, ts->regs + THROT_PRIORITY_CTRL(throt));
  1613. r = REG_SET_MASK(0, THROT_DELAY_LITE_DELAY_MASK, 0);
  1614. writel(r, ts->regs + THROT_DELAY_CTRL(throt));
  1615. r = readl(ts->regs + THROT_PRIORITY_LOCK);
  1616. r = REG_GET_MASK(r, THROT_PRIORITY_LOCK_PRIORITY_MASK);
  1617. if (r >= stc.priority)
  1618. return;
  1619. r = REG_SET_MASK(0, THROT_PRIORITY_LOCK_PRIORITY_MASK,
  1620. stc.priority);
  1621. writel(r, ts->regs + THROT_PRIORITY_LOCK);
  1622. }
  1623. static void tegra_soctherm_throttle(struct device *dev)
  1624. {
  1625. struct tegra_soctherm *ts = dev_get_drvdata(dev);
  1626. u32 v;
  1627. int i;
  1628. /* configure LOW, MED and HIGH levels for CCROC NV_THERM */
  1629. if (ts->soc->use_ccroc) {
  1630. throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_LOW);
  1631. throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_MED);
  1632. throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_HIGH);
  1633. }
  1634. /* Thermal HW throttle programming */
  1635. for (i = 0; i < THROTTLE_SIZE; i++)
  1636. soctherm_throttle_program(ts, i);
  1637. v = REG_SET_MASK(0, THROT_GLOBAL_ENB_MASK, 1);
  1638. if (ts->soc->use_ccroc) {
  1639. ccroc_writel(ts, v, CCROC_GLOBAL_CFG);
  1640. v = ccroc_readl(ts, CCROC_SUPER_CCLKG_DIVIDER);
  1641. v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
  1642. ccroc_writel(ts, v, CCROC_SUPER_CCLKG_DIVIDER);
  1643. } else {
  1644. writel(v, ts->regs + THROT_GLOBAL_CFG);
  1645. v = readl(ts->clk_regs + CAR_SUPER_CCLKG_DIVIDER);
  1646. v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
  1647. writel(v, ts->clk_regs + CAR_SUPER_CCLKG_DIVIDER);
  1648. }
  1649. /* initialize stats collection */
  1650. v = STATS_CTL_CLR_DN | STATS_CTL_EN_DN |
  1651. STATS_CTL_CLR_UP | STATS_CTL_EN_UP;
  1652. writel(v, ts->regs + THERMCTL_STATS_CTL);
  1653. }
  1654. static int soctherm_interrupts_init(struct platform_device *pdev,
  1655. struct tegra_soctherm *tegra)
  1656. {
  1657. struct device_node *np = pdev->dev.of_node;
  1658. int ret;
  1659. ret = soctherm_oc_int_init(np, TEGRA_SOC_OC_IRQ_MAX);
  1660. if (ret < 0) {
  1661. dev_err(&pdev->dev, "soctherm_oc_int_init failed\n");
  1662. return ret;
  1663. }
  1664. tegra->thermal_irq = platform_get_irq(pdev, 0);
  1665. if (tegra->thermal_irq < 0) {
  1666. dev_dbg(&pdev->dev, "get 'thermal_irq' failed.\n");
  1667. return 0;
  1668. }
  1669. tegra->edp_irq = platform_get_irq(pdev, 1);
  1670. if (tegra->edp_irq < 0) {
  1671. dev_dbg(&pdev->dev, "get 'edp_irq' failed.\n");
  1672. return 0;
  1673. }
  1674. ret = devm_request_threaded_irq(&pdev->dev,
  1675. tegra->thermal_irq,
  1676. soctherm_thermal_isr,
  1677. soctherm_thermal_isr_thread,
  1678. IRQF_ONESHOT,
  1679. dev_name(&pdev->dev),
  1680. tegra);
  1681. if (ret < 0) {
  1682. dev_err(&pdev->dev, "request_irq 'thermal_irq' failed.\n");
  1683. return ret;
  1684. }
  1685. ret = devm_request_threaded_irq(&pdev->dev,
  1686. tegra->edp_irq,
  1687. soctherm_edp_isr,
  1688. soctherm_edp_isr_thread,
  1689. IRQF_ONESHOT,
  1690. "soctherm_edp",
  1691. tegra);
  1692. if (ret < 0) {
  1693. dev_err(&pdev->dev, "request_irq 'edp_irq' failed.\n");
  1694. return ret;
  1695. }
  1696. return 0;
  1697. }
  1698. static void soctherm_init(struct platform_device *pdev)
  1699. {
  1700. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1701. const struct tegra_tsensor_group **ttgs = tegra->soc->ttgs;
  1702. int i;
  1703. u32 pdiv, hotspot;
  1704. /* Initialize raw sensors */
  1705. for (i = 0; i < tegra->soc->num_tsensors; ++i)
  1706. enable_tsensor(tegra, i);
  1707. /* program pdiv and hotspot offsets per THERM */
  1708. pdiv = readl(tegra->regs + SENSOR_PDIV);
  1709. hotspot = readl(tegra->regs + SENSOR_HOTSPOT_OFF);
  1710. for (i = 0; i < tegra->soc->num_ttgs; ++i) {
  1711. pdiv = REG_SET_MASK(pdiv, ttgs[i]->pdiv_mask,
  1712. ttgs[i]->pdiv);
  1713. /* hotspot offset from PLLX, doesn't need to configure PLLX */
  1714. if (ttgs[i]->id == TEGRA124_SOCTHERM_SENSOR_PLLX)
  1715. continue;
  1716. hotspot = REG_SET_MASK(hotspot,
  1717. ttgs[i]->pllx_hotspot_mask,
  1718. ttgs[i]->pllx_hotspot_diff);
  1719. }
  1720. writel(pdiv, tegra->regs + SENSOR_PDIV);
  1721. writel(hotspot, tegra->regs + SENSOR_HOTSPOT_OFF);
  1722. /* Configure hw throttle */
  1723. tegra_soctherm_throttle(&pdev->dev);
  1724. }
  1725. static const struct of_device_id tegra_soctherm_of_match[] = {
  1726. #ifdef CONFIG_ARCH_TEGRA_124_SOC
  1727. {
  1728. .compatible = "nvidia,tegra124-soctherm",
  1729. .data = &tegra124_soctherm,
  1730. },
  1731. #endif
  1732. #ifdef CONFIG_ARCH_TEGRA_132_SOC
  1733. {
  1734. .compatible = "nvidia,tegra132-soctherm",
  1735. .data = &tegra132_soctherm,
  1736. },
  1737. #endif
  1738. #ifdef CONFIG_ARCH_TEGRA_210_SOC
  1739. {
  1740. .compatible = "nvidia,tegra210-soctherm",
  1741. .data = &tegra210_soctherm,
  1742. },
  1743. #endif
  1744. { },
  1745. };
  1746. MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
  1747. static int tegra_soctherm_probe(struct platform_device *pdev)
  1748. {
  1749. const struct of_device_id *match;
  1750. struct tegra_soctherm *tegra;
  1751. struct thermal_zone_device *z;
  1752. struct tsensor_shared_calib shared_calib;
  1753. struct tegra_soctherm_soc *soc;
  1754. unsigned int i;
  1755. int err;
  1756. match = of_match_node(tegra_soctherm_of_match, pdev->dev.of_node);
  1757. if (!match)
  1758. return -ENODEV;
  1759. soc = (struct tegra_soctherm_soc *)match->data;
  1760. if (soc->num_ttgs > TEGRA124_SOCTHERM_SENSOR_NUM)
  1761. return -EINVAL;
  1762. tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
  1763. if (!tegra)
  1764. return -ENOMEM;
  1765. mutex_init(&tegra->thermctl_lock);
  1766. dev_set_drvdata(&pdev->dev, tegra);
  1767. tegra->soc = soc;
  1768. tegra->regs = devm_platform_ioremap_resource_byname(pdev, "soctherm-reg");
  1769. if (IS_ERR(tegra->regs)) {
  1770. dev_err(&pdev->dev, "can't get soctherm registers");
  1771. return PTR_ERR(tegra->regs);
  1772. }
  1773. if (!tegra->soc->use_ccroc) {
  1774. tegra->clk_regs = devm_platform_ioremap_resource_byname(pdev, "car-reg");
  1775. if (IS_ERR(tegra->clk_regs)) {
  1776. dev_err(&pdev->dev, "can't get car clk registers");
  1777. return PTR_ERR(tegra->clk_regs);
  1778. }
  1779. } else {
  1780. tegra->ccroc_regs = devm_platform_ioremap_resource_byname(pdev, "ccroc-reg");
  1781. if (IS_ERR(tegra->ccroc_regs)) {
  1782. dev_err(&pdev->dev, "can't get ccroc registers");
  1783. return PTR_ERR(tegra->ccroc_regs);
  1784. }
  1785. }
  1786. tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm");
  1787. if (IS_ERR(tegra->reset)) {
  1788. dev_err(&pdev->dev, "can't get soctherm reset\n");
  1789. return PTR_ERR(tegra->reset);
  1790. }
  1791. tegra->clock_tsensor = devm_clk_get(&pdev->dev, "tsensor");
  1792. if (IS_ERR(tegra->clock_tsensor)) {
  1793. dev_err(&pdev->dev, "can't get tsensor clock\n");
  1794. return PTR_ERR(tegra->clock_tsensor);
  1795. }
  1796. tegra->clock_soctherm = devm_clk_get(&pdev->dev, "soctherm");
  1797. if (IS_ERR(tegra->clock_soctherm)) {
  1798. dev_err(&pdev->dev, "can't get soctherm clock\n");
  1799. return PTR_ERR(tegra->clock_soctherm);
  1800. }
  1801. tegra->calib = devm_kcalloc(&pdev->dev,
  1802. soc->num_tsensors, sizeof(u32),
  1803. GFP_KERNEL);
  1804. if (!tegra->calib)
  1805. return -ENOMEM;
  1806. /* calculate shared calibration data */
  1807. err = tegra_calc_shared_calib(soc->tfuse, &shared_calib);
  1808. if (err)
  1809. return err;
  1810. /* calculate tsensor calibration data */
  1811. for (i = 0; i < soc->num_tsensors; ++i) {
  1812. err = tegra_calc_tsensor_calib(&soc->tsensors[i],
  1813. &shared_calib,
  1814. &tegra->calib[i]);
  1815. if (err)
  1816. return err;
  1817. }
  1818. tegra->thermctl_tzs = devm_kcalloc(&pdev->dev,
  1819. soc->num_ttgs, sizeof(z),
  1820. GFP_KERNEL);
  1821. if (!tegra->thermctl_tzs)
  1822. return -ENOMEM;
  1823. err = soctherm_clk_enable(pdev, true);
  1824. if (err)
  1825. return err;
  1826. soctherm_thermtrips_parse(pdev);
  1827. soctherm_init_hw_throt_cdev(pdev);
  1828. soctherm_init(pdev);
  1829. for (i = 0; i < soc->num_ttgs; ++i) {
  1830. struct tegra_thermctl_zone *zone =
  1831. devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL);
  1832. if (!zone) {
  1833. err = -ENOMEM;
  1834. goto disable_clocks;
  1835. }
  1836. zone->reg = tegra->regs + soc->ttgs[i]->sensor_temp_offset;
  1837. zone->dev = &pdev->dev;
  1838. zone->sg = soc->ttgs[i];
  1839. zone->ts = tegra;
  1840. z = devm_thermal_of_zone_register(&pdev->dev,
  1841. soc->ttgs[i]->id, zone,
  1842. &tegra_of_thermal_ops);
  1843. if (IS_ERR(z)) {
  1844. err = PTR_ERR(z);
  1845. dev_err(&pdev->dev, "failed to register sensor: %d\n",
  1846. err);
  1847. goto disable_clocks;
  1848. }
  1849. zone->tz = z;
  1850. tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
  1851. /* Configure hw trip points */
  1852. err = tegra_soctherm_set_hwtrips(&pdev->dev, soc->ttgs[i], z);
  1853. if (err)
  1854. goto disable_clocks;
  1855. }
  1856. err = soctherm_interrupts_init(pdev, tegra);
  1857. soctherm_debug_init(pdev);
  1858. return 0;
  1859. disable_clocks:
  1860. soctherm_clk_enable(pdev, false);
  1861. return err;
  1862. }
  1863. static void tegra_soctherm_remove(struct platform_device *pdev)
  1864. {
  1865. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1866. debugfs_remove_recursive(tegra->debugfs_dir);
  1867. soctherm_clk_enable(pdev, false);
  1868. }
  1869. static int __maybe_unused soctherm_suspend(struct device *dev)
  1870. {
  1871. struct platform_device *pdev = to_platform_device(dev);
  1872. soctherm_clk_enable(pdev, false);
  1873. return 0;
  1874. }
  1875. static int __maybe_unused soctherm_resume(struct device *dev)
  1876. {
  1877. struct platform_device *pdev = to_platform_device(dev);
  1878. struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
  1879. struct tegra_soctherm_soc *soc = tegra->soc;
  1880. int err, i;
  1881. err = soctherm_clk_enable(pdev, true);
  1882. if (err) {
  1883. dev_err(&pdev->dev,
  1884. "Resume failed: enable clocks failed\n");
  1885. return err;
  1886. }
  1887. soctherm_init(pdev);
  1888. for (i = 0; i < soc->num_ttgs; ++i) {
  1889. struct thermal_zone_device *tz;
  1890. tz = tegra->thermctl_tzs[soc->ttgs[i]->id];
  1891. err = tegra_soctherm_set_hwtrips(dev, soc->ttgs[i], tz);
  1892. if (err) {
  1893. dev_err(&pdev->dev,
  1894. "Resume failed: set hwtrips failed\n");
  1895. return err;
  1896. }
  1897. }
  1898. return 0;
  1899. }
  1900. static SIMPLE_DEV_PM_OPS(tegra_soctherm_pm, soctherm_suspend, soctherm_resume);
  1901. static struct platform_driver tegra_soctherm_driver = {
  1902. .probe = tegra_soctherm_probe,
  1903. .remove_new = tegra_soctherm_remove,
  1904. .driver = {
  1905. .name = "tegra_soctherm",
  1906. .pm = &tegra_soctherm_pm,
  1907. .of_match_table = tegra_soctherm_of_match,
  1908. },
  1909. };
  1910. module_platform_driver(tegra_soctherm_driver);
  1911. MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
  1912. MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver");
  1913. MODULE_LICENSE("GPL v2");