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

sorga102.c (4126B)


      1/*
      2 * Copyright 2021 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 "ior.h"
     23
     24#include <subdev/timer.h>
     25
     26static int
     27ga102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
     28{
     29	struct nvkm_device *device = sor->disp->engine.subdev.device;
     30	const u32 soff = nv50_ior_base(sor);
     31	const u32 loff = nv50_sor_link(sor);
     32	u32 dpctrl = 0x00000000;
     33	u32 clksor = 0x00000000;
     34
     35	switch (sor->dp.bw) {
     36	case 0x06: clksor |= 0x00000000; break;
     37	case 0x0a: clksor |= 0x00040000; break;
     38	case 0x14: clksor |= 0x00080000; break;
     39	case 0x1e: clksor |= 0x000c0000; break;
     40	case 0x08: clksor |= 0x00100000; break;
     41	case 0x09: clksor |= 0x00140000; break;
     42	case 0x0c: clksor |= 0x00180000; break;
     43	case 0x10: clksor |= 0x001c0000; break;
     44	default:
     45		WARN_ON(1);
     46		return -EINVAL;
     47	}
     48
     49	dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
     50	if (sor->dp.mst)
     51		dpctrl |= 0x40000000;
     52	if (sor->dp.ef)
     53		dpctrl |= 0x00004000;
     54
     55	nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
     56
     57	/*XXX*/
     58	nvkm_msec(device, 40, NVKM_DELAY);
     59	nvkm_mask(device, 0x612300 + soff, 0x00030000, 0x00010000);
     60	nvkm_mask(device, 0x61c10c + loff, 0x00000003, 0x00000001);
     61
     62	nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
     63	return 0;
     64}
     65
     66static void
     67ga102_sor_clock(struct nvkm_ior *sor)
     68{
     69	struct nvkm_device *device = sor->disp->engine.subdev.device;
     70	u32 div2 = 0;
     71	if (sor->asy.proto == TMDS) {
     72		if (sor->tmds.high_speed)
     73			div2 = 1;
     74	}
     75	nvkm_wr32(device, 0x00ec08 + (sor->id * 0x10), 0x00000000);
     76	nvkm_wr32(device, 0x00ec04 + (sor->id * 0x10), div2);
     77}
     78
     79static const struct nvkm_ior_func
     80ga102_sor_hda = {
     81	.route = {
     82		.get = gm200_sor_route_get,
     83		.set = gm200_sor_route_set,
     84	},
     85	.state = gv100_sor_state,
     86	.power = nv50_sor_power,
     87	.clock = ga102_sor_clock,
     88	.hdmi = {
     89		.ctrl = gv100_hdmi_ctrl,
     90		.scdc = gm200_hdmi_scdc,
     91	},
     92	.dp = {
     93		.lanes = { 0, 1, 2, 3 },
     94		.links = ga102_sor_dp_links,
     95		.power = g94_sor_dp_power,
     96		.pattern = gm107_sor_dp_pattern,
     97		.drive = gm200_sor_dp_drive,
     98		.vcpi = tu102_sor_dp_vcpi,
     99		.audio = gv100_sor_dp_audio,
    100		.audio_sym = gv100_sor_dp_audio_sym,
    101		.watermark = gv100_sor_dp_watermark,
    102	},
    103	.hda = {
    104		.hpd = gf119_hda_hpd,
    105		.eld = gf119_hda_eld,
    106		.device_entry = gv100_hda_device_entry,
    107	},
    108};
    109
    110static const struct nvkm_ior_func
    111ga102_sor = {
    112	.route = {
    113		.get = gm200_sor_route_get,
    114		.set = gm200_sor_route_set,
    115	},
    116	.state = gv100_sor_state,
    117	.power = nv50_sor_power,
    118	.clock = ga102_sor_clock,
    119	.hdmi = {
    120		.ctrl = gv100_hdmi_ctrl,
    121		.scdc = gm200_hdmi_scdc,
    122	},
    123	.dp = {
    124		.lanes = { 0, 1, 2, 3 },
    125		.links = ga102_sor_dp_links,
    126		.power = g94_sor_dp_power,
    127		.pattern = gm107_sor_dp_pattern,
    128		.drive = gm200_sor_dp_drive,
    129		.vcpi = tu102_sor_dp_vcpi,
    130		.audio = gv100_sor_dp_audio,
    131		.audio_sym = gv100_sor_dp_audio_sym,
    132		.watermark = gv100_sor_dp_watermark,
    133	},
    134};
    135
    136int
    137ga102_sor_new(struct nvkm_disp *disp, int id)
    138{
    139	struct nvkm_device *device = disp->engine.subdev.device;
    140	u32 hda = nvkm_rd32(device, 0x08a15c);
    141	if (hda & BIT(id))
    142		return nvkm_ior_new_(&ga102_sor_hda, disp, SOR, id);
    143	return nvkm_ior_new_(&ga102_sor, disp, SOR, id);
    144}