/*
* Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include "priv.h"
#include "chan.h"
#include "hdmi.h"
#include "head.h"
#include "ior.h"
#include <nvif/class .h>
void
gk104_sor_hdmi_infoframe_vsi(struct nvkm_ior *ior, int head, void *data, u32 size)
{
struct nvkm_device *device = ior->disp->engine.subdev.device;
struct packed_hdmi_infoframe vsi;
const u32 hoff = head * 0 x400;
pack_hdmi_infoframe(&vsi, data, size);
/* GENERIC(?) / Vendor InfoFrame? */
nvkm_mask(device, 0 x690100 + hoff, 0 x00010001, 0 x00000000);
if (!size)
return ;
nvkm_wr32(device, 0 x690108 + hoff, vsi.header);
nvkm_wr32(device, 0 x69010c + hoff, vsi.subpack0_low);
nvkm_wr32(device, 0 x690110 + hoff, vsi.subpack0_high);
/* Is there a second (or further?) set of subpack registers here? */
nvkm_mask(device, 0 x690100 + hoff, 0 x00000001, 0 x00000001);
}
void
gk104_sor_hdmi_infoframe_avi(struct nvkm_ior *ior, int head, void *data, u32 size)
{
struct nvkm_device *device = ior->disp->engine.subdev.device;
struct packed_hdmi_infoframe avi;
const u32 hoff = head * 0 x400;
pack_hdmi_infoframe(&avi, data, size);
/* AVI InfoFrame */
nvkm_mask(device, 0 x690000 + hoff, 0 x00000001, 0 x00000000);
if (!size)
return ;
nvkm_wr32(device, 0 x690008 + hoff, avi.header);
nvkm_wr32(device, 0 x69000c + hoff, avi.subpack0_low);
nvkm_wr32(device, 0 x690010 + hoff, avi.subpack0_high);
nvkm_wr32(device, 0 x690014 + hoff, avi.subpack1_low);
nvkm_wr32(device, 0 x690018 + hoff, avi.subpack1_high);
nvkm_mask(device, 0 x690000 + hoff, 0 x00000001, 0 x00000001);
}
void
gk104_sor_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet, u8 rekey)
{
struct nvkm_device *device = ior->disp->engine.subdev.device;
const u32 ctrl = 0 x40000000 * enable |
max_ac_packet << 16 |
rekey;
const u32 hoff = head * 0 x800;
const u32 hdmi = head * 0 x400;
if (!(ctrl & 0 x40000000)) {
nvkm_mask(device, 0 x616798 + hoff, 0 x40000000, 0 x00000000);
nvkm_mask(device, 0 x690100 + hdmi, 0 x00000001, 0 x00000000);
nvkm_mask(device, 0 x6900c0 + hdmi, 0 x00000001, 0 x00000000);
nvkm_mask(device, 0 x690000 + hdmi, 0 x00000001, 0 x00000000);
return ;
}
/* ??? InfoFrame? */
nvkm_mask(device, 0 x6900c0 + hdmi, 0 x00000001, 0 x00000000);
nvkm_wr32(device, 0 x6900cc + hdmi, 0 x00000010);
nvkm_mask(device, 0 x6900c0 + hdmi, 0 x00000001, 0 x00000001);
/* ??? */
nvkm_wr32(device, 0 x690080 + hdmi, 0 x82000000);
/* HDMI_CTRL */
nvkm_mask(device, 0 x616798 + hoff, 0 x401f007f, ctrl);
}
const struct nvkm_ior_func_hdmi
gk104_sor_hdmi = {
.ctrl = gk104_sor_hdmi_ctrl,
.infoframe_avi = gk104_sor_hdmi_infoframe_avi,
.infoframe_vsi = gk104_sor_hdmi_infoframe_vsi,
};
static const struct nvkm_ior_func
gk104_sor = {
.state = gf119_sor_state,
.power = nv50_sor_power,
.clock = gf119_sor_clock,
.bl = >215_sor_bl,
.hdmi = &gk104_sor_hdmi,
.dp = &gf119_sor_dp,
.hda = &gf119_sor_hda,
};
int
gk104_sor_new(struct nvkm_disp *disp, int id)
{
return nvkm_ior_new_(&gk104_sor, disp, SOR, id, true );
}
static const struct nvkm_disp_mthd_list
gk104_disp_ovly_mthd_base = {
.mthd = 0 x0000,
.data = {
{ 0 x0080, 0 x665080 },
{ 0 x0084, 0 x665084 },
{ 0 x0088, 0 x665088 },
{ 0 x008c, 0 x66508c },
{ 0 x0090, 0 x665090 },
{ 0 x0094, 0 x665094 },
{ 0 x00a0, 0 x6650a0 },
{ 0 x00a4, 0 x6650a4 },
{ 0 x00b0, 0 x6650b0 },
{ 0 x00b4, 0 x6650b4 },
{ 0 x00b8, 0 x6650b8 },
{ 0 x00c0, 0 x6650c0 },
{ 0 x00c4, 0 x6650c4 },
{ 0 x00e0, 0 x6650e0 },
{ 0 x00e4, 0 x6650e4 },
{ 0 x00e8, 0 x6650e8 },
{ 0 x0100, 0 x665100 },
{ 0 x0104, 0 x665104 },
{ 0 x0108, 0 x665108 },
{ 0 x010c, 0 x66510c },
{ 0 x0110, 0 x665110 },
{ 0 x0118, 0 x665118 },
{ 0 x011c, 0 x66511c },
{ 0 x0120, 0 x665120 },
{ 0 x0124, 0 x665124 },
{ 0 x0130, 0 x665130 },
{ 0 x0134, 0 x665134 },
{ 0 x0138, 0 x665138 },
{ 0 x013c, 0 x66513c },
{ 0 x0140, 0 x665140 },
{ 0 x0144, 0 x665144 },
{ 0 x0148, 0 x665148 },
{ 0 x014c, 0 x66514c },
{ 0 x0150, 0 x665150 },
{ 0 x0154, 0 x665154 },
{ 0 x0158, 0 x665158 },
{ 0 x015c, 0 x66515c },
{ 0 x0160, 0 x665160 },
{ 0 x0164, 0 x665164 },
{ 0 x0168, 0 x665168 },
{ 0 x016c, 0 x66516c },
{ 0 x0400, 0 x665400 },
{ 0 x0404, 0 x665404 },
{ 0 x0408, 0 x665408 },
{ 0 x040c, 0 x66540c },
{ 0 x0410, 0 x665410 },
{}
}
};
const struct nvkm_disp_chan_mthd
gk104_disp_ovly_mthd = {
.name = "Overlay" ,
.addr = 0 x001000,
.prev = -0 x020000,
.data = {
{ "Global" , 1 , &gk104_disp_ovly_mthd_base },
{}
}
};
const struct nvkm_disp_chan_user
gk104_disp_ovly = {
.func = &gf119_disp_dmac_func,
.ctrl = 5 ,
.user = 5 ,
.mthd = &gk104_disp_ovly_mthd,
};
static const struct nvkm_disp_mthd_list
gk104_disp_core_mthd_head = {
.mthd = 0 x0300,
.addr = 0 x000300,
.data = {
{ 0 x0400, 0 x660400 },
{ 0 x0404, 0 x660404 },
{ 0 x0408, 0 x660408 },
{ 0 x040c, 0 x66040c },
{ 0 x0410, 0 x660410 },
{ 0 x0414, 0 x660414 },
{ 0 x0418, 0 x660418 },
{ 0 x041c, 0 x66041c },
{ 0 x0420, 0 x660420 },
{ 0 x0424, 0 x660424 },
{ 0 x0428, 0 x660428 },
{ 0 x042c, 0 x66042c },
{ 0 x0430, 0 x660430 },
{ 0 x0434, 0 x660434 },
{ 0 x0438, 0 x660438 },
{ 0 x0440, 0 x660440 },
{ 0 x0444, 0 x660444 },
{ 0 x0448, 0 x660448 },
{ 0 x044c, 0 x66044c },
{ 0 x0450, 0 x660450 },
{ 0 x0454, 0 x660454 },
{ 0 x0458, 0 x660458 },
{ 0 x045c, 0 x66045c },
{ 0 x0460, 0 x660460 },
{ 0 x0468, 0 x660468 },
{ 0 x046c, 0 x66046c },
{ 0 x0470, 0 x660470 },
{ 0 x0474, 0 x660474 },
{ 0 x047c, 0 x66047c },
{ 0 x0480, 0 x660480 },
{ 0 x0484, 0 x660484 },
{ 0 x0488, 0 x660488 },
{ 0 x048c, 0 x66048c },
{ 0 x0490, 0 x660490 },
{ 0 x0494, 0 x660494 },
{ 0 x0498, 0 x660498 },
{ 0 x04a0, 0 x6604a0 },
{ 0 x04b0, 0 x6604b0 },
{ 0 x04b8, 0 x6604b8 },
{ 0 x04bc, 0 x6604bc },
{ 0 x04c0, 0 x6604c0 },
{ 0 x04c4, 0 x6604c4 },
{ 0 x04c8, 0 x6604c8 },
{ 0 x04d0, 0 x6604d0 },
{ 0 x04d4, 0 x6604d4 },
{ 0 x04e0, 0 x6604e0 },
{ 0 x04e4, 0 x6604e4 },
{ 0 x04e8, 0 x6604e8 },
{ 0 x04ec, 0 x6604ec },
{ 0 x04f0, 0 x6604f0 },
{ 0 x04f4, 0 x6604f4 },
{ 0 x04f8, 0 x6604f8 },
{ 0 x04fc, 0 x6604fc },
{ 0 x0500, 0 x660500 },
{ 0 x0504, 0 x660504 },
{ 0 x0508, 0 x660508 },
{ 0 x050c, 0 x66050c },
{ 0 x0510, 0 x660510 },
{ 0 x0514, 0 x660514 },
{ 0 x0518, 0 x660518 },
{ 0 x051c, 0 x66051c },
{ 0 x0520, 0 x660520 },
{ 0 x0524, 0 x660524 },
{ 0 x052c, 0 x66052c },
{ 0 x0530, 0 x660530 },
{ 0 x054c, 0 x66054c },
{ 0 x0550, 0 x660550 },
{ 0 x0554, 0 x660554 },
{ 0 x0558, 0 x660558 },
{ 0 x055c, 0 x66055c },
{}
}
};
const struct nvkm_disp_chan_mthd
gk104_disp_core_mthd = {
.name = "Core" ,
.addr = 0 x000000,
.prev = -0 x020000,
.data = {
{ "Global" , 1 , &gf119_disp_core_mthd_base },
{ "DAC" , 3 , &gf119_disp_core_mthd_dac },
{ "SOR" , 8 , &gf119_disp_core_mthd_sor },
{ "PIOR" , 4 , &gf119_disp_core_mthd_pior },
{ "HEAD" , 4 , &gk104_disp_core_mthd_head },
{}
}
};
const struct nvkm_disp_chan_user
gk104_disp_core = {
.func = &gf119_disp_core_func,
.ctrl = 0 ,
.user = 0 ,
.mthd = &gk104_disp_core_mthd,
};
static const struct nvkm_disp_func
gk104_disp = {
.oneinit = nv50_disp_oneinit,
.init = gf119_disp_init,
.fini = gf119_disp_fini,
.intr = gf119_disp_intr,
.intr_error = gf119_disp_intr_error,
.super = gf119_disp_super,
.uevent = &gf119_disp_chan_uevent,
.head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
.dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new },
.sor = { .cnt = gf119_sor_cnt, .new = gk104_sor_new },
.root = { 0 ,0 ,GK104_DISP },
.user = {
{{0 ,0 ,GK104_DISP_CURSOR }, nvkm_disp_chan_new, &gf119_disp_curs },
{{0 ,0 ,GK104_DISP_OVERLAY }, nvkm_disp_chan_new, &gf119_disp_oimm },
{{0 ,0 ,GK104_DISP_BASE_CHANNEL_DMA }, nvkm_disp_chan_new, &gf119_disp_base },
{{0 ,0 ,GK104_DISP_CORE_CHANNEL_DMA }, nvkm_disp_core_new, &gk104_disp_core },
{{0 ,0 ,GK104_DISP_OVERLAY_CONTROL_DMA}, nvkm_disp_chan_new, &gk104_disp_ovly },
{}
},
};
int
gk104_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_disp **pdisp)
{
return nvkm_disp_new_(&gk104_disp, device, type, inst, pdisp);
}
Messung V0.5 in Prozent C=93 H=98 G=95
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland