dsi_status_6g.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/workqueue.h>
  13. #include <linux/delay.h>
  14. #include <linux/kobject.h>
  15. #include <linux/sysfs.h>
  16. #include "mdss_dsi.h"
  17. #include "mdss_mdp.h"
  18. /*
  19. * mdss_check_dsi_ctrl_status() - Check MDP5 DSI controller status periodically.
  20. * @work : dsi controller status data
  21. * @interval : duration in milliseconds to schedule work queue
  22. *
  23. * This function calls check_status API on DSI controller to send the BTA
  24. * command. If DSI controller fails to acknowledge the BTA command, it sends
  25. * the PANEL_ALIVE=0 status to HAL layer.
  26. */
  27. void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval)
  28. {
  29. struct dsi_status_data *pstatus_data = NULL;
  30. struct mdss_panel_data *pdata = NULL;
  31. struct mipi_panel_info *mipi = NULL;
  32. struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
  33. struct mdss_overlay_private *mdp5_data = NULL;
  34. struct mdss_mdp_ctl *ctl = NULL;
  35. int ret = 0;
  36. pstatus_data = container_of(to_delayed_work(work),
  37. struct dsi_status_data, check_status);
  38. if (!pstatus_data || !(pstatus_data->mfd)) {
  39. pr_err("%s: mfd not available\n", __func__);
  40. return;
  41. }
  42. pdata = dev_get_platdata(&pstatus_data->mfd->pdev->dev);
  43. if (!pdata) {
  44. pr_err("%s: Panel data not available\n", __func__);
  45. return;
  46. }
  47. mipi = &pdata->panel_info.mipi;
  48. ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
  49. panel_data);
  50. if (!ctrl_pdata || !ctrl_pdata->check_status) {
  51. pr_err("%s: DSI ctrl or status_check callback not available\n",
  52. __func__);
  53. return;
  54. }
  55. mdp5_data = mfd_to_mdp5_data(pstatus_data->mfd);
  56. ctl = mfd_to_ctl(pstatus_data->mfd);
  57. if (!ctl) {
  58. pr_err("%s: Display is off\n", __func__);
  59. return;
  60. }
  61. if (!ctl->power_on) {
  62. schedule_delayed_work(&pstatus_data->check_status,
  63. msecs_to_jiffies(interval));
  64. pr_err("%s: ctl not powered on\n", __func__);
  65. return;
  66. }
  67. mutex_lock(&ctrl_pdata->mutex);
  68. /*
  69. * TODO: Because mdss_dsi_cmd_mdp_busy has made sure DMA to
  70. * be idle in mdss_dsi_cmdlist_commit, it is not necessary
  71. * to acquire ov_lock in case of video mode. Removing this
  72. * lock to fix issues so that ESD thread would not block other
  73. * overlay operations. Need refine this lock for command mode
  74. */
  75. if (mipi->mode == DSI_CMD_MODE)
  76. mutex_lock(&mdp5_data->ov_lock);
  77. if (pstatus_data->mfd->shutdown_pending) {
  78. if (mipi->mode == DSI_CMD_MODE)
  79. mutex_unlock(&mdp5_data->ov_lock);
  80. mutex_unlock(&ctrl_pdata->mutex);
  81. pr_err("%s: DSI turning off, avoiding panel status check\n",
  82. __func__);
  83. return;
  84. }
  85. /*
  86. * For the command mode panels, we return pan display
  87. * IOCTL on vsync interrupt. So, after vsync interrupt comes
  88. * and when DMA_P is in progress, if the panel stops responding
  89. * and if we trigger BTA before DMA_P finishes, then the DSI
  90. * FIFO will not be cleared since the DSI data bus control
  91. * doesn't come back to the host after BTA. This may cause the
  92. * display reset not to be proper. Hence, wait for DMA_P done
  93. * for command mode panels before triggering BTA.
  94. */
  95. if (ctl->wait_pingpong)
  96. ctl->wait_pingpong(ctl, NULL);
  97. pr_debug("%s: DSI ctrl wait for ping pong done\n", __func__);
  98. mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
  99. ret = ctrl_pdata->check_status(ctrl_pdata);
  100. mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
  101. if (mipi->mode == DSI_CMD_MODE)
  102. mutex_unlock(&mdp5_data->ov_lock);
  103. mutex_unlock(&ctrl_pdata->mutex);
  104. if ((pstatus_data->mfd->panel_power_on)) {
  105. if (ret > 0) {
  106. schedule_delayed_work(&pstatus_data->check_status,
  107. msecs_to_jiffies(interval));
  108. } else {
  109. char *envp[2] = {"PANEL_ALIVE=0", NULL};
  110. pdata->panel_info.panel_dead = true;
  111. ret = kobject_uevent_env(
  112. &pstatus_data->mfd->fbi->dev->kobj,
  113. KOBJ_CHANGE, envp);
  114. pr_err("%s: Panel has gone bad, sending uevent - %s\n",
  115. __func__, envp[0]);
  116. }
  117. }
  118. }