diff options
author | Dave Airlie <airlied@redhat.com> | 2014-06-11 16:28:10 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-06-11 16:28:10 +1000 |
commit | bc1dfff04a5d4064ba0db1fab13f84ab4f333d2b (patch) | |
tree | dadecc40f36d2cb7d7a8051753e50cf486c0b75f | |
parent | c1a6e9fe82b46159af8cc4cf34fb51ee47862f05 (diff) | |
parent | 1ae5a62bb8b6b544bdfac7bdcb15c9eb22dd6620 (diff) |
Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
display rework fixes lots of displayport issues.
* 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (43 commits)
drm/nouveau/disp/dp: fix tmds passthrough on dp connector
drm/nouveau/dp: probe dpcd to determine connectedness
drm/nv50-: trigger update after all connectors disabled
drm/nv50-: prepare for attaching a SOR to multiple heads
drm/gf119-/disp: fix debug output on update failure
drm/nouveau/disp/dp: make use of postcursor when its available
drm/g94-/disp/dp: take max pullup value across all lanes
drm/nouveau/bios/dp: parse lane postcursor data
drm/nouveau/dp: fix support for dpms
drm/nouveau: register a drm_dp_aux channel for each dp connector
drm/g94-/disp: add method to power-off dp lanes
drm/nouveau/disp/dp: maintain link in response to hpd signal
drm/g94-/disp: bash and wait for something after changing lane power regs
drm/nouveau/disp/dp: split link config/power into two steps
drm/nv50/disp: train PIOR-attached DP from second supervisor
drm/nouveau/disp/dp: make use of existing output data for link training
drm/gf119/disp: start removing direct vbios parsing from supervisor
drm/nv50/disp: start removing direct vbios parsing from supervisor
drm/nouveau/disp/dp: maintain receiver caps in response to hpd signal
drm/nouveau/disp/dp: create subclass for dp outputs
...
90 files changed, 3346 insertions, 1486 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 1aaa2ef577d9..2b6156d0e4b5 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -125,17 +125,22 @@ nouveau-y += core/subdev/fb/gddr5.o nouveau-y += core/subdev/gpio/base.o nouveau-y += core/subdev/gpio/nv10.o nouveau-y += core/subdev/gpio/nv50.o +nouveau-y += core/subdev/gpio/nv92.o nouveau-y += core/subdev/gpio/nvd0.o nouveau-y += core/subdev/gpio/nve0.o nouveau-y += core/subdev/i2c/base.o nouveau-y += core/subdev/i2c/anx9805.o nouveau-y += core/subdev/i2c/aux.o nouveau-y += core/subdev/i2c/bit.o +nouveau-y += core/subdev/i2c/pad.o +nouveau-y += core/subdev/i2c/padnv04.o +nouveau-y += core/subdev/i2c/padnv94.o nouveau-y += core/subdev/i2c/nv04.o nouveau-y += core/subdev/i2c/nv4e.o nouveau-y += core/subdev/i2c/nv50.o nouveau-y += core/subdev/i2c/nv94.o nouveau-y += core/subdev/i2c/nvd0.o +nouveau-y += core/subdev/i2c/nve0.o nouveau-y += core/subdev/ibus/nvc0.o nouveau-y += core/subdev/ibus/nve0.o nouveau-y += core/subdev/ibus/gk20a.o @@ -217,6 +222,9 @@ nouveau-y += core/engine/device/nvc0.o nouveau-y += core/engine/device/nve0.o nouveau-y += core/engine/device/gm100.o nouveau-y += core/engine/disp/base.o +nouveau-y += core/engine/disp/conn.o +nouveau-y += core/engine/disp/outp.o +nouveau-y += core/engine/disp/outpdp.o nouveau-y += core/engine/disp/nv04.o nouveau-y += core/engine/disp/nv50.o nouveau-y += core/engine/disp/nv84.o diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c index 3f3c76581a9e..ae81d3b5d8b7 100644 --- a/drivers/gpu/drm/nouveau/core/core/event.c +++ b/drivers/gpu/drm/nouveau/core/core/event.c @@ -28,14 +28,20 @@ nouveau_event_put(struct nouveau_eventh *handler) { struct nouveau_event *event = handler->event; unsigned long flags; - if (__test_and_clear_bit(NVKM_EVENT_ENABLE, &handler->flags)) { - spin_lock_irqsave(&event->refs_lock, flags); - if (!--event->index[handler->index].refs) { + u32 m, t; + + if (!__test_and_clear_bit(NVKM_EVENT_ENABLE, &handler->flags)) + return; + + spin_lock_irqsave(&event->refs_lock, flags); + for (m = handler->types; t = __ffs(m), m; m &= ~(1 << t)) { + if (!--event->refs[handler->index * event->types_nr + t]) { if (event->disable) - event->disable(event, handler->index); + event->disable(event, 1 << t, handler->index); } - spin_unlock_irqrestore(&event->refs_lock, flags); + } + spin_unlock_irqrestore(&event->refs_lock, flags); } void @@ -43,14 +49,20 @@ nouveau_event_get(struct nouveau_eventh *handler) { struct nouveau_event *event = handler->event; unsigned long flags; - if (!__test_and_set_bit(NVKM_EVENT_ENABLE, &handler->flags)) { - spin_lock_irqsave(&event->refs_lock, flags); - if (!event->index[handler->index].refs++) { + u32 m, t; + + if (__test_and_set_bit(NVKM_EVENT_ENABLE, &handler->flags)) + return; + + spin_lock_irqsave(&event->refs_lock, flags); + for (m = handler->types; t = __ffs(m), m; m &= ~(1 << t)) { + if (!event->refs[handler->index * event->types_nr + t]++) { if (event->enable) - event->enable(event, handler->index); + event->enable(event, 1 << t, handler->index); } - spin_unlock_irqrestore(&event->refs_lock, flags); + } + spin_unlock_irqrestore(&event->refs_lock, flags); } static void @@ -65,38 +77,47 @@ nouveau_event_fini(struct nouveau_eventh *handler) } static int -nouveau_event_init(struct nouveau_event *event, int index, - int (*func)(void *, int), void *priv, +nouveau_event_init(struct nouveau_event *event, u32 types, int index, + int (*func)(void *, u32, int), void *priv, struct nouveau_eventh *handler) { unsigned long flags; + if (types & ~((1 << event->types_nr) - 1)) + return -EINVAL; if (index >= event->index_nr) return -EINVAL; handler->event = event; handler->flags = 0; + handler->types = types; handler->index = index; handler->func = func; handler->priv = priv; spin_lock_irqsave(&event->list_lock, flags); - list_add_tail(&handler->head, &event->index[index].list); + list_add_tail(&handler->head, &event->list[index]); spin_unlock_irqrestore(&event->list_lock, flags); return 0; } int -nouveau_event_new(struct nouveau_event *event, int index, - int (*func)(void *, int), void *priv, +nouveau_event_new(struct nouveau_event *event, u32 types, int index, + int (*func)(void *, u32, int), void *priv, struct nouveau_eventh **phandler) { struct nouveau_eventh *handler; int ret = -ENOMEM; + if (event->check) { + ret = event->check(event, types, index); + if (ret) + return ret; + } + handler = *phandler = kmalloc(sizeof(*handler), GFP_KERNEL); if (handler) { - ret = nouveau_event_init(event, index, func, priv, handler); + ret = nouveau_event_init(event, types, index, func, priv, handler); if (ret) kfree(handler); } @@ -116,7 +137,7 @@ nouveau_event_ref(struct nouveau_eventh *handler, struct nouveau_eventh **ref) } void -nouveau_event_trigger(struct nouveau_event *event, int index) +nouveau_event_trigger(struct nouveau_event *event, u32 types, int index) { struct nouveau_eventh *handler; unsigned long flags; @@ -125,10 +146,15 @@ nouveau_event_trigger(struct nouveau_event *event, int index) return; spin_lock_irqsave(&event->list_lock, flags); - list_for_each_entry(handler, &event->index[index].list, head) { - if (test_bit(NVKM_EVENT_ENABLE, &handler->flags) && - handler->func(handler->priv, index) == NVKM_EVENT_DROP) - nouveau_event_put(handler); + list_for_each_entry(handler, &event->list[index], head) { + if (!test_bit(NVKM_EVENT_ENABLE, &handler->flags)) + continue; + if (!(handler->types & types)) + continue; + if (handler->func(handler->priv, handler->types & types, index) + != NVKM_EVENT_DROP) + continue; + nouveau_event_put(handler); } spin_unlock_irqrestore(&event->list_lock, flags); } @@ -144,20 +170,27 @@ nouveau_event_destroy(struct nouveau_event **pevent) } int -nouveau_event_create(int index_nr, struct nouveau_event **pevent) +nouveau_event_create(int types_nr, int index_nr, struct nouveau_event **pevent) { struct nouveau_event *event; int i; - event = *pevent = kzalloc(sizeof(*event) + index_nr * - sizeof(event->index[0]), GFP_KERNEL); + event = *pevent = kzalloc(sizeof(*event) + (index_nr * types_nr) * + sizeof(event->refs[0]), GFP_KERNEL); if (!event) return -ENOMEM; + event->list = kmalloc(sizeof(*event->list) * index_nr, GFP_KERNEL); + if (!event->list) { + kfree(event); + return -ENOMEM; + } + spin_lock_init(&event->list_lock); spin_lock_init(&event->refs_lock); for (i = 0; i < index_nr; i++) - INIT_LIST_HEAD(&event->index[i].list); + INIT_LIST_HEAD(&event->list[i]); + event->types_nr = types_nr; event->index_nr = index_nr; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/device/gm100.c b/drivers/gpu/drm/nouveau/core/engine/device/gm100.c index d258c21c4a22..a520029e25d9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/gm100.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/gm100.c @@ -60,8 +60,8 @@ gm100_identify(struct nouveau_device *device) case 0x117: device->cname = "GM107"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nvd0_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; #if 0 device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c index 0a51ff4e9e00..40b29d0214cb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c @@ -47,7 +47,7 @@ nv04_identify(struct nouveau_device *device) case 0x04: device->cname = "NV04"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv04_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -65,7 +65,7 @@ nv04_identify(struct nouveau_device *device) case 0x05: device->cname = "NV05"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv05_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c index e008de8b51b0..5f7c25ff523d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c @@ -48,8 +48,8 @@ nv10_identify(struct nouveau_device *device) case 0x10: device->cname = "NV10"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -65,8 +65,8 @@ nv10_identify(struct nouveau_device *device) case 0x15: device->cname = "NV15"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass; |