Commit 773eb04d authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/disp: expose conn event class

This removes some now-unnecessary nesting of workqueues.

v2:
- use ?: (lyude)
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent ffd26641
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#ifndef __NVIF_CONN_H__ #ifndef __NVIF_CONN_H__
#define __NVIF_CONN_H__ #define __NVIF_CONN_H__
#include <nvif/object.h> #include <nvif/object.h>
#include <nvif/event.h>
struct nvif_disp; struct nvif_disp;
struct nvif_conn { struct nvif_conn {
...@@ -11,8 +12,17 @@ struct nvif_conn { ...@@ -11,8 +12,17 @@ struct nvif_conn {
int nvif_conn_ctor(struct nvif_disp *, const char *name, int id, struct nvif_conn *); int nvif_conn_ctor(struct nvif_disp *, const char *name, int id, struct nvif_conn *);
void nvif_conn_dtor(struct nvif_conn *); void nvif_conn_dtor(struct nvif_conn *);
static inline int
nvif_conn_id(struct nvif_conn *conn)
{
return conn->object.handle;
}
#define NVIF_CONN_HPD_STATUS_UNSUPPORTED 0 /* negative if query fails */ #define NVIF_CONN_HPD_STATUS_UNSUPPORTED 0 /* negative if query fails */
#define NVIF_CONN_HPD_STATUS_NOT_PRESENT 1 #define NVIF_CONN_HPD_STATUS_NOT_PRESENT 1
#define NVIF_CONN_HPD_STATUS_PRESENT 2 #define NVIF_CONN_HPD_STATUS_PRESENT 2
int nvif_conn_hpd_status(struct nvif_conn *); int nvif_conn_hpd_status(struct nvif_conn *);
int nvif_conn_event_ctor(struct nvif_conn *, const char *name, nvif_event_func, u8 types,
struct nvif_event *);
#endif #endif
...@@ -52,25 +52,6 @@ struct nvif_notify_rep_v0 { ...@@ -52,25 +52,6 @@ struct nvif_notify_rep_v0 {
__u8 data[]; /* reply data (below) */ __u8 data[]; /* reply data (below) */
}; };
struct nvif_notify_conn_req_v0 {
/* nvif_notify_req ... */
__u8 version;
#define NVIF_NOTIFY_CONN_V0_PLUG 0x01
#define NVIF_NOTIFY_CONN_V0_UNPLUG 0x02
#define NVIF_NOTIFY_CONN_V0_IRQ 0x04
#define NVIF_NOTIFY_CONN_V0_ANY 0x07
__u8 mask;
__u8 conn;
__u8 pad03[5];
};
struct nvif_notify_conn_rep_v0 {
/* nvif_notify_rep ... */
__u8 version;
__u8 mask;
__u8 pad02[6];
};
struct nvif_notify_uevent_req { struct nvif_notify_uevent_req {
/* nvif_notify_req ... */ /* nvif_notify_req ... */
}; };
......
...@@ -10,6 +10,17 @@ union nvif_conn_args { ...@@ -10,6 +10,17 @@ union nvif_conn_args {
} v0; } v0;
}; };
union nvif_conn_event_args {
struct nvif_conn_event_v0 {
__u8 version;
#define NVIF_CONN_EVENT_V0_PLUG 0x01
#define NVIF_CONN_EVENT_V0_UNPLUG 0x02
#define NVIF_CONN_EVENT_V0_IRQ 0x04
__u8 types;
__u8 pad02[6];
} v0;
};
#define NVIF_CONN_V0_HPD_STATUS 0x00000000 #define NVIF_CONN_V0_HPD_STATUS 0x00000000
union nvif_conn_hpd_status_args { union nvif_conn_hpd_status_args {
......
...@@ -8,9 +8,6 @@ ...@@ -8,9 +8,6 @@
#include <subdev/bios/gpio.h> #include <subdev/bios/gpio.h>
struct nvkm_gpio_ntfy_req { struct nvkm_gpio_ntfy_req {
#define NVKM_GPIO_HI 0x01
#define NVKM_GPIO_LO 0x02
#define NVKM_GPIO_TOGGLED 0x03
u8 mask; u8 mask;
u8 line; u8 line;
}; };
...@@ -23,6 +20,9 @@ struct nvkm_gpio { ...@@ -23,6 +20,9 @@ struct nvkm_gpio {
const struct nvkm_gpio_func *func; const struct nvkm_gpio_func *func;
struct nvkm_subdev subdev; struct nvkm_subdev subdev;
#define NVKM_GPIO_HI BIT(0)
#define NVKM_GPIO_LO BIT(1)
#define NVKM_GPIO_TOGGLED (NVKM_GPIO_HI | NVKM_GPIO_LO)
struct nvkm_event event; struct nvkm_event event;
}; };
......
...@@ -7,20 +7,6 @@ ...@@ -7,20 +7,6 @@
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/i2c.h> #include <subdev/bios/i2c.h>
struct nvkm_i2c_ntfy_req {
#define NVKM_I2C_PLUG 0x01
#define NVKM_I2C_UNPLUG 0x02
#define NVKM_I2C_IRQ 0x04
#define NVKM_I2C_DONE 0x08
#define NVKM_I2C_ANY 0x0f
u8 mask;
u8 port;
};
struct nvkm_i2c_ntfy_rep {
u8 mask;
};
struct nvkm_i2c_bus_probe { struct nvkm_i2c_bus_probe {
struct i2c_board_info dev; struct i2c_board_info dev;
u8 udelay; /* set to 0 to use the standard delay */ u8 udelay; /* set to 0 to use the standard delay */
...@@ -79,6 +65,11 @@ struct nvkm_i2c { ...@@ -79,6 +65,11 @@ struct nvkm_i2c {
struct list_head bus; struct list_head bus;
struct list_head aux; struct list_head aux;
#define NVKM_I2C_PLUG BIT(0)
#define NVKM_I2C_UNPLUG BIT(1)
#define NVKM_I2C_IRQ BIT(2)
#define NVKM_I2C_DONE BIT(3)
#define NVKM_I2C_ANY (NVKM_I2C_PLUG | NVKM_I2C_UNPLUG | NVKM_I2C_IRQ | NVKM_I2C_DONE)
struct nvkm_event event; struct nvkm_event event;
}; };
......
...@@ -47,8 +47,7 @@ ...@@ -47,8 +47,7 @@
#include "nouveau_crtc.h" #include "nouveau_crtc.h"
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/cl0046.h> #include <nvif/if0011.h>
#include <nvif/event.h>
struct drm_display_mode * struct drm_display_mode *
nouveau_conn_native_mode(struct drm_connector *connector) nouveau_conn_native_mode(struct drm_connector *connector)
...@@ -396,7 +395,8 @@ static void ...@@ -396,7 +395,8 @@ static void
nouveau_connector_destroy(struct drm_connector *connector) nouveau_connector_destroy(struct drm_connector *connector)
{ {
struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_connector *nv_connector = nouveau_connector(connector);
nvif_notify_dtor(&nv_connector->hpd); nvif_event_dtor(&nv_connector->irq);
nvif_event_dtor(&nv_connector->hpd);
kfree(nv_connector->edid); kfree(nv_connector->edid);
drm_connector_unregister(connector); drm_connector_unregister(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
...@@ -1178,23 +1178,22 @@ nouveau_connector_hpd(struct nouveau_connector *nv_connector, u64 bits) ...@@ -1178,23 +1178,22 @@ nouveau_connector_hpd(struct nouveau_connector *nv_connector, u64 bits)
} }
static int static int
nouveau_connector_hotplug(struct nvif_notify *notify) nouveau_connector_irq(struct nvif_event *event, void *repv, u32 repc)
{ {
struct nouveau_connector *nv_connector = struct nouveau_connector *nv_connector = container_of(event, typeof(*nv_connector), irq);
container_of(notify, typeof(*nv_connector), hpd);
struct drm_connector *connector = &nv_connector->base;
struct drm_device *dev = connector->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
const struct nvif_notify_conn_rep_v0 *rep = notify->data;
if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) { schedule_work(&nv_connector->irq_work);
nouveau_dp_irq(drm, nv_connector); return NVIF_EVENT_KEEP;
return NVIF_NOTIFY_KEEP; }
}
nouveau_connector_hpd(nv_connector, rep->mask); static int
nouveau_connector_hotplug(struct nvif_event *event, void *repv, u32 repc)
{
struct nouveau_connector *nv_connector = container_of(event, typeof(*nv_connector), hpd);
struct nvif_conn_event_v0 *rep = repv;
return NVIF_NOTIFY_KEEP; nouveau_connector_hpd(nv_connector, rep->types);
return NVIF_EVENT_KEEP;
} }
static ssize_t static ssize_t
...@@ -1290,6 +1289,7 @@ nouveau_connector_create(struct drm_device *dev, ...@@ -1290,6 +1289,7 @@ nouveau_connector_create(struct drm_device *dev,
connector = &nv_connector->base; connector = &nv_connector->base;
nv_connector->index = index; nv_connector->index = index;
INIT_WORK(&nv_connector->irq_work, nouveau_dp_irq);
/* attempt to parse vbios connector type and hotplug gpio */ /* attempt to parse vbios connector type and hotplug gpio */
nv_connector->dcb = olddcb_conn(dev, index); nv_connector->dcb = olddcb_conn(dev, index);
...@@ -1401,6 +1401,7 @@ nouveau_connector_create(struct drm_device *dev, ...@@ -1401,6 +1401,7 @@ nouveau_connector_create(struct drm_device *dev,
drm_connector_init(dev, connector, funcs, type); drm_connector_init(dev, connector, funcs, type);
drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
if (nv_connector->dcb && (disp->disp.conn_mask & BIT(nv_connector->index))) { if (nv_connector->dcb && (disp->disp.conn_mask & BIT(nv_connector->index))) {
ret = nvif_conn_ctor(&disp->disp, nv_connector->base.name, nv_connector->index, ret = nvif_conn_ctor(&disp->disp, nv_connector->base.name, nv_connector->index,
...@@ -1409,6 +1410,25 @@ nouveau_connector_create(struct drm_device *dev, ...@@ -1409,6 +1410,25 @@ nouveau_connector_create(struct drm_device *dev,
kfree(nv_connector); kfree(nv_connector);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsHotplug",
nouveau_connector_hotplug,
NVIF_CONN_EVENT_V0_PLUG | NVIF_CONN_EVENT_V0_UNPLUG,
&nv_connector->hpd);
if (ret == 0)
connector->polled = DRM_CONNECTOR_POLL_HPD;
if (nv_connector->aux.transfer) {
ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsDpIrq",
nouveau_connector_irq, NVIF_CONN_EVENT_V0_IRQ,
&nv_connector->irq);
if (ret) {
nvif_event_dtor(&nv_connector->hpd);
nvif_conn_dtor(&nv_connector->conn);
kfree(nv_connector);
return ERR_PTR(ret);
}
}
} }
connector->funcs->reset(connector); connector->funcs->reset(connector);
...@@ -1452,21 +1472,6 @@ nouveau_connector_create(struct drm_device *dev, ...@@ -1452,21 +1472,6 @@ nouveau_connector_create(struct drm_device *dev,
break; break;
} }
ret = nvif_notify_ctor(&disp->disp.object, "kmsHotplug",
nouveau_connector_hotplug,
true, NV04_DISP_NTFY_CONN,
&(struct nvif_notify_conn_req_v0) {
.mask = NVIF_NOTIFY_CONN_V0_ANY,
.conn = index,
},
sizeof(struct nvif_notify_conn_req_v0),
sizeof(struct nvif_notify_conn_rep_v0),
&nv_connector->hpd);
if (ret)
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
else
connector->polled = DRM_CONNECTOR_POLL_HPD;
drm_connector_register(connector); drm_connector_register(connector);
return connector; return connector;
} }
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#ifndef __NOUVEAU_CONNECTOR_H__ #ifndef __NOUVEAU_CONNECTOR_H__
#define __NOUVEAU_CONNECTOR_H__ #define __NOUVEAU_CONNECTOR_H__
#include <nvif/conn.h> #include <nvif/conn.h>
#include <nvif/notify.h> #include <nvif/event.h>
#include <nvhw/class/cl507d.h> #include <nvhw/class/cl507d.h>
#include <nvhw/class/cl907d.h> #include <nvhw/class/cl907d.h>
...@@ -125,7 +125,9 @@ struct nouveau_connector { ...@@ -125,7 +125,9 @@ struct nouveau_connector {
struct nvif_conn conn; struct nvif_conn conn;
u64 hpd_pending; u64 hpd_pending;
struct nvif_notify hpd; struct nvif_event hpd;
struct nvif_event irq;
struct work_struct irq_work;
struct drm_dp_aux aux; struct drm_dp_aux aux;
......
...@@ -42,8 +42,8 @@ ...@@ -42,8 +42,8 @@
#include "nv50_display.h" #include "nv50_display.h"
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/if0011.h>
#include <nvif/if0013.h> #include <nvif/if0013.h>
#include <nvif/event.h>
#include <dispnv50/crc.h> #include <dispnv50/crc.h>
int int
...@@ -497,11 +497,11 @@ nouveau_display_hpd_work(struct work_struct *work) ...@@ -497,11 +497,11 @@ nouveau_display_hpd_work(struct work_struct *work)
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] plug:%d unplug:%d irq:%d\n", drm_dbg_kms(dev, "[CONNECTOR:%d:%s] plug:%d unplug:%d irq:%d\n",
connector->base.id, connector->name, connector->base.id, connector->name,
!!(bits & NVIF_NOTIFY_CONN_V0_PLUG), !!(bits & NVIF_CONN_EVENT_V0_PLUG),
!!(bits & NVIF_NOTIFY_CONN_V0_UNPLUG), !!(bits & NVIF_CONN_EVENT_V0_UNPLUG),
!!(bits & NVIF_NOTIFY_CONN_V0_IRQ)); !!(bits & NVIF_CONN_EVENT_V0_IRQ));
if (bits & NVIF_NOTIFY_CONN_V0_IRQ) { if (bits & NVIF_CONN_EVENT_V0_IRQ) {
if (nouveau_dp_link_check(nv_connector)) if (nouveau_dp_link_check(nv_connector))
continue; continue;
} }
...@@ -584,7 +584,8 @@ nouveau_display_init(struct drm_device *dev, bool resume, bool runtime) ...@@ -584,7 +584,8 @@ nouveau_display_init(struct drm_device *dev, bool resume, bool runtime)
drm_connector_list_iter_begin(dev, &conn_iter); drm_connector_list_iter_begin(dev, &conn_iter);
nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
struct nouveau_connector *conn = nouveau_connector(connector); struct nouveau_connector *conn = nouveau_connector(connector);
nvif_notify_get(&conn->hpd); nvif_event_allow(&conn->hpd);
nvif_event_allow(&conn->irq);
} }
drm_connector_list_iter_end(&conn_iter); drm_connector_list_iter_end(&conn_iter);
...@@ -619,7 +620,8 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime) ...@@ -619,7 +620,8 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
drm_connector_list_iter_begin(dev, &conn_iter); drm_connector_list_iter_begin(dev, &conn_iter);
nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
struct nouveau_connector *conn = nouveau_connector(connector); struct nouveau_connector *conn = nouveau_connector(connector);
nvif_notify_put(&conn->hpd); nvif_event_block(&conn->irq);
nvif_event_block(&conn->hpd);
} }
drm_connector_list_iter_end(&conn_iter); drm_connector_list_iter_end(&conn_iter);
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "nouveau_encoder.h" #include "nouveau_encoder.h"
#include "nouveau_crtc.h" #include "nouveau_crtc.h"
#include <nvif/event.h> #include <nvif/if0011.h>
MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)"); MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)");
static int nouveau_mst = 1; static int nouveau_mst = 1;
...@@ -222,11 +222,14 @@ nouveau_dp_link_check(struct nouveau_connector *nv_connector) ...@@ -222,11 +222,14 @@ nouveau_dp_link_check(struct nouveau_connector *nv_connector)
return nvif_outp_dp_retrain(&nv_encoder->outp) == 0; return nvif_outp_dp_retrain(&nv_encoder->outp) == 0;
} }
void nouveau_dp_irq(struct nouveau_drm *drm, void
struct nouveau_connector *nv_connector) nouveau_dp_irq(struct work_struct *work)
{ {
struct nouveau_connector *nv_connector =
container_of(work, typeof(*nv_connector), irq_work);
struct drm_connector *connector = &nv_connector->base; struct drm_connector *connector = &nv_connector->base;
struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP); struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP);
struct nouveau_drm *drm = nouveau_drm(outp->base.base.dev);
struct nv50_mstm *mstm; struct nv50_mstm *mstm;
u64 hpd = 0; u64 hpd = 0;
int ret; int ret;
...@@ -241,14 +244,14 @@ void nouveau_dp_irq(struct nouveau_drm *drm, ...@@ -241,14 +244,14 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
if (mstm && mstm->is_mst) { if (mstm && mstm->is_mst) {
if (!nv50_mstm_service(drm, nv_connector, mstm)) if (!nv50_mstm_service(drm, nv_connector, mstm))
hpd |= NVIF_NOTIFY_CONN_V0_UNPLUG; hpd |= NVIF_CONN_EVENT_V0_UNPLUG;
} else { } else {
drm_dp_cec_irq(&nv_connector->aux); drm_dp_cec_irq(&nv_connector->aux);
if (nouveau_dp_has_sink_count(connector, outp)) { if (nouveau_dp_has_sink_count(connector, outp)) {
ret = drm_dp_read_sink_count(&nv_connector->aux); ret = drm_dp_read_sink_count(&nv_connector->aux);
if (ret != outp->dp.sink_count) if (ret != outp->dp.sink_count)
hpd |= NVIF_NOTIFY_CONN_V0_PLUG; hpd |= NVIF_CONN_EVENT_V0_PLUG;
if (ret >= 0) if (ret >= 0)
outp->dp.sink_count = ret; outp->dp.sink_count = ret;
} }
...@@ -256,7 +259,7 @@ void nouveau_dp_irq(struct nouveau_drm *drm, ...@@ -256,7 +259,7 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
mutex_unlock(&outp->dp.hpd_irq_lock); mutex_unlock(&outp->dp.hpd_irq_lock);
nouveau_connector_hpd(nv_connector, NVIF_NOTIFY_CONN_V0_IRQ | hpd); nouveau_connector_hpd(nv_connector, NVIF_CONN_EVENT_V0_IRQ | hpd);
} }
/* TODO: /* TODO:
......
...@@ -142,8 +142,7 @@ enum nouveau_dp_status { ...@@ -142,8 +142,7 @@ enum nouveau_dp_status {
int nouveau_dp_detect(struct nouveau_connector *, struct nouveau_encoder *); int nouveau_dp_detect(struct nouveau_connector *, struct nouveau_encoder *);
bool nouveau_dp_link_check(struct nouveau_connector *); bool nouveau_dp_link_check(struct nouveau_connector *);
void nouveau_dp_irq(struct nouveau_drm *drm, void nouveau_dp_irq(struct work_struct *);
struct nouveau_connector *nv_connector);
enum drm_mode_status nv50_dp_mode_valid(struct drm_connector *, enum drm_mode_status nv50_dp_mode_valid(struct drm_connector *,
struct nouveau_encoder *, struct nouveau_encoder *,
const struct drm_display_mode *, const struct drm_display_mode *,
......
...@@ -26,6 +26,25 @@ ...@@ -26,6 +26,25 @@
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/if0011.h> #include <nvif/if0011.h>
int
nvif_conn_event_ctor(struct nvif_conn *conn, const char *name, nvif_event_func func, u8 types,
struct nvif_event *event)
{
struct {
struct nvif_event_v0 base;
struct nvif_conn_event_v0 conn;
} args;
int ret;
args.conn.version = 0;
args.conn.types = types;
ret = nvif_event_ctor_(&conn->object, name ?: "nvifConnHpd", nvif_conn_id(conn),
func, true, &args.base, sizeof(args), false, event);
NVIF_DEBUG(&conn->object, "[NEW EVENT:HPD types:%02x]", types);
return ret;
}
int int
nvif_conn_hpd_status(struct nvif_conn *conn) nvif_conn_hpd_status(struct nvif_conn *conn)
{ {
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "outp.h" #include "outp.h"
#include <core/client.h> #include <core/client.h>
#include <core/notify.h>
#include <core/ramht.h> #include <core/ramht.h>
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/dcb.h> #include <subdev/bios/dcb.h>
...@@ -69,54 +68,6 @@ nvkm_disp_vblank(struct nvkm_disp *disp, int head) ...@@ -69,54 +68,6 @@ nvkm_disp_vblank(struct nvkm_disp *disp, int head)
nvkm_event_send(&disp->vblank, NVKM_DISP_HEAD_EVENT_VBLANK, head, NULL, 0); nvkm_event_send(&disp->vblank, NVKM_DISP_HEAD_EVENT_VBLANK, head, NULL, 0);
} }
static int
nvkm_disp_hpd_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvkm_notify *notify)
{
struct nvkm_disp *disp =
container_of(notify->event, typeof(*disp), hpd);
union {
struct nvif_notify_conn_req_v0 v0;
} *req = data;
struct nvkm_outp *outp;
int ret = -ENOSYS;
if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, false))) {
notify->size = sizeof(struct nvif_notify_conn_rep_v0);
list_for_each_entry(outp, &disp->outps, head) {
if (ret = -ENXIO, outp->conn->index == req->v0.conn) {
if (ret = -ENODEV, outp->conn->hpd.event) {
notify->types = req->v0.mask;
notify->index = req->v0.conn;
ret = 0;
}
break;
}
}
}
return ret;
}
static const struct nvkm_event_func
nvkm_disp_hpd_func = {
.ctor = nvkm_disp_hpd_ctor
};
int
nvkm_disp_ntfy(struct nvkm_object *object, u32 type, struct nvkm_event **event)
{
struct nvkm_disp *disp = nvkm_disp(object->engine);
switch (type) {
case NV04_DISP_NTFY_CONN:
*event = &disp->hpd;
return 0;
default:
break;
}
return -EINVAL;
}
static int static int
nvkm_disp_class_new(struct nvkm_device *device, nvkm_disp_class_new(struct nvkm_device *device,
const struct nvkm_oclass *oclass, void *data, u32 size, const struct nvkm_oclass *oclass, void *data, u32 size,
...@@ -325,10 +276,6 @@ nvkm_disp_oneinit(struct nvkm_engine *engine) ...@@ -325,10 +276,6 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
list_add_tail(&outp->conn->head, &disp->conns); list_add_tail(&outp->conn->head, &disp->conns);
} }
ret = nvkm_event_init(&nvkm_disp_hpd_func, subdev, 3, hpd, &disp->hpd);
if (ret)
return ret;
if (disp->func->oneinit) { if (disp->func->oneinit) {
ret = disp->func->oneinit(disp); ret = disp->func->oneinit(disp);
if (ret) if (ret)
...@@ -376,7 +323,6 @@ nvkm_disp_dtor(struct nvkm_engine *engine) ...@@ -376,7 +323,6 @@ nvkm_disp_dtor(struct nvkm_engine *engine)
} }
nvkm_event_fini(&disp->vblank); nvkm_event_fini(&disp->vblank);
nvkm_event_fini(&disp->hpd);
while (!list_empty(&disp->conns)) { while (!list_empty(&disp->conns)) {
conn = list_first_entry(&disp->conns, typeof(*conn), head); conn = list_first_entry(&disp->conns, typeof(*conn), head);
......
...@@ -29,38 +29,14 @@ ...@@ -29,38 +29,14 @@
#include <nvif/event.h> #include <nvif/event.h>
static int
nvkm_conn_hpd(struct nvkm_notify *notify)
{
struct nvkm_conn *conn = container_of(notify, typeof(*conn), hpd);
struct nvkm_disp *disp = conn->disp;
struct nvkm_gpio *gpio = disp->engine.subdev.device->gpio;
const struct nvkm_gpio_ntfy_rep *line = notify->data;
struct nvif_notify_conn_rep_v0 rep;
int index = conn->index;
CONN_DBG(conn, "HPD: %d", line->mask);
if (!nvkm_gpio_get(gpio, 0, DCB_GPIO_UNUSED, conn->hpd.index))
rep.mask = NVIF_NOTIFY_CONN_V0_UNPLUG;
else
rep.mask = NVIF_NOTIFY_CONN_V0_PLUG;
rep.version = 0;
nvkm_event_send(&disp->hpd, rep.mask, index, &rep, sizeof(rep));
return NVKM_NOTIFY_KEEP;
}
void void
nvkm_conn_fini(struct nvkm_conn *conn) nvkm_conn_fini(struct nvkm_conn *conn)
{ {
nvkm_notify_put(&conn->hpd);
} }
void void
nvkm_conn_init(struct nvkm_conn *conn) nvkm_conn_init(struct nvkm_conn *conn)
{ {
nvkm_notify_get(&conn->hpd);
} }
void void
...@@ -68,7 +44,6 @@ nvkm_conn_del(struct nvkm_conn **pconn) ...@@ -68,7 +44,6 @@ nvkm_conn_del(struct nvkm_conn **pconn)
{ {
struct nvkm_conn *conn = *pconn; struct nvkm_conn *conn = *pconn;
if (conn) { if (conn) {
nvkm_notify_fini(&conn->hpd);
kfree(*pconn); kfree(*pconn);
*pconn = NULL; *pconn = NULL;
} }
...@@ -106,20 +81,6 @@ nvkm_conn_ctor(struct nvkm_disp *disp, int index, struct nvbios_connE *info, ...@@ -106,20 +81,6 @@ nvkm_conn_ctor(struct nvkm_disp *disp, int index, struct nvbios_connE *info,
} }
conn->info.hpd = func.line; conn->info.hpd = func.line;
ret = nvkm_notify_init(NULL, &gpio->event, nvkm_conn_hpd,
true, &(struct nvkm_gpio_ntfy_req) {
.mask = NVKM_GPIO_TOGGLED,
.line = func.line,
},
sizeof(struct nvkm_gpio_ntfy_req),
sizeof(struct nvkm_gpio_ntfy_rep),
&conn->hpd);
if (ret) {
CONN_ERR(conn, "func %02x failed, %d", info->hpd, ret);
} else {
CONN_DBG(conn, "func %02x (HPD)", info->hpd);
}
} }
} }
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
#define __NVKM_DISP_CONN_H__ #define __NVKM_DISP_CONN_H__
#include "priv.h" #include "priv.h"
#include <core/notify.h>
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/conn.h> #include <subdev/bios/conn.h>
...@@ -12,8 +11,6 @@ struct nvkm_conn { ...@@ -12,8 +11,6 @@ struct nvkm_conn {
int index; int index;
struct nvbios_connE info; struct nvbios_connE info;
struct nvkm_notify hpd;
struct list_head head; struct list_head head;
struct nvkm_object object; struct nvkm_object object;
......
...@@ -738,31 +738,9 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr) ...@@ -738,31 +738,9 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
} }
} }
static int
nvkm_dp_hpd(struct nvkm_notify *notify)
{
const struct nvkm_i2c_ntfy_rep *line = notify->data;
struct nvkm_outp *outp = container_of(notify, typeof(*outp), dp.hpd);
struct nvkm_conn *conn = outp->conn;
struct nvkm_disp *disp = outp->disp;
struct nvif_notify_conn_rep_v0 rep = {};
OUTP_DBG(outp, "HPD: %d", line->mask);
if (line->mask & NVKM_I2C_IRQ)
rep.mask |= NVIF_NOTIFY_CONN_V0_IRQ;
if (line->mask & NVKM_I2C_UNPLUG)
rep.mask |= NVIF_NOTIFY_CONN_V0_UNPLUG;
if (line->mask & NVKM_I2C_PLUG)
rep.mask |= NVIF_NOTIFY_CONN_V0_PLUG;
nvkm_event_send(&disp->hpd, rep.mask, conn->index, &rep, sizeof(rep));
return NVKM_NOTIFY_KEEP;
}
static void static void
nvkm_dp_fini(struct nvkm_outp *outp) nvkm_dp_fini(struct nvkm_outp *outp)
{ {
nvkm_notify_put(&outp->dp.hpd);
nvkm_dp_enable(outp, false); nvkm_dp_enable(outp, false);
} }
...@@ -770,14 +748,11 @@ static void ...@@ -770,14 +748,11 @@ static void
nvkm_dp_init(struct nvkm_outp *outp) nvkm_dp_init(struct nvkm_outp *outp)
{ {
nvkm_dp_enable(outp, outp->dp.enabled); nvkm_dp_enable(outp, outp->dp.enabled);
nvkm_notify_put(&outp->conn->hpd);
nvkm_notify_get(&outp->dp.hpd);
} }
static void * static void *
nvkm_dp_dtor(struct nvkm_outp *outp) nvkm_dp_dtor(struct nvkm_outp *outp)
{ {
nvkm_notify_fini(&outp->dp.hpd);
return outp; return outp;
} }
...@@ -826,21 +801,6 @@ nvkm_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE, struct n ...@@ -826,21 +801,6 @@ nvkm_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE, struct n
OUTP_DBG(outp, "bios dp %02x %02x %02x %02x", outp->dp.version, hdr, cnt, len); OUTP_DBG(outp, "bios dp %02x %02x %02x %02x", outp->dp.version, hdr, cnt, len);
/* hotplug detect, replaces gpio-based mechanism with aux events */
ret = nvkm_notify_init(NULL, &i2c->event, nvkm_dp_hpd, true,
&(struct nvkm_i2c_ntfy_req) {
.mask = NVKM_I2C_PLUG | NVKM_I2C_UNPLUG |
NVKM_I2C_IRQ,
.port = outp->dp.aux->id,
},
sizeof(struct nvkm_i2c_ntfy_req),
sizeof(struct nvkm_i2c_ntfy_rep),
&outp->dp.hpd);
if (ret) {
OUTP_ERR(outp, "error monitoring aux hpd: %d", ret);
return ret;
}
mutex_init(&outp->dp.mutex); mutex_init(&outp->dp.mutex);
atomic_set(&outp->dp.lt.done, 0); atomic_set(&outp->dp.lt.done, 0);
return 0; return 0;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#ifndef __NVKM_DISP_OUTP_H__ #ifndef __NVKM_DISP_OUTP_H__
#define __NVKM_DISP_OUTP_H__ #define __NVKM_DISP_OUTP_H__
#include "priv.h" #include "priv.h"
#include <core/notify.h>
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/dcb.h> #include <subdev/bios/dcb.h>
...@@ -38,7 +37,6 @@ struct nvkm_outp { ...@@ -38,7 +37,6 @@ struct nvkm_outp {
struct nvkm_i2c_aux *aux; struct nvkm_i2c_aux *aux;
struct nvkm_notify hpd;
bool enabled; bool enabled;
bool aux_pwr; bool aux_pwr;
bool aux_pwr_pu; bool aux_pwr_pu;
......
...@@ -42,8 +42,6 @@ struct nvkm_disp_func { ...@@ -42,8 +42,6 @@ struct nvkm_disp_func {
} user[]; } user[];
}; };
int nvkm_disp_ntfy(struct nvkm_object *, u32, struct nvkm_event **);
int nv50_disp_oneinit(struct nvkm_disp *); int nv50_disp_oneinit(struct nvkm_disp *);
int nv50_disp_init(struct nvkm_disp *); int nv50_disp_init(struct nvkm_disp *);
void nv50_disp_fini(struct nvkm_disp *); void nv50_disp_fini(struct nvkm_disp *);
......
...@@ -21,11 +21,85 @@ ...@@ -21,11 +21,85 @@
*/ */
#define nvkm_uconn(p) container_of((p), struct nvkm_conn, object) #define nvkm_uconn(p) container_of((p), struct nvkm_conn, object)
#include "conn.h" #include "conn.h"
#include "outp.h"
#include <core/client.h>
#include <core/event.h>
#include <subdev/gpio.h> #include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <nvif/if0011.h> #include <nvif/if0011.h>
static int
nvkm_uconn_uevent_aux(struct nvkm_object *object, u64 token, u32 bits)
{
union nvif_conn_event_args args;
args.v0.version = 0;
args.v0.types = 0;
if (bits & NVKM_I2C_PLUG)
args.v0.types |= NVIF_CONN_EVENT_V0_PLUG;
if (bits & NVKM_I2C_UNPLUG)
args.v0.types |= NVIF_CONN_EVENT_V0_UNPLUG;
if (bits & NVKM_I2C_IRQ)
args.v0.types |= NVIF_CONN_EVENT_V0_IRQ;
return object->client->event(token, &args, sizeof(args.v0));
}
static int
nvkm_uconn_uevent_gpio(struct nvkm_object *object, u64 token, u32 bits)
{
union nvif_conn_event_args args;
args.v0.version = 0;
args.v0.types = 0;
if (bits & NVKM_GPIO_HI)
args.v0.types |= NVIF_CONN_EVENT_V0_PLUG;
if (bits & NVKM_GPIO_LO)
args.v0.types |= NVIF_CONN_EVENT_V0_UNPLUG;
return object->client->event(token, &args, sizeof(args.v0));
}
static int
nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent)
{
struct nvkm_conn *conn = nvkm_uconn(object);
struct nvkm_device *device = conn->disp->engine.subdev.device;
struct nvkm_outp *outp;
union nvif_conn_event_args *args = argv;
u64 bits = 0;
if (!uevent) {
if (conn->info.hpd == DCB_GPIO_UNUSED)
return -ENOSYS;
return 0;
}
if (argc != sizeof(args->v0) || args->v0.version != 0)
return -ENOSYS;
list_for_each_entry(outp, &conn->disp->outps, head) {
if (outp->info.connector == conn->index && outp->dp.aux) {
if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG ) bits |= NVKM_I2C_PLUG;
if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_I2C_UNPLUG;
if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ ) bits |= NVKM_I2C_IRQ;
return nvkm_uevent_add(uevent, &device->i2c->event, outp->dp.aux->id, bits,
nvkm_uconn_uevent_aux);
}
}
if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG ) bits |= NVKM_GPIO_HI;
if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_GPIO_LO;
if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ)
return -EINVAL;
return nvkm_uevent_add(uevent, &device->gpio->event, conn->info.hpd, bits,
nvkm_uconn_uevent_gpio);
}
static int static int
nvkm_uconn_mthd_hpd_status(struct nvkm_conn *conn, void *argv, u32 argc) nvkm_uconn_mthd_hpd_status(struct nvkm_conn *conn, void *argv, u32 argc)
{ {
...@@ -82,6 +156,7 @@ static const struct nvkm_object_func ...@@ -82,6 +156,7 @@ static const struct nvkm_object_func
nvkm_uconn = { nvkm_uconn = {
.dtor = nvkm_uconn_dtor, .dtor = nvkm_uconn_dtor,
.mthd = nvkm_uconn_mthd, .mthd = nvkm_uconn_mthd,
.uevent = nvkm_uconn_uevent,
}; };
int int
......
...@@ -74,7 +74,6 @@ nvkm_udisp_dtor(struct nvkm_object *object) ...@@ -74,7 +74,6 @@ nvkm_udisp_dtor(struct nvkm_object *object)
static const struct nvkm_object_func static const struct nvkm_object_func
nvkm_udisp = { nvkm_udisp = {
.dtor = nvkm_udisp_dtor, .dtor = nvkm_udisp_dtor,
.ntfy = nvkm_disp_ntfy,
.sclass = nvkm_udisp_sclass, .sclass = nvkm_udisp_sclass,
}; };
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "priv.h" #include "priv.h"
#include <core/option.h> #include <core/option.h>
#include <core/notify.h>
static int static int
nvkm_gpio_drive(struct nvkm_gpio *gpio, int idx, int line, int dir, int out) nvkm_gpio_drive(struct nvkm_gpio *gpio, int idx, int line, int dir, int out)
...@@ -123,23 +122,8 @@ nvkm_gpio_intr_init(struct nvkm_event *event, int type, int index) ...@@ -123,23 +122,8 @@ nvkm_gpio_intr_init(struct nvkm_event *event, int type, int index)
gpio->func->intr_mask(gpio, type, 1 << index, 1 << index); gpio->func->intr_mask(gpio, type, 1 << index, 1 << index);
} }
static int
nvkm_gpio_intr_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvkm_notify *notify)
{
struct nvkm_gpio_ntfy_req *req = data;
if (!WARN_ON(size != sizeof(*req))) {
notify->size = sizeof(struct nvkm_gpio_ntfy_rep);
notify->types = req->mask;
notify->index = req->line;
return 0;
}
return -EINVAL;
}
static const struct nvkm_event_func static const struct nvkm_event_func
nvkm_gpio_intr_func = { nvkm_gpio_intr_func = {
.ctor = nvkm_gpio_intr_ctor,
.init = nvkm_gpio_intr_init, .init = nvkm_gpio_intr_init,
.fini = nvkm_gpio_intr_fini, .fini = nvkm_gpio_intr_fini,
}; };
...@@ -153,11 +137,9 @@ nvkm_gpio_intr(struct nvkm_subdev *subdev) ...@@ -153,11 +137,9 @@ nvkm_gpio_intr(struct nvkm_subdev *subdev)
gpio->func->intr_stat(gpio, &hi, &lo); gpio->func->intr_stat(gpio, &hi, &lo);
for (i = 0; (hi | lo) && i < gpio->func->lines; i++) { for (i = 0; (hi | lo) && i < gpio->func->lines; i++) {
struct nvkm_gpio_ntfy_rep rep = { u32 mask = (NVKM_GPIO_HI * !!(hi & (1 << i))) |
.mask = (NVKM_GPIO_HI * !!(hi & (1 << i))) | (NVKM_GPIO_LO * !!(lo & (1 << i)));
(NVKM_GPIO_LO * !!(lo & (1 << i))), nvkm_event_send(&gpio->event, mask, i, NULL, 0);
};
nvkm_event_send(&gpio->event, rep.mask, i, &rep, sizeof(rep));
} }
} }
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "bus.h" #include "bus.h"
#include "pad.h" #include "pad.h"
#include <core/notify.h>
#include <core/option.h> #include <core/option.h>
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/dcb.h> #include <subdev/bios/dcb.h>
...@@ -104,23 +103,8 @@ nvkm_i2c_intr_init(struct nvkm_event *event, int type, int id) ...@@ -104,23 +103,8 @@ nvkm_i2c_intr_init(struct nvkm_event *event, int type, int id)
i2c->func->aux_mask(i2c, type, aux->intr, aux->intr); i2c->func->aux_mask(i2c, type, aux->intr, aux->intr);
} }
static int
nvkm_i2c_intr_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvkm_notify *notify)
{
struct nvkm_i2c_ntfy_req *req = data;
if (!WARN_ON(size != sizeof(*req))) {
notify->size = sizeof(struct nvkm_i2c_ntfy_rep);
notify->types = req->mask;
notify->index = req->port;
return 0;
}
return -EINVAL;
}
static const struct nvkm_event_func static const struct nvkm_event_func
nvkm_i2c_intr_func = { nvkm_i2c_intr_func = {
.ctor = nvkm_i2c_intr_ctor,
.init = nvkm_i2c_intr_init, .init = nvkm_i2c_intr_init,
.fini = nvkm_i2c_intr_fini, .fini = nvkm_i2c_intr_fini,
}; };
...@@ -145,13 +129,8 @@ nvkm_i2c_intr(struct nvkm_subdev *subdev) ...@@ -145,13 +129,8 @@ nvkm_i2c_intr(struct nvkm_subdev *subdev)
if (lo & aux->intr) mask |= NVKM_I2C_UNPLUG; if (lo & aux->intr) mask |= NVKM_I2C_UNPLUG;
if (rq & aux->intr) mask |= NVKM_I2C_IRQ; if (rq & aux->intr) mask |= NVKM_I2C_IRQ;
if (tx & aux->intr) mask |= NVKM_I2C_DONE; if (tx & aux->intr) mask |= NVKM_I2C_DONE;
if (mask) { if (mask)
struct nvkm_i2c_ntfy_rep rep = { nvkm_event_send(&i2c->event, mask, aux->id, NULL, 0);
.mask = mask,
};
nvkm_event_send(&i2c->event, rep.mask, aux->id,
&rep, sizeof(rep));
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment