summaryrefslogtreecommitdiff
path: root/nvkm/subdev/mxm/nv50.c
diff options
context:
space:
mode:
Diffstat (limited to 'nvkm/subdev/mxm/nv50.c')
-rw-r--r--nvkm/subdev/mxm/nv50.c233
1 files changed, 0 insertions, 233 deletions
diff --git a/nvkm/subdev/mxm/nv50.c b/nvkm/subdev/mxm/nv50.c
deleted file mode 100644
index fcaabe845..000000000
--- a/nvkm/subdev/mxm/nv50.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright 2011 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include <subdev/mxm.h>
-#include <subdev/bios.h>
-#include <subdev/bios/conn.h>
-#include <subdev/bios/dcb.h>
-#include <subdev/bios/mxm.h>
-
-#include "mxms.h"
-
-struct nv50_mxm_priv {
- struct nouveau_mxm base;
-};
-
-struct context {
- u32 *outp;
- struct mxms_odev desc;
-};
-
-static bool
-mxm_match_tmds_partner(struct nouveau_mxm *mxm, u8 *data, void *info)
-{
- struct context *ctx = info;
- struct mxms_odev desc;
-
- mxms_output_device(mxm, data, &desc);
- if (desc.outp_type == 2 &&
- desc.dig_conn == ctx->desc.dig_conn)
- return false;
- return true;
-}
-
-static bool
-mxm_match_dcb(struct nouveau_mxm *mxm, u8 *data, void *info)
-{
- struct nouveau_bios *bios = nouveau_bios(mxm);
- struct context *ctx = info;
- u64 desc = *(u64 *)data;
-
- mxms_output_device(mxm, data, &ctx->desc);
-
- /* match dcb encoder type to mxm-ods device type */
- if ((ctx->outp[0] & 0x0000000f) != ctx->desc.outp_type)
- return true;
-
- /* digital output, have some extra stuff to match here, there's a
- * table in the vbios that provides a mapping from the mxm digital
- * connection enum values to SOR/link
- */
- if ((desc & 0x00000000000000f0) >= 0x20) {
- /* check against sor index */
- u8 link = mxm_sor_map(bios, ctx->desc.dig_conn);
- if ((ctx->outp[0] & 0x0f000000) != (link & 0x0f) << 24)
- return true;
-
- /* check dcb entry has a compatible link field */
- link = (link & 0x30) >> 4;
- if ((link & ((ctx->outp[1] & 0x00000030) >> 4)) != link)
- return true;
- }
-
- /* mark this descriptor accounted for by setting invalid device type,
- * except of course some manufactures don't follow specs properly and
- * we need to avoid killing off the TMDS function on DP connectors
- * if MXM-SIS is missing an entry for it.
- */
- data[0] &= ~0xf0;
- if (ctx->desc.outp_type == 6 && ctx->desc.conn_type == 6 &&
- mxms_foreach(mxm, 0x01, mxm_match_tmds_partner, ctx)) {
- data[0] |= 0x20; /* modify descriptor to match TMDS now */
- } else {
- data[0] |= 0xf0;
- }
-
- return false;
-}
-
-static int
-mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb)
-{
- struct nouveau_mxm *mxm = data;
- struct context ctx = { .outp = (u32 *)(bios->data + pdcb) };
- u8 type, i2cidx, link, ver, len;
- u8 *conn;
-
- /* look for an output device structure that matches this dcb entry.
- * if one isn't found, disable it.
- */
- if (mxms_foreach(mxm, 0x01, mxm_match_dcb, &ctx)) {
- nv_debug(mxm, "disable %d: 0x%08x 0x%08x\n",
- idx, ctx.outp[0], ctx.outp[1]);
- ctx.outp[0] |= 0x0000000f;
- return 0;
- }
-
- /* modify the output's ddc/aux port, there's a pointer to a table
- * with the mapping from mxm ddc/aux port to dcb i2c_index in the
- * vbios mxm table
- */
- i2cidx = mxm_ddc_map(bios, ctx.desc.ddc_port);
- if ((ctx.outp[0] & 0x0000000f) != DCB_OUTPUT_DP)
- i2cidx = (i2cidx & 0x0f) << 4;
- else
- i2cidx = (i2cidx & 0xf0);
-
- if (i2cidx != 0xf0) {
- ctx.outp[0] &= ~0x000000f0;
- ctx.outp[0] |= i2cidx;
- }
-
- /* override dcb sorconf.link, based on what mxm data says */
- switch (ctx.desc.outp_type) {
- case 0x00: /* Analog CRT */
- case 0x01: /* Analog TV/HDTV */
- break;
- default:
- link = mxm_sor_map(bios, ctx.desc.dig_conn) & 0x30;
- ctx.outp[1] &= ~0x00000030;
- ctx.outp[1] |= link;
- break;
- }
-
- /* we may need to fixup various other vbios tables based on what
- * the descriptor says the connector type should be.
- *
- * in a lot of cases, the vbios tables will claim DVI-I is possible,
- * and the mxm data says the connector is really HDMI. another
- * common example is DP->eDP.
- */
- conn = bios->data;
- conn += nvbios_connEe(bios, (ctx.outp[0] & 0x0000f000) >> 12, &ver, &len);
- type = conn[0];
- switch (ctx.desc.conn_type) {
- case 0x01: /* LVDS */
- ctx.outp[1] |= 0x00000004; /* use_power_scripts */
- /* XXX: modify default link width in LVDS table */
- break;
- case 0x02: /* HDMI */
- type = DCB_CONNECTOR_HDMI_1;
- break;
- case 0x03: /* DVI-D */
- type = DCB_CONNECTOR_DVI_D;
- break;
- case 0x0e: /* eDP, falls through to DPint */
- ctx.outp[1] |= 0x00010000;
- case 0x07: /* DP internal, wtf is this?? HP8670w */
- ctx.outp[1] |= 0x00000004; /* use_power_scripts? */
- type = DCB_CONNECTOR_eDP;
- break;
- default:
- break;
- }
-
- if (mxms_version(mxm) >= 0x0300)
- conn[0] = type;
-
- return 0;
-}
-
-static bool
-mxm_show_unmatched(struct nouveau_mxm *mxm, u8 *data, void *info)
-{
- u64 desc = *(u64 *)data;
- if ((desc & 0xf0) != 0xf0)
- nv_info(mxm, "unmatched output device 0x%016llx\n", desc);
- return true;
-}
-
-static void
-mxm_dcb_sanitise(struct nouveau_mxm *mxm)
-{
- struct nouveau_bios *bios = nouveau_bios(mxm);
- u8 ver, hdr, cnt, len;
- u16 dcb = dcb_table(bios, &ver, &hdr, &cnt, &len);
- if (dcb == 0x0000 || ver != 0x40) {
- nv_debug(mxm, "unsupported DCB version\n");
- return;
- }
-
- dcb_outp_foreach(bios, mxm, mxm_dcb_sanitise_entry);
- mxms_foreach(mxm, 0x01, mxm_show_unmatched, NULL);
-}
-
-static int
-nv50_mxm_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nv50_mxm_priv *priv;
- int ret;
-
- ret = nouveau_mxm_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- if (priv->base.action & MXM_SANITISE_DCB)
- mxm_dcb_sanitise(&priv->base);
- return 0;
-}
-
-struct nouveau_oclass
-nv50_mxm_oclass = {
- .handle = NV_SUBDEV(MXM, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_mxm_ctor,
- .dtor = _nouveau_mxm_dtor,
- .init = _nouveau_mxm_init,
- .fini = _nouveau_mxm_fini,
- },
-};