armoon

local esynos changes

May 15th, 2025
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 35.48 KB | Writing | 0 0
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * exynos_tmu.c - Samsung Exynos TMU (Thermal Management Unit)
  4. *
  5. * Copyright (C) 2014 Samsung Electronics
  6. * Bartlomiej Zolnierkiewicz <[email protected]>
  7. * Lukasz Majewski <[email protected]>
  8. *
  9. * Copyright (C) 2011 Samsung Electronics
  10. * Donggeun Kim <[email protected]>
  11. * Amit Daniel Kachhap <[email protected]>
  12. */
  13.  
  14. #include <linux/clk.h>
  15. #include <linux/io.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/module.h>
  18. #include <linux/of.h>
  19. #include <linux/of_address.h>
  20. #include <linux/of_irq.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/regulator/consumer.h>
  23. #include <linux/thermal.h>
  24.  
  25. #include <dt-bindings/thermal/thermal_exynos.h>
  26.  
  27. /* Exynos generic registers */
  28. #define EXYNOS_TMU_REG_TRIMINFO 0x0
  29. #define EXYNOS_TMU_REG_CONTROL 0x20
  30. #define EXYNOS_TMU_REG_STATUS 0x28
  31. #define EXYNOS_TMU_REG_CURRENT_TEMP 0x40
  32. #define EXYNOS_TMU_REG_INTEN 0x70
  33. #define EXYNOS_TMU_REG_INTSTAT 0x74
  34. #define EXYNOS_TMU_REG_INTCLEAR 0x78
  35.  
  36. #define EXYNOS_TMU_TEMP_MASK 0xff
  37. #define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24
  38. #define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f
  39. #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
  40. #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8
  41. #define EXYNOS_TMU_CORE_EN_SHIFT 0
  42.  
  43. /* Exynos3250 specific registers */
  44. #define EXYNOS_TMU_TRIMINFO_CON1 0x10
  45.  
  46. /* Exynos4210 specific registers */
  47. #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44
  48. #define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50
  49.  
  50. /* Exynos5250, Exynos4412, Exynos3250 specific registers */
  51. #define EXYNOS_TMU_TRIMINFO_CON2 0x14
  52. #define EXYNOS_THD_TEMP_RISE 0x50
  53. #define EXYNOS_THD_TEMP_FALL 0x54
  54. #define EXYNOS_EMUL_CON 0x80
  55.  
  56. #define EXYNOS_TRIMINFO_RELOAD_ENABLE 1
  57. #define EXYNOS_TRIMINFO_25_SHIFT 0
  58. #define EXYNOS_TRIMINFO_85_SHIFT 8
  59. #define EXYNOS_TMU_TRIP_MODE_SHIFT 13
  60. #define EXYNOS_TMU_TRIP_MODE_MASK 0x7
  61. #define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12
  62.  
  63. #define EXYNOS_TMU_INTEN_RISE0_SHIFT 0
  64. #define EXYNOS_TMU_INTEN_FALL0_SHIFT 16
  65.  
  66. #define EXYNOS_EMUL_TIME 0x57F0
  67. #define EXYNOS_EMUL_TIME_MASK 0xffff
  68. #define EXYNOS_EMUL_TIME_SHIFT 16
  69. #define EXYNOS_EMUL_DATA_SHIFT 8
  70. #define EXYNOS_EMUL_DATA_MASK 0xFF
  71. #define EXYNOS_EMUL_ENABLE 0x1
  72.  
  73. /* Exynos5260 specific */
  74. #define EXYNOS5260_TMU_REG_INTEN 0xC0
  75. #define EXYNOS5260_TMU_REG_INTSTAT 0xC4
  76. #define EXYNOS5260_TMU_REG_INTCLEAR 0xC8
  77. #define EXYNOS5260_EMUL_CON 0x100
  78.  
  79. /* Exynos4412 specific */
  80. #define EXYNOS4412_MUX_ADDR_VALUE 6
  81. #define EXYNOS4412_MUX_ADDR_SHIFT 20
  82.  
  83. /* Exynos5433 specific registers */
  84. #define EXYNOS5433_THD_TEMP_RISE3_0 0x050
  85. #define EXYNOS5433_THD_TEMP_RISE7_4 0x054
  86. #define EXYNOS5433_THD_TEMP_FALL3_0 0x060
  87. #define EXYNOS5433_THD_TEMP_FALL7_4 0x064
  88. #define EXYNOS5433_TMU_REG_INTEN 0x0c0
  89. #define EXYNOS5433_TMU_REG_INTPEND 0x0c8
  90. #define EXYNOS5433_TMU_EMUL_CON 0x110
  91. #define EXYNOS5433_TMU_PD_DET_EN 0x130
  92.  
  93. #define EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT 16
  94. #define EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT 23
  95. #define EXYNOS5433_TRIMINFO_SENSOR_ID_MASK \
  96. (0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT)
  97. #define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK BIT(23)
  98.  
  99. #define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING 0
  100. #define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING 1
  101.  
  102. #define EXYNOS5433_PD_DET_EN 1
  103.  
  104. #define EXYNOS5433_G3D_BASE 0x10070000
  105.  
  106. /* Exynos7 specific registers */
  107. #define EXYNOS7_THD_TEMP_RISE7_6 0x50
  108. #define EXYNOS7_THD_TEMP_FALL7_6 0x60
  109. #define EXYNOS7_TMU_REG_INTEN 0x110
  110. #define EXYNOS7_TMU_REG_INTPEND 0x118
  111. #define EXYNOS7_TMU_REG_EMUL_CON 0x160
  112.  
  113. #define EXYNOS7_TMU_TEMP_MASK 0x1ff
  114. #define EXYNOS7_PD_DET_EN_SHIFT 23
  115. #define EXYNOS7_TMU_INTEN_RISE0_SHIFT 0
  116. #define EXYNOS7_EMUL_DATA_SHIFT 7
  117. #define EXYNOS7_EMUL_DATA_MASK 0x1ff
  118.  
  119. #define EXYNOS_FIRST_POINT_TRIM 25
  120. #define EXYNOS_SECOND_POINT_TRIM 85
  121.  
  122. #define EXYNOS_NOISE_CANCEL_MODE 4
  123.  
  124. #define MCELSIUS 1000
  125.  
  126. enum soc_type {
  127. SOC_ARCH_EXYNOS3250 = 1,
  128. SOC_ARCH_EXYNOS4210,
  129. SOC_ARCH_EXYNOS4412,
  130. SOC_ARCH_EXYNOS5250,
  131. SOC_ARCH_EXYNOS5260,
  132. SOC_ARCH_EXYNOS5420,
  133. SOC_ARCH_EXYNOS5420_TRIMINFO,
  134. SOC_ARCH_EXYNOS5433,
  135. SOC_ARCH_EXYNOS7,
  136. };
  137.  
  138. /**
  139. * struct exynos_tmu_data : A structure to hold the private data of the TMU
  140. * driver
  141. * @base: base address of the single instance of the TMU controller.
  142. * @base_second: base address of the common registers of the TMU controller.
  143. * @irq: irq number of the TMU controller.
  144. * @soc_config: configuration data for the SOC type.
  145. * @lock: lock to implement synchronization.
  146. * @clk: pointer to the clock structure.
  147. * @clk_sec: pointer to the clock structure for accessing the base_second.
  148. * @sclk: pointer to the clock structure for accessing the tmu special clk.
  149. * @cal_type: calibration type for temperature
  150. * @temp_error1: fused value of the first point trim.
  151. * @temp_error2: fused value of the second point trim.
  152. * @enabled: current status of TMU device
  153. */
  154.  
  155. struct exynos_tmu_data {
  156. void __iomem *base;
  157. void __iomem *base_second;
  158. int irq;
  159. const struct exynos_tmu_soc_config *soc_config;
  160. struct mutex lock;
  161. struct clk *clk, *clk_sec, *sclk;
  162. u32 cal_type;
  163. u16 temp_error1, temp_error2;
  164. struct thermal_zone_device *tzd;
  165. bool enabled;
  166. };
  167.  
  168. /**
  169. * struct exynos_tmu_soc_config : Structure to hold SOC-specific TMU
  170. * configuration data.
  171. * @soc: id of the SOC type.
  172. * @gain: gain of amplifier in the positive-TC generator block
  173. * 0 < gain <= 15
  174. * @reference_voltage: reference voltage of amplifier
  175. * in the positive-TC generator block
  176. * 0 < reference_voltage <= 31
  177. * @efuse_value: SoC defined fuse value
  178. * @min_efuse_value: minimum valid trimming data
  179. * @max_efuse_value: maximum valid trimming data
  180. * @tmu_set_low_temp: SoC specific method to set trip (falling threshold)
  181. * @tmu_set_high_temp: SoC specific method to set trip (rising threshold)
  182. * @tmu_set_crit_temp: SoC specific method to set critical temperature
  183. * @tmu_disable_low: SoC specific method to disable an interrupt (falling threshold)
  184. * @tmu_disable_high: SoC specific method to disable an interrupt (rising threshold)
  185. * @tmu_initialize: SoC specific TMU initialization method
  186. * @tmu_control: SoC specific TMU control method
  187. * @tmu_read: SoC specific TMU temperature read method
  188. * @tmu_set_emulation: SoC specific TMU emulation setting method
  189. * @tmu_clear_irqs: SoC specific TMU interrupts clearing method
  190. * @tmu_ops: pointer to thermal_zone_device structure
  191. */
  192.  
  193. struct exynos_tmu_soc_config {
  194. enum soc_type soc;
  195. u8 gain;
  196. u8 reference_voltage;
  197. u32 efuse_value;
  198. u32 min_efuse_value;
  199. u32 max_efuse_value;
  200. void (*tmu_set_low_temp)(struct exynos_tmu_data *data, u8 temp);
  201. void (*tmu_set_high_temp)(struct exynos_tmu_data *data, u8 temp);
  202. void (*tmu_set_crit_temp)(struct exynos_tmu_data *data, u8 temp);
  203. void (*tmu_disable_low)(struct exynos_tmu_data *data);
  204. void (*tmu_disable_high)(struct exynos_tmu_data *data);
  205. void (*tmu_initialize)(struct platform_device *pdev);
  206. void (*tmu_control)(struct platform_device *pdev, bool on);
  207. int (*tmu_read)(struct exynos_tmu_data *data);
  208. void (*tmu_set_emulation)(struct exynos_tmu_data *data, int temp);
  209. void (*tmu_clear_irqs)(struct exynos_tmu_data *data);
  210. const struct thermal_zone_device_ops *tmu_ops;
  211. };
  212.  
  213. /*
  214. * TMU treats temperature as a mapped temperature code.
  215. * The temperature is converted differently depending on the calibration type.
  216. */
  217. static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
  218. {
  219. if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
  220. return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM;
  221.  
  222. return (temp - EXYNOS_FIRST_POINT_TRIM) *
  223. (data->temp_error2 - data->temp_error1) /
  224. (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) +
  225. data->temp_error1;
  226. }
  227.  
  228. /*
  229. * Calculate a temperature value from a temperature code.
  230. * The unit of the temperature is degree Celsius.
  231. */
  232. static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code)
  233. {
  234. if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
  235. return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM;
  236.  
  237. return (temp_code - data->temp_error1) *
  238. (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) /
  239. (data->temp_error2 - data->temp_error1) +
  240. EXYNOS_FIRST_POINT_TRIM;
  241. }
  242.  
  243. static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
  244. {
  245. u16 tmu_temp_mask =
  246. (data->soc_config->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
  247. : EXYNOS_TMU_TEMP_MASK;
  248.  
  249. data->temp_error1 = trim_info & tmu_temp_mask;
  250. data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) &
  251. EXYNOS_TMU_TEMP_MASK);
  252.  
  253. if (!data->temp_error1 ||
  254. (data->soc_config->min_efuse_value > data->temp_error1) ||
  255. (data->temp_error1 > data->soc_config->max_efuse_value))
  256. data->temp_error1 = data->soc_config->efuse_value & EXYNOS_TMU_TEMP_MASK;
  257.  
  258. if (!data->temp_error2)
  259. data->temp_error2 =
  260. (data->soc_config->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) &
  261. EXYNOS_TMU_TEMP_MASK;
  262. }
  263.  
  264. static int exynos_tmu_initialize(struct platform_device *pdev)
  265. {
  266. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  267. unsigned int status;
  268. int ret = 0;
  269.  
  270. mutex_lock(&data->lock);
  271. clk_enable(data->clk);
  272. clk_enable(data->clk_sec);
  273.  
  274. status = readb(data->base + EXYNOS_TMU_REG_STATUS);
  275. if (!status) {
  276. ret = -EBUSY;
  277. } else {
  278. data->soc_config->tmu_initialize(pdev);
  279. data->soc_config->tmu_clear_irqs(data);
  280. }
  281.  
  282. clk_disable(data->clk_sec);
  283. clk_disable(data->clk);
  284. mutex_unlock(&data->lock);
  285.  
  286. return ret;
  287. }
  288.  
  289. static int exynos_thermal_zone_configure(struct platform_device *pdev)
  290. {
  291. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  292. struct thermal_zone_device *tzd = data->tzd;
  293. int ret, temp;
  294.  
  295. ret = thermal_zone_get_crit_temp(tzd, &temp);
  296. if (ret) {
  297. /* FIXME: Remove this special case */
  298. if (data->soc_config->soc == SOC_ARCH_EXYNOS5433)
  299. return 0;
  300.  
  301. dev_err(&pdev->dev,
  302. "No CRITICAL trip point defined in device tree!\n");
  303. return ret;
  304. }
  305.  
  306. mutex_lock(&data->lock);
  307. clk_enable(data->clk);
  308.  
  309. data->soc_config->tmu_set_crit_temp(data, temp / MCELSIUS);
  310.  
  311. clk_disable(data->clk);
  312. mutex_unlock(&data->lock);
  313.  
  314. return 0;
  315. }
  316.  
  317. static u32 get_con_reg(struct exynos_tmu_data *data, u32 con)
  318. {
  319. if (data->soc_config->soc == SOC_ARCH_EXYNOS4412 ||
  320. data->soc_config->soc == SOC_ARCH_EXYNOS3250)
  321. con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT);
  322.  
  323. con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT);
  324. con |= data->soc_config->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
  325.  
  326. con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
  327. con |= (data->soc_config->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
  328.  
  329. con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT);
  330. con |= (EXYNOS_NOISE_CANCEL_MODE << EXYNOS_TMU_TRIP_MODE_SHIFT);
  331.  
  332. return con;
  333. }
  334.  
  335. static void exynos_tmu_control(struct platform_device *pdev, bool on)
  336. {
  337. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  338.  
  339. mutex_lock(&data->lock);
  340. clk_enable(data->clk);
  341. data->soc_config->tmu_control(pdev, on);
  342. data->enabled = on;
  343. clk_disable(data->clk);
  344. mutex_unlock(&data->lock);
  345. }
  346.  
  347. static void exynos_tmu_update_bit(struct exynos_tmu_data *data, int reg_off,
  348. int bit_off, bool enable)
  349. {
  350. u32 interrupt_en;
  351.  
  352. interrupt_en = readl(data->base + reg_off);
  353. if (enable)
  354. interrupt_en |= BIT(bit_off);
  355. else
  356. interrupt_en &= ~BIT(bit_off);
  357. writel(interrupt_en, data->base + reg_off);
  358. }
  359.  
  360. static void exynos_tmu_update_temp(struct exynos_tmu_data *data, int reg_off,
  361. int bit_off, u8 temp)
  362. {
  363. u16 tmu_temp_mask;
  364. u32 th;
  365.  
  366. tmu_temp_mask =
  367. (data->soc_config->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
  368. : EXYNOS_TMU_TEMP_MASK;
  369.  
  370. th = readl(data->base + reg_off);
  371. th &= ~(tmu_temp_mask << bit_off);
  372. th |= temp_to_code(data, temp) << bit_off;
  373. writel(th, data->base + reg_off);
  374. }
  375.  
  376. static void exynos4210_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
  377. {
  378. /*
  379. * Failing thresholds are not supported on Exynos 4210.
  380. * We use polling instead.
  381. */
  382. }
  383.  
  384. static void exynos4210_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
  385. {
  386. temp = temp_to_code(data, temp);
  387. writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + 4);
  388. exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
  389. EXYNOS_TMU_INTEN_RISE0_SHIFT + 4, true);
  390. }
  391.  
  392. static void exynos4210_tmu_disable_low(struct exynos_tmu_data *data)
  393. {
  394. /* Again, this is handled by polling. */
  395. }
  396.  
  397. static void exynos4210_tmu_disable_high(struct exynos_tmu_data *data)
  398. {
  399. exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
  400. EXYNOS_TMU_INTEN_RISE0_SHIFT + 4, false);
  401. }
  402.  
  403. static void exynos4210_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
  404. {
  405. /*
  406. * Hardware critical temperature handling is not supported on Exynos 4210.
  407. * We still set the critical temperature threshold, but this is only to
  408. * make sure it is handled as soon as possible. It is just a normal interrupt.
  409. */
  410.  
  411. temp = temp_to_code(data, temp);
  412. writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + 12);
  413. exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
  414. EXYNOS_TMU_INTEN_RISE0_SHIFT + 12, true);
  415. }
  416.  
  417. static void exynos4210_tmu_initialize(struct platform_device *pdev)
  418. {
  419. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  420.  
  421. sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO));
  422.  
  423. writeb(0, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
  424. }
  425.  
  426. static void exynos4412_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
  427. {
  428. exynos_tmu_update_temp(data, EXYNOS_THD_TEMP_FALL, 0, temp);
  429. exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
  430. EXYNOS_TMU_INTEN_FALL0_SHIFT, true);
  431. }
  432.  
  433. static void exynos4412_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
  434. {
  435. exynos_tmu_update_temp(data, EXYNOS_THD_TEMP_RISE, 8, temp);
  436. exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
  437. EXYNOS_TMU_INTEN_RISE0_SHIFT + 4, true);
  438. }
  439.  
  440. static void exynos4412_tmu_disable_low(struct exynos_tmu_data *data)
  441. {
  442. exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
  443. EXYNOS_TMU_INTEN_FALL0_SHIFT, false);
  444. }
  445.  
  446. static void exynos4412_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
  447. {
  448. exynos_tmu_update_temp(data, EXYNOS_THD_TEMP_RISE, 24, temp);
  449. exynos_tmu_update_bit(data, EXYNOS_TMU_REG_CONTROL,
  450. EXYNOS_TMU_THERM_TRIP_EN_SHIFT, true);
  451. }
  452.  
  453. static void exynos4412_tmu_initialize(struct platform_device *pdev)
  454. {
  455. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  456. unsigned int trim_info, ctrl;
  457.  
  458. if (data->soc_config->soc == SOC_ARCH_EXYNOS3250 ||
  459. data->soc_config->soc == SOC_ARCH_EXYNOS4412 ||
  460. data->soc_config->soc == SOC_ARCH_EXYNOS5250) {
  461. if (data->soc_config->soc == SOC_ARCH_EXYNOS3250) {
  462. ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1);
  463. ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
  464. writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1);
  465. }
  466. ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
  467. ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
  468. writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
  469. }
  470.  
  471. /* On exynos5420 the triminfo register is in the shared space */
  472. if (data->soc_config->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
  473. trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
  474. else
  475. trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
  476.  
  477. sanitize_temp_error(data, trim_info);
  478. }
  479.  
  480. static void exynos5433_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
  481. {
  482. exynos_tmu_update_temp(data, EXYNOS5433_THD_TEMP_FALL3_0, 0, temp);
  483. exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
  484. EXYNOS_TMU_INTEN_FALL0_SHIFT, true);
  485. }
  486.  
  487. static void exynos5433_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
  488. {
  489. exynos_tmu_update_temp(data, EXYNOS5433_THD_TEMP_RISE3_0, 8, temp);
  490. exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
  491. EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, true);
  492. }
  493.  
  494. static void exynos5433_tmu_disable_low(struct exynos_tmu_data *data)
  495. {
  496. exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
  497. EXYNOS_TMU_INTEN_FALL0_SHIFT, false);
  498. }
  499.  
  500. static void exynos5433_tmu_disable_high(struct exynos_tmu_data *data)
  501. {
  502. exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
  503. EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, false);
  504. }
  505.  
  506. static void exynos5433_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
  507. {
  508. exynos_tmu_update_temp(data, EXYNOS5433_THD_TEMP_RISE7_4, 24, temp);
  509. exynos_tmu_update_bit(data, EXYNOS_TMU_REG_CONTROL,
  510. EXYNOS_TMU_THERM_TRIP_EN_SHIFT, true);
  511. exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
  512. EXYNOS7_TMU_INTEN_RISE0_SHIFT + 7, true);
  513. }
  514.  
  515. static void exynos5433_tmu_initialize(struct platform_device *pdev)
  516. {
  517. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  518. unsigned int trim_info;
  519. int sensor_id, cal_type;
  520.  
  521. trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
  522. sanitize_temp_error(data, trim_info);
  523.  
  524. /* Read the temperature sensor id */
  525. sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK)
  526. >> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT;
  527. dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id);
  528.  
  529. /* Read the calibration mode */
  530. writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO);
  531. cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK)
  532. >> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT;
  533.  
  534. switch (cal_type) {
  535. case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING:
  536. data->cal_type = TYPE_TWO_POINT_TRIMMING;
  537. break;
  538. case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING:
  539. default:
  540. data->cal_type = TYPE_ONE_POINT_TRIMMING;
  541. break;
  542. }
  543.  
  544. dev_info(&pdev->dev, "Calibration type is %d-point calibration\n",
  545. cal_type ? 2 : 1);
  546. }
  547.  
  548. static void exynos7_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
  549. {
  550. exynos_tmu_update_temp(data, EXYNOS7_THD_TEMP_FALL7_6 + 12, 0, temp);
  551. exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
  552. EXYNOS_TMU_INTEN_FALL0_SHIFT + 0, true);
  553. }
  554.  
  555. static void exynos7_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
  556. {
  557. exynos_tmu_update_temp(data, EXYNOS7_THD_TEMP_RISE7_6 + 12, 16, temp);
  558. exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
  559. EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, true);
  560. }
  561.  
  562. static void exynos7_tmu_disable_low(struct exynos_tmu_data *data)
  563. {
  564. exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
  565. EXYNOS_TMU_INTEN_FALL0_SHIFT + 0, false);
  566. }
  567.  
  568. static void exynos7_tmu_disable_high(struct exynos_tmu_data *data)
  569. {
  570. exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
  571. EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, false);
  572. }
  573.  
  574. static void exynos7_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
  575. {
  576. /*
  577. * Like Exynos 4210, Exynos 7 does not seem to support critical temperature
  578. * handling in hardware. Again, we still set a separate interrupt for it.
  579. */
  580. exynos_tmu_update_temp(data, EXYNOS7_THD_TEMP_RISE7_6 + 0, 16, temp);
  581. exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
  582. EXYNOS7_TMU_INTEN_RISE0_SHIFT + 7, true);
  583. }
  584.  
  585. static void exynos7_tmu_initialize(struct platform_device *pdev)
  586. {
  587. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  588. unsigned int trim_info;
  589.  
  590. trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
  591. sanitize_temp_error(data, trim_info);
  592. }
  593.  
  594. static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
  595. {
  596. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  597. unsigned int con;
  598.  
  599. con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
  600.  
  601. if (on)
  602. con |= BIT(EXYNOS_TMU_CORE_EN_SHIFT);
  603. else
  604. con &= ~BIT(EXYNOS_TMU_CORE_EN_SHIFT);
  605.  
  606. writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
  607. }
  608.  
  609. static void exynos5433_tmu_control(struct platform_device *pdev, bool on)
  610. {
  611. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  612. unsigned int con, pd_det_en;
  613.  
  614. con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
  615.  
  616. if (on)
  617. con |= BIT(EXYNOS_TMU_CORE_EN_SHIFT);
  618. else
  619. con &= ~BIT(EXYNOS_TMU_CORE_EN_SHIFT);
  620.  
  621. pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0;
  622.  
  623. writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN);
  624. writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
  625. }
  626.  
  627. static void exynos7_tmu_control(struct platform_device *pdev, bool on)
  628. {
  629. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  630. unsigned int con;
  631.  
  632. con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
  633.  
  634. if (on) {
  635. con |= BIT(EXYNOS_TMU_CORE_EN_SHIFT);
  636. con |= BIT(EXYNOS7_PD_DET_EN_SHIFT);
  637. } else {
  638. con &= ~BIT(EXYNOS_TMU_CORE_EN_SHIFT);
  639. con &= ~BIT(EXYNOS7_PD_DET_EN_SHIFT);
  640. }
  641.  
  642. writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
  643. }
  644.  
  645. static int exynos_get_temp(struct thermal_zone_device *tz, int *temp)
  646. {
  647. struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
  648. int value, ret = 0;
  649.  
  650. printk("Anand In %s , data = %pa: soc %d\n", __func__, data, data->soc_config->soc );
  651.  
  652. if (!data || !data->soc_config || !data->soc_config->tmu_read)
  653. return -EINVAL;
  654. else if (!data->enabled)
  655. /*
  656. * Called too early, probably
  657. * from thermal_zone_of_sensor_register().
  658. */
  659. return -EAGAIN;
  660.  
  661. printk("Anand In %s , data = %pa: soc %d\n", __func__, data, data->soc_config->soc );
  662. mutex_lock(&data->lock);
  663. clk_enable(data->clk);
  664.  
  665. printk("Anand SoC config %s....: %pa\n", __func__, data);
  666. value = data->soc_config->tmu_read(data);
  667. if (value < 0)
  668. ret = value;
  669. else
  670. *temp = code_to_temp(data, value) * MCELSIUS;
  671.  
  672. clk_disable(data->clk);
  673. mutex_unlock(&data->lock);
  674.  
  675. printk("Anand In %s , data = %pa: soc %d\n", __func__, data, data->soc_config->soc );
  676.  
  677. return ret;
  678. }
  679.  
  680. #ifdef CONFIG_THERMAL_EMULATION
  681. static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val,
  682. int temp)
  683. {
  684. if (temp) {
  685. temp /= MCELSIUS;
  686.  
  687. val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT);
  688. val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT);
  689. if (data->soc_config->soc == SOC_ARCH_EXYNOS7) {
  690. val &= ~(EXYNOS7_EMUL_DATA_MASK <<
  691. EXYNOS7_EMUL_DATA_SHIFT);
  692. val |= (temp_to_code(data, temp) <<
  693. EXYNOS7_EMUL_DATA_SHIFT) |
  694. EXYNOS_EMUL_ENABLE;
  695. } else {
  696. val &= ~(EXYNOS_EMUL_DATA_MASK <<
  697. EXYNOS_EMUL_DATA_SHIFT);
  698. val |= (temp_to_code(data, temp) <<
  699. EXYNOS_EMUL_DATA_SHIFT) |
  700. EXYNOS_EMUL_ENABLE;
  701. }
  702. } else {
  703. val &= ~EXYNOS_EMUL_ENABLE;
  704. }
  705.  
  706. return val;
  707. }
  708.  
  709. static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
  710. int temp)
  711. {
  712. unsigned int val;
  713. u32 emul_con;
  714.  
  715. if (data->soc_config->soc == SOC_ARCH_EXYNOS5260)
  716. emul_con = EXYNOS5260_EMUL_CON;
  717. else if (data->soc_config->soc == SOC_ARCH_EXYNOS5433)
  718. emul_con = EXYNOS5433_TMU_EMUL_CON;
  719. else if (data->soc_config->soc == SOC_ARCH_EXYNOS7)
  720. emul_con = EXYNOS7_TMU_REG_EMUL_CON;
  721. else
  722. emul_con = EXYNOS_EMUL_CON;
  723.  
  724. printk("Anand In %s , data = %pa: soc %d\n", __func__, data, data->soc_config->soc );
  725.  
  726. val = readl(data->base + emul_con);
  727. val = get_emul_con_reg(data, val, temp);
  728. writel(val, data->base + emul_con);
  729. }
  730.  
  731. static int exynos_tmu_set_emulation(struct thermal_zone_device *tz, int temp)
  732. {
  733. struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
  734. int ret = -EINVAL;
  735.  
  736. printk("Anand In %s , data = %pa: soc %d\n", __func__, data, data->soc_config->soc );
  737. if (!data) {
  738. printk("exynos_tmu_data is NULL!\n");
  739. return -ENODEV;
  740. }
  741.  
  742. if (data->soc_config->soc == SOC_ARCH_EXYNOS4210)
  743. goto out;
  744.  
  745. if (temp && temp < MCELSIUS)
  746. goto out;
  747.  
  748. printk("Anand SoC config %s....: %pa\n", __func__, data);
  749. mutex_lock(&data->lock);
  750. clk_enable(data->clk);
  751. data->soc_config->tmu_set_emulation(data, temp);
  752. clk_disable(data->clk);
  753. mutex_unlock(&data->lock);
  754. return 0;
  755. out:
  756. return ret;
  757. }
  758. #else
  759. #define exynos4412_tmu_set_emulation NULL
  760. static int exynos_tmu_set_emulation(struct thermal_zone_device *tz, int temp)
  761. { return -EINVAL; }
  762. #endif /* CONFIG_THERMAL_EMULATION */
  763.  
  764. static int exynos4210_tmu_read(struct exynos_tmu_data *data)
  765. {
  766. int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
  767.  
  768. printk("Anand SoC config %s....: %pa\n", __func__, data);
  769. /* "temp_code" should range between 75 and 175 */
  770. return (ret < 75 || ret > 175) ? -ENODATA : ret;
  771. }
  772.  
  773. static int exynos4412_tmu_read(struct exynos_tmu_data *data)
  774. {
  775. printk("Anand SoC config %s....: %pa\n", __func__, data);
  776. return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
  777. }
  778.  
  779. static int exynos7_tmu_read(struct exynos_tmu_data *data)
  780. {
  781. return readw(data->base + EXYNOS_TMU_REG_CURRENT_TEMP) &
  782. EXYNOS7_TMU_TEMP_MASK;
  783. }
  784.  
  785. static irqreturn_t exynos_tmu_threaded_irq(int irq, void *id)
  786. {
  787. struct exynos_tmu_data *data = id;
  788.  
  789. thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED);
  790.  
  791. mutex_lock(&data->lock);
  792. clk_enable(data->clk);
  793.  
  794. /* TODO: take action based on particular interrupt */
  795. data->soc_config->tmu_clear_irqs(data);
  796.  
  797. clk_disable(data->clk);
  798. mutex_unlock(&data->lock);
  799.  
  800. return IRQ_HANDLED;
  801. }
  802.  
  803. static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
  804. {
  805. unsigned int val_irq;
  806. u32 tmu_intstat, tmu_intclear;
  807.  
  808. if (data->soc_config->soc == SOC_ARCH_EXYNOS5260) {
  809. tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
  810. tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
  811. } else if (data->soc_config->soc == SOC_ARCH_EXYNOS7) {
  812. tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
  813. tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
  814. } else if (data->soc_config->soc == SOC_ARCH_EXYNOS5433) {
  815. tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
  816. tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
  817. } else {
  818. tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
  819. tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
  820. }
  821.  
  822. val_irq = readl(data->base + tmu_intstat);
  823. /*
  824. * Clear the interrupts. Please note that the documentation for
  825. * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
  826. * states that INTCLEAR register has a different placing of bits
  827. * responsible for FALL IRQs than INTSTAT register. Exynos5420
  828. * and Exynos5440 documentation is correct (Exynos4210 doesn't
  829. * support FALL IRQs at all).
  830. */
  831. writel(val_irq, data->base + tmu_intclear);
  832. }
  833.  
  834. static int exynos_set_trips(struct thermal_zone_device *tz, int low, int high)
  835. {
  836. struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
  837.  
  838. printk("Anand In %s , data = %pa: soc %d\n", __func__, data, data->soc_config->soc );
  839. if (!data) {
  840. printk("exynos_tmu_data is NULL!\n");
  841. return -ENODEV;
  842. }
  843.  
  844. mutex_lock(&data->lock);
  845. clk_enable(data->clk);
  846.  
  847. if (low > INT_MIN)
  848. data->soc_config->tmu_set_low_temp(data, low / MCELSIUS);
  849. else
  850. data->soc_config->tmu_disable_low(data);
  851. if (high < INT_MAX)
  852. data->soc_config->tmu_set_high_temp(data, high / MCELSIUS);
  853. else
  854. data->soc_config->tmu_disable_high(data);
  855.  
  856. clk_disable(data->clk);
  857. mutex_unlock(&data->lock);
  858.  
  859. return 0;
  860. }
  861. static const struct thermal_zone_device_ops exynos_sensor_ops = {
  862. .get_temp = exynos_get_temp,
  863. .set_emul_temp = exynos_tmu_set_emulation,
  864. .set_trips = exynos_set_trips,
  865. };
  866.  
  867. static const struct exynos_tmu_soc_config exynos3250_data __initconst = {
  868. .soc = SOC_ARCH_EXYNOS3250,
  869. .tmu_set_low_temp = exynos4412_tmu_set_low_temp,
  870. .tmu_set_high_temp = exynos4412_tmu_set_high_temp,
  871. .tmu_disable_low = exynos4412_tmu_disable_low,
  872. .tmu_disable_high = exynos4210_tmu_disable_high,
  873. .tmu_set_crit_temp = exynos4412_tmu_set_crit_temp,
  874. .tmu_initialize = exynos4412_tmu_initialize,
  875. .tmu_control = exynos4210_tmu_control,
  876. .tmu_read = exynos4412_tmu_read,
  877. .tmu_set_emulation = exynos4412_tmu_set_emulation,
  878. .tmu_clear_irqs = exynos4210_tmu_clear_irqs,
  879. .gain = 8,
  880. .reference_voltage = 16,
  881. .efuse_value = 55,
  882. .min_efuse_value = 40,
  883. .max_efuse_value = 100,
  884. .tmu_ops = &exynos_sensor_ops,
  885. };
  886.  
  887. static const struct exynos_tmu_soc_config exynos4210_data __initconst = {
  888. .soc = SOC_ARCH_EXYNOS4210,
  889. .tmu_set_low_temp = exynos4210_tmu_set_low_temp,
  890. .tmu_set_high_temp = exynos4210_tmu_set_high_temp,
  891. .tmu_disable_low = exynos4210_tmu_disable_low,
  892. .tmu_disable_high = exynos4210_tmu_disable_high,
  893. .tmu_set_crit_temp = exynos4210_tmu_set_crit_temp,
  894. .tmu_initialize = exynos4210_tmu_initialize,
  895. .tmu_control = exynos4210_tmu_control,
  896. .tmu_read = exynos4210_tmu_read,
  897. .tmu_clear_irqs = exynos4210_tmu_clear_irqs,
  898. .gain = 15,
  899. .reference_voltage = 7,
  900. .efuse_value = 55,
  901. .min_efuse_value = 40,
  902. .max_efuse_value = 100,
  903. .tmu_ops = &exynos_sensor_ops,
  904. };
  905.  
  906. static const struct exynos_tmu_soc_config exynos4412_data __initconst = {
  907. .soc = SOC_ARCH_EXYNOS4412,
  908. .tmu_set_low_temp = exynos4412_tmu_set_low_temp,
  909. .tmu_set_high_temp = exynos4412_tmu_set_high_temp,
  910. .tmu_disable_low = exynos4412_tmu_disable_low,
  911. .tmu_disable_high = exynos4210_tmu_disable_high,
  912. .tmu_set_crit_temp = exynos4412_tmu_set_crit_temp,
  913. .tmu_initialize = exynos4412_tmu_initialize,
  914. .tmu_control = exynos4210_tmu_control,
  915. .tmu_read = exynos4412_tmu_read,
  916. .tmu_set_emulation = exynos4412_tmu_set_emulation,
  917. .tmu_clear_irqs = exynos4210_tmu_clear_irqs,
  918. .gain = 8,
  919. .reference_voltage = 16,
  920. .efuse_value = 55,
  921. .min_efuse_value = 40,
  922. .max_efuse_value = 100,
  923. .tmu_ops = &exynos_sensor_ops,
  924. };
  925.  
  926. static const struct exynos_tmu_soc_config exynos5420_data __initconst = {
  927. .soc = SOC_ARCH_EXYNOS5420,
  928. .tmu_set_low_temp = exynos4412_tmu_set_low_temp,
  929. .tmu_set_high_temp = exynos4412_tmu_set_high_temp,
  930. .tmu_disable_low = exynos4412_tmu_disable_low,
  931. .tmu_disable_high = exynos4210_tmu_disable_high,
  932. .tmu_set_crit_temp = exynos4412_tmu_set_crit_temp,
  933. .tmu_initialize = exynos4412_tmu_initialize,
  934. .tmu_control = exynos4210_tmu_control,
  935. .tmu_read = exynos4412_tmu_read,
  936. .tmu_set_emulation = exynos4412_tmu_set_emulation,
  937. .tmu_clear_irqs = exynos4210_tmu_clear_irqs,
  938. .gain = 8,
  939. .reference_voltage = 16,
  940. .efuse_value = 55,
  941. .min_efuse_value = 16,
  942. .max_efuse_value = 76,
  943. .tmu_ops = &exynos_sensor_ops,
  944. };
  945.  
  946. static const struct exynos_tmu_soc_config exynos5433_data __initconst = {
  947. .soc = SOC_ARCH_EXYNOS5433,
  948. .tmu_set_low_temp = exynos5433_tmu_set_low_temp,
  949. .tmu_set_high_temp = exynos5433_tmu_set_high_temp,
  950. .tmu_disable_low = exynos5433_tmu_disable_low,
  951. .tmu_disable_high = exynos5433_tmu_disable_high,
  952. .tmu_set_crit_temp = exynos5433_tmu_set_crit_temp,
  953. .tmu_initialize = exynos5433_tmu_initialize,
  954. .tmu_control = exynos5433_tmu_control,
  955. .tmu_read = exynos4412_tmu_read,
  956. .tmu_set_emulation = exynos4412_tmu_set_emulation,
  957. .tmu_clear_irqs = exynos4210_tmu_clear_irqs,
  958. .gain = 8,
  959. .reference_voltage = 16,
  960. .efuse_value = 75,
  961. .min_efuse_value = 40,
  962. .max_efuse_value = 150,
  963. .tmu_ops = &exynos_sensor_ops,
  964. };
  965.  
  966. static const struct exynos_tmu_soc_config exynos7_data __initconst = {
  967. .soc = SOC_ARCH_EXYNOS7,
  968. .tmu_set_low_temp = exynos7_tmu_set_low_temp,
  969. .tmu_set_high_temp = exynos7_tmu_set_high_temp,
  970. .tmu_disable_low = exynos7_tmu_disable_low,
  971. .tmu_disable_high = exynos7_tmu_disable_high,
  972. .tmu_set_crit_temp = exynos7_tmu_set_crit_temp,
  973. .tmu_initialize = exynos7_tmu_initialize,
  974. .tmu_control = exynos7_tmu_control,
  975. .tmu_read = exynos7_tmu_read,
  976. .tmu_set_emulation = exynos4412_tmu_set_emulation,
  977. .tmu_clear_irqs = exynos4210_tmu_clear_irqs,
  978. .gain = 9,
  979. .reference_voltage = 17,
  980. .efuse_value = 75,
  981. .min_efuse_value = 15,
  982. .max_efuse_value = 100,
  983. .tmu_ops = &exynos_sensor_ops,
  984. };
  985.  
  986. static const struct of_device_id exynos_tmu_match[] = {
  987. {
  988. .compatible = "samsung,exynos3250-tmu",
  989. .data = &exynos3250_data,
  990. }, {
  991. .compatible = "samsung,exynos4210-tmu",
  992. .data = &exynos4210_data,
  993. }, {
  994. .compatible = "samsung,exynos4412-tmu",
  995. .data = &exynos4412_data,
  996. }, {
  997. .compatible = "samsung,exynos5250-tmu",
  998. .data = &exynos4412_data,
  999. }, {
  1000. .compatible = "samsung,exynos5260-tmu",
  1001. .data = &exynos4412_data,
  1002. }, {
  1003. .compatible = "samsung,exynos5420-tmu",
  1004. .data = &exynos5420_data,
  1005. }, {
  1006. .compatible = "samsung,exynos5420-tmu-ext-triminfo",
  1007. .data = &exynos5420_data,
  1008. }, {
  1009. .compatible = "samsung,exynos5433-tmu",
  1010. .data = &exynos5433_data,
  1011. }, {
  1012. .compatible = "samsung,exynos7-tmu",
  1013. .data = &exynos7_data,
  1014. },
  1015. { },
  1016. };
  1017. MODULE_DEVICE_TABLE(of, exynos_tmu_match);
  1018.  
  1019. static int exynos_map_dt_data(struct platform_device *pdev)
  1020. {
  1021. struct exynos_tmu_data *data = platform_get_drvdata(pdev);
  1022. const struct exynos_tmu_soc_config *soc_config;
  1023. struct resource res;
  1024.  
  1025. if (!data || !pdev->dev.of_node)
  1026. return -ENODEV;
  1027.  
  1028. data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
  1029. if (data->irq <= 0) {
  1030. dev_err(&pdev->dev, "failed to get IRQ\n");
  1031. return -ENODEV;
  1032. }
  1033.  
  1034. if (of_address_to_resource(pdev->dev.of_node, 0, &res)) {
  1035. dev_err(&pdev->dev, "failed to get Resource 0\n");
  1036. return -ENODEV;
  1037. }
  1038.  
  1039. data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
  1040. if (!data->base) {
  1041. dev_err(&pdev->dev, "Failed to ioremap memory\n");
  1042. return -EADDRNOTAVAIL;
  1043. }
  1044.  
  1045. soc_config = of_device_get_match_data(&pdev->dev);
  1046. if (!soc_config)
  1047. return -EINVAL;
  1048. else {
  1049. data->soc_config = soc_config;
  1050. }
  1051.  
  1052. dev_info(&pdev->dev, "Detected SoC: %d\n", data->soc_config->soc);
  1053.  
  1054. data->cal_type = TYPE_ONE_POINT_TRIMMING;
  1055.  
  1056. /*
  1057. * Check if the TMU shares some registers and then try to map the
  1058. * memory of common registers.
  1059. */
  1060. if (data->soc_config->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
  1061. return 0;
  1062.  
  1063. if (of_address_to_resource(pdev->dev.of_node, 1, &res)) {
  1064. dev_err(&pdev->dev, "failed to get Resource 1\n");
  1065. return -ENODEV;
  1066. }
  1067.  
  1068. data->base_second = devm_ioremap(&pdev->dev, res.start,
  1069. resource_size(&res));
  1070. if (!data->base_second) {
  1071. dev_err(&pdev->dev, "Failed to ioremap memory\n");
  1072. return -ENOMEM;
  1073. }
  1074.  
  1075. return 0;
  1076. }
  1077.  
  1078.  
  1079.  
  1080.  
  1081. static int exynos_tmu_probe(struct platform_device *pdev)
  1082. {
  1083. struct device *dev = &pdev->dev;
  1084. struct exynos_tmu_data *data;
  1085. int ret;
  1086.  
  1087. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  1088. if (!data)
  1089. return -ENOMEM;
  1090.  
  1091. dev_info(&pdev->dev, "kzalloc Initialized data at %pa\n", data);
  1092. platform_set_drvdata(pdev, data);
  1093. mutex_init(&data->lock);
  1094.  
  1095. /*
  1096. * Try enabling the regulator if found
  1097. * TODO: Add regulator as an SOC feature, so that regulator enable
  1098. * is a compulsory call.
  1099. */
  1100. ret = devm_regulator_get_enable_optional(dev, "vtmu");
  1101. switch (ret) {
  1102. case 0:
  1103. case -ENODEV:
  1104. break;
  1105. case -EPROBE_DEFER:
  1106. return -EPROBE_DEFER;
  1107. default:
  1108. dev_err(dev, "Failed to get enabled regulator: %d\n", ret);
  1109. return ret;
  1110. }
  1111.  
  1112. ret = exynos_map_dt_data(pdev);
  1113. if (ret)
  1114. return ret;
  1115.  
  1116. dev_info(&pdev->dev, "Initialized data at %pa\n", data);
  1117. dev_set_drvdata(&pdev->dev, data);
  1118. dev_info(&pdev->dev, "Set devdata, data at %pa\n", data);
  1119.  
  1120. data->clk = devm_clk_get_enabled(dev, "tmu_apbif");
  1121. if (IS_ERR(data->clk))
  1122. return dev_err_probe(dev, PTR_ERR(data->clk),
  1123. "Failed to get clock\n");
  1124.  
  1125. if (data->soc_config->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
  1126. data->clk_sec = devm_clk_get_enabled(dev, "tmu_triminfo_apbif");
  1127. if (IS_ERR(data->clk_sec))
  1128. return dev_err_probe(dev, PTR_ERR(data->clk_sec),
  1129. "Failed to get clk_sec clock\n");
  1130. } else if (data->soc_config->soc == SOC_ARCH_EXYNOS5433 ||
  1131. data->soc_config->soc == SOC_ARCH_EXYNOS7) {
  1132. data->sclk = devm_clk_get_enabled(dev, "tmu_sclk");
  1133. if (IS_ERR(data->sclk))
  1134. return dev_err_probe(dev, PTR_ERR(data->sclk),
  1135. "Failed to get sclk\n");
  1136. }
  1137.  
  1138. ret = exynos_tmu_initialize(pdev);
  1139. if (ret) {
  1140. dev_err(dev, "Failed to initialize TMU\n");
  1141. return ret;
  1142. }
  1143.  
  1144. data->tzd = devm_thermal_of_zone_register(dev, 0, data,
  1145. data->soc_config->tmu_ops);
  1146. if (IS_ERR(data->tzd)) {
  1147. return dev_err_probe(dev, PTR_ERR(data->tzd),
  1148. "Failed to register sensor\n");
  1149. }
  1150.  
  1151. ret = exynos_thermal_zone_configure(pdev);
  1152. if (ret) {
  1153. dev_err(dev, "Failed to configure the thermal zone\n");
  1154. return ret;
  1155. } else {
  1156. dev_info(&pdev->dev, "Registered thermal zone\n");
  1157. }
  1158.  
  1159. ret = devm_request_threaded_irq(dev, data->irq, NULL,
  1160. exynos_tmu_threaded_irq,
  1161. IRQF_TRIGGER_RISING
  1162. | IRQF_SHARED | IRQF_ONESHOT,
  1163. dev_name(dev), data);
  1164. if (ret) {
  1165. dev_err(dev, "Failed to request irq: %d\n", data->irq);
  1166. return ret;
  1167. }
  1168.  
  1169. exynos_tmu_control(pdev, true);
  1170.  
  1171. return ret;
  1172. }
  1173.  
  1174. static void exynos_tmu_remove(struct platform_device *pdev)
  1175. {
  1176. exynos_tmu_control(pdev, false);
  1177. }
  1178.  
  1179. #ifdef CONFIG_PM_SLEEP
  1180. static int exynos_tmu_suspend(struct device *dev)
  1181. {
  1182. exynos_tmu_control(to_platform_device(dev), false);
  1183.  
  1184. return 0;
  1185. }
  1186.  
  1187. static int exynos_tmu_resume(struct device *dev)
  1188. {
  1189. struct platform_device *pdev = to_platform_device(dev);
  1190.  
  1191. exynos_tmu_initialize(pdev);
  1192. exynos_tmu_control(pdev, true);
  1193.  
  1194. return 0;
  1195. }
  1196.  
  1197. static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
  1198. exynos_tmu_suspend, exynos_tmu_resume);
  1199. #define EXYNOS_TMU_PM (&exynos_tmu_pm)
  1200. #else
  1201. #define EXYNOS_TMU_PM NULL
  1202. #endif
  1203.  
  1204. static struct platform_driver exynos_tmu_driver = {
  1205. .driver = {
  1206. .name = "exynos-tmu",
  1207. .pm = EXYNOS_TMU_PM,
  1208. .of_match_table = exynos_tmu_match,
  1209. },
  1210. .probe = exynos_tmu_probe,
  1211. .remove = exynos_tmu_remove,
  1212. };
  1213.  
  1214. module_platform_driver(exynos_tmu_driver);
  1215.  
  1216. MODULE_DESCRIPTION("Exynos TMU Driver");
  1217. MODULE_AUTHOR("Donggeun Kim <[email protected]>");
  1218. MODULE_LICENSE("GPL");
  1219. MODULE_ALIAS("platform:exynos-tmu");
  1220.  
Tags: source code
Advertisement
Add Comment
Please, Sign In to add comment