/* ... except prior to G80, where the code
* doesn't support such things.
*/
- if (disp->disp.oclass < NV50_DISP)
+ if (disp->disp.object.oclass < NV50_DISP)
return -EINVAL;
break;
default:
asyc->procamp.color_vibrance = 150;
asyc->procamp.vibrant_hue = 90;
- if (nouveau_display(connector->dev)->disp.oclass < NV50_DISP) {
+ if (nouveau_display(connector->dev)->disp.object.oclass < NV50_DISP) {
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_LVDS:
/* See note in nouveau_conn_atomic_set_property(). */
case DRM_MODE_CONNECTOR_TV:
break;
case DRM_MODE_CONNECTOR_VGA:
- if (disp->disp.oclass < NV50_DISP)
+ if (disp->disp.object.oclass < NV50_DISP)
break; /* Can only scale on DFPs. */
/* Fall-through. */
default:
}
/* HDMI 3D support */
- if ((disp->disp.oclass >= G82_DISP)
+ if ((disp->disp.object.oclass >= G82_DISP)
&& ((type == DRM_MODE_CONNECTOR_DisplayPort)
|| (type == DRM_MODE_CONNECTOR_eDP)
|| (type == DRM_MODE_CONNECTOR_HDMIA)))
case DCB_CONNECTOR_LVDS_SPWG:
case DCB_CONNECTOR_eDP:
/* see note in nouveau_connector_set_property() */
- if (disp->disp.oclass < NV50_DISP) {
+ if (disp->disp.object.oclass < NV50_DISP) {
nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
break;
}
break;
}
- ret = nvif_notify_init(&disp->disp, nouveau_connector_hotplug, true,
- NV04_DISP_NTFY_CONN,
+ ret = nvif_notify_init(&disp->disp.object, nouveau_connector_hotplug,
+ true, NV04_DISP_NTFY_CONN,
&(struct nvif_notify_conn_req_v0) {
.mask = NVIF_NOTIFY_CONN_V0_ANY,
.conn = index,
bool ret = false;
do {
- ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args));
+ ret = nvif_mthd(&disp->disp.object, 0, &args, sizeof(args));
if (ret != 0)
return false;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- ret = nvif_notify_init(&disp->disp,
+ ret = nvif_notify_init(&disp->disp.object,
nouveau_display_vblank_handler, false,
NV04_DISP_NTFY_VBLANK,
&(struct nvif_notify_head_req_v0) {
struct nouveau_display *disp = nouveau_display(dev);
int gen;
- if (disp->disp.oclass < NV50_DISP)
+ if (disp->disp.object.oclass < NV50_DISP)
gen = 0;
else
- if (disp->disp.oclass < GF110_DISP)
+ if (disp->disp.object.oclass < GF110_DISP)
gen = 1;
else
gen = 2;
drm_kms_helper_poll_disable(dev);
if (nouveau_modeset != 2 && drm->vbios.dcb.entries) {
- static const u16 oclass[] = {
- GP102_DISP,
- GP100_DISP,
- GM200_DISP,
- GM107_DISP,
- GK110_DISP,
- GK104_DISP,
- GF110_DISP,
- GT214_DISP,
- GT206_DISP,
- GT200_DISP,
- G82_DISP,
- NV50_DISP,
- NV04_DISP,
- };
- int i;
-
- for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) {
- ret = nvif_object_init(&drm->client.device.object, 0,
- oclass[i], NULL, 0, &disp->disp);
- }
-
+ ret = nvif_disp_ctor(&drm->client.device, 0, &disp->disp);
if (ret == 0) {
nouveau_display_create_properties(dev);
- if (disp->disp.oclass < NV50_DISP)
+ if (disp->disp.object.oclass < NV50_DISP)
ret = nv04_display_create(dev);
else
ret = nv50_display_create(dev);
if (disp->dtor)
disp->dtor(dev);
- nvif_object_fini(&disp->disp);
+ nvif_disp_dtor(&disp->disp);
nouveau_drm(dev)->display = NULL;
kfree(disp);
#define nv50_vers(c) nv50_chan(c)->user.oclass
struct nv50_disp {
- struct nvif_object *disp;
+ struct nvif_disp *disp;
struct nv50_mast mast;
struct nouveau_bo *sync;
struct nv50_curs *curs;
int cid, ret;
- cid = nvif_mclass(disp->disp, curses);
+ cid = nvif_mclass(&disp->disp->object, curses);
if (cid < 0) {
NV_ERROR(drm, "No supported cursor immediate class\n");
return cid;
return ret;
}
- ret = nvif_object_init(disp->disp, 0, curses[cid].oclass, &args,
- sizeof(args), &curs->chan);
+ ret = nvif_object_init(&disp->disp->object, 0, curses[cid].oclass,
+ &args, sizeof(args), &curs->chan);
if (ret) {
NV_ERROR(drm, "curs%04x allocation failed: %d\n",
curses[cid].oclass, ret);
return ret;
}
- ret = nv50_base_create(&drm->client.device, disp->disp, base->id,
- disp->sync->bo.offset, &base->chan);
+ ret = nv50_base_create(&drm->client.device, &disp->disp->object,
+ base->id, disp->sync->bo.offset, &base->chan);
if (ret)
return ret;
return;
}
- if (disp->disp->oclass < GF110_DISP) {
+ if (disp->disp->object.oclass < GF110_DISP) {
asyh->lut.mode = (asyh->base.cpp == 1) ? 0 : 1;
asyh->set.ilut = true;
} else {
}
/* allocate overlay resources */
- ret = nv50_oimm_create(device, disp->disp, index, &head->oimm);
+ ret = nv50_oimm_create(device, &disp->disp->object, index, &head->oimm);
if (ret)
goto out;
- ret = nv50_ovly_create(device, disp->disp, index, disp->sync->bo.offset,
- &head->ovly);
+ ret = nv50_ovly_create(device, &disp->disp->object, index,
+ disp->sync->bo.offset, &head->ovly);
if (ret)
goto out;
.base.hashm = nv_encoder->dcb->hashm,
};
- nvif_mthd(disp->disp, 0, &args, sizeof(args));
+ nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
nv_encoder->or = -1;
nv_encoder->link = 0;
}
};
int ret;
- ret = nvif_mthd(disp->disp, 0, &args, sizeof(args));
+ ret = nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
if (ret) {
NV_ERROR(drm, "error acquiring output path: %d\n", ret);
return ret;
if (args.load.data == 0)
args.load.data = 340;
- ret = nvif_mthd(disp->disp, 0, &args, sizeof(args));
+ ret = nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
if (ret || !args.load.load)
return connector_status_disconnected;
(0x0100 << nv_crtc->index),
};
- nvif_mthd(disp->disp, 0, &args, sizeof(args));
+ nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
}
static void
memcpy(args.data, nv_connector->base.eld, sizeof(args.data));
- nvif_mthd(disp->disp, 0, &args,
+ nvif_mthd(&disp->disp->object, 0, &args,
sizeof(args.base) + drm_eld_size(args.data));
}
(0x0100 << nv_crtc->index),
};
- nvif_mthd(disp->disp, 0, &args, sizeof(args));
+ nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
}
static void
+ sizeof(args.pwr)
+ args.pwr.avi_infoframe_length
+ args.pwr.vendor_infoframe_length;
- nvif_mthd(disp->disp, 0, &args, size);
+ nvif_mthd(&disp->disp->object, 0, &args, size);
nv50_audio_enable(encoder, mode);
}
msto->encoder.name, msto->head->base.base.name,
args.vcpi.start_slot, args.vcpi.num_slots,
args.vcpi.pbn, args.vcpi.aligned_pbn);
- nvif_mthd(&drm->display->disp, 0, &args, sizeof(args));
+ nvif_mthd(&drm->display->disp.object, 0, &args, sizeof(args));
}
static int
.mst.state = state,
};
struct nouveau_drm *drm = nouveau_drm(outp->base.base.dev);
- struct nvif_object *disp = &drm->display->disp;
+ struct nvif_object *disp = &drm->display->disp.object;
int ret;
if (dpcd >= 0x12) {
lvds.lvds.script |= 0x0200;
}
- nvif_mthd(disp->disp, 0, &lvds, sizeof(lvds));
+ nvif_mthd(&disp->disp->object, 0, &lvds, sizeof(lvds));
break;
case DCB_OUTPUT_DP:
if (nv_connector->base.display_info.bpc == 6)
struct nvkm_i2c_aux *aux =
nvkm_i2c_aux_find(i2c, dcbe->i2c_index);
if (aux) {
- if (disp->disp->oclass < GF110_DISP) {
+ if (disp->disp->object.oclass < GF110_DISP) {
/* HW has no support for address-only
* transactions, so we're required to
* use custom I2C-over-AUX code.
}
/*TODO: Use DP Info Table to check for support. */
- if (disp->disp->oclass >= GF110_DISP) {
+ if (disp->disp->object.oclass >= GF110_DISP) {
ret = nv50_mstm_new(nv_encoder, &nv_connector->aux, 16,
nv_connector->base.base.id,
&nv_encoder->dp.mstm);
goto out;
/* allocate master evo channel */
- ret = nv50_core_create(device, disp->disp, disp->sync->bo.offset,
- &disp->mast);
+ ret = nv50_core_create(device, &disp->disp->object,
+ disp->sync->bo.offset, &disp->mast);
if (ret)
goto out;
/* create crtc objects to represent the hw heads */
- if (disp->disp->oclass >= GF110_DISP)
+ if (disp->disp->object.oclass >= GF110_DISP)
crtcs = nvif_rd32(&device->object, 0x612004) & 0xf;
else
crtcs = 0x3;
--- /dev/null
+/*
+ * Copyright 2018 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.
+ */
+#include <nvif/disp.h>
+#include <nvif/device.h>
+
+#include <nvif/class.h>
+
+void
+nvif_disp_dtor(struct nvif_disp *disp)
+{
+ nvif_object_fini(&disp->object);
+}
+
+int
+nvif_disp_ctor(struct nvif_device *device, s32 oclass, struct nvif_disp *disp)
+{
+ static const struct nvif_mclass disps[] = {
+ { GP102_DISP, -1 },
+ { GP100_DISP, -1 },
+ { GM200_DISP, -1 },
+ { GM107_DISP, -1 },
+ { GK110_DISP, -1 },
+ { GK104_DISP, -1 },
+ { GF110_DISP, -1 },
+ { GT214_DISP, -1 },
+ { GT206_DISP, -1 },
+ { GT200_DISP, -1 },
+ { G82_DISP, -1 },
+ { NV50_DISP, -1 },
+ { NV04_DISP, -1 },
+ {}
+ };
+ int cid = nvif_sclass(&device->object, disps, oclass);
+ disp->object.client = NULL;
+ if (cid < 0)
+ return cid;
+
+ return nvif_object_init(&device->object, 0, disps[cid].oclass,
+ NULL, 0, &disp->object);
+}