1 1.1 riastrad /* $NetBSD: intel_bw.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad // SPDX-License-Identifier: MIT 4 1.1 riastrad /* 5 1.1 riastrad * Copyright 2019 Intel Corporation 6 1.1 riastrad */ 7 1.1 riastrad 8 1.1 riastrad #include <sys/cdefs.h> 9 1.1 riastrad __KERNEL_RCSID(0, "$NetBSD: intel_bw.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $"); 10 1.1 riastrad 11 1.1 riastrad #include <drm/drm_atomic_state_helper.h> 12 1.1 riastrad 13 1.1 riastrad #include "intel_bw.h" 14 1.1 riastrad #include "intel_display_types.h" 15 1.1 riastrad #include "intel_sideband.h" 16 1.1 riastrad 17 1.1 riastrad /* Parameters for Qclk Geyserville (QGV) */ 18 1.1 riastrad struct intel_qgv_point { 19 1.1 riastrad u16 dclk, t_rp, t_rdpre, t_rc, t_ras, t_rcd; 20 1.1 riastrad }; 21 1.1 riastrad 22 1.1 riastrad struct intel_qgv_info { 23 1.1 riastrad struct intel_qgv_point points[I915_NUM_QGV_POINTS]; 24 1.1 riastrad u8 num_points; 25 1.1 riastrad u8 num_channels; 26 1.1 riastrad u8 t_bl; 27 1.1 riastrad enum intel_dram_type dram_type; 28 1.1 riastrad }; 29 1.1 riastrad 30 1.1 riastrad static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv, 31 1.1 riastrad struct intel_qgv_info *qi) 32 1.1 riastrad { 33 1.1 riastrad u32 val = 0; 34 1.1 riastrad int ret; 35 1.1 riastrad 36 1.1 riastrad ret = sandybridge_pcode_read(dev_priv, 37 1.1 riastrad ICL_PCODE_MEM_SUBSYSYSTEM_INFO | 38 1.1 riastrad ICL_PCODE_MEM_SS_READ_GLOBAL_INFO, 39 1.1 riastrad &val, NULL); 40 1.1 riastrad if (ret) 41 1.1 riastrad return ret; 42 1.1 riastrad 43 1.1 riastrad if (IS_GEN(dev_priv, 12)) { 44 1.1 riastrad switch (val & 0xf) { 45 1.1 riastrad case 0: 46 1.1 riastrad qi->dram_type = INTEL_DRAM_DDR4; 47 1.1 riastrad break; 48 1.1 riastrad case 3: 49 1.1 riastrad qi->dram_type = INTEL_DRAM_LPDDR4; 50 1.1 riastrad break; 51 1.1 riastrad case 4: 52 1.1 riastrad qi->dram_type = INTEL_DRAM_DDR3; 53 1.1 riastrad break; 54 1.1 riastrad case 5: 55 1.1 riastrad qi->dram_type = INTEL_DRAM_LPDDR3; 56 1.1 riastrad break; 57 1.1 riastrad default: 58 1.1 riastrad MISSING_CASE(val & 0xf); 59 1.1 riastrad break; 60 1.1 riastrad } 61 1.1 riastrad } else if (IS_GEN(dev_priv, 11)) { 62 1.1 riastrad switch (val & 0xf) { 63 1.1 riastrad case 0: 64 1.1 riastrad qi->dram_type = INTEL_DRAM_DDR4; 65 1.1 riastrad break; 66 1.1 riastrad case 1: 67 1.1 riastrad qi->dram_type = INTEL_DRAM_DDR3; 68 1.1 riastrad break; 69 1.1 riastrad case 2: 70 1.1 riastrad qi->dram_type = INTEL_DRAM_LPDDR3; 71 1.1 riastrad break; 72 1.1 riastrad case 3: 73 1.1 riastrad qi->dram_type = INTEL_DRAM_LPDDR4; 74 1.1 riastrad break; 75 1.1 riastrad default: 76 1.1 riastrad MISSING_CASE(val & 0xf); 77 1.1 riastrad break; 78 1.1 riastrad } 79 1.1 riastrad } else { 80 1.1 riastrad MISSING_CASE(INTEL_GEN(dev_priv)); 81 1.1 riastrad qi->dram_type = INTEL_DRAM_LPDDR3; /* Conservative default */ 82 1.1 riastrad } 83 1.1 riastrad 84 1.1 riastrad qi->num_channels = (val & 0xf0) >> 4; 85 1.1 riastrad qi->num_points = (val & 0xf00) >> 8; 86 1.1 riastrad 87 1.1 riastrad if (IS_GEN(dev_priv, 12)) 88 1.1 riastrad qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 16; 89 1.1 riastrad else if (IS_GEN(dev_priv, 11)) 90 1.1 riastrad qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 8; 91 1.1 riastrad 92 1.1 riastrad return 0; 93 1.1 riastrad } 94 1.1 riastrad 95 1.1 riastrad static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv, 96 1.1 riastrad struct intel_qgv_point *sp, 97 1.1 riastrad int point) 98 1.1 riastrad { 99 1.1 riastrad u32 val = 0, val2 = 0; 100 1.1 riastrad int ret; 101 1.1 riastrad 102 1.1 riastrad ret = sandybridge_pcode_read(dev_priv, 103 1.1 riastrad ICL_PCODE_MEM_SUBSYSYSTEM_INFO | 104 1.1 riastrad ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), 105 1.1 riastrad &val, &val2); 106 1.1 riastrad if (ret) 107 1.1 riastrad return ret; 108 1.1 riastrad 109 1.1 riastrad sp->dclk = val & 0xffff; 110 1.1 riastrad sp->t_rp = (val & 0xff0000) >> 16; 111 1.1 riastrad sp->t_rcd = (val & 0xff000000) >> 24; 112 1.1 riastrad 113 1.1 riastrad sp->t_rdpre = val2 & 0xff; 114 1.1 riastrad sp->t_ras = (val2 & 0xff00) >> 8; 115 1.1 riastrad 116 1.1 riastrad sp->t_rc = sp->t_rp + sp->t_ras; 117 1.1 riastrad 118 1.1 riastrad return 0; 119 1.1 riastrad } 120 1.1 riastrad 121 1.1 riastrad static int icl_get_qgv_points(struct drm_i915_private *dev_priv, 122 1.1 riastrad struct intel_qgv_info *qi) 123 1.1 riastrad { 124 1.1 riastrad int i, ret; 125 1.1 riastrad 126 1.1 riastrad ret = icl_pcode_read_mem_global_info(dev_priv, qi); 127 1.1 riastrad if (ret) 128 1.1 riastrad return ret; 129 1.1 riastrad 130 1.1 riastrad if (WARN_ON(qi->num_points > ARRAY_SIZE(qi->points))) 131 1.1 riastrad qi->num_points = ARRAY_SIZE(qi->points); 132 1.1 riastrad 133 1.1 riastrad for (i = 0; i < qi->num_points; i++) { 134 1.1 riastrad struct intel_qgv_point *sp = &qi->points[i]; 135 1.1 riastrad 136 1.1 riastrad ret = icl_pcode_read_qgv_point_info(dev_priv, sp, i); 137 1.1 riastrad if (ret) 138 1.1 riastrad return ret; 139 1.1 riastrad 140 1.1 riastrad DRM_DEBUG_KMS("QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n", 141 1.1 riastrad i, sp->dclk, sp->t_rp, sp->t_rdpre, sp->t_ras, 142 1.1 riastrad sp->t_rcd, sp->t_rc); 143 1.1 riastrad } 144 1.1 riastrad 145 1.1 riastrad return 0; 146 1.1 riastrad } 147 1.1 riastrad 148 1.1 riastrad static int icl_calc_bw(int dclk, int num, int den) 149 1.1 riastrad { 150 1.1 riastrad /* multiples of 16.666MHz (100/6) */ 151 1.1 riastrad return DIV_ROUND_CLOSEST(num * dclk * 100, den * 6); 152 1.1 riastrad } 153 1.1 riastrad 154 1.1 riastrad static int icl_sagv_max_dclk(const struct intel_qgv_info *qi) 155 1.1 riastrad { 156 1.1 riastrad u16 dclk = 0; 157 1.1 riastrad int i; 158 1.1 riastrad 159 1.1 riastrad for (i = 0; i < qi->num_points; i++) 160 1.1 riastrad dclk = max(dclk, qi->points[i].dclk); 161 1.1 riastrad 162 1.1 riastrad return dclk; 163 1.1 riastrad } 164 1.1 riastrad 165 1.1 riastrad struct intel_sa_info { 166 1.1 riastrad u16 displayrtids; 167 1.1 riastrad u8 deburst, deprogbwlimit; 168 1.1 riastrad }; 169 1.1 riastrad 170 1.1 riastrad static const struct intel_sa_info icl_sa_info = { 171 1.1 riastrad .deburst = 8, 172 1.1 riastrad .deprogbwlimit = 25, /* GB/s */ 173 1.1 riastrad .displayrtids = 128, 174 1.1 riastrad }; 175 1.1 riastrad 176 1.1 riastrad static const struct intel_sa_info tgl_sa_info = { 177 1.1 riastrad .deburst = 16, 178 1.1 riastrad .deprogbwlimit = 34, /* GB/s */ 179 1.1 riastrad .displayrtids = 256, 180 1.1 riastrad }; 181 1.1 riastrad 182 1.1 riastrad static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa) 183 1.1 riastrad { 184 1.1 riastrad struct intel_qgv_info qi = {}; 185 1.1 riastrad bool is_y_tile = true; /* assume y tile may be used */ 186 1.1 riastrad int num_channels; 187 1.1 riastrad int deinterleave; 188 1.1 riastrad int ipqdepth, ipqdepthpch; 189 1.1 riastrad int dclk_max; 190 1.1 riastrad int maxdebw; 191 1.1 riastrad int i, ret; 192 1.1 riastrad 193 1.1 riastrad ret = icl_get_qgv_points(dev_priv, &qi); 194 1.1 riastrad if (ret) { 195 1.1 riastrad DRM_DEBUG_KMS("Failed to get memory subsystem information, ignoring bandwidth limits"); 196 1.1 riastrad return ret; 197 1.1 riastrad } 198 1.1 riastrad num_channels = qi.num_channels; 199 1.1 riastrad 200 1.1 riastrad deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); 201 1.1 riastrad dclk_max = icl_sagv_max_dclk(&qi); 202 1.1 riastrad 203 1.1 riastrad ipqdepthpch = 16; 204 1.1 riastrad 205 1.1 riastrad maxdebw = min(sa->deprogbwlimit * 1000, 206 1.1 riastrad icl_calc_bw(dclk_max, 16, 1) * 6 / 10); /* 60% */ 207 1.1 riastrad ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels); 208 1.1 riastrad 209 1.1 riastrad for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) { 210 1.1 riastrad struct intel_bw_info *bi = &dev_priv->max_bw[i]; 211 1.1 riastrad int clpchgroup; 212 1.1 riastrad int j; 213 1.1 riastrad 214 1.1 riastrad clpchgroup = (sa->deburst * deinterleave / num_channels) << i; 215 1.1 riastrad bi->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1; 216 1.1 riastrad 217 1.1 riastrad bi->num_qgv_points = qi.num_points; 218 1.1 riastrad 219 1.1 riastrad for (j = 0; j < qi.num_points; j++) { 220 1.1 riastrad const struct intel_qgv_point *sp = &qi.points[j]; 221 1.1 riastrad int ct, bw; 222 1.1 riastrad 223 1.1 riastrad /* 224 1.1 riastrad * Max row cycle time 225 1.1 riastrad * 226 1.1 riastrad * FIXME what is the logic behind the 227 1.1 riastrad * assumed burst length? 228 1.1 riastrad */ 229 1.1 riastrad ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd + 230 1.1 riastrad (clpchgroup - 1) * qi.t_bl + sp->t_rdpre); 231 1.1 riastrad bw = icl_calc_bw(sp->dclk, clpchgroup * 32 * num_channels, ct); 232 1.1 riastrad 233 1.1 riastrad bi->deratedbw[j] = min(maxdebw, 234 1.1 riastrad bw * 9 / 10); /* 90% */ 235 1.1 riastrad 236 1.1 riastrad DRM_DEBUG_KMS("BW%d / QGV %d: num_planes=%d deratedbw=%u\n", 237 1.1 riastrad i, j, bi->num_planes, bi->deratedbw[j]); 238 1.1 riastrad } 239 1.1 riastrad 240 1.1 riastrad if (bi->num_planes == 1) 241 1.1 riastrad break; 242 1.1 riastrad } 243 1.1 riastrad 244 1.1 riastrad return 0; 245 1.1 riastrad } 246 1.1 riastrad 247 1.1 riastrad static unsigned int icl_max_bw(struct drm_i915_private *dev_priv, 248 1.1 riastrad int num_planes, int qgv_point) 249 1.1 riastrad { 250 1.1 riastrad int i; 251 1.1 riastrad 252 1.1 riastrad for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) { 253 1.1 riastrad const struct intel_bw_info *bi = 254 1.1 riastrad &dev_priv->max_bw[i]; 255 1.1 riastrad 256 1.1 riastrad /* 257 1.1 riastrad * Pcode will not expose all QGV points when 258 1.1 riastrad * SAGV is forced to off/min/med/max. 259 1.1 riastrad */ 260 1.1 riastrad if (qgv_point >= bi->num_qgv_points) 261 1.1 riastrad return UINT_MAX; 262 1.1 riastrad 263 1.1 riastrad if (num_planes >= bi->num_planes) 264 1.1 riastrad return bi->deratedbw[qgv_point]; 265 1.1 riastrad } 266 1.1 riastrad 267 1.1 riastrad return 0; 268 1.1 riastrad } 269 1.1 riastrad 270 1.1 riastrad void intel_bw_init_hw(struct drm_i915_private *dev_priv) 271 1.1 riastrad { 272 1.1 riastrad if (!HAS_DISPLAY(dev_priv)) 273 1.1 riastrad return; 274 1.1 riastrad 275 1.1 riastrad if (IS_GEN(dev_priv, 12)) 276 1.1 riastrad icl_get_bw_info(dev_priv, &tgl_sa_info); 277 1.1 riastrad else if (IS_GEN(dev_priv, 11)) 278 1.1 riastrad icl_get_bw_info(dev_priv, &icl_sa_info); 279 1.1 riastrad } 280 1.1 riastrad 281 1.1 riastrad static unsigned int intel_max_data_rate(struct drm_i915_private *dev_priv, 282 1.1 riastrad int num_planes) 283 1.1 riastrad { 284 1.1 riastrad if (INTEL_GEN(dev_priv) >= 11) { 285 1.1 riastrad /* 286 1.1 riastrad * Any bw group has same amount of QGV points 287 1.1 riastrad */ 288 1.1 riastrad const struct intel_bw_info *bi = 289 1.1 riastrad &dev_priv->max_bw[0]; 290 1.1 riastrad unsigned int min_bw = UINT_MAX; 291 1.1 riastrad int i; 292 1.1 riastrad 293 1.1 riastrad /* 294 1.1 riastrad * FIXME with SAGV disabled maybe we can assume 295 1.1 riastrad * point 1 will always be used? Seems to match 296 1.1 riastrad * the behaviour observed in the wild. 297 1.1 riastrad */ 298 1.1 riastrad for (i = 0; i < bi->num_qgv_points; i++) { 299 1.1 riastrad unsigned int bw = icl_max_bw(dev_priv, num_planes, i); 300 1.1 riastrad 301 1.1 riastrad min_bw = min(bw, min_bw); 302 1.1 riastrad } 303 1.1 riastrad return min_bw; 304 1.1 riastrad } else { 305 1.1 riastrad return UINT_MAX; 306 1.1 riastrad } 307 1.1 riastrad } 308 1.1 riastrad 309 1.1 riastrad static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state) 310 1.1 riastrad { 311 1.1 riastrad /* 312 1.1 riastrad * We assume cursors are small enough 313 1.1 riastrad * to not not cause bandwidth problems. 314 1.1 riastrad */ 315 1.1 riastrad return hweight8(crtc_state->active_planes & ~BIT(PLANE_CURSOR)); 316 1.1 riastrad } 317 1.1 riastrad 318 1.1 riastrad static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_state) 319 1.1 riastrad { 320 1.1 riastrad struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 321 1.1 riastrad unsigned int data_rate = 0; 322 1.1 riastrad enum plane_id plane_id; 323 1.1 riastrad 324 1.1 riastrad for_each_plane_id_on_crtc(crtc, plane_id) { 325 1.1 riastrad /* 326 1.1 riastrad * We assume cursors are small enough 327 1.1 riastrad * to not not cause bandwidth problems. 328 1.1 riastrad */ 329 1.1 riastrad if (plane_id == PLANE_CURSOR) 330 1.1 riastrad continue; 331 1.1 riastrad 332 1.1 riastrad data_rate += crtc_state->data_rate[plane_id]; 333 1.1 riastrad } 334 1.1 riastrad 335 1.1 riastrad return data_rate; 336 1.1 riastrad } 337 1.1 riastrad 338 1.1 riastrad void intel_bw_crtc_update(struct intel_bw_state *bw_state, 339 1.1 riastrad const struct intel_crtc_state *crtc_state) 340 1.1 riastrad { 341 1.1 riastrad struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 342 1.1 riastrad 343 1.1 riastrad bw_state->data_rate[crtc->pipe] = 344 1.1 riastrad intel_bw_crtc_data_rate(crtc_state); 345 1.1 riastrad bw_state->num_active_planes[crtc->pipe] = 346 1.1 riastrad intel_bw_crtc_num_active_planes(crtc_state); 347 1.1 riastrad 348 1.1 riastrad DRM_DEBUG_KMS("pipe %c data rate %u num active planes %u\n", 349 1.1 riastrad pipe_name(crtc->pipe), 350 1.1 riastrad bw_state->data_rate[crtc->pipe], 351 1.1 riastrad bw_state->num_active_planes[crtc->pipe]); 352 1.1 riastrad } 353 1.1 riastrad 354 1.1 riastrad static unsigned int intel_bw_num_active_planes(struct drm_i915_private *dev_priv, 355 1.1 riastrad const struct intel_bw_state *bw_state) 356 1.1 riastrad { 357 1.1 riastrad unsigned int num_active_planes = 0; 358 1.1 riastrad enum pipe pipe; 359 1.1 riastrad 360 1.1 riastrad for_each_pipe(dev_priv, pipe) 361 1.1 riastrad num_active_planes += bw_state->num_active_planes[pipe]; 362 1.1 riastrad 363 1.1 riastrad return num_active_planes; 364 1.1 riastrad } 365 1.1 riastrad 366 1.1 riastrad static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv, 367 1.1 riastrad const struct intel_bw_state *bw_state) 368 1.1 riastrad { 369 1.1 riastrad unsigned int data_rate = 0; 370 1.1 riastrad enum pipe pipe; 371 1.1 riastrad 372 1.1 riastrad for_each_pipe(dev_priv, pipe) 373 1.1 riastrad data_rate += bw_state->data_rate[pipe]; 374 1.1 riastrad 375 1.1 riastrad return data_rate; 376 1.1 riastrad } 377 1.1 riastrad 378 1.1 riastrad static struct intel_bw_state * 379 1.1 riastrad intel_atomic_get_bw_state(struct intel_atomic_state *state) 380 1.1 riastrad { 381 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(state->base.dev); 382 1.1 riastrad struct drm_private_state *bw_state; 383 1.1 riastrad 384 1.1 riastrad bw_state = drm_atomic_get_private_obj_state(&state->base, 385 1.1 riastrad &dev_priv->bw_obj); 386 1.1 riastrad if (IS_ERR(bw_state)) 387 1.1 riastrad return ERR_CAST(bw_state); 388 1.1 riastrad 389 1.1 riastrad return to_intel_bw_state(bw_state); 390 1.1 riastrad } 391 1.1 riastrad 392 1.1 riastrad int intel_bw_atomic_check(struct intel_atomic_state *state) 393 1.1 riastrad { 394 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(state->base.dev); 395 1.1 riastrad struct intel_crtc_state *new_crtc_state, *old_crtc_state; 396 1.1 riastrad struct intel_bw_state *bw_state = NULL; 397 1.1 riastrad unsigned int data_rate, max_data_rate; 398 1.1 riastrad unsigned int num_active_planes; 399 1.1 riastrad struct intel_crtc *crtc; 400 1.1 riastrad int i; 401 1.1 riastrad 402 1.1 riastrad /* FIXME earlier gens need some checks too */ 403 1.1 riastrad if (INTEL_GEN(dev_priv) < 11) 404 1.1 riastrad return 0; 405 1.1 riastrad 406 1.1 riastrad for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, 407 1.1 riastrad new_crtc_state, i) { 408 1.1 riastrad unsigned int old_data_rate = 409 1.1 riastrad intel_bw_crtc_data_rate(old_crtc_state); 410 1.1 riastrad unsigned int new_data_rate = 411 1.1 riastrad intel_bw_crtc_data_rate(new_crtc_state); 412 1.1 riastrad unsigned int old_active_planes = 413 1.1 riastrad intel_bw_crtc_num_active_planes(old_crtc_state); 414 1.1 riastrad unsigned int new_active_planes = 415 1.1 riastrad intel_bw_crtc_num_active_planes(new_crtc_state); 416 1.1 riastrad 417 1.1 riastrad /* 418 1.1 riastrad * Avoid locking the bw state when 419 1.1 riastrad * nothing significant has changed. 420 1.1 riastrad */ 421 1.1 riastrad if (old_data_rate == new_data_rate && 422 1.1 riastrad old_active_planes == new_active_planes) 423 1.1 riastrad continue; 424 1.1 riastrad 425 1.1 riastrad bw_state = intel_atomic_get_bw_state(state); 426 1.1 riastrad if (IS_ERR(bw_state)) 427 1.1 riastrad return PTR_ERR(bw_state); 428 1.1 riastrad 429 1.1 riastrad bw_state->data_rate[crtc->pipe] = new_data_rate; 430 1.1 riastrad bw_state->num_active_planes[crtc->pipe] = new_active_planes; 431 1.1 riastrad 432 1.1 riastrad DRM_DEBUG_KMS("pipe %c data rate %u num active planes %u\n", 433 1.1 riastrad pipe_name(crtc->pipe), 434 1.1 riastrad bw_state->data_rate[crtc->pipe], 435 1.1 riastrad bw_state->num_active_planes[crtc->pipe]); 436 1.1 riastrad } 437 1.1 riastrad 438 1.1 riastrad if (!bw_state) 439 1.1 riastrad return 0; 440 1.1 riastrad 441 1.1 riastrad data_rate = intel_bw_data_rate(dev_priv, bw_state); 442 1.1 riastrad num_active_planes = intel_bw_num_active_planes(dev_priv, bw_state); 443 1.1 riastrad 444 1.1 riastrad max_data_rate = intel_max_data_rate(dev_priv, num_active_planes); 445 1.1 riastrad 446 1.1 riastrad data_rate = DIV_ROUND_UP(data_rate, 1000); 447 1.1 riastrad 448 1.1 riastrad if (data_rate > max_data_rate) { 449 1.1 riastrad DRM_DEBUG_KMS("Bandwidth %u MB/s exceeds max available %d MB/s (%d active planes)\n", 450 1.1 riastrad data_rate, max_data_rate, num_active_planes); 451 1.1 riastrad return -EINVAL; 452 1.1 riastrad } 453 1.1 riastrad 454 1.1 riastrad return 0; 455 1.1 riastrad } 456 1.1 riastrad 457 1.1 riastrad static struct drm_private_state *intel_bw_duplicate_state(struct drm_private_obj *obj) 458 1.1 riastrad { 459 1.1 riastrad struct intel_bw_state *state; 460 1.1 riastrad 461 1.1 riastrad state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); 462 1.1 riastrad if (!state) 463 1.1 riastrad return NULL; 464 1.1 riastrad 465 1.1 riastrad __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); 466 1.1 riastrad 467 1.1 riastrad return &state->base; 468 1.1 riastrad } 469 1.1 riastrad 470 1.1 riastrad static void intel_bw_destroy_state(struct drm_private_obj *obj, 471 1.1 riastrad struct drm_private_state *state) 472 1.1 riastrad { 473 1.1 riastrad kfree(state); 474 1.1 riastrad } 475 1.1 riastrad 476 1.1 riastrad static const struct drm_private_state_funcs intel_bw_funcs = { 477 1.1 riastrad .atomic_duplicate_state = intel_bw_duplicate_state, 478 1.1 riastrad .atomic_destroy_state = intel_bw_destroy_state, 479 1.1 riastrad }; 480 1.1 riastrad 481 1.1 riastrad int intel_bw_init(struct drm_i915_private *dev_priv) 482 1.1 riastrad { 483 1.1 riastrad struct intel_bw_state *state; 484 1.1 riastrad 485 1.1 riastrad state = kzalloc(sizeof(*state), GFP_KERNEL); 486 1.1 riastrad if (!state) 487 1.1 riastrad return -ENOMEM; 488 1.1 riastrad 489 1.1 riastrad drm_atomic_private_obj_init(&dev_priv->drm, &dev_priv->bw_obj, 490 1.1 riastrad &state->base, &intel_bw_funcs); 491 1.1 riastrad 492 1.1 riastrad return 0; 493 1.1 riastrad } 494 1.1 riastrad 495 1.1 riastrad void intel_bw_cleanup(struct drm_i915_private *dev_priv) 496 1.1 riastrad { 497 1.1 riastrad drm_atomic_private_obj_fini(&dev_priv->bw_obj); 498 1.1 riastrad } 499