Esempio n. 1
0
static u16
exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl,
            struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
            struct nvbios_outp *info)
{
    struct nouveau_bios *bios = nouveau_bios(priv);
    u16 mask, type, data;

    if (outp < 4) {
        type = DCB_OUTPUT_ANALOG;
        mask = 0;
    } else {
        outp -= 4;
        switch (ctrl & 0x00000f00) {
        case 0x00000000:
            type = DCB_OUTPUT_LVDS;
            mask = 1;
            break;
        case 0x00000100:
            type = DCB_OUTPUT_TMDS;
            mask = 1;
            break;
        case 0x00000200:
            type = DCB_OUTPUT_TMDS;
            mask = 2;
            break;
        case 0x00000500:
            type = DCB_OUTPUT_TMDS;
            mask = 3;
            break;
        case 0x00000800:
            type = DCB_OUTPUT_DP;
            mask = 1;
            break;
        case 0x00000900:
            type = DCB_OUTPUT_DP;
            mask = 2;
            break;
        default:
            nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl);
            return 0x0000;
        }
        dcb->sorconf.link = mask;
    }

    mask  = 0x00c0 & (mask << 6);
    mask |= 0x0001 << outp;
    mask |= 0x0100 << head;

    data = dcb_outp_match(bios, type, mask, ver, hdr, dcb);
    if (!data)
        return 0x0000;

    return nvbios_outp_match(bios, type, mask, ver, hdr, cnt, len, info);
}
Esempio n. 2
0
File: nv50.c Progetto: 24hours/linux
static u16
exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl,
	    struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
	    struct nvbios_outp *info)
{
	struct nouveau_bios *bios = nouveau_bios(priv);
	u16 mask, type, data;

	if (outp < 4) {
		type = DCB_OUTPUT_ANALOG;
		mask = 0;
	} else
	if (outp < 8) {
		switch (ctrl & 0x00000f00) {
		case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break;
		case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break;
		case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break;
		case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break;
		case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break;
		case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break;
		default:
			nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl);
			return 0x0000;
		}
		outp -= 4;
	} else {
		outp = outp - 8;
		type = 0x0010;
		mask = 0;
		switch (ctrl & 0x00000f00) {
		case 0x00000000: type |= priv->pior.type[outp]; break;
		default:
			nv_error(priv, "unknown PIOR mc 0x%08x\n", ctrl);
			return 0x0000;
		}
	}

	mask  = 0x00c0 & (mask << 6);
	mask |= 0x0001 << outp;
	mask |= 0x0100 << head;

	data = dcb_outp_match(bios, type, mask, ver, hdr, dcb);
	if (!data)
		return 0x0000;

	/* off-chip encoders require matching the exact encoder type */
	if (dcb->location != 0)
		type |= dcb->extdev << 8;

	return nvbios_outp_match(bios, type, mask, ver, hdr, cnt, len, info);
}
Esempio n. 3
0
int
nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
{
	struct nv50_disp_priv *priv = (void *)object->engine;
	struct nouveau_bios *bios = nouveau_bios(priv);
	const u16 type = (mthd & NV50_DISP_SOR_MTHD_TYPE) >> 12;
	const u8  head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3;
	const u8  link = (mthd & NV50_DISP_SOR_MTHD_LINK) >> 2;
	const u8    or = (mthd & NV50_DISP_SOR_MTHD_OR);
	const u16 mask = (0x0100 << head) | (0x0040 << link) | (0x0001 << or);
	struct dcb_output outp;
	u8  ver, hdr;
	u32 data;
	int ret = -EINVAL;

	if (size < sizeof(u32))
		return -EINVAL;
	data = *(u32 *)args;

	if (type && !dcb_outp_match(bios, type, mask, &ver, &hdr, &outp))
		return -ENODEV;

	switch (mthd & ~0x3f) {
	case NV50_DISP_SOR_PWR:
		ret = priv->sor.power(priv, or, data);
		break;
	case NVA3_DISP_SOR_HDA_ELD:
		ret = priv->sor.hda_eld(priv, or, args, size);
		break;
	case NV84_DISP_SOR_HDMI_PWR:
		ret = priv->sor.hdmi(priv, head, or, data);
		break;
	case NV50_DISP_SOR_LVDS_SCRIPT:
		priv->sor.lvdsconf = data & NV50_DISP_SOR_LVDS_SCRIPT_ID;
		ret = 0;
		break;
	default:
		BUG_ON(1);
	}

	return ret;
}