qti_amoled_ecm.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "AMOLED_ECM: %s: " fmt, __func__
  6. #include <linux/device.h>
  7. #include <linux/errno.h>
  8. #include <linux/hwmon.h>
  9. #include <linux/hwmon-sysfs.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/nvmem-consumer.h>
  14. #include <linux/of.h>
  15. #include <linux/of_irq.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/regmap.h>
  18. #include <linux/workqueue.h>
  19. #include <linux/soc/qcom/panel_event_notifier.h>
  20. /* AMOLED AB register definitions */
  21. #define AB_REVISION2 0x01
  22. /* AMOLED ECM register definitions */
  23. #define AB_ECM_EN_CTL 0xA0
  24. #define ECM_EN BIT(7)
  25. #define AB_ECM_COUNTER_CTL 0xA1
  26. #define ECM_COUNTER_START BIT(7)
  27. /* AMOLED ECM SDAM Offsets */
  28. #define ECM_SDAM_START_BASE 0x40
  29. #define ECM_SDAMX_SAMPLE_START_ADDR 0x46
  30. #define ECM_FAULT_LOG 0x48
  31. #define ECM_ROUTINE_LOG 0x49
  32. #define ECM_ACTIVE_SDAM 0x4D
  33. #define ECM_SDAM0_ACTIVE BIT(0)
  34. #define ECM_SDAM1_ACTIVE BIT(1)
  35. #define ECM_SAMPLE_CNT_LSB 0x4E
  36. #define ECM_SAMPLE_CNT_MSB 0x4F
  37. #define ECM_STATUS_SET 0x50
  38. #define ECM_STATUS_CLR 0x51
  39. #define ECM_ONGOING BIT(0)
  40. #define ECM_DONE BIT(1)
  41. #define ECM_ABORT BIT(2)
  42. #define ECM_SDAM0_FULL BIT(3)
  43. #define ECM_SDAM1_FULL BIT(4)
  44. #define ECM_SDAM0_INDEX 0x52
  45. #define ECM_SDAM1_INDEX 0x53
  46. #define ECM_SDAM2_INDEX 0x61
  47. #define ECM_MODE 0x54
  48. #define ECM_CONTINUOUS 0
  49. #define ECM_N_ESWIRE 1
  50. #define ECM_M_ASWIRE 2
  51. #define ECM_ESWIRE_ASWIRE 3
  52. #define ECM_USE_TIMER 4
  53. #define ECM_N_ESWIRE_COUNT_LSB 0x55
  54. #define ECM_N_ESWIRE_COUNT_MSB 0x56
  55. #define ECM_M_ASWIRE_COUNT_LSB 0x57
  56. #define ECM_M_ASWIRE_COUNT_MSB 0x58
  57. #define ECM_ESWIRE_ASWIRE_SKIP_COUNT_LSB 0x59
  58. #define ECM_ESWIRE_ASWIRE_SKIP_COUNT_MSB 0x5A
  59. #define ECM_TIMER_LSB 0x5B
  60. #define ECM_TIMER_MSB 0x5C
  61. #define ECM_TIMER_SKIP_LSB 0x5D
  62. #define ECM_TIMER_SKIP_MSB 0x5E
  63. #define ECM_SEND_IRQ 0x5F
  64. #define SEND_SDAM0_IRQ BIT(0)
  65. #define SEND_SDAM1_IRQ BIT(1)
  66. #define SEND_SDAM2_IRQ BIT(2)
  67. #define ECM_WRITE_TO_SDAM 0x60
  68. #define WRITE_SDAM0_DATA BIT(0)
  69. #define WRITE_SDAM1_DATA BIT(1)
  70. #define WRITE_SDAM2_DATA BIT(2)
  71. #define OVERWRITE_SDAM0_DATA BIT(4)
  72. #define OVERWRITE_SDAM1_DATA BIT(5)
  73. #define OVERWRITE_SDAM2_DATA BIT(6)
  74. #define ECM_AVERAGE_LSB 0x61
  75. #define ECM_AVERAGE_MSB 0x62
  76. #define ECM_MIN_LSB 0x63
  77. #define ECM_MIN_MSB 0x64
  78. #define ECM_MAX_LSB 0x65
  79. #define ECM_MAX_MSB 0x66
  80. #define ECM_SDAM0_SAMPLE_START_ADDR 0x6C
  81. #define ECM_SDAM_SAMPLE_END_ADDR 0xBF
  82. /* ECM specific definitions */
  83. #define ECM_SAMPLE_GAIN_V1 15
  84. #define ECM_SAMPLE_GAIN_V2 16
  85. #define ECM_MIN_M_SAMPLES 10
  86. #define AMOLED_AB_REVISION_1P0 0
  87. #define AMOLED_AB_REVISION_2P0 1
  88. enum amoled_ecm_mode {
  89. ECM_MODE_CONTINUOUS = 0,
  90. ECM_MODE_MULTI_FRAMES,
  91. ECM_MODE_IDLE,
  92. };
  93. struct amoled_ecm_sdam_config {
  94. u8 reg;
  95. u8 reset_val;
  96. };
  97. /**
  98. * struct amoled_ecm_sdam - AMOLED ECM sdam data structure
  99. * @nvmem: Pointer to nvmem device
  100. * @start_addr: Start address of ECM samples in SDAM
  101. * @irq_name: Interrupt name for SDAM
  102. * @irq: Interrupt associated with the SDAM
  103. */
  104. struct amoled_ecm_sdam {
  105. struct nvmem_device *nvmem;
  106. u32 start_addr;
  107. const char *irq_name;
  108. int irq;
  109. };
  110. /**
  111. * struct amoled_ecm_data - Structure for AMOLED ECM data
  112. * @m_cumulative: Cumulative of M sample values
  113. * @num_m_samples: Number of M samples available
  114. * @time_period_ms: Time period(in milli seconds) for ECM request
  115. * @frames: Number of frames for ECM request
  116. * @avg_current: AMOLED ECM average calculated
  117. * @mode: AMOLED ECM mode of operation
  118. */
  119. struct amoled_ecm_data {
  120. unsigned long long m_cumulative;
  121. u32 num_m_samples;
  122. u32 time_period_ms;
  123. u16 frames;
  124. u16 avg_current;
  125. enum amoled_ecm_mode mode;
  126. };
  127. /**
  128. * struct amoled ecm - Structure for AMOLED ECM device
  129. * @regmap: Pointer for regmap structure
  130. * @dev: Pointer for AMOLED ECM device
  131. * @data: AMOLED ECM data structure
  132. * @sdam: Pointer for array of ECM sdams
  133. * @sdam_lock: Locking for mutual exclusion
  134. * @average_work: Delayed work to calculate ECM average
  135. * @active_panel: Active DRM panel which sends panel notifications
  136. * @notifier_cookie: The cookie from panel notifier
  137. * @num_sdams: Number of SDAMs used for AMOLED ECM
  138. * @base: Base address of the AMOLED ECM module
  139. * @ab_revision: Revision of the AMOLED AB module
  140. * @enable: Flag to enable/disable AMOLED ECM
  141. * @abort: Flag to indicated AMOLED ECM has aborted
  142. * @reenable: Flag to reenable ECM when display goes unblank
  143. */
  144. struct amoled_ecm {
  145. struct regmap *regmap;
  146. struct device *dev;
  147. struct amoled_ecm_data data;
  148. struct amoled_ecm_sdam *sdam;
  149. struct mutex sdam_lock;
  150. struct delayed_work average_work;
  151. struct drm_panel *active_panel;
  152. void *notifier_cookie;
  153. u32 num_sdams;
  154. u32 base;
  155. u8 ab_revision;
  156. bool enable;
  157. bool abort;
  158. bool reenable;
  159. };
  160. static struct amoled_ecm_sdam_config ecm_reset_config[] = {
  161. { ECM_FAULT_LOG, 0x00 },
  162. { ECM_ROUTINE_LOG, 0x00 },
  163. { ECM_ACTIVE_SDAM, 0x01 },
  164. { ECM_SAMPLE_CNT_LSB, 0x00 },
  165. { ECM_SAMPLE_CNT_MSB, 0x00 },
  166. { ECM_STATUS_SET, 0x00 },
  167. { ECM_STATUS_CLR, 0xFF },
  168. { ECM_SDAM0_INDEX, 0x6C },
  169. { ECM_SDAM1_INDEX, 0x46 },
  170. { ECM_SDAM2_INDEX, 0x46 },
  171. { ECM_MODE, 0x00 },
  172. };
  173. static int ecm_nvmem_device_write(struct nvmem_device *nvmem,
  174. unsigned int offset,
  175. size_t bytes, void *buf)
  176. {
  177. size_t i;
  178. u8 *ptr = buf;
  179. for (i = 0; i < bytes; i++)
  180. pr_debug("Wrote %#x to %#x\n", *ptr++, offset + i);
  181. return nvmem_device_write(nvmem, offset, bytes, buf);
  182. }
  183. static int ecm_reset_sdam_config(struct amoled_ecm *ecm)
  184. {
  185. int rc, i;
  186. u8 val = 0, val2 = 0;
  187. for (i = 0; i < ARRAY_SIZE(ecm_reset_config); i++) {
  188. rc = ecm_nvmem_device_write(ecm->sdam[0].nvmem,
  189. ecm_reset_config[i].reg,
  190. 1, &ecm_reset_config[i].reset_val);
  191. if (rc < 0) {
  192. pr_err("Failed to write %u to SDAM, rc=%d\n",
  193. ecm_reset_config[i].reg, rc);
  194. return rc;
  195. }
  196. }
  197. for (i = 0; i < ecm->num_sdams; i++) {
  198. val |= (SEND_SDAM0_IRQ << i);
  199. val2 |= (WRITE_SDAM0_DATA << i);
  200. }
  201. rc = ecm_nvmem_device_write(ecm->sdam[0].nvmem, ECM_SEND_IRQ, 1, &val);
  202. if (rc < 0) {
  203. pr_err("Failed to write %u to ECM_SEND_IRQ, rc=%d\n", val, rc);
  204. return rc;
  205. }
  206. rc = ecm_nvmem_device_write(ecm->sdam[0].nvmem, ECM_WRITE_TO_SDAM, 1,
  207. &val2);
  208. if (rc < 0)
  209. pr_err("Failed to write %u to ECM_WRITE_TO_SDAM, rc=%d\n", val2,
  210. rc);
  211. usleep_range(10000, 12000);
  212. return rc;
  213. }
  214. static int amoled_ecm_enable(struct amoled_ecm *ecm)
  215. {
  216. struct amoled_ecm_data *data = &ecm->data;
  217. int rc;
  218. if (data->frames) {
  219. rc = ecm_nvmem_device_write(ecm->sdam[0].nvmem,
  220. ECM_N_ESWIRE_COUNT_LSB, 2, &data->frames);
  221. if (rc < 0) {
  222. pr_err("Failed to write swire count to SDAM, rc=%d\n",
  223. rc);
  224. return rc;
  225. }
  226. data->mode = ECM_MODE_MULTI_FRAMES;
  227. } else {
  228. if (!data->time_period_ms)
  229. return -EINVAL;
  230. data->mode = ECM_MODE_CONTINUOUS;
  231. }
  232. if ((ecm->ab_revision != AMOLED_AB_REVISION_1P0) &&
  233. (ecm->ab_revision != AMOLED_AB_REVISION_2P0)) {
  234. pr_err("ECM is not supported for AB version %u\n",
  235. ecm->ab_revision);
  236. return -ENODEV;
  237. }
  238. rc = ecm_reset_sdam_config(ecm);
  239. if (rc < 0) {
  240. pr_err("Failed to reset ECM SDAM configuration, rc=%d\n", rc);
  241. return rc;
  242. }
  243. rc = ecm_nvmem_device_write(ecm->sdam[0].nvmem, ECM_MODE, 1,
  244. &data->mode);
  245. if (rc < 0) {
  246. pr_err("Failed to write ECM mode to SDAM, rc=%d\n", rc);
  247. return rc;
  248. }
  249. rc = regmap_write(ecm->regmap, ecm->base + AB_ECM_EN_CTL, ECM_EN);
  250. if (rc < 0) {
  251. pr_err("Failed to enable ECM, rc=%d\n", rc);
  252. return rc;
  253. }
  254. rc = regmap_write(ecm->regmap, ecm->base + AB_ECM_COUNTER_CTL,
  255. ECM_COUNTER_START);
  256. if (rc < 0) {
  257. pr_err("Failed to enable ECM counter, rc=%d\n", rc);
  258. return rc;
  259. }
  260. if (data->mode == ECM_MODE_CONTINUOUS)
  261. schedule_delayed_work(&ecm->average_work,
  262. msecs_to_jiffies(data->time_period_ms));
  263. ecm->enable = true;
  264. return rc;
  265. }
  266. static int amoled_ecm_disable(struct amoled_ecm *ecm)
  267. {
  268. int rc;
  269. rc = regmap_write(ecm->regmap, ecm->base + AB_ECM_COUNTER_CTL, 0);
  270. if (rc < 0) {
  271. pr_err("Failed to disable ECM counter, rc=%d\n", rc);
  272. return rc;
  273. }
  274. rc = regmap_write(ecm->regmap, ecm->base + AB_ECM_EN_CTL, 0);
  275. if (rc < 0) {
  276. pr_err("Failed to disable ECM, rc=%d\n", rc);
  277. return rc;
  278. }
  279. rc = ecm_nvmem_device_write(ecm->sdam[0].nvmem, ECM_AVERAGE_LSB, 2,
  280. &ecm->data.avg_current);
  281. if (rc < 0) {
  282. pr_err("Failed to write ECM average to SDAM, rc=%d\n", rc);
  283. return rc;
  284. }
  285. pr_debug("ECM_AVERAGE:%u\n", ecm->data.avg_current);
  286. cancel_delayed_work(&ecm->average_work);
  287. ecm->data.avg_current = 0;
  288. ecm->data.m_cumulative = 0;
  289. ecm->data.num_m_samples = 0;
  290. ecm->data.mode = ECM_MODE_IDLE;
  291. ecm->abort = false;
  292. ecm->enable = false;
  293. return rc;
  294. }
  295. static void ecm_average_work(struct work_struct *work)
  296. {
  297. struct amoled_ecm *ecm = container_of(work, struct amoled_ecm,
  298. average_work.work);
  299. struct amoled_ecm_data *data = &ecm->data;
  300. mutex_lock(&ecm->sdam_lock);
  301. if (!data->num_m_samples || !data->m_cumulative) {
  302. pr_warn_ratelimited("Invalid data, num_m_samples=%u m_cumulative:%u\n",
  303. data->num_m_samples, data->m_cumulative);
  304. data->avg_current = 0;
  305. } else {
  306. data->avg_current = data->m_cumulative / data->num_m_samples;
  307. pr_debug("avg_current=%u mA\n", data->avg_current);
  308. }
  309. data->m_cumulative = 0;
  310. data->num_m_samples = 0;
  311. mutex_unlock(&ecm->sdam_lock);
  312. /*
  313. * If ECM is not aborted and still enabled, run it one more time
  314. */
  315. if (!ecm->abort && ecm->enable)
  316. schedule_delayed_work(&ecm->average_work,
  317. msecs_to_jiffies(ecm->data.time_period_ms));
  318. }
  319. static ssize_t enable_show(struct device *dev,
  320. struct device_attribute *attr, char *buf)
  321. {
  322. struct amoled_ecm *ecm = dev_get_drvdata(dev);
  323. return scnprintf(buf, PAGE_SIZE, "%d\n", ecm->enable);
  324. }
  325. static ssize_t enable_store(struct device *dev,
  326. struct device_attribute *attr,
  327. const char *buf, size_t count)
  328. {
  329. struct amoled_ecm *ecm = dev_get_drvdata(dev);
  330. bool val;
  331. int rc;
  332. rc = kstrtobool(buf, &val);
  333. if (rc < 0)
  334. return rc;
  335. if (ecm->enable == val) {
  336. pr_err("AMOLED ECM is already %s\n",
  337. val ? "enabled" : "disabled");
  338. return -EINVAL;
  339. }
  340. if (val) {
  341. rc = amoled_ecm_enable(ecm);
  342. if (rc < 0) {
  343. pr_err("Failed to enable AMOLED ECM, rc=%d\n", rc);
  344. return rc;
  345. }
  346. } else {
  347. rc = amoled_ecm_disable(ecm);
  348. if (rc < 0) {
  349. pr_err("Failed to disable AMOLED ECM, rc=%d\n", rc);
  350. return rc;
  351. }
  352. ecm->data.frames = 0;
  353. ecm->data.time_period_ms = 0;
  354. }
  355. return count;
  356. }
  357. static DEVICE_ATTR_RW(enable);
  358. static ssize_t frames_show(struct device *dev,
  359. struct device_attribute *attr, char *buf)
  360. {
  361. struct amoled_ecm *ecm = dev_get_drvdata(dev);
  362. return scnprintf(buf, PAGE_SIZE, "%u\n", ecm->data.frames);
  363. }
  364. static ssize_t frames_store(struct device *dev,
  365. struct device_attribute *attr,
  366. const char *buf, size_t count)
  367. {
  368. struct amoled_ecm *ecm = dev_get_drvdata(dev);
  369. u16 val;
  370. int rc;
  371. if (ecm->enable) {
  372. pr_err("Failed to configure frames, ECM is already running\n");
  373. return -EINVAL;
  374. }
  375. rc = kstrtou16(buf, 0, &val);
  376. if ((rc < 0) || !val)
  377. return -EINVAL;
  378. ecm->data.frames = val;
  379. return count;
  380. }
  381. static DEVICE_ATTR_RW(frames);
  382. static ssize_t time_period_show(struct device *dev,
  383. struct device_attribute *attr, char *buf)
  384. {
  385. struct amoled_ecm *ecm = dev_get_drvdata(dev);
  386. return scnprintf(buf, PAGE_SIZE, "%u\n", ecm->data.time_period_ms);
  387. }
  388. static ssize_t time_period_store(struct device *dev,
  389. struct device_attribute *attr,
  390. const char *buf, size_t count)
  391. {
  392. struct amoled_ecm *ecm = dev_get_drvdata(dev);
  393. u32 val;
  394. int rc;
  395. if (ecm->enable) {
  396. pr_err("Failed to configure time_period, ECM is already running\n");
  397. return -EINVAL;
  398. }
  399. rc = kstrtou32(buf, 0, &val);
  400. if ((rc < 0) || !val)
  401. return -EINVAL;
  402. ecm->data.time_period_ms = val;
  403. return count;
  404. }
  405. static DEVICE_ATTR_RW(time_period);
  406. static ssize_t avg_current_show(struct device *dev,
  407. struct device_attribute *attr, char *buf)
  408. {
  409. struct amoled_ecm *ecm = dev_get_drvdata(dev);
  410. return scnprintf(buf, PAGE_SIZE, "%u\n", ecm->data.avg_current);
  411. }
  412. static DEVICE_ATTR_RO(avg_current);
  413. static struct attribute *amoled_ecm_attrs[] = {
  414. &dev_attr_enable.attr,
  415. &dev_attr_frames.attr,
  416. &dev_attr_time_period.attr,
  417. &dev_attr_avg_current.attr,
  418. NULL,
  419. };
  420. static const struct attribute_group amoled_ecm_group = {
  421. .name = "amoled_ecm",
  422. .attrs = amoled_ecm_attrs,
  423. };
  424. __ATTRIBUTE_GROUPS(amoled_ecm);
  425. static int get_sdam_from_irq(struct amoled_ecm *ecm, int irq)
  426. {
  427. int i;
  428. for (i = 0; i < ecm->num_sdams; i++)
  429. if (ecm->sdam[i].irq == irq)
  430. return i;
  431. return -ENOENT;
  432. }
  433. static int handle_ecm_abort(struct amoled_ecm *ecm)
  434. {
  435. struct amoled_ecm_data *data = &ecm->data;
  436. int rc;
  437. u8 mode = data->mode;
  438. switch (mode) {
  439. case ECM_MODE_MULTI_FRAMES:
  440. pr_warn_ratelimited("Multiple frames mode is not supported\n");
  441. data->avg_current = 0;
  442. break;
  443. case ECM_MODE_CONTINUOUS:
  444. if (data->num_m_samples < ECM_MIN_M_SAMPLES) {
  445. pr_warn_ratelimited("Too few samples %u for continuous mode\n",
  446. data->num_m_samples);
  447. data->avg_current = 0;
  448. break;
  449. }
  450. ecm->abort = true;
  451. schedule_delayed_work(&ecm->average_work, 0);
  452. break;
  453. default:
  454. pr_err_ratelimited("Invalid ECM operation mode: %u\n", mode);
  455. data->avg_current = 0;
  456. return -EINVAL;
  457. }
  458. rc = amoled_ecm_disable(ecm);
  459. if (rc < 0)
  460. pr_err("Failed to disable AMOLED ECM, rc=%d\n", rc);
  461. return rc;
  462. }
  463. static int get_sdam_index(struct nvmem_device *nvmem, int sdam_num, u8 *index)
  464. {
  465. unsigned int addr;
  466. switch (sdam_num) {
  467. case 0:
  468. addr = ECM_SDAM0_INDEX;
  469. break;
  470. case 1:
  471. addr = ECM_SDAM1_INDEX;
  472. break;
  473. case 2:
  474. addr = ECM_SDAM2_INDEX;
  475. break;
  476. default:
  477. return -EINVAL;
  478. }
  479. return nvmem_device_read(nvmem, addr, 1, index);
  480. }
  481. static irqreturn_t sdam_full_irq_handler(int irq, void *_ecm)
  482. {
  483. struct amoled_ecm *ecm = _ecm;
  484. struct amoled_ecm_data *data = &ecm->data;
  485. u64 cumulative = 0, m_sample;
  486. int rc, i, sdam_num, sdam_start, num_ecm_samples, max_samples;
  487. u16 ecm_sample, gain;
  488. u8 buf[2], int_status, sdam_index, overwrite;
  489. sdam_num = get_sdam_from_irq(ecm, irq);
  490. if (sdam_num < 0) {
  491. pr_err("Invalid SDAM interrupt, err=%d\n", sdam_num);
  492. return IRQ_HANDLED;
  493. }
  494. rc = nvmem_device_read(ecm->sdam[0].nvmem, ECM_STATUS_SET, 1,
  495. &int_status);
  496. if (rc < 0) {
  497. pr_err("Failed to read interrupt status from SDAM, rc=%d\n",
  498. rc);
  499. return IRQ_HANDLED;
  500. }
  501. pr_debug("ECM_STATUS_SET: %#x\n", int_status);
  502. if (data->mode != ECM_MODE_CONTINUOUS &&
  503. data->mode != ECM_MODE_MULTI_FRAMES)
  504. return IRQ_HANDLED;
  505. if (int_status & ECM_ABORT) {
  506. rc = handle_ecm_abort(ecm);
  507. if (rc < 0) {
  508. pr_err("Failed to handle ECM_ABORT interrupt, rc=%d\n",
  509. rc);
  510. return IRQ_HANDLED;
  511. }
  512. }
  513. rc = get_sdam_index(ecm->sdam[0].nvmem, sdam_num, &sdam_index);
  514. if (rc < 0) {
  515. pr_err("Failed to read SDAM index, rc=%d\n", rc);
  516. goto irq_exit;
  517. }
  518. pr_debug("sdam_num:%d sdam_index:%#x\n", sdam_num, sdam_index);
  519. sdam_start = ecm->sdam[sdam_num].start_addr;
  520. max_samples = (ECM_SDAM_SAMPLE_END_ADDR + 1 - sdam_start) / 2;
  521. num_ecm_samples = (sdam_index + 1 - sdam_start) / 2;
  522. if (!num_ecm_samples || (num_ecm_samples > max_samples)) {
  523. pr_err("Incorrect number of ECM samples, num_ecm_samples:%d max_samples:%d\n",
  524. num_ecm_samples, max_samples);
  525. return IRQ_HANDLED;
  526. }
  527. mutex_lock(&ecm->sdam_lock);
  528. rc = nvmem_device_read(ecm->sdam[0].nvmem, ECM_WRITE_TO_SDAM, 1,
  529. &overwrite);
  530. if (rc < 0) {
  531. pr_err("Failed to read ECM_WRITE_TO_SDAM from SDAM, rc=%d\n",
  532. rc);
  533. goto irq_exit;
  534. }
  535. overwrite &= ~(OVERWRITE_SDAM0_DATA << sdam_num);
  536. rc = ecm_nvmem_device_write(ecm->sdam[0].nvmem, ECM_WRITE_TO_SDAM,
  537. 1, &overwrite);
  538. if (rc < 0) {
  539. pr_err("Failed to write ECM_WRITE_TO_SDAM to SDAM, rc=%d\n",
  540. rc);
  541. goto irq_exit;
  542. }
  543. /*
  544. * For AMOLED AB peripheral,
  545. * Revision 1.0:
  546. * ECM measured current = 15 times of each LSB
  547. *
  548. * Revision 2.0:
  549. * ECM measured current = 16 times of each LSB
  550. */
  551. if (ecm->ab_revision == AMOLED_AB_REVISION_1P0)
  552. gain = ECM_SAMPLE_GAIN_V1;
  553. else
  554. gain = ECM_SAMPLE_GAIN_V2;
  555. for (i = sdam_start; i < sdam_index; i += 2) {
  556. rc = nvmem_device_read(ecm->sdam[sdam_num].nvmem, i, 2, buf);
  557. if (rc < 0) {
  558. pr_err("Failed to read SDAM sample, rc=%d\n", rc);
  559. goto irq_exit;
  560. }
  561. ecm_sample = (buf[1] << 8) | buf[0];
  562. cumulative += ((ecm_sample * 1000) / gain) / 1000;
  563. }
  564. overwrite |= (OVERWRITE_SDAM0_DATA << sdam_num);
  565. rc = ecm_nvmem_device_write(ecm->sdam[0].nvmem, ECM_WRITE_TO_SDAM,
  566. 1, &overwrite);
  567. if (rc < 0) {
  568. pr_err("Failed to write ECM_WRITE_TO_SDAM to SDAM, rc=%d\n",
  569. rc);
  570. goto irq_exit;
  571. }
  572. if (!cumulative) {
  573. pr_err("Error, No ECM samples captured. Cumulative:%lu\n",
  574. cumulative);
  575. goto irq_exit;
  576. }
  577. m_sample = cumulative / num_ecm_samples;
  578. data->m_cumulative += m_sample;
  579. data->num_m_samples++;
  580. buf[0] = (ECM_SDAM0_FULL << sdam_num);
  581. rc = ecm_nvmem_device_write(ecm->sdam[0].nvmem, ECM_STATUS_CLR, 1,
  582. &buf[0]);
  583. if (rc < 0) {
  584. pr_err("Failed to clear interrupt status in SDAM, rc=%d\n",
  585. rc);
  586. goto irq_exit;
  587. }
  588. if ((data->mode == ECM_MODE_MULTI_FRAMES) &&
  589. (sdam_index < max_samples))
  590. schedule_delayed_work(&ecm->average_work, 0);
  591. irq_exit:
  592. mutex_unlock(&ecm->sdam_lock);
  593. return IRQ_HANDLED;
  594. }
  595. static int amoled_ecm_parse_dt(struct amoled_ecm *ecm)
  596. {
  597. int rc = 0, i;
  598. u32 val;
  599. u8 buf[20];
  600. rc = of_property_read_u32(ecm->dev->of_node, "reg", &val);
  601. if (rc < 0) {
  602. pr_err("Failed to get reg, rc = %d\n", rc);
  603. return rc;
  604. }
  605. ecm->base = val;
  606. rc = of_property_count_strings(ecm->dev->of_node, "nvmem-names");
  607. if (rc < 0) {
  608. pr_err("Could not find nvmem device\n");
  609. return rc;
  610. }
  611. ecm->num_sdams = rc;
  612. ecm->sdam = devm_kcalloc(ecm->dev, ecm->num_sdams,
  613. sizeof(*ecm->sdam), GFP_KERNEL);
  614. if (!ecm->sdam)
  615. return -ENOMEM;
  616. for (i = 0; i < ecm->num_sdams; i++) {
  617. scnprintf(buf, sizeof(buf), "ecm-sdam%d", i);
  618. rc = of_irq_get_byname(ecm->dev->of_node, buf);
  619. if (rc < 0) {
  620. pr_err("Failed to get irq for ecm sdam, err=%d\n", rc);
  621. return -EINVAL;
  622. }
  623. ecm->sdam[i].irq_name = devm_kstrdup(ecm->dev, buf,
  624. GFP_KERNEL);
  625. if (!ecm->sdam[i].irq_name)
  626. return -ENOMEM;
  627. ecm->sdam[i].irq = rc;
  628. scnprintf(buf, sizeof(buf), "amoled-ecm-sdam%d", i);
  629. ecm->sdam[i].nvmem = devm_nvmem_device_get(ecm->dev, buf);
  630. if (IS_ERR(ecm->sdam[i].nvmem)) {
  631. rc = PTR_ERR(ecm->sdam[i].nvmem);
  632. if (rc != -EPROBE_DEFER)
  633. pr_err("Failed to get nvmem device, rc=%d\n",
  634. rc);
  635. ecm->sdam[i].nvmem = NULL;
  636. return rc;
  637. }
  638. }
  639. return 0;
  640. }
  641. #if IS_ENABLED(CONFIG_QCOM_PANEL_EVENT_NOTIFIER)
  642. static void panel_event_notifier_callback(enum panel_event_notifier_tag tag,
  643. struct panel_event_notification *notification, void *data)
  644. {
  645. struct amoled_ecm *ecm = data;
  646. int rc;
  647. if (!notification) {
  648. pr_err("Invalid panel notification\n");
  649. return;
  650. }
  651. pr_debug("panel event received, type: %d\n", notification->notif_type);
  652. switch (notification->notif_type) {
  653. case DRM_PANEL_EVENT_BLANK:
  654. if (ecm->enable) {
  655. rc = amoled_ecm_disable(ecm);
  656. if (rc < 0) {
  657. pr_err("Failed to disable ECM for display BLANK, rc=%d\n",
  658. rc);
  659. return;
  660. }
  661. ecm->reenable = true;
  662. pr_debug("Disabled ECM for display BLANK\n");
  663. }
  664. break;
  665. case DRM_PANEL_EVENT_UNBLANK:
  666. if (ecm->reenable) {
  667. rc = amoled_ecm_enable(ecm);
  668. if (rc < 0) {
  669. pr_err("Failed to re-enable ECM for display UNBLANK, rc=%d\n",
  670. rc);
  671. return;
  672. }
  673. ecm->reenable = false;
  674. pr_debug("Enabled ECM for display UNBLANK\n");
  675. }
  676. break;
  677. default:
  678. pr_debug("Ignore panel event: %d\n", notification->notif_type);
  679. break;
  680. }
  681. }
  682. static int qti_amoled_register_panel_notifier(struct amoled_ecm *ecm)
  683. {
  684. struct device_node *np = ecm->dev->of_node;
  685. struct device_node *pnode;
  686. struct drm_panel *panel;
  687. void *cookie = NULL;
  688. int i, count, rc;
  689. count = of_count_phandle_with_args(np, "display-panels", NULL);
  690. if (count <= 0)
  691. return 0;
  692. for (i = 0; i < count; i++) {
  693. pnode = of_parse_phandle(np, "display-panels", i);
  694. if (!pnode)
  695. return -ENODEV;
  696. panel = of_drm_find_panel(pnode);
  697. of_node_put(pnode);
  698. if (!IS_ERR(panel)) {
  699. ecm->active_panel = panel;
  700. break;
  701. }
  702. }
  703. if (!ecm->active_panel) {
  704. rc = PTR_ERR(panel);
  705. if (rc != -EPROBE_DEFER)
  706. pr_err("failed to find active panel, rc=%d\n", rc);
  707. return rc;
  708. }
  709. cookie = panel_event_notifier_register(
  710. PANEL_EVENT_NOTIFICATION_PRIMARY,
  711. PANEL_EVENT_NOTIFIER_CLIENT_ECM,
  712. ecm->active_panel,
  713. panel_event_notifier_callback,
  714. (void *)ecm);
  715. if (IS_ERR(cookie)) {
  716. rc = PTR_ERR(cookie);
  717. pr_err("failed to register panel event notifier, rc=%d\n", rc);
  718. return rc;
  719. }
  720. pr_debug("register panel notifier successfully\n");
  721. ecm->notifier_cookie = cookie;
  722. return 0;
  723. }
  724. static int qti_amoled_unregister_panel_notifier(struct amoled_ecm *ecm)
  725. {
  726. if (ecm->notifier_cookie)
  727. panel_event_notifier_unregister(ecm->notifier_cookie);
  728. return 0;
  729. }
  730. #else
  731. static inline int qti_amoled_register_panel_notifier(struct amoled_ecm *ecm)
  732. {
  733. return 0;
  734. }
  735. static inline int qti_amoled_unregister_panel_notifier(struct amoled_ecm *ecm)
  736. {
  737. return 0;
  738. }
  739. #endif
  740. static int qti_amoled_ecm_probe(struct platform_device *pdev)
  741. {
  742. struct device *hwmon_dev;
  743. struct amoled_ecm *ecm;
  744. int rc, i;
  745. unsigned int temp;
  746. ecm = devm_kzalloc(&pdev->dev, sizeof(*ecm), GFP_KERNEL);
  747. if (!ecm)
  748. return -ENOMEM;
  749. ecm->dev = &pdev->dev;
  750. ecm->regmap = dev_get_regmap(pdev->dev.parent, NULL);
  751. if (!ecm->regmap) {
  752. dev_err(&pdev->dev, "Failed to get regmap\n");
  753. return -EINVAL;
  754. }
  755. rc = amoled_ecm_parse_dt(ecm);
  756. if (rc < 0) {
  757. dev_err(&pdev->dev, "Failed to parse AMOLED ECM rc=%d\n", rc);
  758. return rc;
  759. }
  760. rc = regmap_read(ecm->regmap, ecm->base + AB_REVISION2, &temp);
  761. if (rc < 0) {
  762. dev_err(&pdev->dev, "Failed to read AB revision, rc=%d\n", rc);
  763. return rc;
  764. }
  765. ecm->ab_revision = temp;
  766. ecm->enable = false;
  767. ecm->abort = false;
  768. ecm->data.m_cumulative = 0;
  769. ecm->data.num_m_samples = 0;
  770. ecm->data.time_period_ms = 0;
  771. ecm->data.frames = 0;
  772. ecm->data.avg_current = 0;
  773. ecm->data.mode = ECM_MODE_IDLE;
  774. INIT_DELAYED_WORK(&ecm->average_work, ecm_average_work);
  775. mutex_init(&ecm->sdam_lock);
  776. dev_set_drvdata(ecm->dev, ecm);
  777. for (i = 0; i < ecm->num_sdams; i++) {
  778. rc = devm_request_threaded_irq(ecm->dev, ecm->sdam[i].irq,
  779. NULL, sdam_full_irq_handler,
  780. IRQF_ONESHOT, ecm->sdam[i].irq_name, ecm);
  781. if (rc < 0) {
  782. dev_err(&pdev->dev, "Failed to request IRQ(%s), rc=%d\n",
  783. ecm->sdam[i].irq_name, rc);
  784. return rc;
  785. }
  786. ecm->sdam[i].start_addr = i ? ECM_SDAMX_SAMPLE_START_ADDR
  787. : ECM_SDAM0_SAMPLE_START_ADDR;
  788. }
  789. hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev,
  790. "amoled_ecm", ecm, amoled_ecm_groups);
  791. if (IS_ERR_OR_NULL(hwmon_dev)) {
  792. rc = PTR_ERR(hwmon_dev);
  793. pr_err("failed to register hwmon device for amoled-ecm, rc=%d\n",
  794. rc);
  795. return rc;
  796. }
  797. return qti_amoled_register_panel_notifier(ecm);
  798. }
  799. static int qti_amoled_ecm_remove(struct platform_device *pdev)
  800. {
  801. struct amoled_ecm *ecm = dev_get_drvdata(&pdev->dev);
  802. return qti_amoled_unregister_panel_notifier(ecm);
  803. }
  804. static const struct of_device_id amoled_ecm_match_table[] = {
  805. { .compatible = "qcom,amoled-ecm", },
  806. { },
  807. };
  808. static struct platform_driver qti_amoled_ecm_driver = {
  809. .driver = {
  810. .name = "qti_amoled_ecm",
  811. .of_match_table = amoled_ecm_match_table,
  812. },
  813. .probe = qti_amoled_ecm_probe,
  814. .remove = qti_amoled_ecm_remove,
  815. };
  816. module_platform_driver(qti_amoled_ecm_driver);
  817. MODULE_DESCRIPTION("QTI AMOLED ECM driver");
  818. MODULE_LICENSE("GPL v2");