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

wndwc37e.c (11332B)


      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/clc37e.h>
     33
     34static int
     35wndwc37e_csc_clr(struct nv50_wndw *wndw)
     36{
     37	return 0;
     38}
     39
     40static int
     41wndwc37e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
     42{
     43	struct nvif_push *push = wndw->wndw.push;
     44	int ret;
     45
     46	if ((ret = PUSH_WAIT(push, 13)))
     47		return ret;
     48
     49	PUSH_MTHD(push, NVC37E, SET_CSC_RED2RED, asyw->csc.matrix, 12);
     50	return 0;
     51}
     52
     53static int
     54wndwc37e_ilut_clr(struct nv50_wndw *wndw)
     55{
     56	struct nvif_push *push = wndw->wndw.push;
     57	int ret;
     58
     59	if ((ret = PUSH_WAIT(push, 2)))
     60		return ret;
     61
     62	PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_INPUT_LUT, 0x00000000);
     63	return 0;
     64}
     65
     66static int
     67wndwc37e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
     68{
     69	struct nvif_push *push = wndw->wndw.push;
     70	int ret;
     71
     72	if ((ret = PUSH_WAIT(push, 4)))
     73		return ret;
     74
     75	PUSH_MTHD(push, NVC37E, SET_CONTROL_INPUT_LUT,
     76		  NVVAL(NVC37E, SET_CONTROL_INPUT_LUT, OUTPUT_MODE, asyw->xlut.i.output_mode) |
     77		  NVVAL(NVC37E, SET_CONTROL_INPUT_LUT, RANGE, asyw->xlut.i.range) |
     78		  NVVAL(NVC37E, SET_CONTROL_INPUT_LUT, SIZE, asyw->xlut.i.size),
     79
     80				SET_OFFSET_INPUT_LUT, asyw->xlut.i.offset >> 8,
     81				SET_CONTEXT_DMA_INPUT_LUT, asyw->xlut.handle);
     82	return 0;
     83}
     84
     85static void
     86wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
     87{
     88	asyw->xlut.i.size = size == 1024 ? NVC37E_SET_CONTROL_INPUT_LUT_SIZE_SIZE_1025 :
     89					   NVC37E_SET_CONTROL_INPUT_LUT_SIZE_SIZE_257;
     90	asyw->xlut.i.range = NVC37E_SET_CONTROL_INPUT_LUT_RANGE_UNITY;
     91	asyw->xlut.i.output_mode = NVC37E_SET_CONTROL_INPUT_LUT_OUTPUT_MODE_INTERPOLATE;
     92	asyw->xlut.i.load = head907d_olut_load;
     93}
     94
     95int
     96wndwc37e_blend_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
     97{
     98	struct nvif_push *push = wndw->wndw.push;
     99	int ret;
    100
    101	if ((ret = PUSH_WAIT(push, 8)))
    102		return ret;
    103
    104	PUSH_MTHD(push, NVC37E, SET_COMPOSITION_CONTROL,
    105		  NVDEF(NVC37E, SET_COMPOSITION_CONTROL, COLOR_KEY_SELECT, DISABLE) |
    106		  NVVAL(NVC37E, SET_COMPOSITION_CONTROL, DEPTH, asyw->blend.depth),
    107
    108				SET_COMPOSITION_CONSTANT_ALPHA,
    109		  NVVAL(NVC37E, SET_COMPOSITION_CONSTANT_ALPHA, K1, asyw->blend.k1) |
    110		  NVVAL(NVC37E, SET_COMPOSITION_CONSTANT_ALPHA, K2, 0),
    111
    112				SET_COMPOSITION_FACTOR_SELECT,
    113		  NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, SRC_COLOR_FACTOR_MATCH_SELECT,
    114							       asyw->blend.src_color) |
    115		  NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, SRC_COLOR_FACTOR_NO_MATCH_SELECT,
    116							       asyw->blend.src_color) |
    117		  NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, DST_COLOR_FACTOR_MATCH_SELECT,
    118							       asyw->blend.dst_color) |
    119		  NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, DST_COLOR_FACTOR_NO_MATCH_SELECT,
    120							       asyw->blend.dst_color),
    121
    122				SET_KEY_ALPHA,
    123		  NVVAL(NVC37E, SET_KEY_ALPHA, MIN, 0x0000) |
    124		  NVVAL(NVC37E, SET_KEY_ALPHA, MAX, 0xffff),
    125
    126				SET_KEY_RED_CR,
    127		  NVVAL(NVC37E, SET_KEY_RED_CR, MIN, 0x0000) |
    128		  NVVAL(NVC37E, SET_KEY_RED_CR, MAX, 0xffff),
    129
    130				SET_KEY_GREEN_Y,
    131		  NVVAL(NVC37E, SET_KEY_GREEN_Y, MIN, 0x0000) |
    132		  NVVAL(NVC37E, SET_KEY_GREEN_Y, MAX, 0xffff),
    133
    134				SET_KEY_BLUE_CB,
    135		  NVVAL(NVC37E, SET_KEY_BLUE_CB, MIN, 0x0000) |
    136		  NVVAL(NVC37E, SET_KEY_BLUE_CB, MAX, 0xffff));
    137	return 0;
    138}
    139
    140int
    141wndwc37e_image_clr(struct nv50_wndw *wndw)
    142{
    143	struct nvif_push *push = wndw->wndw.push;
    144	int ret;
    145
    146	if ((ret = PUSH_WAIT(push, 4)))
    147		return ret;
    148
    149	PUSH_MTHD(push, NVC37E, SET_PRESENT_CONTROL,
    150		  NVVAL(NVC37E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, 0) |
    151		  NVDEF(NVC37E, SET_PRESENT_CONTROL, BEGIN_MODE, NON_TEARING));
    152
    153	PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_ISO(0), 0x00000000);
    154	return 0;
    155}
    156
    157static int
    158wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
    159{
    160	struct nvif_push *push = wndw->wndw.push;
    161	int ret;
    162
    163	if ((ret = PUSH_WAIT(push, 17)))
    164		return ret;
    165
    166	PUSH_MTHD(push, NVC37E, SET_PRESENT_CONTROL,
    167		  NVVAL(NVC37E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) |
    168		  NVVAL(NVC37E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
    169		  NVDEF(NVC37E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE));
    170
    171	PUSH_MTHD(push, NVC37E, SET_SIZE,
    172		  NVVAL(NVC37E, SET_SIZE, WIDTH, asyw->image.w) |
    173		  NVVAL(NVC37E, SET_SIZE, HEIGHT, asyw->image.h),
    174
    175				SET_STORAGE,
    176		  NVVAL(NVC37E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
    177		  NVVAL(NVC37E, SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
    178
    179				SET_PARAMS,
    180		  NVVAL(NVC37E, SET_PARAMS, FORMAT, asyw->image.format) |
    181		  NVVAL(NVC37E, SET_PARAMS, COLOR_SPACE, asyw->image.colorspace) |
    182		  NVDEF(NVC37E, SET_PARAMS, INPUT_RANGE, BYPASS) |
    183		  NVDEF(NVC37E, SET_PARAMS, UNDERREPLICATE, DISABLE) |
    184		  NVDEF(NVC37E, SET_PARAMS, DE_GAMMA, NONE) |
    185		  NVVAL(NVC37E, SET_PARAMS, CSC, asyw->csc.valid) |
    186		  NVDEF(NVC37E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) |
    187		  NVDEF(NVC37E, SET_PARAMS, SWAP_UV, DISABLE),
    188
    189				SET_PLANAR_STORAGE(0),
    190		  NVVAL(NVC37E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) |
    191		  NVVAL(NVC37E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6));
    192
    193	PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_ISO(0), asyw->image.handle, 1);
    194	PUSH_MTHD(push, NVC37E, SET_OFFSET(0), asyw->image.offset[0] >> 8);
    195
    196	PUSH_MTHD(push, NVC37E, SET_POINT_IN(0),
    197		  NVVAL(NVC37E, SET_POINT_IN, X, asyw->state.src_x >> 16) |
    198		  NVVAL(NVC37E, SET_POINT_IN, Y, asyw->state.src_y >> 16));
    199
    200	PUSH_MTHD(push, NVC37E, SET_SIZE_IN,
    201		  NVVAL(NVC37E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) |
    202		  NVVAL(NVC37E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16));
    203
    204	PUSH_MTHD(push, NVC37E, SET_SIZE_OUT,
    205		  NVVAL(NVC37E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) |
    206		  NVVAL(NVC37E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h));
    207	return 0;
    208}
    209
    210int
    211wndwc37e_ntfy_clr(struct nv50_wndw *wndw)
    212{
    213	struct nvif_push *push = wndw->wndw.push;
    214	int ret;
    215
    216	if ((ret = PUSH_WAIT(push, 2)))
    217		return ret;
    218
    219	PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_NOTIFIER, 0x00000000);
    220	return 0;
    221}
    222
    223int
    224wndwc37e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
    225{
    226	struct nvif_push *push = wndw->wndw.push;
    227	int ret;
    228
    229	if ((ret = PUSH_WAIT(push, 3)))
    230		return ret;
    231
    232	PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_NOTIFIER, asyw->ntfy.handle,
    233
    234				SET_NOTIFIER_CONTROL,
    235		  NVVAL(NVC37E, SET_NOTIFIER_CONTROL, MODE, asyw->ntfy.awaken) |
    236		  NVVAL(NVC37E, SET_NOTIFIER_CONTROL, OFFSET, asyw->ntfy.offset >> 4));
    237	return 0;
    238}
    239
    240int
    241wndwc37e_sema_clr(struct nv50_wndw *wndw)
    242{
    243	struct nvif_push *push = wndw->wndw.push;
    244	int ret;
    245
    246	if ((ret = PUSH_WAIT(push, 2)))
    247		return ret;
    248
    249	PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_SEMAPHORE, 0x00000000);
    250	return 0;
    251}
    252
    253int
    254wndwc37e_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
    255{
    256	struct nvif_push *push = wndw->wndw.push;
    257	int ret;
    258
    259	if ((ret = PUSH_WAIT(push, 5)))
    260		return ret;
    261
    262	PUSH_MTHD(push, NVC37E, SET_SEMAPHORE_CONTROL, asyw->sema.offset,
    263				SET_SEMAPHORE_ACQUIRE, asyw->sema.acquire,
    264				SET_SEMAPHORE_RELEASE, asyw->sema.release,
    265				SET_CONTEXT_DMA_SEMAPHORE, asyw->sema.handle);
    266	return 0;
    267}
    268
    269int
    270wndwc37e_update(struct nv50_wndw *wndw, u32 *interlock)
    271{
    272	struct nvif_push *push = wndw->wndw.push;
    273	int ret;
    274
    275	if ((ret = PUSH_WAIT(push, 5)))
    276		return ret;
    277
    278	PUSH_MTHD(push, NVC37E, SET_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_CURS] << 1 |
    279						     interlock[NV50_DISP_INTERLOCK_CORE],
    280				SET_WINDOW_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_WNDW]);
    281
    282	PUSH_MTHD(push, NVC37E, UPDATE, 0x00000001 |
    283		  NVVAL(NVC37E, UPDATE, INTERLOCK_WITH_WIN_IMM,
    284			  !!(interlock[NV50_DISP_INTERLOCK_WIMM] & wndw->interlock.data)));
    285
    286	return PUSH_KICK(push);
    287}
    288
    289void
    290wndwc37e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
    291		 struct nv50_head_atom *asyh)
    292{
    293}
    294
    295int
    296wndwc37e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
    297		 struct nv50_head_atom *asyh)
    298{
    299	return drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
    300						   DRM_PLANE_HELPER_NO_SCALING,
    301						   DRM_PLANE_HELPER_NO_SCALING,
    302						   true, true);
    303}
    304
    305static const u32
    306wndwc37e_format[] = {
    307	DRM_FORMAT_C8,
    308	DRM_FORMAT_YUYV,
    309	DRM_FORMAT_UYVY,
    310	DRM_FORMAT_XRGB8888,
    311	DRM_FORMAT_ARGB8888,
    312	DRM_FORMAT_RGB565,
    313	DRM_FORMAT_XRGB1555,
    314	DRM_FORMAT_ARGB1555,
    315	DRM_FORMAT_XBGR2101010,
    316	DRM_FORMAT_ABGR2101010,
    317	DRM_FORMAT_XBGR8888,
    318	DRM_FORMAT_ABGR8888,
    319	DRM_FORMAT_XRGB2101010,
    320	DRM_FORMAT_ARGB2101010,
    321	DRM_FORMAT_XBGR16161616F,
    322	DRM_FORMAT_ABGR16161616F,
    323	0
    324};
    325
    326static const struct nv50_wndw_func
    327wndwc37e = {
    328	.acquire = wndwc37e_acquire,
    329	.release = wndwc37e_release,
    330	.sema_set = wndwc37e_sema_set,
    331	.sema_clr = wndwc37e_sema_clr,
    332	.ntfy_set = wndwc37e_ntfy_set,
    333	.ntfy_clr = wndwc37e_ntfy_clr,
    334	.ntfy_reset = corec37d_ntfy_init,
    335	.ntfy_wait_begun = base507c_ntfy_wait_begun,
    336	.ilut = wndwc37e_ilut,
    337	.ilut_size = 1024,
    338	.xlut_set = wndwc37e_ilut_set,
    339	.xlut_clr = wndwc37e_ilut_clr,
    340	.csc = base907c_csc,
    341	.csc_set = wndwc37e_csc_set,
    342	.csc_clr = wndwc37e_csc_clr,
    343	.image_set = wndwc37e_image_set,
    344	.image_clr = wndwc37e_image_clr,
    345	.blend_set = wndwc37e_blend_set,
    346	.update = wndwc37e_update,
    347};
    348
    349int
    350wndwc37e_new_(const struct nv50_wndw_func *func, struct nouveau_drm *drm,
    351	      enum drm_plane_type type, int index, s32 oclass, u32 heads,
    352	      struct nv50_wndw **pwndw)
    353{
    354	struct nvc37e_window_channel_dma_v0 args = {
    355		.pushbuf = 0xb0007e00 | index,
    356		.index = index,
    357	};
    358	struct nv50_disp *disp = nv50_disp(drm->dev);
    359	struct nv50_wndw *wndw;
    360	int ret;
    361
    362	ret = nv50_wndw_new_(func, drm->dev, type, "wndw", index,
    363			     wndwc37e_format, heads, NV50_DISP_INTERLOCK_WNDW,
    364			     BIT(index), &wndw);
    365	if (*pwndw = wndw, ret)
    366		return ret;
    367
    368	ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
    369			       &oclass, 0, &args, sizeof(args),
    370			       disp->sync->offset, &wndw->wndw);
    371	if (ret) {
    372		NV_ERROR(drm, "qndw%04x allocation failed: %d\n", oclass, ret);
    373		return ret;
    374	}
    375
    376	wndw->ntfy = NV50_DISP_WNDW_NTFY(wndw->id);
    377	wndw->sema = NV50_DISP_WNDW_SEM0(wndw->id);
    378	wndw->data = 0x00000000;
    379	return 0;
    380}
    381
    382int
    383wndwc37e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
    384	     s32 oclass, struct nv50_wndw **pwndw)
    385{
    386	return wndwc37e_new_(&wndwc37e, drm, type, index, oclass,
    387			     BIT(index >> 1), pwndw);
    388}