sde_hw_uidle.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
  4. *
  5. */
  6. #include "sde_hwio.h"
  7. #include "sde_hw_catalog.h"
  8. #include "sde_hw_top.h"
  9. #include "sde_dbg.h"
  10. #include "sde_kms.h"
  11. #define UIDLE_CTL 0x0
  12. #define UIDLE_STATUS 0x4
  13. #define UIDLE_FAL10_VETO_OVERRIDE 0x8
  14. #define UIDLE_WD_TIMER_CTL 0x10
  15. #define UIDLE_WD_TIMER_CTL2 0x14
  16. #define UIDLE_WD_TIMER_LOAD_VALUE 0x18
  17. #define UIDLE_DANGER_STATUS_0 0x20
  18. #define UIDLE_DANGER_STATUS_1 0x24
  19. #define UIDLE_SAFE_STATUS_0 0x30
  20. #define UIDLE_SAFE_STATUS_1 0x34
  21. #define UIDLE_IDLE_STATUS_0 0x38
  22. #define UIDLE_IDLE_STATUS_1 0x3c
  23. #define UIDLE_FAL_STATUS_0 0x40
  24. #define UIDLE_FAL_STATUS_1 0x44
  25. #define UIDLE_GATE_CNTR_CTL 0x50
  26. #define UIDLE_FAL1_GATE_CNTR 0x54
  27. #define UIDLE_FAL10_GATE_CNTR 0x58
  28. #define UIDLE_FAL_WAIT_GATE_CNTR 0x5c
  29. #define UIDLE_FAL1_NUM_TRANSITIONS_CNTR 0x60
  30. #define UIDLE_FAL10_NUM_TRANSITIONS_CNTR 0x64
  31. #define UIDLE_MIN_GATE_CNTR 0x68
  32. #define UIDLE_MAX_GATE_CNTR 0x6c
  33. static const struct sde_uidle_cfg *_top_offset(enum sde_uidle uidle,
  34. struct sde_mdss_cfg *m, void __iomem *addr,
  35. unsigned long len, struct sde_hw_blk_reg_map *b)
  36. {
  37. /* Make sure length of regs offsets is within the mapped memory */
  38. if ((uidle == m->uidle_cfg.id) &&
  39. (m->uidle_cfg.base + m->uidle_cfg.len) < len) {
  40. b->base_off = addr;
  41. b->blk_off = m->uidle_cfg.base;
  42. b->length = m->uidle_cfg.len;
  43. b->hwversion = m->hwversion;
  44. b->log_mask = SDE_DBG_MASK_UIDLE;
  45. SDE_DEBUG("base:0x%p blk_off:0x%x length:%d hwversion:0x%x\n",
  46. b->base_off, b->blk_off, b->length, b->hwversion);
  47. return &m->uidle_cfg;
  48. }
  49. SDE_ERROR("wrong uidle mapping params, will disable UIDLE!\n");
  50. SDE_ERROR("base_off:0x%pK id:%d base:0x%x len:%d mmio_len:%ld\n",
  51. addr, m->uidle_cfg.id, m->uidle_cfg.base,
  52. m->uidle_cfg.len, len);
  53. m->uidle_cfg.uidle_rev = 0;
  54. return ERR_PTR(-EINVAL);
  55. }
  56. void sde_hw_uidle_get_status(struct sde_hw_uidle *uidle,
  57. struct sde_uidle_status *status)
  58. {
  59. struct sde_hw_blk_reg_map *c = &uidle->hw;
  60. status->uidle_danger_status_0 =
  61. SDE_REG_READ(c, UIDLE_DANGER_STATUS_0);
  62. status->uidle_danger_status_1 =
  63. SDE_REG_READ(c, UIDLE_DANGER_STATUS_1);
  64. status->uidle_safe_status_0 =
  65. SDE_REG_READ(c, UIDLE_SAFE_STATUS_0);
  66. status->uidle_safe_status_1 =
  67. SDE_REG_READ(c, UIDLE_SAFE_STATUS_1);
  68. status->uidle_idle_status_0 =
  69. SDE_REG_READ(c, UIDLE_IDLE_STATUS_0);
  70. status->uidle_idle_status_1 =
  71. SDE_REG_READ(c, UIDLE_IDLE_STATUS_1);
  72. status->uidle_fal_status_0 =
  73. SDE_REG_READ(c, UIDLE_FAL_STATUS_0);
  74. status->uidle_fal_status_1 =
  75. SDE_REG_READ(c, UIDLE_FAL_STATUS_1);
  76. }
  77. void sde_hw_uidle_get_cntr(struct sde_hw_uidle *uidle,
  78. struct sde_uidle_cntr *cntr)
  79. {
  80. struct sde_hw_blk_reg_map *c = &uidle->hw;
  81. u32 reg_val;
  82. cntr->fal1_gate_cntr =
  83. SDE_REG_READ(c, UIDLE_FAL1_GATE_CNTR);
  84. cntr->fal10_gate_cntr =
  85. SDE_REG_READ(c, UIDLE_FAL10_GATE_CNTR);
  86. cntr->fal_wait_gate_cntr =
  87. SDE_REG_READ(c, UIDLE_FAL_WAIT_GATE_CNTR);
  88. cntr->fal1_num_transitions_cntr =
  89. SDE_REG_READ(c, UIDLE_FAL1_NUM_TRANSITIONS_CNTR);
  90. cntr->fal10_num_transitions_cntr =
  91. SDE_REG_READ(c, UIDLE_FAL10_NUM_TRANSITIONS_CNTR);
  92. cntr->min_gate_cntr =
  93. SDE_REG_READ(c, UIDLE_MIN_GATE_CNTR);
  94. cntr->max_gate_cntr =
  95. SDE_REG_READ(c, UIDLE_MAX_GATE_CNTR);
  96. /* clear counters after read */
  97. reg_val = SDE_REG_READ(c, UIDLE_GATE_CNTR_CTL);
  98. reg_val = reg_val | BIT(31);
  99. SDE_REG_WRITE(c, UIDLE_GATE_CNTR_CTL, reg_val);
  100. reg_val = (reg_val & ~BIT(31));
  101. SDE_REG_WRITE(c, UIDLE_GATE_CNTR_CTL, reg_val);
  102. }
  103. void sde_hw_uidle_setup_cntr(struct sde_hw_uidle *uidle, bool enable)
  104. {
  105. struct sde_hw_blk_reg_map *c = &uidle->hw;
  106. u32 reg_val;
  107. reg_val = SDE_REG_READ(c, UIDLE_GATE_CNTR_CTL);
  108. reg_val = (reg_val & ~BIT(8)) | (enable ? BIT(8) : 0);
  109. SDE_REG_WRITE(c, UIDLE_GATE_CNTR_CTL, reg_val);
  110. }
  111. void sde_hw_uidle_setup_wd_timer(struct sde_hw_uidle *uidle,
  112. struct sde_uidle_wd_cfg *cfg)
  113. {
  114. struct sde_hw_blk_reg_map *c = &uidle->hw;
  115. u32 val_ctl, val_ctl2, val_ld;
  116. val_ctl = SDE_REG_READ(c, UIDLE_WD_TIMER_CTL);
  117. val_ctl2 = SDE_REG_READ(c, UIDLE_WD_TIMER_CTL2);
  118. val_ld = SDE_REG_READ(c, UIDLE_WD_TIMER_LOAD_VALUE);
  119. val_ctl = (val_ctl & ~BIT(0)) | (cfg->clear ? BIT(0) : 0);
  120. val_ctl2 = (val_ctl2 & ~BIT(0)) | (cfg->enable ? BIT(0) : 0);
  121. val_ctl2 = (val_ctl2 & ~GENMASK(4, 1)) |
  122. ((cfg->granularity & 0xF) << 1);
  123. val_ctl2 = (val_ctl2 & ~BIT(8)) | (cfg->heart_beat ? BIT(8) : 0);
  124. val_ld = cfg->load_value;
  125. SDE_REG_WRITE(c, UIDLE_WD_TIMER_CTL, val_ctl);
  126. SDE_REG_WRITE(c, UIDLE_WD_TIMER_CTL2, val_ctl2);
  127. SDE_REG_WRITE(c, UIDLE_WD_TIMER_LOAD_VALUE, val_ld);
  128. }
  129. void sde_hw_uidle_setup_ctl(struct sde_hw_uidle *uidle,
  130. struct sde_uidle_ctl_cfg *cfg)
  131. {
  132. struct sde_hw_blk_reg_map *c = &uidle->hw;
  133. u32 reg_val;
  134. reg_val = SDE_REG_READ(c, UIDLE_CTL);
  135. reg_val = (reg_val & ~BIT(31)) | (cfg->uidle_enable ? BIT(31) : 0);
  136. reg_val = (reg_val & ~FAL10_DANGER_MSK) |
  137. ((cfg->fal10_danger << FAL10_DANGER_SHFT) &
  138. FAL10_DANGER_MSK);
  139. reg_val = (reg_val & ~FAL10_EXIT_DANGER_MSK) |
  140. ((cfg->fal10_exit_danger << FAL10_EXIT_DANGER_SHFT) &
  141. FAL10_EXIT_DANGER_MSK);
  142. reg_val = (reg_val & ~FAL10_EXIT_CNT_MSK) |
  143. ((cfg->fal10_exit_cnt << FAL10_EXIT_CNT_SHFT) &
  144. FAL10_EXIT_CNT_MSK);
  145. SDE_REG_WRITE(c, UIDLE_CTL, reg_val);
  146. }
  147. static inline void _setup_uidle_ops(struct sde_hw_uidle_ops *ops,
  148. unsigned long cap)
  149. {
  150. ops->set_uidle_ctl = sde_hw_uidle_setup_ctl;
  151. ops->setup_wd_timer = sde_hw_uidle_setup_wd_timer;
  152. ops->uidle_setup_cntr = sde_hw_uidle_setup_cntr;
  153. ops->uidle_get_cntr = sde_hw_uidle_get_cntr;
  154. ops->uidle_get_status = sde_hw_uidle_get_status;
  155. }
  156. struct sde_hw_uidle *sde_hw_uidle_init(enum sde_uidle idx,
  157. void __iomem *addr, unsigned long len,
  158. struct sde_mdss_cfg *m)
  159. {
  160. struct sde_hw_uidle *c;
  161. const struct sde_uidle_cfg *cfg;
  162. c = kzalloc(sizeof(*c), GFP_KERNEL);
  163. if (!c)
  164. return ERR_PTR(-ENOMEM);
  165. cfg = _top_offset(idx, m, addr, len, &c->hw);
  166. if (IS_ERR_OR_NULL(cfg)) {
  167. kfree(c);
  168. return ERR_PTR(-EINVAL);
  169. }
  170. /*
  171. * Assign ops
  172. */
  173. c->idx = idx;
  174. c->cap = cfg;
  175. _setup_uidle_ops(&c->ops, c->cap->features);
  176. sde_dbg_reg_register_dump_range(SDE_DBG_NAME, "uidle", c->hw.blk_off,
  177. c->hw.blk_off + c->hw.length, 0);
  178. return c;
  179. }