diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c index 61becfa732e..ae7249b0979 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c @@ -22,6 +22,10 @@ * Authors: Ben Skeggs */ +#include <subdev/bios.h> +#include <subdev/bios/dcb.h> +#include <subdev/bios/disp.h> +#include <subdev/bios/init.h> #include <subdev/devinit.h> #include <subdev/vga.h> @@ -55,7 +59,12 @@ nv50_devinit_dtor(struct nouveau_object *object) static int nv50_devinit_init(struct nouveau_object *object) { + struct nouveau_bios *bios = nouveau_bios(object); struct nv50_devinit_priv *priv = (void *)object; + struct nvbios_outp info; + struct dcb_output outp; + u8 ver = 0xff, hdr, cnt, len; + int ret, i = 0; if (!priv->base.post) { if (!nv_rdvgac(priv, 0, 0x00) && @@ -65,7 +74,30 @@ nv50_devinit_init(struct nouveau_object *object) } } - return nouveau_devinit_init(&priv->base); + ret = nouveau_devinit_init(&priv->base); + if (ret) + return ret; + + /* if we ran the init tables, execute first script pointer for each + * display table output entry that has a matching dcb entry. + */ + while (priv->base.post && ver) { + u16 data = nvbios_outp_parse(bios, i++, &ver, &hdr, &cnt, &len, &info); + if (data && dcb_outp_match(bios, info.type, info.mask, &ver, &len, &outp)) { + struct nvbios_init init = { + .subdev = nv_subdev(priv), + .bios = bios, + .offset = info.script[0], + .outp = &outp, + .crtc = -1, + .execute = 1, + }; + + nvbios_exec(&init); + } + }; + + return 0; } static int |