Home | History | Annotate | Line # | Download | only in display
      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