summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c146
1 files changed, 4 insertions, 142 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
index 73104b59f97f..39f7e7ce9f4a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
@@ -23,15 +23,12 @@
*/
#include "priv.h"
#include "conn.h"
-#include "dp.h"
#include "head.h"
#include "ior.h"
#include "outp.h"
#include <core/client.h>
#include <core/ramht.h>
-#include <subdev/bios.h>
-#include <subdev/bios/dcb.h>
#include <nvif/class.h>
#include <nvif/cl0046.h>
@@ -105,18 +102,14 @@ static int
nvkm_disp_fini(struct nvkm_engine *engine, bool suspend)
{
struct nvkm_disp *disp = nvkm_disp(engine);
- struct nvkm_conn *conn;
struct nvkm_outp *outp;
if (disp->func->fini)
disp->func->fini(disp);
list_for_each_entry(outp, &disp->outps, head) {
- nvkm_outp_fini(outp);
- }
-
- list_for_each_entry(conn, &disp->conns, head) {
- nvkm_conn_fini(conn);
+ if (outp->func->fini)
+ outp->func->fini(outp);
}
return 0;
@@ -126,16 +119,12 @@ static int
nvkm_disp_init(struct nvkm_engine *engine)
{
struct nvkm_disp *disp = nvkm_disp(engine);
- struct nvkm_conn *conn;
struct nvkm_outp *outp;
struct nvkm_ior *ior;
- list_for_each_entry(conn, &disp->conns, head) {
- nvkm_conn_init(conn);
- }
-
list_for_each_entry(outp, &disp->outps, head) {
- nvkm_outp_init(outp);
+ if (outp->func->init)
+ outp->func->init(outp);
}
if (disp->func->init) {
@@ -159,142 +148,15 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
{
struct nvkm_disp *disp = nvkm_disp(engine);
struct nvkm_subdev *subdev = &disp->engine.subdev;
- struct nvkm_bios *bios = subdev->device->bios;
- struct nvkm_outp *outp, *outt, *pair;
- struct nvkm_conn *conn;
struct nvkm_head *head;
- struct nvkm_ior *ior;
- struct nvbios_connE connE;
- struct dcb_output dcbE;
- u8 hpd = 0, ver, hdr;
- u32 data;
int ret, i;
- /* Create output path objects for each VBIOS display path. */
- i = -1;
- while ((data = dcb_outp_parse(bios, ++i, &ver, &hdr, &dcbE))) {
- if (ver < 0x40) /* No support for chipsets prior to NV50. */
- break;
- if (dcbE.type == DCB_OUTPUT_UNUSED)
- continue;
- if (dcbE.type == DCB_OUTPUT_EOL)
- break;
- outp = NULL;
-
- switch (dcbE.type) {
- case DCB_OUTPUT_ANALOG:
- case DCB_OUTPUT_TV:
- case DCB_OUTPUT_TMDS:
- case DCB_OUTPUT_LVDS:
- ret = nvkm_outp_new(disp, i, &dcbE, &outp);
- break;
- case DCB_OUTPUT_DP:
- ret = nvkm_dp_new(disp, i, &dcbE, &outp);
- break;
- case DCB_OUTPUT_WFD:
- /* No support for WFD yet. */
- ret = -ENODEV;
- continue;
- default:
- nvkm_warn(subdev, "dcb %d type %d unknown\n",
- i, dcbE.type);
- continue;
- }
-
- if (ret) {
- if (outp) {
- if (ret != -ENODEV)
- OUTP_ERR(outp, "ctor failed: %d", ret);
- else
- OUTP_DBG(outp, "not supported");
- nvkm_outp_del(&outp);
- continue;
- }
- nvkm_error(subdev, "failed to create outp %d\n", i);
- continue;
- }
-
- list_add_tail(&outp->head, &disp->outps);
- hpd = max(hpd, (u8)(dcbE.connector + 1));
- }
-
- /* Create connector objects based on available output paths. */
- list_for_each_entry_safe(outp, outt, &disp->outps, head) {
- /* VBIOS data *should* give us the most useful information. */
- data = nvbios_connEp(bios, outp->info.connector, &ver, &hdr,
- &connE);
-
- /* No bios connector data... */
- if (!data) {
- /* Heuristic: anything with the same ccb index is
- * considered to be on the same connector, any
- * output path without an associated ccb entry will
- * be put on its own connector.
- */
- int ccb_index = outp->info.i2c_index;
- if (ccb_index != 0xf) {
- list_for_each_entry(pair, &disp->outps, head) {
- if (pair->info.i2c_index == ccb_index) {
- outp->conn = pair->conn;
- break;
- }
- }
- }
-
- /* Connector shared with another output path. */
- if (outp->conn)
- continue;
-
- memset(&connE, 0x00, sizeof(connE));
- connE.type = DCB_CONNECTOR_NONE;
- i = -1;
- } else {
- i = outp->info.connector;
- }
-
- /* Check that we haven't already created this connector. */
- list_for_each_entry(conn, &disp->conns, head) {
- if (conn->index == outp->info.connector) {
- outp->conn = conn;
- break;
- }
- }
-
- if (outp->conn)
- continue;
-
- /* Apparently we need to create a new one! */
- ret = nvkm_conn_new(disp, i, &connE, &outp->conn);
- if (ret) {
- nvkm_error(subdev, "failed to create outp %d conn: %d\n", outp->index, ret);
- nvkm_conn_del(&outp->conn);
- list_del(&outp->head);
- nvkm_outp_del(&outp);
- continue;
- }
-
- list_add_tail(&outp->conn->head, &disp->conns);
- }
-
if (disp->func->oneinit) {
ret = disp->func->oneinit(disp);
if (ret)
return ret;
}
- /* Enforce identity-mapped SOR assignment for panels, which have
- * certain bits (ie. backlight controls) wired to a specific SOR.
- */
- list_for_each_entry(outp, &disp->outps, head) {
- if (outp->conn->info.type == DCB_CONNECTOR_LVDS ||
- outp->conn->info.type == DCB_CONNECTOR_eDP) {
- ior = nvkm_ior_find(disp, SOR, ffs(outp->info.or) - 1);
- if (!WARN_ON(!ior))
- ior->identity = true;
- outp->identity = true;
- }
- }
-
i = 0;
list_for_each_entry(head, &disp->heads, head)
i = max(i, head->id + 1);