Lloyd Atkinson | 7715873 | 2016-10-23 13:02:00 -0400 | [diff] [blame] | 1 | /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 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 | |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 13 | #include <linux/iopoll.h> |
| 14 | |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 15 | #include "sde_hw_mdss.h" |
| 16 | #include "sde_hwio.h" |
| 17 | #include "sde_hw_catalog.h" |
| 18 | #include "sde_hw_pingpong.h" |
Lloyd Atkinson | 113aefd | 2016-10-23 13:15:18 -0400 | [diff] [blame] | 19 | #include "sde_dbg.h" |
Lloyd Atkinson | 652e59b | 2017-05-03 11:20:30 -0400 | [diff] [blame] | 20 | #include "sde_kms.h" |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 21 | |
| 22 | #define PP_TEAR_CHECK_EN 0x000 |
| 23 | #define PP_SYNC_CONFIG_VSYNC 0x004 |
| 24 | #define PP_SYNC_CONFIG_HEIGHT 0x008 |
| 25 | #define PP_SYNC_WRCOUNT 0x00C |
| 26 | #define PP_VSYNC_INIT_VAL 0x010 |
| 27 | #define PP_INT_COUNT_VAL 0x014 |
| 28 | #define PP_SYNC_THRESH 0x018 |
| 29 | #define PP_START_POS 0x01C |
| 30 | #define PP_RD_PTR_IRQ 0x020 |
| 31 | #define PP_WR_PTR_IRQ 0x024 |
| 32 | #define PP_OUT_LINE_COUNT 0x028 |
| 33 | #define PP_LINE_COUNT 0x02C |
| 34 | #define PP_AUTOREFRESH_CONFIG 0x030 |
| 35 | |
| 36 | #define PP_FBC_MODE 0x034 |
| 37 | #define PP_FBC_BUDGET_CTL 0x038 |
| 38 | #define PP_FBC_LOSSY_MODE 0x03C |
| 39 | #define PP_DSC_MODE 0x0a0 |
| 40 | #define PP_DCE_DATA_IN_SWAP 0x0ac |
| 41 | #define PP_DCE_DATA_OUT_SWAP 0x0c8 |
| 42 | |
Ping Li | 8430ee1 | 2017-02-24 14:14:44 -0800 | [diff] [blame] | 43 | #define DITHER_DEPTH_MAP_INDEX 9 |
| 44 | static u32 dither_depth_map[DITHER_DEPTH_MAP_INDEX] = { |
| 45 | 0, 0, 0, 0, 0, 1, 2, 3, 3 |
| 46 | }; |
| 47 | |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 48 | static struct sde_pingpong_cfg *_pingpong_offset(enum sde_pingpong pp, |
| 49 | struct sde_mdss_cfg *m, |
| 50 | void __iomem *addr, |
| 51 | struct sde_hw_blk_reg_map *b) |
| 52 | { |
| 53 | int i; |
| 54 | |
| 55 | for (i = 0; i < m->pingpong_count; i++) { |
| 56 | if (pp == m->pingpong[i].id) { |
| 57 | b->base_off = addr; |
| 58 | b->blk_off = m->pingpong[i].base; |
Lloyd Atkinson | 7715873 | 2016-10-23 13:02:00 -0400 | [diff] [blame] | 59 | b->length = m->pingpong[i].len; |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 60 | b->hwversion = m->hwversion; |
Clarence Ip | 4ce5932 | 2016-06-26 22:27:51 -0400 | [diff] [blame] | 61 | b->log_mask = SDE_DBG_MASK_PINGPONG; |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 62 | return &m->pingpong[i]; |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | return ERR_PTR(-EINVAL); |
| 67 | } |
| 68 | |
| 69 | static int sde_hw_pp_setup_te_config(struct sde_hw_pingpong *pp, |
| 70 | struct sde_hw_tear_check *te) |
| 71 | { |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 72 | struct sde_hw_blk_reg_map *c; |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 73 | int cfg; |
| 74 | |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 75 | if (!pp || !te) |
| 76 | return -EINVAL; |
| 77 | c = &pp->hw; |
| 78 | |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 79 | cfg = BIT(19); /*VSYNC_COUNTER_EN */ |
| 80 | if (te->hw_vsync_mode) |
| 81 | cfg |= BIT(20); |
| 82 | |
| 83 | cfg |= te->vsync_count; |
| 84 | |
| 85 | SDE_REG_WRITE(c, PP_SYNC_CONFIG_VSYNC, cfg); |
| 86 | SDE_REG_WRITE(c, PP_SYNC_CONFIG_HEIGHT, te->sync_cfg_height); |
| 87 | SDE_REG_WRITE(c, PP_VSYNC_INIT_VAL, te->vsync_init_val); |
| 88 | SDE_REG_WRITE(c, PP_RD_PTR_IRQ, te->rd_ptr_irq); |
| 89 | SDE_REG_WRITE(c, PP_START_POS, te->start_pos); |
| 90 | SDE_REG_WRITE(c, PP_SYNC_THRESH, |
| 91 | ((te->sync_threshold_continue << 16) | |
| 92 | te->sync_threshold_start)); |
| 93 | SDE_REG_WRITE(c, PP_SYNC_WRCOUNT, |
| 94 | (te->start_pos + te->sync_threshold_start + 1)); |
| 95 | |
| 96 | return 0; |
| 97 | } |
| 98 | |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 99 | static int sde_hw_pp_setup_autorefresh_config(struct sde_hw_pingpong *pp, |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 100 | struct sde_hw_autorefresh *cfg) |
| 101 | { |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 102 | struct sde_hw_blk_reg_map *c; |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 103 | u32 refresh_cfg; |
| 104 | |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 105 | if (!pp || !cfg) |
| 106 | return -EINVAL; |
| 107 | c = &pp->hw; |
| 108 | |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 109 | if (cfg->enable) |
| 110 | refresh_cfg = BIT(31) | cfg->frame_count; |
| 111 | else |
| 112 | refresh_cfg = 0; |
| 113 | |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 114 | SDE_REG_WRITE(c, PP_AUTOREFRESH_CONFIG, refresh_cfg); |
| 115 | SDE_EVT32(pp->idx - PINGPONG_0, refresh_cfg); |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 116 | |
| 117 | return 0; |
| 118 | } |
| 119 | |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 120 | static int sde_hw_pp_get_autorefresh_config(struct sde_hw_pingpong *pp, |
| 121 | struct sde_hw_autorefresh *cfg) |
| 122 | { |
| 123 | struct sde_hw_blk_reg_map *c; |
| 124 | u32 val; |
| 125 | |
| 126 | if (!pp || !cfg) |
| 127 | return -EINVAL; |
| 128 | |
| 129 | c = &pp->hw; |
| 130 | val = SDE_REG_READ(c, PP_AUTOREFRESH_CONFIG); |
| 131 | cfg->enable = (val & BIT(31)) >> 31; |
| 132 | cfg->frame_count = val & 0xffff; |
| 133 | |
| 134 | return 0; |
| 135 | } |
| 136 | |
| 137 | static int sde_hw_pp_poll_timeout_wr_ptr(struct sde_hw_pingpong *pp, |
| 138 | u32 timeout_us) |
| 139 | { |
| 140 | struct sde_hw_blk_reg_map *c; |
| 141 | u32 val; |
| 142 | int rc; |
| 143 | |
| 144 | if (!pp) |
| 145 | return -EINVAL; |
| 146 | |
| 147 | c = &pp->hw; |
| 148 | rc = readl_poll_timeout(c->base_off + c->blk_off + PP_LINE_COUNT, |
| 149 | val, (val & 0xffff) >= 1, 10, timeout_us); |
| 150 | |
| 151 | return rc; |
| 152 | } |
| 153 | |
| 154 | static void sde_hw_pp_dsc_enable(struct sde_hw_pingpong *pp) |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 155 | { |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 156 | struct sde_hw_blk_reg_map *c; |
| 157 | |
| 158 | if (!pp) |
| 159 | return; |
| 160 | c = &pp->hw; |
Jeykumar Sankaran | 5c2f070 | 2017-03-09 18:03:15 -0800 | [diff] [blame] | 161 | |
| 162 | SDE_REG_WRITE(c, PP_DSC_MODE, 1); |
| 163 | } |
| 164 | |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 165 | static void sde_hw_pp_dsc_disable(struct sde_hw_pingpong *pp) |
Jeykumar Sankaran | 5c2f070 | 2017-03-09 18:03:15 -0800 | [diff] [blame] | 166 | { |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 167 | struct sde_hw_blk_reg_map *c; |
Ingrid Gallardo | 2a2befb | 2017-08-07 15:02:51 -0700 | [diff] [blame] | 168 | u32 data; |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 169 | |
| 170 | if (!pp) |
| 171 | return; |
| 172 | c = &pp->hw; |
Jeykumar Sankaran | 5c2f070 | 2017-03-09 18:03:15 -0800 | [diff] [blame] | 173 | |
Ingrid Gallardo | 2a2befb | 2017-08-07 15:02:51 -0700 | [diff] [blame] | 174 | data = SDE_REG_READ(c, PP_DCE_DATA_OUT_SWAP); |
| 175 | data &= ~BIT(18); /* disable endian flip */ |
| 176 | SDE_REG_WRITE(c, PP_DCE_DATA_OUT_SWAP, data); |
| 177 | |
Jeykumar Sankaran | 5c2f070 | 2017-03-09 18:03:15 -0800 | [diff] [blame] | 178 | SDE_REG_WRITE(c, PP_DSC_MODE, 0); |
| 179 | } |
| 180 | |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 181 | static int sde_hw_pp_setup_dsc(struct sde_hw_pingpong *pp) |
Jeykumar Sankaran | 5c2f070 | 2017-03-09 18:03:15 -0800 | [diff] [blame] | 182 | { |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 183 | struct sde_hw_blk_reg_map *c; |
Jeykumar Sankaran | 5c2f070 | 2017-03-09 18:03:15 -0800 | [diff] [blame] | 184 | int data; |
| 185 | |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 186 | if (!pp) |
| 187 | return -EINVAL; |
| 188 | c = &pp->hw; |
| 189 | |
| 190 | data = SDE_REG_READ(c, PP_DCE_DATA_OUT_SWAP); |
Jeykumar Sankaran | 5c2f070 | 2017-03-09 18:03:15 -0800 | [diff] [blame] | 191 | data |= BIT(18); /* endian flip */ |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 192 | SDE_REG_WRITE(c, PP_DCE_DATA_OUT_SWAP, data); |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 193 | return 0; |
| 194 | } |
Jeykumar Sankaran | 5c2f070 | 2017-03-09 18:03:15 -0800 | [diff] [blame] | 195 | |
Ping Li | 8430ee1 | 2017-02-24 14:14:44 -0800 | [diff] [blame] | 196 | static int sde_hw_pp_setup_dither_v1(struct sde_hw_pingpong *pp, |
| 197 | void *cfg, size_t len) |
| 198 | { |
| 199 | struct sde_hw_blk_reg_map *c; |
| 200 | struct drm_msm_dither *dither = (struct drm_msm_dither *)cfg; |
| 201 | u32 base = 0, offset = 0, data = 0, i = 0; |
| 202 | |
| 203 | if (!pp) |
| 204 | return -EINVAL; |
| 205 | |
| 206 | c = &pp->hw; |
| 207 | base = pp->caps->sblk->dither.base; |
| 208 | if (!dither) { |
| 209 | /* dither property disable case */ |
| 210 | SDE_REG_WRITE(c, base, 0); |
| 211 | return 0; |
| 212 | } |
| 213 | |
| 214 | if (len != sizeof(struct drm_msm_dither)) { |
| 215 | DRM_ERROR("input len %zu, expected len %zu\n", len, |
| 216 | sizeof(struct drm_msm_dither)); |
| 217 | return -EINVAL; |
| 218 | } |
| 219 | |
| 220 | if (dither->c0_bitdepth >= DITHER_DEPTH_MAP_INDEX || |
| 221 | dither->c1_bitdepth >= DITHER_DEPTH_MAP_INDEX || |
| 222 | dither->c2_bitdepth >= DITHER_DEPTH_MAP_INDEX || |
| 223 | dither->c3_bitdepth >= DITHER_DEPTH_MAP_INDEX) |
| 224 | return -EINVAL; |
| 225 | |
| 226 | offset += 4; |
| 227 | data = dither_depth_map[dither->c0_bitdepth] & REG_MASK(2); |
| 228 | data |= (dither_depth_map[dither->c1_bitdepth] & REG_MASK(2)) << 2; |
| 229 | data |= (dither_depth_map[dither->c2_bitdepth] & REG_MASK(2)) << 4; |
| 230 | data |= (dither_depth_map[dither->c3_bitdepth] & REG_MASK(2)) << 6; |
| 231 | data |= (dither->temporal_en) ? (1 << 8) : 0; |
| 232 | SDE_REG_WRITE(c, base + offset, data); |
| 233 | |
| 234 | for (i = 0; i < DITHER_MATRIX_SZ - 3; i += 4) { |
| 235 | offset += 4; |
| 236 | data = (dither->matrix[i] & REG_MASK(4)) | |
| 237 | ((dither->matrix[i + 1] & REG_MASK(4)) << 4) | |
| 238 | ((dither->matrix[i + 2] & REG_MASK(4)) << 8) | |
| 239 | ((dither->matrix[i + 3] & REG_MASK(4)) << 12); |
| 240 | SDE_REG_WRITE(c, base + offset, data); |
| 241 | } |
| 242 | SDE_REG_WRITE(c, base, 1); |
| 243 | |
| 244 | return 0; |
| 245 | } |
| 246 | |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 247 | static int sde_hw_pp_enable_te(struct sde_hw_pingpong *pp, bool enable) |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 248 | { |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 249 | struct sde_hw_blk_reg_map *c; |
| 250 | |
| 251 | if (!pp) |
| 252 | return -EINVAL; |
| 253 | c = &pp->hw; |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 254 | |
| 255 | SDE_REG_WRITE(c, PP_TEAR_CHECK_EN, enable); |
| 256 | return 0; |
| 257 | } |
| 258 | |
Dhaval Patel | ac65103 | 2017-08-11 14:06:19 -0700 | [diff] [blame] | 259 | static int sde_hw_pp_connect_external_te(struct sde_hw_pingpong *pp, |
| 260 | bool enable_external_te) |
| 261 | { |
| 262 | struct sde_hw_blk_reg_map *c = &pp->hw; |
| 263 | u32 cfg; |
| 264 | int orig; |
| 265 | |
| 266 | if (!pp) |
| 267 | return -EINVAL; |
| 268 | |
| 269 | c = &pp->hw; |
| 270 | cfg = SDE_REG_READ(c, PP_SYNC_CONFIG_VSYNC); |
| 271 | orig = (bool)(cfg & BIT(20)); |
| 272 | if (enable_external_te) |
| 273 | cfg |= BIT(20); |
| 274 | else |
| 275 | cfg &= ~BIT(20); |
| 276 | SDE_REG_WRITE(c, PP_SYNC_CONFIG_VSYNC, cfg); |
| 277 | SDE_EVT32(pp->idx - PINGPONG_0, cfg); |
| 278 | |
| 279 | return orig; |
| 280 | } |
| 281 | |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 282 | static int sde_hw_pp_get_vsync_info(struct sde_hw_pingpong *pp, |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 283 | struct sde_hw_pp_vsync_info *info) |
| 284 | { |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 285 | struct sde_hw_blk_reg_map *c; |
Lloyd Atkinson | 3127a09 | 2016-05-30 13:46:55 -0400 | [diff] [blame] | 286 | u32 val; |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 287 | |
Lloyd Atkinson | 6a5359d | 2017-06-21 10:18:08 -0400 | [diff] [blame] | 288 | if (!pp || !info) |
| 289 | return -EINVAL; |
| 290 | c = &pp->hw; |
| 291 | |
Lloyd Atkinson | 3127a09 | 2016-05-30 13:46:55 -0400 | [diff] [blame] | 292 | val = SDE_REG_READ(c, PP_VSYNC_INIT_VAL); |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 293 | info->rd_ptr_init_val = val & 0xffff; |
Lloyd Atkinson | 3127a09 | 2016-05-30 13:46:55 -0400 | [diff] [blame] | 294 | |
| 295 | val = SDE_REG_READ(c, PP_INT_COUNT_VAL); |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 296 | info->rd_ptr_frame_count = (val & 0xffff0000) >> 16; |
| 297 | info->rd_ptr_line_count = val & 0xffff; |
| 298 | |
| 299 | val = SDE_REG_READ(c, PP_LINE_COUNT); |
| 300 | info->wr_ptr_line_count = val & 0xffff; |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 301 | |
| 302 | return 0; |
| 303 | } |
| 304 | |
Benjamin Chan | 9cd866d | 2017-08-15 14:56:34 -0400 | [diff] [blame] | 305 | static u32 sde_hw_pp_get_line_count(struct sde_hw_pingpong *pp) |
| 306 | { |
| 307 | struct sde_hw_blk_reg_map *c = &pp->hw; |
| 308 | u32 height, init; |
| 309 | u32 line = 0xFFFF; |
| 310 | |
| 311 | if (!pp) |
| 312 | return 0; |
| 313 | c = &pp->hw; |
| 314 | |
| 315 | init = SDE_REG_READ(c, PP_VSYNC_INIT_VAL) & 0xFFFF; |
| 316 | height = SDE_REG_READ(c, PP_SYNC_CONFIG_HEIGHT) & 0xFFFF; |
| 317 | |
| 318 | if (height < init) |
| 319 | goto line_count_exit; |
| 320 | |
| 321 | line = SDE_REG_READ(c, PP_INT_COUNT_VAL) & 0xFFFF; |
| 322 | |
| 323 | if (line < init) |
| 324 | line += (0xFFFF - init); |
| 325 | else |
| 326 | line -= init; |
| 327 | |
| 328 | line_count_exit: |
| 329 | return line; |
| 330 | } |
| 331 | |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 332 | static void _setup_pingpong_ops(struct sde_hw_pingpong_ops *ops, |
Ping Li | 8430ee1 | 2017-02-24 14:14:44 -0800 | [diff] [blame] | 333 | const struct sde_pingpong_cfg *hw_cap) |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 334 | { |
Ping Li | 8430ee1 | 2017-02-24 14:14:44 -0800 | [diff] [blame] | 335 | u32 version = 0; |
| 336 | |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 337 | ops->setup_tearcheck = sde_hw_pp_setup_te_config; |
| 338 | ops->enable_tearcheck = sde_hw_pp_enable_te; |
Dhaval Patel | ac65103 | 2017-08-11 14:06:19 -0700 | [diff] [blame] | 339 | ops->connect_external_te = sde_hw_pp_connect_external_te; |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 340 | ops->get_vsync_info = sde_hw_pp_get_vsync_info; |
| 341 | ops->setup_autorefresh = sde_hw_pp_setup_autorefresh_config; |
Jeykumar Sankaran | 5c2f070 | 2017-03-09 18:03:15 -0800 | [diff] [blame] | 342 | ops->setup_dsc = sde_hw_pp_setup_dsc; |
| 343 | ops->enable_dsc = sde_hw_pp_dsc_enable; |
| 344 | ops->disable_dsc = sde_hw_pp_dsc_disable; |
Lloyd Atkinson | 45da92f | 2017-02-28 14:34:51 -0500 | [diff] [blame] | 345 | ops->get_autorefresh = sde_hw_pp_get_autorefresh_config; |
| 346 | ops->poll_timeout_wr_ptr = sde_hw_pp_poll_timeout_wr_ptr; |
Benjamin Chan | 9cd866d | 2017-08-15 14:56:34 -0400 | [diff] [blame] | 347 | ops->get_line_count = sde_hw_pp_get_line_count; |
Ping Li | 8430ee1 | 2017-02-24 14:14:44 -0800 | [diff] [blame] | 348 | |
| 349 | version = SDE_COLOR_PROCESS_MAJOR(hw_cap->sblk->dither.version); |
| 350 | switch (version) { |
| 351 | case 1: |
| 352 | ops->setup_dither = sde_hw_pp_setup_dither_v1; |
| 353 | break; |
| 354 | default: |
| 355 | ops->setup_dither = NULL; |
| 356 | break; |
| 357 | } |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 358 | }; |
| 359 | |
Shashank Babu Chinta Venkata | 5d641d4 | 2017-09-29 12:16:28 -0700 | [diff] [blame] | 360 | #define MDP_PP_DSC_OFFSET(index) (0x71000 + (0x800 * index) + 0x0a0) |
| 361 | #define MDP_PP_AUTOREFRESH_OFFSET(index) (0x71000 + (0x800 * index) + 0x030) |
| 362 | |
| 363 | int sde_get_pp_dsc_for_cont_splash(void __iomem *mmio, |
| 364 | int max_dsc_cnt, u8 *dsc_ids) |
| 365 | { |
| 366 | int index; |
| 367 | int value, dsc_cnt = 0; |
| 368 | |
| 369 | if (!mmio || !dsc_ids) { |
| 370 | SDE_ERROR("invalid input parameters\n"); |
| 371 | return 0; |
| 372 | } |
| 373 | |
| 374 | SDE_DEBUG("max_dsc_cnt = %d\n", max_dsc_cnt); |
| 375 | for (index = 0; index < max_dsc_cnt; index++) { |
| 376 | value = readl_relaxed(mmio |
| 377 | + MDP_PP_DSC_OFFSET(index)); |
| 378 | SDE_DEBUG("DSC[%d]=0x%x\n", |
| 379 | index, value); |
| 380 | SDE_DEBUG("dsc_cnt = %d\n", dsc_cnt); |
| 381 | if (value) { |
| 382 | dsc_ids[dsc_cnt] = index + DSC_0; |
| 383 | dsc_cnt++; |
| 384 | } |
| 385 | value = readl_relaxed(mmio |
| 386 | + MDP_PP_AUTOREFRESH_OFFSET(index)); |
| 387 | SDE_DEBUG("AUTOREFRESH[%d]=0x%x\n", |
| 388 | index, value); |
| 389 | if (value) { |
| 390 | SDE_DEBUG("Disabling autoreferesh\n"); |
| 391 | writel_relaxed(0x0, mmio |
| 392 | + MDP_PP_AUTOREFRESH_OFFSET(index)); |
Chandan Uddaraju | 9bb109a | 2017-10-29 18:08:51 -0700 | [diff] [blame] | 393 | /* |
| 394 | * Wait for one frame update so that auto refresh |
| 395 | * disable is through |
| 396 | */ |
| 397 | usleep_range(16000, 20000); |
Shashank Babu Chinta Venkata | 5d641d4 | 2017-09-29 12:16:28 -0700 | [diff] [blame] | 398 | } |
| 399 | } |
| 400 | return dsc_cnt; |
| 401 | } |
| 402 | |
Lloyd Atkinson | 652e59b | 2017-05-03 11:20:30 -0400 | [diff] [blame] | 403 | static struct sde_hw_blk_ops sde_hw_ops = { |
| 404 | .start = NULL, |
| 405 | .stop = NULL, |
| 406 | }; |
| 407 | |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 408 | struct sde_hw_pingpong *sde_hw_pingpong_init(enum sde_pingpong idx, |
| 409 | void __iomem *addr, |
| 410 | struct sde_mdss_cfg *m) |
| 411 | { |
| 412 | struct sde_hw_pingpong *c; |
| 413 | struct sde_pingpong_cfg *cfg; |
Lloyd Atkinson | 652e59b | 2017-05-03 11:20:30 -0400 | [diff] [blame] | 414 | int rc; |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 415 | |
| 416 | c = kzalloc(sizeof(*c), GFP_KERNEL); |
| 417 | if (!c) |
| 418 | return ERR_PTR(-ENOMEM); |
| 419 | |
| 420 | cfg = _pingpong_offset(idx, m, addr, &c->hw); |
| 421 | if (IS_ERR_OR_NULL(cfg)) { |
| 422 | kfree(c); |
| 423 | return ERR_PTR(-EINVAL); |
| 424 | } |
| 425 | |
| 426 | c->idx = idx; |
Lloyd Atkinson | 4a752fc | 2017-05-19 16:09:17 -0400 | [diff] [blame] | 427 | c->caps = cfg; |
Ping Li | 8430ee1 | 2017-02-24 14:14:44 -0800 | [diff] [blame] | 428 | _setup_pingpong_ops(&c->ops, c->caps); |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 429 | |
Lloyd Atkinson | 652e59b | 2017-05-03 11:20:30 -0400 | [diff] [blame] | 430 | rc = sde_hw_blk_init(&c->base, SDE_HW_BLK_PINGPONG, idx, &sde_hw_ops); |
| 431 | if (rc) { |
| 432 | SDE_ERROR("failed to init hw blk %d\n", rc); |
| 433 | goto blk_init_error; |
| 434 | } |
| 435 | |
Lloyd Atkinson | 113aefd | 2016-10-23 13:15:18 -0400 | [diff] [blame] | 436 | sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name, c->hw.blk_off, |
| 437 | c->hw.blk_off + c->hw.length, c->hw.xin_id); |
| 438 | |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 439 | return c; |
Lloyd Atkinson | 652e59b | 2017-05-03 11:20:30 -0400 | [diff] [blame] | 440 | |
| 441 | blk_init_error: |
| 442 | kzfree(c); |
| 443 | |
| 444 | return ERR_PTR(rc); |
Narendra Muppalla | 1b0b335 | 2015-09-29 10:16:51 -0700 | [diff] [blame] | 445 | } |
| 446 | |
Lloyd Atkinson | 3127a09 | 2016-05-30 13:46:55 -0400 | [diff] [blame] | 447 | void sde_hw_pingpong_destroy(struct sde_hw_pingpong *pp) |
| 448 | { |
Lloyd Atkinson | 652e59b | 2017-05-03 11:20:30 -0400 | [diff] [blame] | 449 | if (pp) |
| 450 | sde_hw_blk_destroy(&pp->base); |
Lloyd Atkinson | 3127a09 | 2016-05-30 13:46:55 -0400 | [diff] [blame] | 451 | kfree(pp); |
| 452 | } |