Home | History | Annotate | Line # | Download | only in gvt
      1  1.1  riastrad /*	$NetBSD: mmio_context.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
      5  1.1  riastrad  *
      6  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      7  1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
      8  1.1  riastrad  * to deal in the Software without restriction, including without limitation
      9  1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     11  1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     12  1.1  riastrad  *
     13  1.1  riastrad  * The above copyright notice and this permission notice (including the next
     14  1.1  riastrad  * paragraph) shall be included in all copies or substantial portions of the
     15  1.1  riastrad  * Software.
     16  1.1  riastrad  *
     17  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  1.1  riastrad  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  1.1  riastrad  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  1.1  riastrad  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  1.1  riastrad  * SOFTWARE.
     24  1.1  riastrad  *
     25  1.1  riastrad  * Authors:
     26  1.1  riastrad  *    Eddie Dong <eddie.dong (at) intel.com>
     27  1.1  riastrad  *    Kevin Tian <kevin.tian (at) intel.com>
     28  1.1  riastrad  *
     29  1.1  riastrad  * Contributors:
     30  1.1  riastrad  *    Zhi Wang <zhi.a.wang (at) intel.com>
     31  1.1  riastrad  *    Changbin Du <changbin.du (at) intel.com>
     32  1.1  riastrad  *    Zhenyu Wang <zhenyuw (at) linux.intel.com>
     33  1.1  riastrad  *    Tina Zhang <tina.zhang (at) intel.com>
     34  1.1  riastrad  *    Bing Niu <bing.niu (at) intel.com>
     35  1.1  riastrad  *
     36  1.1  riastrad  */
     37  1.1  riastrad 
     38  1.1  riastrad #include <sys/cdefs.h>
     39  1.1  riastrad __KERNEL_RCSID(0, "$NetBSD: mmio_context.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $");
     40  1.1  riastrad 
     41  1.1  riastrad #include "i915_drv.h"
     42  1.1  riastrad #include "gt/intel_context.h"
     43  1.1  riastrad #include "gt/intel_ring.h"
     44  1.1  riastrad #include "gvt.h"
     45  1.1  riastrad #include "trace.h"
     46  1.1  riastrad 
     47  1.1  riastrad #define GEN9_MOCS_SIZE		64
     48  1.1  riastrad 
     49  1.1  riastrad /* Raw offset is appened to each line for convenience. */
     50  1.1  riastrad static struct engine_mmio gen8_engine_mmio_list[] __cacheline_aligned = {
     51  1.1  riastrad 	{RCS0, GFX_MODE_GEN7, 0xffff, false}, /* 0x229c */
     52  1.1  riastrad 	{RCS0, GEN9_CTX_PREEMPT_REG, 0x0, false}, /* 0x2248 */
     53  1.1  riastrad 	{RCS0, HWSTAM, 0x0, false}, /* 0x2098 */
     54  1.1  riastrad 	{RCS0, INSTPM, 0xffff, true}, /* 0x20c0 */
     55  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 0), 0, false}, /* 0x24d0 */
     56  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 1), 0, false}, /* 0x24d4 */
     57  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 2), 0, false}, /* 0x24d8 */
     58  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 3), 0, false}, /* 0x24dc */
     59  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 4), 0, false}, /* 0x24e0 */
     60  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 5), 0, false}, /* 0x24e4 */
     61  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 6), 0, false}, /* 0x24e8 */
     62  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 7), 0, false}, /* 0x24ec */
     63  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 8), 0, false}, /* 0x24f0 */
     64  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 9), 0, false}, /* 0x24f4 */
     65  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 10), 0, false}, /* 0x24f8 */
     66  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 11), 0, false}, /* 0x24fc */
     67  1.1  riastrad 	{RCS0, CACHE_MODE_1, 0xffff, true}, /* 0x7004 */
     68  1.1  riastrad 	{RCS0, GEN7_GT_MODE, 0xffff, true}, /* 0x7008 */
     69  1.1  riastrad 	{RCS0, CACHE_MODE_0_GEN7, 0xffff, true}, /* 0x7000 */
     70  1.1  riastrad 	{RCS0, GEN7_COMMON_SLICE_CHICKEN1, 0xffff, true}, /* 0x7010 */
     71  1.1  riastrad 	{RCS0, HDC_CHICKEN0, 0xffff, true}, /* 0x7300 */
     72  1.1  riastrad 	{RCS0, VF_GUARDBAND, 0xffff, true}, /* 0x83a4 */
     73  1.1  riastrad 
     74  1.1  riastrad 	{BCS0, RING_GFX_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2229c */
     75  1.1  riastrad 	{BCS0, RING_MI_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2209c */
     76  1.1  riastrad 	{BCS0, RING_INSTPM(BLT_RING_BASE), 0xffff, false}, /* 0x220c0 */
     77  1.1  riastrad 	{BCS0, RING_HWSTAM(BLT_RING_BASE), 0x0, false}, /* 0x22098 */
     78  1.1  riastrad 	{BCS0, RING_EXCC(BLT_RING_BASE), 0xffff, false}, /* 0x22028 */
     79  1.1  riastrad 	{RCS0, INVALID_MMIO_REG, 0, false } /* Terminated */
     80  1.1  riastrad };
     81  1.1  riastrad 
     82  1.1  riastrad static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = {
     83  1.1  riastrad 	{RCS0, GFX_MODE_GEN7, 0xffff, false}, /* 0x229c */
     84  1.1  riastrad 	{RCS0, GEN9_CTX_PREEMPT_REG, 0x0, false}, /* 0x2248 */
     85  1.1  riastrad 	{RCS0, HWSTAM, 0x0, false}, /* 0x2098 */
     86  1.1  riastrad 	{RCS0, INSTPM, 0xffff, true}, /* 0x20c0 */
     87  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 0), 0, false}, /* 0x24d0 */
     88  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 1), 0, false}, /* 0x24d4 */
     89  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 2), 0, false}, /* 0x24d8 */
     90  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 3), 0, false}, /* 0x24dc */
     91  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 4), 0, false}, /* 0x24e0 */
     92  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 5), 0, false}, /* 0x24e4 */
     93  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 6), 0, false}, /* 0x24e8 */
     94  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 7), 0, false}, /* 0x24ec */
     95  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 8), 0, false}, /* 0x24f0 */
     96  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 9), 0, false}, /* 0x24f4 */
     97  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 10), 0, false}, /* 0x24f8 */
     98  1.1  riastrad 	{RCS0, RING_FORCE_TO_NONPRIV(RENDER_RING_BASE, 11), 0, false}, /* 0x24fc */
     99  1.1  riastrad 	{RCS0, CACHE_MODE_1, 0xffff, true}, /* 0x7004 */
    100  1.1  riastrad 	{RCS0, GEN7_GT_MODE, 0xffff, true}, /* 0x7008 */
    101  1.1  riastrad 	{RCS0, CACHE_MODE_0_GEN7, 0xffff, true}, /* 0x7000 */
    102  1.1  riastrad 	{RCS0, GEN7_COMMON_SLICE_CHICKEN1, 0xffff, true}, /* 0x7010 */
    103  1.1  riastrad 	{RCS0, HDC_CHICKEN0, 0xffff, true}, /* 0x7300 */
    104  1.1  riastrad 	{RCS0, VF_GUARDBAND, 0xffff, true}, /* 0x83a4 */
    105  1.1  riastrad 
    106  1.1  riastrad 	{RCS0, GEN8_PRIVATE_PAT_LO, 0, false}, /* 0x40e0 */
    107  1.1  riastrad 	{RCS0, GEN8_PRIVATE_PAT_HI, 0, false}, /* 0x40e4 */
    108  1.1  riastrad 	{RCS0, GEN8_CS_CHICKEN1, 0xffff, true}, /* 0x2580 */
    109  1.1  riastrad 	{RCS0, COMMON_SLICE_CHICKEN2, 0xffff, true}, /* 0x7014 */
    110  1.1  riastrad 	{RCS0, GEN9_CS_DEBUG_MODE1, 0xffff, false}, /* 0x20ec */
    111  1.1  riastrad 	{RCS0, GEN8_L3SQCREG4, 0, false}, /* 0xb118 */
    112  1.1  riastrad 	{RCS0, GEN7_HALF_SLICE_CHICKEN1, 0xffff, true}, /* 0xe100 */
    113  1.1  riastrad 	{RCS0, HALF_SLICE_CHICKEN2, 0xffff, true}, /* 0xe180 */
    114  1.1  riastrad 	{RCS0, HALF_SLICE_CHICKEN3, 0xffff, true}, /* 0xe184 */
    115  1.1  riastrad 	{RCS0, GEN9_HALF_SLICE_CHICKEN5, 0xffff, true}, /* 0xe188 */
    116  1.1  riastrad 	{RCS0, GEN9_HALF_SLICE_CHICKEN7, 0xffff, true}, /* 0xe194 */
    117  1.1  riastrad 	{RCS0, GEN8_ROW_CHICKEN, 0xffff, true}, /* 0xe4f0 */
    118  1.1  riastrad 	{RCS0, TRVATTL3PTRDW(0), 0, true}, /* 0x4de0 */
    119  1.1  riastrad 	{RCS0, TRVATTL3PTRDW(1), 0, true}, /* 0x4de4 */
    120  1.1  riastrad 	{RCS0, TRNULLDETCT, 0, true}, /* 0x4de8 */
    121  1.1  riastrad 	{RCS0, TRINVTILEDETCT, 0, true}, /* 0x4dec */
    122  1.1  riastrad 	{RCS0, TRVADR, 0, true}, /* 0x4df0 */
    123  1.1  riastrad 	{RCS0, TRTTE, 0, true}, /* 0x4df4 */
    124  1.1  riastrad 	{RCS0, _MMIO(0x4dfc), 0, true},
    125  1.1  riastrad 
    126  1.1  riastrad 	{BCS0, RING_GFX_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2229c */
    127  1.1  riastrad 	{BCS0, RING_MI_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2209c */
    128  1.1  riastrad 	{BCS0, RING_INSTPM(BLT_RING_BASE), 0xffff, false}, /* 0x220c0 */
    129  1.1  riastrad 	{BCS0, RING_HWSTAM(BLT_RING_BASE), 0x0, false}, /* 0x22098 */
    130  1.1  riastrad 	{BCS0, RING_EXCC(BLT_RING_BASE), 0xffff, false}, /* 0x22028 */
    131  1.1  riastrad 
    132  1.1  riastrad 	{VCS1, RING_EXCC(GEN8_BSD2_RING_BASE), 0xffff, false}, /* 0x1c028 */
    133  1.1  riastrad 
    134  1.1  riastrad 	{VECS0, RING_EXCC(VEBOX_RING_BASE), 0xffff, false}, /* 0x1a028 */
    135  1.1  riastrad 
    136  1.1  riastrad 	{RCS0, GEN8_HDC_CHICKEN1, 0xffff, true}, /* 0x7304 */
    137  1.1  riastrad 	{RCS0, GEN9_CTX_PREEMPT_REG, 0x0, false}, /* 0x2248 */
    138  1.1  riastrad 	{RCS0, GEN7_UCGCTL4, 0x0, false}, /* 0x940c */
    139  1.1  riastrad 	{RCS0, GAMT_CHKN_BIT_REG, 0x0, false}, /* 0x4ab8 */
    140  1.1  riastrad 
    141  1.1  riastrad 	{RCS0, GEN9_GAMT_ECO_REG_RW_IA, 0x0, false}, /* 0x4ab0 */
    142  1.1  riastrad 	{RCS0, GEN9_CSFE_CHICKEN1_RCS, 0xffff, false}, /* 0x20d4 */
    143  1.1  riastrad 	{RCS0, _MMIO(0x20D8), 0xffff, true}, /* 0x20d8 */
    144  1.1  riastrad 
    145  1.1  riastrad 	{RCS0, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */
    146  1.1  riastrad 	{RCS0, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */
    147  1.1  riastrad 	{RCS0, FF_SLICE_CS_CHICKEN2, 0xffff, false}, /* 0x20e4 */
    148  1.1  riastrad 	{RCS0, INVALID_MMIO_REG, 0, false } /* Terminated */
    149  1.1  riastrad };
    150  1.1  riastrad 
    151  1.1  riastrad static struct {
    152  1.1  riastrad 	bool initialized;
    153  1.1  riastrad 	u32 control_table[I915_NUM_ENGINES][GEN9_MOCS_SIZE];
    154  1.1  riastrad 	u32 l3cc_table[GEN9_MOCS_SIZE / 2];
    155  1.1  riastrad } gen9_render_mocs;
    156  1.1  riastrad 
    157  1.1  riastrad static u32 gen9_mocs_mmio_offset_list[] = {
    158  1.1  riastrad 	[RCS0]  = 0xc800,
    159  1.1  riastrad 	[VCS0]  = 0xc900,
    160  1.1  riastrad 	[VCS1]  = 0xca00,
    161  1.1  riastrad 	[BCS0]  = 0xcc00,
    162  1.1  riastrad 	[VECS0] = 0xcb00,
    163  1.1  riastrad };
    164  1.1  riastrad 
    165  1.1  riastrad static void load_render_mocs(struct drm_i915_private *dev_priv)
    166  1.1  riastrad {
    167  1.1  riastrad 	struct intel_gvt *gvt = dev_priv->gvt;
    168  1.1  riastrad 	i915_reg_t offset;
    169  1.1  riastrad 	u32 cnt = gvt->engine_mmio_list.mocs_mmio_offset_list_cnt;
    170  1.1  riastrad 	u32 *regs = gvt->engine_mmio_list.mocs_mmio_offset_list;
    171  1.1  riastrad 	int ring_id, i;
    172  1.1  riastrad 
    173  1.1  riastrad 	/* Platform doesn't have mocs mmios. */
    174  1.1  riastrad 	if (!regs)
    175  1.1  riastrad 		return;
    176  1.1  riastrad 
    177  1.1  riastrad 	for (ring_id = 0; ring_id < cnt; ring_id++) {
    178  1.1  riastrad 		if (!HAS_ENGINE(dev_priv, ring_id))
    179  1.1  riastrad 			continue;
    180  1.1  riastrad 		offset.reg = regs[ring_id];
    181  1.1  riastrad 		for (i = 0; i < GEN9_MOCS_SIZE; i++) {
    182  1.1  riastrad 			gen9_render_mocs.control_table[ring_id][i] =
    183  1.1  riastrad 				I915_READ_FW(offset);
    184  1.1  riastrad 			offset.reg += 4;
    185  1.1  riastrad 		}
    186  1.1  riastrad 	}
    187  1.1  riastrad 
    188  1.1  riastrad 	offset.reg = 0xb020;
    189  1.1  riastrad 	for (i = 0; i < GEN9_MOCS_SIZE / 2; i++) {
    190  1.1  riastrad 		gen9_render_mocs.l3cc_table[i] =
    191  1.1  riastrad 			I915_READ_FW(offset);
    192  1.1  riastrad 		offset.reg += 4;
    193  1.1  riastrad 	}
    194  1.1  riastrad 	gen9_render_mocs.initialized = true;
    195  1.1  riastrad }
    196  1.1  riastrad 
    197  1.1  riastrad static int
    198  1.1  riastrad restore_context_mmio_for_inhibit(struct intel_vgpu *vgpu,
    199  1.1  riastrad 				 struct i915_request *req)
    200  1.1  riastrad {
    201  1.1  riastrad 	u32 *cs;
    202  1.1  riastrad 	int ret;
    203  1.1  riastrad 	struct engine_mmio *mmio;
    204  1.1  riastrad 	struct intel_gvt *gvt = vgpu->gvt;
    205  1.1  riastrad 	int ring_id = req->engine->id;
    206  1.1  riastrad 	int count = gvt->engine_mmio_list.ctx_mmio_count[ring_id];
    207  1.1  riastrad 
    208  1.1  riastrad 	if (count == 0)
    209  1.1  riastrad 		return 0;
    210  1.1  riastrad 
    211  1.1  riastrad 	ret = req->engine->emit_flush(req, EMIT_BARRIER);
    212  1.1  riastrad 	if (ret)
    213  1.1  riastrad 		return ret;
    214  1.1  riastrad 
    215  1.1  riastrad 	cs = intel_ring_begin(req, count * 2 + 2);
    216  1.1  riastrad 	if (IS_ERR(cs))
    217  1.1  riastrad 		return PTR_ERR(cs);
    218  1.1  riastrad 
    219  1.1  riastrad 	*cs++ = MI_LOAD_REGISTER_IMM(count);
    220  1.1  riastrad 	for (mmio = gvt->engine_mmio_list.mmio;
    221  1.1  riastrad 	     i915_mmio_reg_valid(mmio->reg); mmio++) {
    222  1.1  riastrad 		if (mmio->ring_id != ring_id ||
    223  1.1  riastrad 		    !mmio->in_context)
    224  1.1  riastrad 			continue;
    225  1.1  riastrad 
    226  1.1  riastrad 		*cs++ = i915_mmio_reg_offset(mmio->reg);
    227  1.1  riastrad 		*cs++ = vgpu_vreg_t(vgpu, mmio->reg) |
    228  1.1  riastrad 				(mmio->mask << 16);
    229  1.1  riastrad 		gvt_dbg_core("add lri reg pair 0x%x:0x%x in inhibit ctx, vgpu:%d, rind_id:%d\n",
    230  1.1  riastrad 			      *(cs-2), *(cs-1), vgpu->id, ring_id);
    231  1.1  riastrad 	}
    232  1.1  riastrad 
    233  1.1  riastrad 	*cs++ = MI_NOOP;
    234  1.1  riastrad 	intel_ring_advance(req, cs);
    235  1.1  riastrad 
    236  1.1  riastrad 	ret = req->engine->emit_flush(req, EMIT_BARRIER);
    237  1.1  riastrad 	if (ret)
    238  1.1  riastrad 		return ret;
    239  1.1  riastrad 
    240  1.1  riastrad 	return 0;
    241  1.1  riastrad }
    242  1.1  riastrad 
    243  1.1  riastrad static int
    244  1.1  riastrad restore_render_mocs_control_for_inhibit(struct intel_vgpu *vgpu,
    245  1.1  riastrad 					struct i915_request *req)
    246  1.1  riastrad {
    247  1.1  riastrad 	unsigned int index;
    248  1.1  riastrad 	u32 *cs;
    249  1.1  riastrad 
    250  1.1  riastrad 	cs = intel_ring_begin(req, 2 * GEN9_MOCS_SIZE + 2);
    251  1.1  riastrad 	if (IS_ERR(cs))
    252  1.1  riastrad 		return PTR_ERR(cs);
    253  1.1  riastrad 
    254  1.1  riastrad 	*cs++ = MI_LOAD_REGISTER_IMM(GEN9_MOCS_SIZE);
    255  1.1  riastrad 
    256  1.1  riastrad 	for (index = 0; index < GEN9_MOCS_SIZE; index++) {
    257  1.1  riastrad 		*cs++ = i915_mmio_reg_offset(GEN9_GFX_MOCS(index));
    258  1.1  riastrad 		*cs++ = vgpu_vreg_t(vgpu, GEN9_GFX_MOCS(index));
    259  1.1  riastrad 		gvt_dbg_core("add lri reg pair 0x%x:0x%x in inhibit ctx, vgpu:%d, rind_id:%d\n",
    260  1.1  riastrad 			      *(cs-2), *(cs-1), vgpu->id, req->engine->id);
    261  1.1  riastrad 
    262  1.1  riastrad 	}
    263  1.1  riastrad 
    264  1.1  riastrad 	*cs++ = MI_NOOP;
    265  1.1  riastrad 	intel_ring_advance(req, cs);
    266  1.1  riastrad 
    267  1.1  riastrad 	return 0;
    268  1.1  riastrad }
    269  1.1  riastrad 
    270  1.1  riastrad static int
    271  1.1  riastrad restore_render_mocs_l3cc_for_inhibit(struct intel_vgpu *vgpu,
    272  1.1  riastrad 				     struct i915_request *req)
    273  1.1  riastrad {
    274  1.1  riastrad 	unsigned int index;
    275  1.1  riastrad 	u32 *cs;
    276  1.1  riastrad 
    277  1.1  riastrad 	cs = intel_ring_begin(req, 2 * GEN9_MOCS_SIZE / 2 + 2);
    278  1.1  riastrad 	if (IS_ERR(cs))
    279  1.1  riastrad 		return PTR_ERR(cs);
    280  1.1  riastrad 
    281  1.1  riastrad 	*cs++ = MI_LOAD_REGISTER_IMM(GEN9_MOCS_SIZE / 2);
    282  1.1  riastrad 
    283  1.1  riastrad 	for (index = 0; index < GEN9_MOCS_SIZE / 2; index++) {
    284  1.1  riastrad 		*cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(index));
    285  1.1  riastrad 		*cs++ = vgpu_vreg_t(vgpu, GEN9_LNCFCMOCS(index));
    286  1.1  riastrad 		gvt_dbg_core("add lri reg pair 0x%x:0x%x in inhibit ctx, vgpu:%d, rind_id:%d\n",
    287  1.1  riastrad 			      *(cs-2), *(cs-1), vgpu->id, req->engine->id);
    288  1.1  riastrad 
    289  1.1  riastrad 	}
    290  1.1  riastrad 
    291  1.1  riastrad 	*cs++ = MI_NOOP;
    292  1.1  riastrad 	intel_ring_advance(req, cs);
    293  1.1  riastrad 
    294  1.1  riastrad 	return 0;
    295  1.1  riastrad }
    296  1.1  riastrad 
    297  1.1  riastrad /*
    298  1.1  riastrad  * Use lri command to initialize the mmio which is in context state image for
    299  1.1  riastrad  * inhibit context, it contains tracked engine mmio, render_mocs and
    300  1.1  riastrad  * render_mocs_l3cc.
    301  1.1  riastrad  */
    302  1.1  riastrad int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu,
    303  1.1  riastrad 				       struct i915_request *req)
    304  1.1  riastrad {
    305  1.1  riastrad 	int ret;
    306  1.1  riastrad 	u32 *cs;
    307  1.1  riastrad 
    308  1.1  riastrad 	cs = intel_ring_begin(req, 2);
    309  1.1  riastrad 	if (IS_ERR(cs))
    310  1.1  riastrad 		return PTR_ERR(cs);
    311  1.1  riastrad 
    312  1.1  riastrad 	*cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE;
    313  1.1  riastrad 	*cs++ = MI_NOOP;
    314  1.1  riastrad 	intel_ring_advance(req, cs);
    315  1.1  riastrad 
    316  1.1  riastrad 	ret = restore_context_mmio_for_inhibit(vgpu, req);
    317  1.1  riastrad 	if (ret)
    318  1.1  riastrad 		goto out;
    319  1.1  riastrad 
    320  1.1  riastrad 	/* no MOCS register in context except render engine */
    321  1.1  riastrad 	if (req->engine->id != RCS0)
    322  1.1  riastrad 		goto out;
    323  1.1  riastrad 
    324  1.1  riastrad 	ret = restore_render_mocs_control_for_inhibit(vgpu, req);
    325  1.1  riastrad 	if (ret)
    326  1.1  riastrad 		goto out;
    327  1.1  riastrad 
    328  1.1  riastrad 	ret = restore_render_mocs_l3cc_for_inhibit(vgpu, req);
    329  1.1  riastrad 	if (ret)
    330  1.1  riastrad 		goto out;
    331  1.1  riastrad 
    332  1.1  riastrad out:
    333  1.1  riastrad 	cs = intel_ring_begin(req, 2);
    334  1.1  riastrad 	if (IS_ERR(cs))
    335  1.1  riastrad 		return PTR_ERR(cs);
    336  1.1  riastrad 
    337  1.1  riastrad 	*cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
    338  1.1  riastrad 	*cs++ = MI_NOOP;
    339  1.1  riastrad 	intel_ring_advance(req, cs);
    340  1.1  riastrad 
    341  1.1  riastrad 	return ret;
    342  1.1  riastrad }
    343  1.1  riastrad 
    344  1.1  riastrad static u32 gen8_tlb_mmio_offset_list[] = {
    345  1.1  riastrad 	[RCS0]  = 0x4260,
    346  1.1  riastrad 	[VCS0]  = 0x4264,
    347  1.1  riastrad 	[VCS1]  = 0x4268,
    348  1.1  riastrad 	[BCS0]  = 0x426c,
    349  1.1  riastrad 	[VECS0] = 0x4270,
    350  1.1  riastrad };
    351  1.1  riastrad 
    352  1.1  riastrad static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
    353  1.1  riastrad {
    354  1.1  riastrad 	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
    355  1.1  riastrad 	struct intel_uncore *uncore = &dev_priv->uncore;
    356  1.1  riastrad 	struct intel_vgpu_submission *s = &vgpu->submission;
    357  1.1  riastrad 	u32 *regs = vgpu->gvt->engine_mmio_list.tlb_mmio_offset_list;
    358  1.1  riastrad 	u32 cnt = vgpu->gvt->engine_mmio_list.tlb_mmio_offset_list_cnt;
    359  1.1  riastrad 	enum forcewake_domains fw;
    360  1.1  riastrad 	i915_reg_t reg;
    361  1.1  riastrad 
    362  1.1  riastrad 	if (!regs)
    363  1.1  riastrad 		return;
    364  1.1  riastrad 
    365  1.1  riastrad 	if (WARN_ON(ring_id >= cnt))
    366  1.1  riastrad 		return;
    367  1.1  riastrad 
    368  1.1  riastrad 	if (!test_and_clear_bit(ring_id, (void *)s->tlb_handle_pending))
    369  1.1  riastrad 		return;
    370  1.1  riastrad 
    371  1.1  riastrad 	reg = _MMIO(regs[ring_id]);
    372  1.1  riastrad 
    373  1.1  riastrad 	/* WaForceWakeRenderDuringMmioTLBInvalidate:skl
    374  1.1  riastrad 	 * we need to put a forcewake when invalidating RCS TLB caches,
    375  1.1  riastrad 	 * otherwise device can go to RC6 state and interrupt invalidation
    376  1.1  riastrad 	 * process
    377  1.1  riastrad 	 */
    378  1.1  riastrad 	fw = intel_uncore_forcewake_for_reg(uncore, reg,
    379  1.1  riastrad 					    FW_REG_READ | FW_REG_WRITE);
    380  1.1  riastrad 	if (ring_id == RCS0 && INTEL_GEN(dev_priv) >= 9)
    381  1.1  riastrad 		fw |= FORCEWAKE_RENDER;
    382  1.1  riastrad 
    383  1.1  riastrad 	intel_uncore_forcewake_get(uncore, fw);
    384  1.1  riastrad 
    385  1.1  riastrad 	intel_uncore_write_fw(uncore, reg, 0x1);
    386  1.1  riastrad 
    387  1.1  riastrad 	if (wait_for_atomic((intel_uncore_read_fw(uncore, reg) == 0), 50))
    388  1.1  riastrad 		gvt_vgpu_err("timeout in invalidate ring (%d) tlb\n", ring_id);
    389  1.1  riastrad 	else
    390  1.1  riastrad 		vgpu_vreg_t(vgpu, reg) = 0;
    391  1.1  riastrad 
    392  1.1  riastrad 	intel_uncore_forcewake_put(uncore, fw);
    393  1.1  riastrad 
    394  1.1  riastrad 	gvt_dbg_core("invalidate TLB for ring %d\n", ring_id);
    395  1.1  riastrad }
    396  1.1  riastrad 
    397  1.1  riastrad static void switch_mocs(struct intel_vgpu *pre, struct intel_vgpu *next,
    398  1.1  riastrad 			int ring_id)
    399  1.1  riastrad {
    400  1.1  riastrad 	struct drm_i915_private *dev_priv;
    401  1.1  riastrad 	i915_reg_t offset, l3_offset;
    402  1.1  riastrad 	u32 old_v, new_v;
    403  1.1  riastrad 
    404  1.1  riastrad 	u32 regs[] = {
    405  1.1  riastrad 		[RCS0]  = 0xc800,
    406  1.1  riastrad 		[VCS0]  = 0xc900,
    407  1.1  riastrad 		[VCS1]  = 0xca00,
    408  1.1  riastrad 		[BCS0]  = 0xcc00,
    409  1.1  riastrad 		[VECS0] = 0xcb00,
    410  1.1  riastrad 	};
    411  1.1  riastrad 	int i;
    412  1.1  riastrad 
    413  1.1  riastrad 	dev_priv = pre ? pre->gvt->dev_priv : next->gvt->dev_priv;
    414  1.1  riastrad 	if (WARN_ON(ring_id >= ARRAY_SIZE(regs)))
    415  1.1  riastrad 		return;
    416  1.1  riastrad 
    417  1.1  riastrad 	if (ring_id == RCS0 && IS_GEN(dev_priv, 9))
    418  1.1  riastrad 		return;
    419  1.1  riastrad 
    420  1.1  riastrad 	if (!pre && !gen9_render_mocs.initialized)
    421  1.1  riastrad 		load_render_mocs(dev_priv);
    422  1.1  riastrad 
    423  1.1  riastrad 	offset.reg = regs[ring_id];
    424  1.1  riastrad 	for (i = 0; i < GEN9_MOCS_SIZE; i++) {
    425  1.1  riastrad 		if (pre)
    426  1.1  riastrad 			old_v = vgpu_vreg_t(pre, offset);
    427  1.1  riastrad 		else
    428  1.1  riastrad 			old_v = gen9_render_mocs.control_table[ring_id][i];
    429  1.1  riastrad 		if (next)
    430  1.1  riastrad 			new_v = vgpu_vreg_t(next, offset);
    431  1.1  riastrad 		else
    432  1.1  riastrad 			new_v = gen9_render_mocs.control_table[ring_id][i];
    433  1.1  riastrad 
    434  1.1  riastrad 		if (old_v != new_v)
    435  1.1  riastrad 			I915_WRITE_FW(offset, new_v);
    436  1.1  riastrad 
    437  1.1  riastrad 		offset.reg += 4;
    438  1.1  riastrad 	}
    439  1.1  riastrad 
    440  1.1  riastrad 	if (ring_id == RCS0) {
    441  1.1  riastrad 		l3_offset.reg = 0xb020;
    442  1.1  riastrad 		for (i = 0; i < GEN9_MOCS_SIZE / 2; i++) {
    443  1.1  riastrad 			if (pre)
    444  1.1  riastrad 				old_v = vgpu_vreg_t(pre, l3_offset);
    445  1.1  riastrad 			else
    446  1.1  riastrad 				old_v = gen9_render_mocs.l3cc_table[i];
    447  1.1  riastrad 			if (next)
    448  1.1  riastrad 				new_v = vgpu_vreg_t(next, l3_offset);
    449  1.1  riastrad 			else
    450  1.1  riastrad 				new_v = gen9_render_mocs.l3cc_table[i];
    451  1.1  riastrad 
    452  1.1  riastrad 			if (old_v != new_v)
    453  1.1  riastrad 				I915_WRITE_FW(l3_offset, new_v);
    454  1.1  riastrad 
    455  1.1  riastrad 			l3_offset.reg += 4;
    456  1.1  riastrad 		}
    457  1.1  riastrad 	}
    458  1.1  riastrad }
    459  1.1  riastrad 
    460  1.1  riastrad #define CTX_CONTEXT_CONTROL_VAL	0x03
    461  1.1  riastrad 
    462  1.1  riastrad bool is_inhibit_context(struct intel_context *ce)
    463  1.1  riastrad {
    464  1.1  riastrad 	const u32 *reg_state = ce->lrc_reg_state;
    465  1.1  riastrad 	u32 inhibit_mask =
    466  1.1  riastrad 		_MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
    467  1.1  riastrad 
    468  1.1  riastrad 	return inhibit_mask ==
    469  1.1  riastrad 		(reg_state[CTX_CONTEXT_CONTROL_VAL] & inhibit_mask);
    470  1.1  riastrad }
    471  1.1  riastrad 
    472  1.1  riastrad /* Switch ring mmio values (context). */
    473  1.1  riastrad static void switch_mmio(struct intel_vgpu *pre,
    474  1.1  riastrad 			struct intel_vgpu *next,
    475  1.1  riastrad 			int ring_id)
    476  1.1  riastrad {
    477  1.1  riastrad 	struct drm_i915_private *dev_priv;
    478  1.1  riastrad 	struct intel_vgpu_submission *s;
    479  1.1  riastrad 	struct engine_mmio *mmio;
    480  1.1  riastrad 	u32 old_v, new_v;
    481  1.1  riastrad 
    482  1.1  riastrad 	dev_priv = pre ? pre->gvt->dev_priv : next->gvt->dev_priv;
    483  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 9)
    484  1.1  riastrad 		switch_mocs(pre, next, ring_id);
    485  1.1  riastrad 
    486  1.1  riastrad 	for (mmio = dev_priv->gvt->engine_mmio_list.mmio;
    487  1.1  riastrad 	     i915_mmio_reg_valid(mmio->reg); mmio++) {
    488  1.1  riastrad 		if (mmio->ring_id != ring_id)
    489  1.1  riastrad 			continue;
    490  1.1  riastrad 		/*
    491  1.1  riastrad 		 * No need to do save or restore of the mmio which is in context
    492  1.1  riastrad 		 * state image on gen9, it's initialized by lri command and
    493  1.1  riastrad 		 * save or restore with context together.
    494  1.1  riastrad 		 */
    495  1.1  riastrad 		if (IS_GEN(dev_priv, 9) && mmio->in_context)
    496  1.1  riastrad 			continue;
    497  1.1  riastrad 
    498  1.1  riastrad 		// save
    499  1.1  riastrad 		if (pre) {
    500  1.1  riastrad 			vgpu_vreg_t(pre, mmio->reg) = I915_READ_FW(mmio->reg);
    501  1.1  riastrad 			if (mmio->mask)
    502  1.1  riastrad 				vgpu_vreg_t(pre, mmio->reg) &=
    503  1.1  riastrad 						~(mmio->mask << 16);
    504  1.1  riastrad 			old_v = vgpu_vreg_t(pre, mmio->reg);
    505  1.1  riastrad 		} else
    506  1.1  riastrad 			old_v = mmio->value = I915_READ_FW(mmio->reg);
    507  1.1  riastrad 
    508  1.1  riastrad 		// restore
    509  1.1  riastrad 		if (next) {
    510  1.1  riastrad 			s = &next->submission;
    511  1.1  riastrad 			/*
    512  1.1  riastrad 			 * No need to restore the mmio which is in context state
    513  1.1  riastrad 			 * image if it's not inhibit context, it will restore
    514  1.1  riastrad 			 * itself.
    515  1.1  riastrad 			 */
    516  1.1  riastrad 			if (mmio->in_context &&
    517  1.1  riastrad 			    !is_inhibit_context(s->shadow[ring_id]))
    518  1.1  riastrad 				continue;
    519  1.1  riastrad 
    520  1.1  riastrad 			if (mmio->mask)
    521  1.1  riastrad 				new_v = vgpu_vreg_t(next, mmio->reg) |
    522  1.1  riastrad 							(mmio->mask << 16);
    523  1.1  riastrad 			else
    524  1.1  riastrad 				new_v = vgpu_vreg_t(next, mmio->reg);
    525  1.1  riastrad 		} else {
    526  1.1  riastrad 			if (mmio->in_context)
    527  1.1  riastrad 				continue;
    528  1.1  riastrad 			if (mmio->mask)
    529  1.1  riastrad 				new_v = mmio->value | (mmio->mask << 16);
    530  1.1  riastrad 			else
    531  1.1  riastrad 				new_v = mmio->value;
    532  1.1  riastrad 		}
    533  1.1  riastrad 
    534  1.1  riastrad 		I915_WRITE_FW(mmio->reg, new_v);
    535  1.1  riastrad 
    536  1.1  riastrad 		trace_render_mmio(pre ? pre->id : 0,
    537  1.1  riastrad 				  next ? next->id : 0,
    538  1.1  riastrad 				  "switch",
    539  1.1  riastrad 				  i915_mmio_reg_offset(mmio->reg),
    540  1.1  riastrad 				  old_v, new_v);
    541  1.1  riastrad 	}
    542  1.1  riastrad 
    543  1.1  riastrad 	if (next)
    544  1.1  riastrad 		handle_tlb_pending_event(next, ring_id);
    545  1.1  riastrad }
    546  1.1  riastrad 
    547  1.1  riastrad /**
    548  1.1  riastrad  * intel_gvt_switch_render_mmio - switch mmio context of specific engine
    549  1.1  riastrad  * @pre: the last vGPU that own the engine
    550  1.1  riastrad  * @next: the vGPU to switch to
    551  1.1  riastrad  * @ring_id: specify the engine
    552  1.1  riastrad  *
    553  1.1  riastrad  * If pre is null indicates that host own the engine. If next is null
    554  1.1  riastrad  * indicates that we are switching to host workload.
    555  1.1  riastrad  */
    556  1.1  riastrad void intel_gvt_switch_mmio(struct intel_vgpu *pre,
    557  1.1  riastrad 			   struct intel_vgpu *next, int ring_id)
    558  1.1  riastrad {
    559  1.1  riastrad 	struct drm_i915_private *dev_priv;
    560  1.1  riastrad 
    561  1.1  riastrad 	if (WARN_ON(!pre && !next))
    562  1.1  riastrad 		return;
    563  1.1  riastrad 
    564  1.1  riastrad 	gvt_dbg_render("switch ring %d from %s to %s\n", ring_id,
    565  1.1  riastrad 		       pre ? "vGPU" : "host", next ? "vGPU" : "HOST");
    566  1.1  riastrad 
    567  1.1  riastrad 	dev_priv = pre ? pre->gvt->dev_priv : next->gvt->dev_priv;
    568  1.1  riastrad 
    569  1.1  riastrad 	/**
    570  1.1  riastrad 	 * We are using raw mmio access wrapper to improve the
    571  1.1  riastrad 	 * performace for batch mmio read/write, so we need
    572  1.1  riastrad 	 * handle forcewake mannually.
    573  1.1  riastrad 	 */
    574  1.1  riastrad 	intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
    575  1.1  riastrad 	switch_mmio(pre, next, ring_id);
    576  1.1  riastrad 	intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
    577  1.1  riastrad }
    578  1.1  riastrad 
    579  1.1  riastrad /**
    580  1.1  riastrad  * intel_gvt_init_engine_mmio_context - Initiate the engine mmio list
    581  1.1  riastrad  * @gvt: GVT device
    582  1.1  riastrad  *
    583  1.1  riastrad  */
    584  1.1  riastrad void intel_gvt_init_engine_mmio_context(struct intel_gvt *gvt)
    585  1.1  riastrad {
    586  1.1  riastrad 	struct engine_mmio *mmio;
    587  1.1  riastrad 
    588  1.1  riastrad 	if (INTEL_GEN(gvt->dev_priv) >= 9) {
    589  1.1  riastrad 		gvt->engine_mmio_list.mmio = gen9_engine_mmio_list;
    590  1.1  riastrad 		gvt->engine_mmio_list.tlb_mmio_offset_list = gen8_tlb_mmio_offset_list;
    591  1.1  riastrad 		gvt->engine_mmio_list.tlb_mmio_offset_list_cnt = ARRAY_SIZE(gen8_tlb_mmio_offset_list);
    592  1.1  riastrad 		gvt->engine_mmio_list.mocs_mmio_offset_list = gen9_mocs_mmio_offset_list;
    593  1.1  riastrad 		gvt->engine_mmio_list.mocs_mmio_offset_list_cnt = ARRAY_SIZE(gen9_mocs_mmio_offset_list);
    594  1.1  riastrad 	} else {
    595  1.1  riastrad 		gvt->engine_mmio_list.mmio = gen8_engine_mmio_list;
    596  1.1  riastrad 		gvt->engine_mmio_list.tlb_mmio_offset_list = gen8_tlb_mmio_offset_list;
    597  1.1  riastrad 		gvt->engine_mmio_list.tlb_mmio_offset_list_cnt = ARRAY_SIZE(gen8_tlb_mmio_offset_list);
    598  1.1  riastrad 	}
    599  1.1  riastrad 
    600  1.1  riastrad 	for (mmio = gvt->engine_mmio_list.mmio;
    601  1.1  riastrad 	     i915_mmio_reg_valid(mmio->reg); mmio++) {
    602  1.1  riastrad 		if (mmio->in_context) {
    603  1.1  riastrad 			gvt->engine_mmio_list.ctx_mmio_count[mmio->ring_id]++;
    604  1.1  riastrad 			intel_gvt_mmio_set_in_ctx(gvt, mmio->reg.reg);
    605  1.1  riastrad 		}
    606  1.1  riastrad 	}
    607  1.1  riastrad }
    608