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

ovly507e.c (5927B)


      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 "ovly.h"
     23#include "atom.h"
     24
     25#include <drm/drm_atomic_helper.h>
     26#include <drm/drm_fourcc.h>
     27#include <drm/drm_plane_helper.h>
     28
     29#include <nvif/cl507e.h>
     30#include <nvif/event.h>
     31#include <nvif/push507c.h>
     32
     33#include <nvhw/class/cl507e.h>
     34
     35int
     36ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
     37{
     38	struct nvif_push *push = wndw->wndw.push;
     39	int ret;
     40
     41	if ((ret = PUSH_WAIT(push, 4)))
     42		return ret;
     43
     44	PUSH_MTHD(push, NV507E, SET_POINT_IN,
     45		  NVVAL(NV507E, SET_POINT_IN, X, asyw->scale.sx) |
     46		  NVVAL(NV507E, SET_POINT_IN, Y, asyw->scale.sy),
     47
     48				SET_SIZE_IN,
     49		  NVVAL(NV507E, SET_SIZE_IN, WIDTH, asyw->scale.sw) |
     50		  NVVAL(NV507E, SET_SIZE_IN, HEIGHT, asyw->scale.sh),
     51
     52				SET_SIZE_OUT,
     53		  NVVAL(NV507E, SET_SIZE_OUT, WIDTH, asyw->scale.dw));
     54	return 0;
     55}
     56
     57static int
     58ovly507e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
     59{
     60	struct nvif_push *push = wndw->wndw.push;
     61	int ret;
     62
     63	if ((ret = PUSH_WAIT(push, 12)))
     64		return ret;
     65
     66	PUSH_MTHD(push, NV507E, SET_PRESENT_CONTROL,
     67		  NVDEF(NV507E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) |
     68		  NVVAL(NV507E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
     69
     70	PUSH_MTHD(push, NV507E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
     71
     72	PUSH_MTHD(push, NV507E, SET_COMPOSITION_CONTROL,
     73		  NVDEF(NV507E, SET_COMPOSITION_CONTROL, MODE, OPAQUE_SUSPEND_BASE));
     74
     75	PUSH_MTHD(push, NV507E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8);
     76
     77	PUSH_MTHD(push, NV507E, SURFACE_SET_SIZE,
     78		  NVVAL(NV507E, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
     79		  NVVAL(NV507E, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
     80
     81				SURFACE_SET_STORAGE,
     82		  NVVAL(NV507E, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
     83		  NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, (asyw->image.pitch[0] >> 8)) |
     84		  NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
     85		  NVVAL(NV507E, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
     86
     87				SURFACE_SET_PARAMS,
     88		  NVVAL(NV507E, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
     89		  NVVAL(NV507E, SURFACE_SET_PARAMS, COLOR_SPACE, asyw->image.colorspace) |
     90		  NVVAL(NV507E, SURFACE_SET_PARAMS, KIND, asyw->image.kind) |
     91		  NVDEF(NV507E, SURFACE_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256));
     92	return 0;
     93}
     94
     95void
     96ovly507e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
     97		 struct nv50_head_atom *asyh)
     98{
     99	asyh->ovly.cpp = 0;
    100}
    101
    102int
    103ovly507e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
    104		 struct nv50_head_atom *asyh)
    105{
    106	const struct drm_framebuffer *fb = asyw->state.fb;
    107	int ret;
    108
    109	ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
    110						  DRM_PLANE_HELPER_NO_SCALING,
    111						  DRM_PLANE_HELPER_NO_SCALING,
    112						  true, true);
    113	if (ret)
    114		return ret;
    115
    116	asyh->ovly.cpp = fb->format->cpp[0];
    117	return 0;
    118}
    119
    120#include "nouveau_bo.h"
    121
    122static const struct nv50_wndw_func
    123ovly507e = {
    124	.acquire = ovly507e_acquire,
    125	.release = ovly507e_release,
    126	.ntfy_set = base507c_ntfy_set,
    127	.ntfy_clr = base507c_ntfy_clr,
    128	.ntfy_reset = base507c_ntfy_reset,
    129	.ntfy_wait_begun = base507c_ntfy_wait_begun,
    130	.image_set = ovly507e_image_set,
    131	.image_clr = base507c_image_clr,
    132	.scale_set = ovly507e_scale_set,
    133	.update = base507c_update,
    134};
    135
    136static const u32
    137ovly507e_format[] = {
    138	DRM_FORMAT_YUYV,
    139	DRM_FORMAT_UYVY,
    140	DRM_FORMAT_XRGB8888,
    141	DRM_FORMAT_XRGB1555,
    142	0
    143};
    144
    145int
    146ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
    147	      struct nouveau_drm *drm, int head, s32 oclass, u32 interlock_data,
    148	      struct nv50_wndw **pwndw)
    149{
    150	struct nv50_disp_overlay_channel_dma_v0 args = {
    151		.head = head,
    152	};
    153	struct nv50_disp *disp = nv50_disp(drm->dev);
    154	struct nv50_wndw *wndw;
    155	int ret;
    156
    157	ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_OVERLAY,
    158			     "ovly", head, format, BIT(head),
    159			     NV50_DISP_INTERLOCK_OVLY, interlock_data,
    160			     &wndw);
    161	if (*pwndw = wndw, ret)
    162		return ret;
    163
    164	ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
    165			       &oclass, 0, &args, sizeof(args),
    166			       disp->sync->offset, &wndw->wndw);
    167	if (ret) {
    168		NV_ERROR(drm, "ovly%04x allocation failed: %d\n", oclass, ret);
    169		return ret;
    170	}
    171
    172	ret = nvif_notify_ctor(&wndw->wndw.base.user, "kmsOvlyNtfy",
    173			       wndw->notify.func, false,
    174			       NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT,
    175			       &(struct nvif_notify_uevent_req) {},
    176			       sizeof(struct nvif_notify_uevent_req),
    177			       sizeof(struct nvif_notify_uevent_rep),
    178			       &wndw->notify);
    179	if (ret)
    180		return ret;
    181
    182	wndw->ntfy = NV50_DISP_OVLY_NTFY(wndw->id);
    183	wndw->sema = NV50_DISP_OVLY_SEM0(wndw->id);
    184	wndw->data = 0x00000000;
    185	return 0;
    186}
    187
    188int
    189ovly507e_new(struct nouveau_drm *drm, int head, s32 oclass,
    190	     struct nv50_wndw **pwndw)
    191{
    192	return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass,
    193			     0x00000004 << (head * 8), pwndw);
    194}