cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

wndwc57e.c (7851B)


      1/*
      2 * Copyright 2018 Red Hat Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 */
     22#include "wndw.h"
     23#include "atom.h"
     24
     25#include <drm/drm_atomic_helper.h>
     26#include <drm/drm_plane_helper.h>
     27#include <nouveau_bo.h>
     28
     29#include <nvif/clc37e.h>
     30#include <nvif/pushc37b.h>
     31
     32#include <nvhw/class/clc57e.h>
     33
     34static int
     35wndwc57e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
     36{
     37	struct nvif_push *push = wndw->wndw.push;
     38	int ret;
     39
     40	if ((ret = PUSH_WAIT(push, 17)))
     41		return ret;
     42
     43	PUSH_MTHD(push, NVC57E, SET_PRESENT_CONTROL,
     44		  NVVAL(NVC57E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) |
     45		  NVVAL(NVC57E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
     46		  NVDEF(NVC57E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE));
     47
     48	PUSH_MTHD(push, NVC57E, SET_SIZE,
     49		  NVVAL(NVC57E, SET_SIZE, WIDTH, asyw->image.w) |
     50		  NVVAL(NVC57E, SET_SIZE, HEIGHT, asyw->image.h),
     51
     52				SET_STORAGE,
     53		  NVVAL(NVC57E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
     54		  NVVAL(NVC57E, SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
     55
     56				SET_PARAMS,
     57		  NVVAL(NVC57E, SET_PARAMS, FORMAT, asyw->image.format) |
     58		  NVDEF(NVC57E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) |
     59		  NVDEF(NVC57E, SET_PARAMS, SWAP_UV, DISABLE) |
     60		  NVDEF(NVC57E, SET_PARAMS, FMT_ROUNDING_MODE, ROUND_TO_NEAREST),
     61
     62				SET_PLANAR_STORAGE(0),
     63		  NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) |
     64		  NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6));
     65
     66	PUSH_MTHD(push, NVC57E, SET_CONTEXT_DMA_ISO(0), asyw->image.handle, 1);
     67	PUSH_MTHD(push, NVC57E, SET_OFFSET(0), asyw->image.offset[0] >> 8);
     68
     69	PUSH_MTHD(push, NVC57E, SET_POINT_IN(0),
     70		  NVVAL(NVC57E, SET_POINT_IN, X, asyw->state.src_x >> 16) |
     71		  NVVAL(NVC57E, SET_POINT_IN, Y, asyw->state.src_y >> 16));
     72
     73	PUSH_MTHD(push, NVC57E, SET_SIZE_IN,
     74		  NVVAL(NVC57E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) |
     75		  NVVAL(NVC57E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16));
     76
     77	PUSH_MTHD(push, NVC57E, SET_SIZE_OUT,
     78		  NVVAL(NVC57E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) |
     79		  NVVAL(NVC57E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h));
     80	return 0;
     81}
     82
     83int
     84wndwc57e_csc_clr(struct nv50_wndw *wndw)
     85{
     86	struct nvif_push *push = wndw->wndw.push;
     87	const u32 identity[12] = {
     88		0x00010000, 0x00000000, 0x00000000, 0x00000000,
     89		0x00000000, 0x00010000, 0x00000000, 0x00000000,
     90		0x00000000, 0x00000000, 0x00010000, 0x00000000,
     91	};
     92	int ret;
     93
     94	if ((ret = PUSH_WAIT(push, 1 + ARRAY_SIZE(identity))))
     95		return ret;
     96
     97	PUSH_MTHD(push, NVC57E, SET_FMT_COEFFICIENT_C00, identity, ARRAY_SIZE(identity));
     98	return 0;
     99}
    100
    101int
    102wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
    103{
    104	struct nvif_push *push = wndw->wndw.push;
    105	int ret;
    106
    107	if ((ret = PUSH_WAIT(push, 13)))
    108		return ret;
    109
    110	PUSH_MTHD(push, NVC57E, SET_FMT_COEFFICIENT_C00, asyw->csc.matrix, 12);
    111	return 0;
    112}
    113
    114int
    115wndwc57e_ilut_clr(struct nv50_wndw *wndw)
    116{
    117	struct nvif_push *push = wndw->wndw.push;
    118	int ret;
    119
    120	if ((ret = PUSH_WAIT(push, 2)))
    121		return ret;
    122
    123	PUSH_MTHD(push, NVC57E, SET_CONTEXT_DMA_ILUT, 0x00000000);
    124	return 0;
    125}
    126
    127int
    128wndwc57e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
    129{
    130	struct nvif_push *push = wndw->wndw.push;
    131	int ret;
    132
    133	if ((ret = PUSH_WAIT(push, 4)))
    134		return ret;
    135
    136	PUSH_MTHD(push, NVC57E, SET_ILUT_CONTROL,
    137		  NVVAL(NVC57E, SET_ILUT_CONTROL, SIZE, asyw->xlut.i.size) |
    138		  NVVAL(NVC57E, SET_ILUT_CONTROL, MODE, asyw->xlut.i.mode) |
    139		  NVVAL(NVC57E, SET_ILUT_CONTROL, INTERPOLATE, asyw->xlut.i.output_mode),
    140
    141				SET_CONTEXT_DMA_ILUT, asyw->xlut.handle,
    142				SET_OFFSET_ILUT, asyw->xlut.i.offset >> 8);
    143	return 0;
    144}
    145
    146static u16
    147fixedU0_16_FP16(u16 fixed)
    148{
    149        int sign = 0, exp = 0, man = 0;
    150        if (fixed) {
    151                while (--exp && !(fixed & 0x8000))
    152                        fixed <<= 1;
    153                man = ((fixed << 1) & 0xffc0) >> 6;
    154                exp += 15;
    155        }
    156        return (sign << 15) | (exp << 10) | man;
    157}
    158
    159static void
    160wndwc57e_ilut_load(struct drm_color_lut *in, int size, void __iomem *mem)
    161{
    162	memset_io(mem, 0x00, 0x20); /* VSS header. */
    163	mem += 0x20;
    164
    165	for (; size--; in++, mem += 0x08) {
    166		u16 r = fixedU0_16_FP16(drm_color_lut_extract(in->  red, 16));
    167		u16 g = fixedU0_16_FP16(drm_color_lut_extract(in->green, 16));
    168		u16 b = fixedU0_16_FP16(drm_color_lut_extract(in-> blue, 16));
    169		writew(r, mem + 0);
    170		writew(g, mem + 2);
    171		writew(b, mem + 4);
    172	}
    173
    174	/* INTERPOLATE modes require a "next" entry to interpolate with,
    175	 * so we replicate the last entry to deal with this for now.
    176	 */
    177	writew(readw(mem - 8), mem + 0);
    178	writew(readw(mem - 6), mem + 2);
    179	writew(readw(mem - 4), mem + 4);
    180}
    181
    182void
    183wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
    184{
    185	if (!size)
    186		size = 1024;
    187
    188	if (size == 256)
    189		asyw->xlut.i.mode = NVC57E_SET_ILUT_CONTROL_MODE_DIRECT8;
    190	else
    191		asyw->xlut.i.mode = NVC57E_SET_ILUT_CONTROL_MODE_DIRECT10;
    192
    193	asyw->xlut.i.size = 4 /* VSS header. */ + size + 1 /* Entries. */;
    194	asyw->xlut.i.output_mode = NVC57E_SET_ILUT_CONTROL_INTERPOLATE_DISABLE;
    195	asyw->xlut.i.load = wndwc57e_ilut_load;
    196}
    197
    198/****************************************************************
    199 *            Log2(block height) ----------------------------+  *
    200 *            Page Kind ----------------------------------+  |  *
    201 *            Gob Height/Page Kind Generation ------+     |  |  *
    202 *                          Sector layout -------+  |     |  |  *
    203 *                          Compression ------+  |  |     |  |  */
    204const u64 wndwc57e_modifiers[] = { /*         |  |  |     |  |  */
    205	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0),
    206	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1),
    207	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2),
    208	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3),
    209	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4),
    210	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5),
    211	DRM_FORMAT_MOD_LINEAR,
    212	DRM_FORMAT_MOD_INVALID
    213};
    214
    215static const struct nv50_wndw_func
    216wndwc57e = {
    217	.acquire = wndwc37e_acquire,
    218	.release = wndwc37e_release,
    219	.sema_set = wndwc37e_sema_set,
    220	.sema_clr = wndwc37e_sema_clr,
    221	.ntfy_set = wndwc37e_ntfy_set,
    222	.ntfy_clr = wndwc37e_ntfy_clr,
    223	.ntfy_reset = corec37d_ntfy_init,
    224	.ntfy_wait_begun = base507c_ntfy_wait_begun,
    225	.ilut = wndwc57e_ilut,
    226	.ilut_identity = true,
    227	.ilut_size = 1024,
    228	.xlut_set = wndwc57e_ilut_set,
    229	.xlut_clr = wndwc57e_ilut_clr,
    230	.csc = base907c_csc,
    231	.csc_set = wndwc57e_csc_set,
    232	.csc_clr = wndwc57e_csc_clr,
    233	.image_set = wndwc57e_image_set,
    234	.image_clr = wndwc37e_image_clr,
    235	.blend_set = wndwc37e_blend_set,
    236	.update = wndwc37e_update,
    237};
    238
    239int
    240wndwc57e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
    241	     s32 oclass, struct nv50_wndw **pwndw)
    242{
    243	return wndwc37e_new_(&wndwc57e, drm, type, index, oclass,
    244			     BIT(index >> 1), pwndw);
    245}