int nv50_dac_power(NV50_DISP_MTHD_V1) { const u32 doff = outp->or * 0x800; union { struct nv50_disp_dac_pwr_v0 v0; } *args = data; u32 stat; int ret; nv_ioctl(object, "disp dac pwr size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(object, "disp dac pwr vers %d state %d data %d " "vsync %d hsync %d\n", args->v0.version, args->v0.state, args->v0.data, args->v0.vsync, args->v0.hsync); stat = 0x00000040 * !args->v0.state; stat |= 0x00000010 * !args->v0.data; stat |= 0x00000004 * !args->v0.vsync; stat |= 0x00000001 * !args->v0.hsync; } else return ret; nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); nv_mask(priv, 0x61a004 + doff, 0xc000007f, 0x80000000 | stat); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); return 0; }
static int nv50_disp_pioc_init(struct nouveau_object *object) { struct nv50_disp_priv *priv = (void *)object->engine; struct nv50_disp_pioc *pioc = (void *)object; int chid = pioc->base.chid; int ret; ret = nv50_disp_chan_init(&pioc->base); if (ret) return ret; nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00002000); if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00000000, 0x00000000)) { nv_error(pioc, "timeout0: 0x%08x\n", nv_rd32(priv, 0x610200 + (chid * 0x10))); return -EBUSY; } nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00000001); if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00010000)) { nv_error(pioc, "timeout1: 0x%08x\n", nv_rd32(priv, 0x610200 + (chid * 0x10))); return -EBUSY; } return 0; }
int nv50_pior_power(NV50_DISP_MTHD_V1) { const u32 soff = outp->or * 0x800; union { struct nv50_disp_pior_pwr_v0 v0; } *args = data; u32 ctrl, type; int ret; nv_ioctl(object, "disp pior pwr size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(object, "disp pior pwr vers %d state %d type %x\n", args->v0.version, args->v0.state, args->v0.type); if (args->v0.type > 0x0f) return -EINVAL; ctrl = !!args->v0.state; type = args->v0.type; } else return ret; nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | ctrl); nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); priv->pior.type[outp->or] = type; return 0; }
int nv50_sor_power(struct nv50_disp_priv *priv, int or, u32 data) { const u32 stat = data & NV50_DISP_SOR_PWR_STATE; const u32 soff = (or * 0x800); nv_wait(priv, 0x61c004 + soff, 0x80000000, 0x00000000); nv_mask(priv, 0x61c004 + soff, 0x80000001, 0x80000000 | stat); nv_wait(priv, 0x61c004 + soff, 0x80000000, 0x00000000); nv_wait(priv, 0x61c030 + soff, 0x10000000, 0x00000000); return 0; }
int nv50_dac_power(struct nv50_disp_priv *priv, int or, u32 data) { const u32 stat = (data & NV50_DISP_DAC_PWR_HSYNC) | (data & NV50_DISP_DAC_PWR_VSYNC) | (data & NV50_DISP_DAC_PWR_DATA) | (data & NV50_DISP_DAC_PWR_STATE); const u32 doff = (or * 0x800); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); nv_mask(priv, 0x61a004 + doff, 0xc000007f, 0x80000000 | stat); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); return 0; }
struct nouveau_channel * nv50_graph_channel(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t inst; int i; /* Be sure we're not in the middle of a context switch or bad things * will happen, such as unloading the wrong pgraph context. */ if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000)) NV_ERROR(dev, "Ctxprog is still running\n"); inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) return NULL; inst = (inst & NV50_PGRAPH_CTXCTL_CUR_INSTANCE) << 12; for (i = 0; i < dev_priv->engine.fifo.channels; i++) { struct nouveau_channel *chan = dev_priv->channels.ptr[i]; if (chan && chan->ramin && chan->ramin->vinst == inst) return chan; } return NULL; }
static int nvd0_disp_mast_init(struct nouveau_object *object) { struct nv50_disp_priv *priv = (void *)object->engine; struct nv50_disp_dmac *mast = (void *)object; int ret; ret = nv50_disp_chan_init(&mast->base); if (ret) return ret; /* enable error reporting */ nv_mask(priv, 0x610090, 0x00000001, 0x00000001); nv_mask(priv, 0x6100a0, 0x00000001, 0x00000001); /* initialise channel for dma command submission */ nv_wr32(priv, 0x610494, mast->push); nv_wr32(priv, 0x610498, 0x00010000); nv_wr32(priv, 0x61049c, 0x00000001); nv_mask(priv, 0x610490, 0x00000010, 0x00000010); nv_wr32(priv, 0x640000, 0x00000000); nv_wr32(priv, 0x610490, 0x01000013); /* wait for it to go inactive */ if (!nv_wait(priv, 0x610490, 0x80000000, 0x00000000)) { nv_error(mast, "init: 0x%08x\n", nv_rd32(priv, 0x610490)); return -EBUSY; } return 0; }
static int nvd0_disp_pioc_init(struct nouveau_object *object) { struct nv50_disp_priv *priv = (void *)object->engine; struct nv50_disp_pioc *pioc = (void *)object; int chid = pioc->base.chid; int ret; ret = nv50_disp_chan_init(&pioc->base); if (ret) return ret; /* enable error reporting */ nv_mask(priv, 0x610090, 0x00000001 << chid, 0x00000001 << chid); nv_mask(priv, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid); /* activate channel */ nv_wr32(priv, 0x610490 + (chid * 0x10), 0x00000001); if (!nv_wait(priv, 0x610490 + (chid * 0x10), 0x00030000, 0x00010000)) { nv_error(pioc, "init: 0x%08x\n", nv_rd32(priv, 0x610490 + (chid * 0x10))); return -EBUSY; } return 0; }
static int nv50_disp_dmac_init(struct nouveau_object *object) { struct nv50_disp_priv *priv = (void *)object->engine; struct nv50_disp_dmac *dmac = (void *)object; int chid = dmac->base.chid; int ret; ret = nv50_disp_chan_init(&dmac->base); if (ret) return ret; /* enable error reporting */ nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00010001 << chid); /* initialise channel for dma command submission */ nv_wr32(priv, 0x610204 + (chid * 0x0010), dmac->push); nv_wr32(priv, 0x610208 + (chid * 0x0010), 0x00010000); nv_wr32(priv, 0x61020c + (chid * 0x0010), chid); nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00000010, 0x00000010); nv_wr32(priv, 0x640000 + (chid * 0x1000), 0x00000000); nv_wr32(priv, 0x610200 + (chid * 0x0010), 0x00000013); /* wait for it to go inactive */ if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x80000000, 0x00000000)) { nv_error(dmac, "init timeout, 0x%08x\n", nv_rd32(priv, 0x610200 + (chid * 0x10))); return -EBUSY; } return 0; }
static int nvc0_graph_construct_context(struct nouveau_channel *chan) { struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; struct drm_device *dev = chan->dev; int ret, i; u32 *ctx; ctx = kmalloc(priv->grctx_size, GFP_KERNEL); if (!ctx) return -ENOMEM; if (!nouveau_ctxfw) { nv_wr32(dev, 0x409840, 0x80000000); nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12); nv_wr32(dev, 0x409504, 0x00000001); if (!nv_wait(dev, 0x409800, 0x80000000, 0x80000000)) { NV_ERROR(dev, "PGRAPH: HUB_SET_CHAN timeout\n"); nvc0_graph_ctxctl_debug(dev); ret = -EBUSY; goto err; } } else {
int nv50_mpeg_init(struct nvkm_object *object) { struct nv50_mpeg_priv *priv = (void *)object; int ret; ret = nvkm_mpeg_init(&priv->base); if (ret) return ret; nv_wr32(priv, 0x00b32c, 0x00000000); nv_wr32(priv, 0x00b314, 0x00000100); nv_wr32(priv, 0x00b0e0, 0x0000001a); nv_wr32(priv, 0x00b220, 0x00000044); nv_wr32(priv, 0x00b300, 0x00801ec1); nv_wr32(priv, 0x00b390, 0x00000000); nv_wr32(priv, 0x00b394, 0x00000000); nv_wr32(priv, 0x00b398, 0x00000000); nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001); nv_wr32(priv, 0x00b100, 0xffffffff); nv_wr32(priv, 0x00b140, 0xffffffff); if (!nv_wait(priv, 0x00b200, 0x00000001, 0x00000000)) { nv_error(priv, "timeout 0x%08x\n", nv_rd32(priv, 0x00b200)); return -EBUSY; } return 0; }
static int nvd0_disp_base_init(struct nouveau_object *object) { struct nv50_disp_priv *priv = (void *)object->engine; struct nv50_disp_base *base = (void *)object; int ret, i; u32 tmp; ret = nouveau_parent_init(&base->base); if (ret) return ret; /* The below segments of code copying values from one register to * another appear to inform EVO of the display capabilities or * something similar. */ /* ... CRTC caps */ for (i = 0; i < priv->head.nr; i++) { tmp = nv_rd32(priv, 0x616104 + (i * 0x800)); nv_wr32(priv, 0x6101b4 + (i * 0x800), tmp); tmp = nv_rd32(priv, 0x616108 + (i * 0x800)); nv_wr32(priv, 0x6101b8 + (i * 0x800), tmp); tmp = nv_rd32(priv, 0x61610c + (i * 0x800)); nv_wr32(priv, 0x6101bc + (i * 0x800), tmp); } /* ... DAC caps */ for (i = 0; i < priv->dac.nr; i++) { tmp = nv_rd32(priv, 0x61a000 + (i * 0x800)); nv_wr32(priv, 0x6101c0 + (i * 0x800), tmp); } /* ... SOR caps */ for (i = 0; i < priv->sor.nr; i++) { tmp = nv_rd32(priv, 0x61c000 + (i * 0x800)); nv_wr32(priv, 0x6301c4 + (i * 0x800), tmp); } /* steal display away from vbios, or something like that */ if (nv_rd32(priv, 0x6100ac) & 0x00000100) { nv_wr32(priv, 0x6100ac, 0x00000100); nv_mask(priv, 0x6194e8, 0x00000001, 0x00000000); if (!nv_wait(priv, 0x6194e8, 0x00000002, 0x00000000)) { nv_error(priv, "timeout acquiring display\n"); return -EBUSY; } } /* point at display engine memory area (hash table, objects) */ nv_wr32(priv, 0x610010, (nv_gpuobj(object->parent)->addr >> 8) | 9); /* enable supervisor interrupts, disable everything else */ nv_wr32(priv, 0x610090, 0x00000000); nv_wr32(priv, 0x6100a0, 0x00000000); nv_wr32(priv, 0x6100b0, 0x00000307); return 0; }
static int nv84_graph_tlb_flush(struct nouveau_engine *engine) { struct nouveau_timer *ptimer = nouveau_timer(engine); struct nv50_graph_priv *priv = (void *)engine; bool idle, timeout = false; unsigned long flags; u64 start; u32 tmp; spin_lock_irqsave(&priv->lock, flags); nv_mask(priv, 0x400500, 0x00000001, 0x00000000); start = ptimer->read(ptimer); do { idle = true; for (tmp = nv_rd32(priv, 0x400380); tmp && idle; tmp >>= 3) { if ((tmp & 7) == 1) idle = false; } for (tmp = nv_rd32(priv, 0x400384); tmp && idle; tmp >>= 3) { if ((tmp & 7) == 1) idle = false; } for (tmp = nv_rd32(priv, 0x400388); tmp && idle; tmp >>= 3) { if ((tmp & 7) == 1) idle = false; } } while (!idle && !(timeout = ptimer->read(ptimer) - start > 2000000000)); if (timeout) { nv_error(priv, "PGRAPH TLB flush idle timeout fail\n"); tmp = nv_rd32(priv, 0x400700); nv_error(priv, "PGRAPH_STATUS : 0x%08x", tmp); nouveau_bitfield_print(nv50_pgraph_status, tmp); pr_cont("\n"); nouveau_pgraph_vstatus_print(priv, 0, nv50_pgraph_vstatus_0, nv_rd32(priv, 0x400380)); nouveau_pgraph_vstatus_print(priv, 1, nv50_pgraph_vstatus_1, nv_rd32(priv, 0x400384)); nouveau_pgraph_vstatus_print(priv, 2, nv50_pgraph_vstatus_2, nv_rd32(priv, 0x400388)); } nv_wr32(priv, 0x100c80, 0x00000001); if (!nv_wait(priv, 0x100c80, 0x00000001, 0x00000000)) nv_error(priv, "vm flush timeout\n"); nv_mask(priv, 0x400500, 0x00000001, 0x00000001); spin_unlock_irqrestore(&priv->lock, flags); return timeout ? -EBUSY : 0; }
void gf100_ltc_cbc_wait(struct nvkm_ltc_priv *priv) { int c, s; for (c = 0; c < priv->ltc_nr; c++) { for (s = 0; s < priv->lts_nr; s++) nv_wait(priv, 0x1410c8 + c * 0x2000 + s * 0x400, ~0, 0); } }
static void gm107_ltc_cbc_wait(struct nvkm_ltc_priv *priv) { int c, s; for (c = 0; c < priv->ltc_nr; c++) { for (s = 0; s < priv->lts_nr; s++) nv_wait(priv, 0x14046c + c * 0x2000 + s * 0x200, ~0, 0); } }
static enum drm_connector_status nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; enum drm_connector_status status = connector_status_disconnected; uint32_t dpms_state, load_pattern, load_state; int or = nv_encoder->or; nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001); dpms_state = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)); nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), 0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or), NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) { NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or))); return status; } /* Use bios provided value if possible. */ if (dev_priv->vbios->dactestval) { load_pattern = dev_priv->vbios->dactestval; NV_DEBUG(dev, "Using bios provided load_pattern of %d\n", load_pattern); } else { load_pattern = 340; NV_DEBUG(dev, "Using default load_pattern of %d\n", load_pattern); } nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or), NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE | load_pattern); mdelay(45); /* give it some time to process */ load_state = nv_rd32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or)); nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0); nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); if ((load_state & NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) == NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) status = connector_status_connected; if (status == connector_status_connected) NV_DEBUG(dev, "Load was detected on output with or %d\n", or); else NV_DEBUG(dev, "Load was not detected on output with or %d\n", or); return status; }
void nv84_bar_flush(struct nouveau_bar *bar) { struct nv50_bar_priv *priv = (void *)bar; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); nv_wr32(bar, 0x070000, 0x00000001); if (!nv_wait(priv, 0x070000, 0x00000002, 0x00000000)) nv_warn(priv, "flush timeout\n"); spin_unlock_irqrestore(&priv->lock, flags); }
void nv84_instmem_flush(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; unsigned long flags; spin_lock_irqsave(&dev_priv->vm_lock, flags); nv_wr32(dev, 0x070000, 0x00000001); if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); spin_unlock_irqrestore(&dev_priv->vm_lock, flags); }
static inline int evo_icmd(struct drm_device *dev, int id, u32 mthd, u32 data) { int ret = 0; nv_mask(dev, 0x610700 + (id * 0x10), 0x00000001, 0x00000001); nv_wr32(dev, 0x610704 + (id * 0x10), data); nv_mask(dev, 0x610704 + (id * 0x10), 0x80000ffc, 0x80000000 | mthd); if (!nv_wait(dev, 0x610704 + (id * 0x10), 0x80000000, 0x00000000)) ret = -EBUSY; nv_mask(dev, 0x610700 + (id * 0x10), 0x00000001, 0x00000000); return ret; }
static int nv50_graph_fini(struct drm_device *dev, int engine, bool suspend) { nv_mask(dev, 0x400500, 0x00010001, 0x00000000); if (!nv_wait(dev, 0x400700, ~0, 0) && suspend) { nv_mask(dev, 0x400500, 0x00010001, 0x00010001); return -EBUSY; } nv50_graph_unload_context(dev); nv_wr32(dev, 0x40013c, 0x00000000); return 0; }
static int nvc0_graph_load_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; nv_wr32(dev, 0x409840, 0x00000030); nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12); nv_wr32(dev, 0x409504, 0x00000003); if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010)) NV_ERROR(dev, "PGRAPH: load_ctx timeout\n"); return 0; }
static int nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan) { nv_wr32(dev, 0x409840, 0x00000003); nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12); nv_wr32(dev, 0x409504, 0x00000009); if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) { NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n"); return -EBUSY; } return 0; }
int nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) { const u32 doff = (or * 0x800); nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); mdelay(9); udelay(500); loadval = nv_mask(priv, 0x61a00c + doff, 0xffffffff, 0x00000000); nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); nv_debug(priv, "DAC%d sense: 0x%08x\n", or, loadval); if (!(loadval & 0x80000000)) return -ETIMEDOUT; return (loadval & 0x38000000) >> 27; }
int nv50_dac_sense(NV50_DISP_MTHD_V1) { union { struct nv50_disp_dac_load_v0 v0; } *args = data; const u32 doff = outp->or * 0x800; u32 loadval; int ret; nv_ioctl(object, "disp dac load size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(object, "disp dac load vers %d data %08x\n", args->v0.version, args->v0.data); if (args->v0.data & 0xfff00000) return -EINVAL; loadval = args->v0.data; } else return ret; nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); mdelay(9); udelay(500); loadval = nv_mask(priv, 0x61a00c + doff, 0xffffffff, 0x00000000); nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); nv_debug(priv, "DAC%d sense: 0x%08x\n", outp->or, loadval); if (!(loadval & 0x80000000)) return -ETIMEDOUT; args->v0.load = (loadval & 0x38000000) >> 27; return 0; }
static void nv41_vm_flush(struct nouveau_vm *vm) { struct nv04_vm_priv *priv = (void *)vm->vmm; mutex_lock(&nv_subdev(priv)->mutex); nv_wr32(priv, 0x100810, 0x00000022); if (!nv_wait(priv, 0x100810, 0x00000020, 0x00000020)) { nv_warn(priv, "flush timeout, 0x%08x\n", nv_rd32(priv, 0x100810)); } nv_wr32(priv, 0x100810, 0x00000000); mutex_unlock(&nv_subdev(priv)->mutex); }
static void nv50_sor_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); uint32_t val; int or = nv_encoder->or; NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); /* wait for it to be done */ if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_CTRL(or), NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING, 0)) { NV_ERROR(dev, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or); NV_ERROR(dev, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or, nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or))); } val = nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or)); if (mode == DRM_MODE_DPMS_ON) val |= NV50_PDISPLAY_SOR_DPMS_CTRL_ON; else val &= ~NV50_PDISPLAY_SOR_DPMS_CTRL_ON; nv_wr32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val | NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING); if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(or), NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) { NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or); NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", or, nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or))); } if (nv_encoder->dcb->type == OUTPUT_DP && mode == DRM_MODE_DPMS_ON) nv50_sor_dp_link_train(encoder); }
void gk110_pmu_pgob(struct nvkm_pmu *pmu, bool enable) { static const struct { u32 addr; u32 data; } magic[] = { { 0x020520, 0xfffffffc }, { 0x020524, 0xfffffffe }, { 0x020524, 0xfffffffc }, { 0x020524, 0xfffffff8 }, { 0x020524, 0xffffffe0 }, { 0x020530, 0xfffffffe }, { 0x02052c, 0xfffffffa }, { 0x02052c, 0xfffffff0 }, { 0x02052c, 0xffffffc0 }, { 0x02052c, 0xffffff00 }, { 0x02052c, 0xfffffc00 }, { 0x02052c, 0xfffcfc00 }, { 0x02052c, 0xfff0fc00 }, { 0x02052c, 0xff80fc00 }, { 0x020528, 0xfffffffe }, { 0x020528, 0xfffffffc }, }; int i; nv_mask(pmu, 0x000200, 0x00001000, 0x00000000); nv_rd32(pmu, 0x000200); nv_mask(pmu, 0x000200, 0x08000000, 0x08000000); msleep(50); nv_mask(pmu, 0x10a78c, 0x00000002, 0x00000002); nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001); nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000); nv_mask(pmu, 0x0206b4, 0x00000000, 0x00000000); for (i = 0; i < ARRAY_SIZE(magic); i++) { nv_wr32(pmu, magic[i].addr, magic[i].data); nv_wait(pmu, magic[i].addr, 0x80000000, 0x00000000); } nv_mask(pmu, 0x10a78c, 0x00000002, 0x00000000); nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001); nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000); nv_mask(pmu, 0x000200, 0x08000000, 0x00000000); nv_mask(pmu, 0x000200, 0x00001000, 0x00001000); nv_rd32(pmu, 0x000200); }
static int nv94_bus_hwsq_exec(struct nouveau_bus *pbus, u32 *data, u32 size) { struct nv50_bus_priv *priv = (void *)pbus; int i; nv_mask(pbus, 0x001098, 0x00000008, 0x00000000); nv_wr32(pbus, 0x001304, 0x00000000); nv_wr32(pbus, 0x001318, 0x00000000); for (i = 0; i < size; i++) nv_wr32(priv, 0x080000 + (i * 4), data[i]); nv_mask(pbus, 0x001098, 0x00000018, 0x00000018); nv_wr32(pbus, 0x00130c, 0x00000001); return nv_wait(pbus, 0x001308, 0x00000100, 0x00000000) ? 0 : -ETIMEDOUT; }
void nv50_cursor_fini(struct nouveau_crtc *nv_crtc) { struct drm_device *dev = nv_crtc->base.dev; int idx = nv_crtc->index; NV_DEBUG_KMS(dev, "\n"); nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0); if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); } }
static int nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend) { struct nv50_disp_priv *priv = (void *)object->engine; struct nv50_disp_pioc *pioc = (void *)object; int chid = pioc->base.chid; nv_mask(priv, 0x610200 + (chid * 0x10), 0x00000001, 0x00000000); if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00000000)) { nv_error(pioc, "timeout: 0x%08x\n", nv_rd32(priv, 0x610200 + (chid * 0x10))); if (suspend) return -EBUSY; } return nv50_disp_chan_fini(&pioc->base, suspend); }