Merge branch 'linux-5.2' of git://github.com/skeggsb/linux into drm-next

Mostly fixes for a number of modesetting-related issues that have been
reported, as well as initial support for TU117 modesetting.  TU116
also exists these days, but is not officially supported, as I don't
have HW yet to verify against.

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Ben Skeggs <skeggsb@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CACAvsv77U7_bWYy9CUVGU8zAE0NZcKOLp6kUgppgq9HPd0tBnw@mail.gmail.com
This commit is contained in:
Dave Airlie 2019-05-15 13:29:03 +10:00
commit f266fdc760
7 changed files with 75 additions and 8 deletions

View File

@ -41,6 +41,7 @@ struct nv50_disp_interlock {
NV50_DISP_INTERLOCK__SIZE
} type;
u32 data;
u32 wimm;
};
void corec37d_ntfy_init(struct nouveau_bo *, u32);

View File

@ -306,7 +306,7 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
asyh->set.or = head->func->or != NULL;
}
if (asyh->state.mode_changed)
if (asyh->state.mode_changed || asyh->state.connectors_changed)
nv50_head_atomic_check_mode(head, asyh);
if (asyh->state.color_mgmt_changed ||
@ -413,6 +413,7 @@ nv50_head_atomic_duplicate_state(struct drm_crtc *crtc)
asyh->ovly = armh->ovly;
asyh->dither = armh->dither;
asyh->procamp = armh->procamp;
asyh->or = armh->or;
asyh->dp = armh->dp;
asyh->clr.mask = 0;
asyh->set.mask = 0;

View File

@ -75,6 +75,7 @@ wimmc37b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
return ret;
}
wndw->interlock.wimm = wndw->interlock.data;
wndw->immd = func;
return 0;
}

View File

@ -127,7 +127,7 @@ void
nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
struct nv50_wndw_atom *asyw)
{
if (interlock) {
if (interlock[NV50_DISP_INTERLOCK_CORE]) {
asyw->image.mode = 0;
asyw->image.interval = 1;
}
@ -149,7 +149,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
if (asyw->set.point) {
if (asyw->set.point = false, asyw->set.mask)
interlock[wndw->interlock.type] |= wndw->interlock.data;
interlock[NV50_DISP_INTERLOCK_WIMM] |= wndw->interlock.data;
interlock[NV50_DISP_INTERLOCK_WIMM] |= wndw->interlock.wimm;
wndw->immd->point(wndw, asyw);
wndw->immd->update(wndw, interlock);

View File

@ -631,7 +631,8 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
/* We need to check that the chipset is supported before booting
* fbdev off the hardware, as there's no way to put it back.
*/
ret = nvkm_device_pci_new(pdev, NULL, "error", true, false, 0, &device);
ret = nvkm_device_pci_new(pdev, nouveau_config, "error",
true, false, 0, &device);
if (ret)
return ret;

View File

@ -2540,6 +2540,41 @@ nv166_chipset = {
.sec2 = tu102_sec2_new,
};
static const struct nvkm_device_chip
nv167_chipset = {
.name = "TU117",
.bar = tu102_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
.devinit = tu102_devinit_new,
.fault = tu102_fault_new,
.fb = gv100_fb_new,
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.gsp = gv100_gsp_new,
.i2c = gm200_i2c_new,
.ibus = gm200_ibus_new,
.imem = nv50_instmem_new,
.ltc = gp102_ltc_new,
.mc = tu102_mc_new,
.mmu = tu102_mmu_new,
.pci = gp100_pci_new,
.pmu = gp102_pmu_new,
.therm = gp100_therm_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
.ce[0] = tu102_ce_new,
.ce[1] = tu102_ce_new,
.ce[2] = tu102_ce_new,
.ce[3] = tu102_ce_new,
.ce[4] = tu102_ce_new,
.disp = tu102_disp_new,
.dma = gv100_dma_new,
.fifo = tu102_fifo_new,
.nvdec[0] = gp102_nvdec_new,
.sec2 = tu102_sec2_new,
};
static int
nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvkm_notify *notify)
@ -2824,8 +2859,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
u64 mmio_base, mmio_size;
u32 boot0, strap;
void __iomem *map;
int ret = -EEXIST;
int i;
int ret = -EEXIST, i;
unsigned chipset;
mutex_lock(&nv_devices_mutex);
if (nvkm_device_find_locked(handle))
@ -2870,6 +2905,26 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
strap = ioread32_native(map + 0x101000);
iounmap(map);
/* chipset can be overridden for devel/testing purposes */
chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0);
if (chipset) {
u32 override_boot0;
if (chipset >= 0x10) {
override_boot0 = ((chipset & 0x1ff) << 20);
override_boot0 |= 0x000000a1;
} else {
if (chipset != 0x04)
override_boot0 = 0x20104000;
else
override_boot0 = 0x20004000;
}
nvdev_warn(device, "CHIPSET OVERRIDE: %08x -> %08x\n",
boot0, override_boot0);
boot0 = override_boot0;
}
/* determine chipset and derive architecture from it */
if ((boot0 & 0x1f000000) > 0) {
device->chipset = (boot0 & 0x1ff00000) >> 20;
@ -2996,6 +3051,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x162: device->chip = &nv162_chipset; break;
case 0x164: device->chip = &nv164_chipset; break;
case 0x166: device->chip = &nv166_chipset; break;
case 0x167: device->chip = &nv167_chipset; break;
default:
nvdev_error(device, "unknown chipset (%08x)\n", boot0);
goto done;

View File

@ -365,8 +365,15 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps)
* and it's better to have a failed modeset than that.
*/
for (cfg = nvkm_dp_rates; cfg->rate; cfg++) {
if (cfg->nr <= outp_nr && cfg->nr <= outp_bw)
failsafe = cfg;
if (cfg->nr <= outp_nr && cfg->nr <= outp_bw) {
/* Try to respect sink limits too when selecting
* lowest link configuration.
*/
if (!failsafe ||
(cfg->nr <= sink_nr && cfg->bw <= sink_bw))
failsafe = cfg;
}
if (failsafe && cfg[1].rate < dataKBps)
break;
}