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; }
static int nva3_copy_context_new(struct nouveau_channel *chan, int engine) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *ramin = chan->ramin; struct nouveau_gpuobj *ctx = NULL; int ret; NV_DEBUG(dev, "ch%d\n", chan->id); ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, &ctx); if (ret) return ret; nv_wo32(ramin, 0xc0, 0x00190000); nv_wo32(ramin, 0xc4, ctx->vinst + ctx->size - 1); nv_wo32(ramin, 0xc8, ctx->vinst); nv_wo32(ramin, 0xcc, 0x00000000); nv_wo32(ramin, 0xd0, 0x00000000); nv_wo32(ramin, 0xd4, 0x00000000); dev_priv->engine.instmem.flush(dev); atomic_inc(&chan->vm->engref[engine]); chan->engctx[engine] = ctx; return 0; }
void nv50_graph_destroy_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; unsigned long flags; NV_DEBUG(dev, "ch%d\n", chan->id); if (!chan->ramin) return; spin_lock_irqsave(&dev_priv->context_switch_lock, flags); pfifo->reassign(dev, false); pgraph->fifo_access(dev, false); if (pgraph->channel(dev) == chan) pgraph->unload_context(dev); for (i = hdr; i < hdr + 24; i += 4) nv_wo32(chan->ramin, i, 0); dev_priv->engine.instmem.flush(dev); pgraph->fifo_access(dev, true); pfifo->reassign(dev, true); spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); atomic_dec(&chan->vm->pgraph_refs); }
static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nv04_mode_state *state = &nv04_display(dev)->mode_reg; uint8_t crtc1A; NV_DEBUG(drm, "Setting dpms mode %d on TV encoder (output %d)\n", mode, nv_encoder->dcb->index); state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); if (mode == DRM_MODE_DPMS_ON) { int head = nouveau_crtc(encoder->crtc)->index; crtc1A = NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX); state->pllsel |= head ? PLLSEL_TV_CRTC2_MASK : PLLSEL_TV_CRTC1_MASK; /* Inhibit hsync */ crtc1A |= 0x80; NVWriteVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX, crtc1A); } NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); get_slave_funcs(encoder)->dpms(encoder, mode); }
static void nv50_graph_init_regs__nv(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t units = nv_rd32(dev, 0x1540); int i; NV_DEBUG(dev, "\n"); nv_wr32(dev, 0x400804, 0xc0000000); nv_wr32(dev, 0x406800, 0xc0000000); nv_wr32(dev, 0x400c04, 0xc0000000); nv_wr32(dev, 0x401800, 0xc0000000); nv_wr32(dev, 0x405018, 0xc0000000); nv_wr32(dev, 0x402000, 0xc0000000); for (i = 0; i < 16; i++) { if (units & 1 << i) { if (dev_priv->chipset < 0xa0) { nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000); nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000); nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000); } else { nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000); nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000); nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000); } } } nv_wr32(dev, 0x400108, 0xffffffff); nv_wr32(dev, 0x400824, 0x00004000); nv_wr32(dev, 0x400500, 0x00010001); }
static void nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) { struct drm_device *dev = nv_crtc->base.dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_channel *evo = nv50_display(dev)->master; int ret; NV_DEBUG(drm, "\n"); if (update && !nv_crtc->cursor.visible) return; ret = RING_SPACE(evo, (nv_device(drm->device)->chipset != 0x50 ? 5 : 3) + update * 2); if (ret) { NV_ERROR(drm, "no space while hiding cursor\n"); return; } BEGIN_NV04(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CURSOR_CTRL), 2); OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_HIDE); OUT_RING(evo, 0); if (nv_device(drm->device)->chipset != 0x50) { BEGIN_NV04(evo, 0, NV84_EVO_CRTC(nv_crtc->index, CURSOR_DMA), 1); OUT_RING(evo, NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE); } if (update) { BEGIN_NV04(evo, 0, NV50_EVO_UPDATE, 1); OUT_RING(evo, 0); FIRE_RING(evo); nv_crtc->cursor.visible = false; } }
int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) { struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; NV_DEBUG(dev, "\n"); NV_INFO(dev, "Detected a DAC output\n"); nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); if (!nv_encoder) return -ENOMEM; encoder = to_drm_encoder(nv_encoder); nv_encoder->dcb = entry; nv_encoder->or = ffs(entry->or) - 1; nv_encoder->disconnect = nv50_dac_disconnect; drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs, DRM_MODE_ENCODER_DAC); drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); encoder->possible_crtcs = entry->heads; encoder->possible_clones = 0; return 0; }
int nva3_pm_clock_get(struct drm_device *dev, u32 id) { u32 src0, src1, ctrl, coef; struct pll_lims pll; int ret, off; int P, N, M; ret = get_pll_limits(dev, id, &pll); if (ret) return ret; off = nva3_pm_pll_offset(id); if (off < 0) return off; src0 = nv_rd32(dev, 0x4120 + (off * 4)); src1 = nv_rd32(dev, 0x4160 + (off * 4)); ctrl = nv_rd32(dev, pll.reg + 0); coef = nv_rd32(dev, pll.reg + 4); NV_DEBUG(dev, "PLL %02x: 0x%08x 0x%08x 0x%08x 0x%08x\n", id, src0, src1, ctrl, coef); if (ctrl & 0x00000008) { u32 div = ((src1 & 0x003c0000) >> 18) + 1; return (pll.refclk * 2) / div; }
void nv50_graph_takedown(struct drm_device *dev) { NV_DEBUG(dev, "\n"); nv_wr32(dev, 0x40013c, 0x00000000); nouveau_irq_unregister(dev, 12); }
static int nv50_mpeg_context_new(struct nouveau_channel *chan, int engine) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *ramin = chan->ramin; struct nouveau_gpuobj *ctx = NULL; int ret; NV_DEBUG(dev, "ch%d\n", chan->id); ret = nouveau_gpuobj_new(dev, chan, 128 * 4, 0, NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, &ctx); if (ret) return ret; nv_wo32(ramin, CTX_PTR(dev, 0x00), 0x80190002); nv_wo32(ramin, CTX_PTR(dev, 0x04), ctx->vinst + ctx->size - 1); nv_wo32(ramin, CTX_PTR(dev, 0x08), ctx->vinst); nv_wo32(ramin, CTX_PTR(dev, 0x0c), 0); nv_wo32(ramin, CTX_PTR(dev, 0x10), 0); nv_wo32(ramin, CTX_PTR(dev, 0x14), 0x00010000); nv_wo32(ctx, 0x70, 0x00801ec1); nv_wo32(ctx, 0x7c, 0x0000037c); dev_priv->engine.instmem.flush(dev); chan->engctx[engine] = ctx; return 0; }
static void nv50_fifo_playlist_update(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; struct nouveau_gpuobj *cur; int i, nr; NV_DEBUG(dev, "\n"); cur = pfifo->playlist[pfifo->cur_playlist]; pfifo->cur_playlist = !pfifo->cur_playlist; /* We never schedule channel 0 or 127 */ for (i = 1, nr = 0; i < 127; i++) { if (dev_priv->channels.ptr[i] && dev_priv->channels.ptr[i]->ramfc) { nv_wo32(cur, (nr * 4), i); nr++; } } dev_priv->engine.instmem.flush(dev); nv_wr32(dev, 0x32f4, cur->vinst >> 12); nv_wr32(dev, 0x32ec, nr); nv_wr32(dev, 0x2500, 0x101); }
int nouveau_load(struct drm_device *dev, unsigned long flags) { struct drm_nouveau_private *dev_priv; uint32_t reg0; resource_size_t mmio_start_offs; int ret; dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (!dev_priv) { ret = -ENOMEM; goto err_out; } dev->dev_private = dev_priv; dev_priv->dev = dev; dev_priv->flags = flags & NOUVEAU_FLAGS; NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", dev->pci_vendor, dev->pci_device, dev->pdev->class); dev_priv->wq = create_workqueue("nouveau"); if (!dev_priv->wq) { ret = -EINVAL; goto err_priv; } /* resource 0 is mmio regs */ /* resource 1 is linear FB */ /* resource 2 is RAMIN (mmio regs + 0x1000000) */ /* resource 6 is bios */ /* map the mmio regs */ mmio_start_offs = pci_resource_start(dev->pdev, 0); dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000); if (!dev_priv->mmio) { NV_ERROR(dev, "Unable to initialize the mmio mapping. " "Please report your setup to " DRIVER_EMAIL "\n"); ret = -EINVAL; goto err_wq; } NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", (unsigned long long)mmio_start_offs); #ifdef __BIG_ENDIAN /* Put the card in BE mode if it's not */ if (nv_rd32(dev, NV03_PMC_BOOT_1)) nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001); DRM_MEMORYBARRIER(); #endif /* Time to determine the card architecture */ reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); /* We're dealing with >=NV10 */ if ((reg0 & 0x0f000000) > 0) { /* Bit 27-20 contain the architecture in hex */ dev_priv->chipset = (reg0 & 0xff00000) >> 20; /* NV04 or NV05 */ } else if ((reg0 & 0xff00fff0) == 0x20004000) {
static int nv50_graph_fini(struct drm_device *dev, int engine) { NV_DEBUG(dev, "\n"); nv50_graph_unload_context(dev); nv_wr32(dev, 0x40013c, 0x00000000); return 0; }
static void legacy_perf_init(struct drm_device *dev) { struct nouveau_device *device = nouveau_dev(dev); struct nouveau_drm *drm = nouveau_drm(dev); struct nvbios *bios = &drm->vbios; struct nouveau_pm *pm = nouveau_pm(dev); char *perf, *entry, *bmp = &bios->data[bios->offset]; int headerlen, use_straps; if (bmp[5] < 0x5 || bmp[6] < 0x14) { NV_DEBUG(drm, "BMP version too old for perf\n"); return; } perf = ROMPTR(dev, bmp[0x73]); if (!perf) { NV_DEBUG(drm, "No memclock table pointer found.\n"); return; } switch (perf[0]) { case 0x12: case 0x14: case 0x18: use_straps = 0; headerlen = 1; break; case 0x01: use_straps = perf[1] & 1; headerlen = (use_straps ? 8 : 2); break; default: NV_WARN(drm, "Unknown memclock table version %x.\n", perf[0]); return; } entry = perf + headerlen; if (use_straps) entry += (nv_rd32(device, NV_PEXTDEV_BOOT_0) & 0x3c) >> 1; sprintf(pm->perflvl[0].name, "performance_level_0"); pm->perflvl[0].memory = ROM16(entry[0]) * 20; pm->nr_perflvl = 1; }
static void nv50_graph_init_intr(struct drm_device *dev) { NV_DEBUG(dev, "\n"); nv_wr32(dev, NV03_PGRAPH_INTR, 0xffffffff); nv_wr32(dev, 0x400138, 0xffffffff); nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xffffffff); }
static void nv50_graph_init_reset(struct drm_device *dev) { uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21); NV_DEBUG(dev, "\n"); nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e); nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | pmc_e); }
static void nv50_graph_init_regs(struct drm_device *dev) { NV_DEBUG(dev, "\n"); nv_wr32(dev, NV04_PGRAPH_DEBUG_3, (1 << 2) /* HW_CONTEXT_SWITCH_ENABLED */); nv_wr32(dev, 0x402ca8, 0x800); }
static void nouveau_notifier_gpuobj_dtor(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) { NV_DEBUG(dev, "\n"); if (gpuobj->priv) nouveau_mem_free_block(gpuobj->priv); }
static void nouveau_dp_probe_oui(struct drm_device *dev, struct nvkm_i2c_aux *aux, u8 *dpcd) { struct nouveau_drm *drm = nouveau_drm(dev); u8 buf[3]; if (!(dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) return; if (!nvkm_rdaux(aux, DP_SINK_OUI, buf, 3)) NV_DEBUG(drm, "Sink OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); if (!nvkm_rdaux(aux, DP_BRANCH_OUI, buf, 3)) NV_DEBUG(drm, "Branch OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); }
int nouveau_dp_detect(struct nouveau_encoder *nv_encoder) { struct drm_device *dev = nv_encoder->base.base.dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nvkm_i2c_aux *aux; u8 dpcd[8]; int ret; aux = nv_encoder->aux; if (!aux) return -ENODEV; ret = nvkm_rdaux(aux, DP_DPCD_REV, dpcd, sizeof(dpcd)); if (ret) return ret; nv_encoder->dp.link_bw = 27000 * dpcd[1]; nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; NV_DEBUG(drm, "display: %dx%d dpcd 0x%02x\n", nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]); NV_DEBUG(drm, "encoder: %dx%d\n", nv_encoder->dcb->dpconf.link_nr, nv_encoder->dcb->dpconf.link_bw); if (nv_encoder->dcb->dpconf.link_nr < nv_encoder->dp.link_nr) nv_encoder->dp.link_nr = nv_encoder->dcb->dpconf.link_nr; if (nv_encoder->dcb->dpconf.link_bw < nv_encoder->dp.link_bw) nv_encoder->dp.link_bw = nv_encoder->dcb->dpconf.link_bw; NV_DEBUG(drm, "maximum: %dx%d\n", nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); nouveau_dp_probe_oui(dev, aux, dpcd); ret = nv50_mstm_detect(nv_encoder->dp.mstm, dpcd, nouveau_mst); if (ret == 1) return NOUVEAU_DP_MST; if (ret == 0) return NOUVEAU_DP_SST; return ret; }
static void nv50_graph_init_intr(struct drm_device *dev) { NV_DEBUG(dev, "\n"); nouveau_irq_register(dev, 12, nv50_graph_isr); nv_wr32(dev, NV03_PGRAPH_INTR, 0xffffffff); nv_wr32(dev, 0x400138, 0xffffffff); nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xffffffff); }
static void nouveau_perf_voltage(struct drm_device *dev, struct bit_entry *P, struct nouveau_pm_level *perflvl) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvbios *bios = &dev_priv->vbios; u8 *vmap; int id; id = perflvl->volt_min; perflvl->volt_min = 0; /* boards using voltage table version <0x40 store the voltage * level directly in the perflvl entry as a multiple of 10mV */ if (dev_priv->engine.pm.voltage.version < 0x40) { perflvl->volt_min = id * 10000; perflvl->volt_max = perflvl->volt_min; return; } /* on newer ones, the perflvl stores an index into yet another * vbios table containing a min/max voltage value for the perflvl */ if (P->version != 2 || P->length < 34) { NV_DEBUG(dev, "where's our volt map table ptr? %d %d\n", P->version, P->length); return; } vmap = ROMPTR(bios, P->data[32]); if (!vmap) { NV_DEBUG(dev, "volt map table pointer invalid\n"); return; } if (id < vmap[3]) { vmap += vmap[1] + (vmap[2] * id); perflvl->volt_min = ROM32(vmap[0]); perflvl->volt_max = ROM32(vmap[4]); } }
static void nv50_fifo_channel_enable(struct drm_device *dev, int channel) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->fifos[channel]; uint32_t inst; NV_DEBUG(dev, "ch%d\n", channel); if (dev_priv->chipset == 0x50) inst = chan->ramfc->instance >> 12; else
static uint32_t nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t hash = 0; int i; NV_DEBUG(dev, "ch%d handle=0x%08x\n", channel, handle); for (i = 32; i > 0; i -= dev_priv->ramht_bits) { hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1)); handle >>= dev_priv->ramht_bits; } if (dev_priv->card_type < NV_50) hash ^= channel << (dev_priv->ramht_bits - 4); hash <<= 3; NV_DEBUG(dev, "hash=0x%08x\n", hash); return hash; }
static void nv04_tv_commit(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct drm_device *dev = encoder->dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct drm_encoder_helper_funcs *helper = encoder->helper_private; helper->dpms(encoder, DRM_MODE_DPMS_ON); NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); }
static void nv50_dac_destroy(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); if (!encoder) return; NV_DEBUG(encoder->dev, "\n"); drm_encoder_cleanup(encoder); kfree(nv_encoder); }
int nouveau_dp_detect(struct nouveau_encoder *nv_encoder) { struct drm_device *dev = nv_encoder->base.base.dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_i2c_port *auxch; u8 *dpcd = nv_encoder->dp.dpcd; int ret; auxch = nv_encoder->i2c; if (!auxch) return -ENODEV; ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8); if (ret) return ret; nv_encoder->dp.link_bw = 27000 * dpcd[1]; nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; NV_DEBUG(drm, "display: %dx%d dpcd 0x%02x\n", nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]); NV_DEBUG(drm, "encoder: %dx%d\n", nv_encoder->dcb->dpconf.link_nr, nv_encoder->dcb->dpconf.link_bw); if (nv_encoder->dcb->dpconf.link_nr < nv_encoder->dp.link_nr) nv_encoder->dp.link_nr = nv_encoder->dcb->dpconf.link_nr; if (nv_encoder->dcb->dpconf.link_bw < nv_encoder->dp.link_bw) nv_encoder->dp.link_bw = nv_encoder->dcb->dpconf.link_bw; NV_DEBUG(drm, "maximum: %dx%d\n", nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); nouveau_dp_probe_oui(dev, auxch, dpcd); return 0; }
int nv50_graph_create_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; struct nouveau_gpuobj *ctx; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; int hdr, ret; NV_DEBUG(dev, "ch%d\n", chan->id); ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, 0x1000, NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); if (ret) return ret; ctx = chan->ramin_grctx->gpuobj; hdr = IS_G80 ? 0x200 : 0x20; dev_priv->engine.instmem.prepare_access(dev, true); nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + pgraph->grctx_size - 1); nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance); nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000); dev_priv->engine.instmem.finish_access(dev); dev_priv->engine.instmem.prepare_access(dev, true); if (!pgraph->ctxprog) { struct nouveau_grctx ctx = {}; ctx.dev = chan->dev; ctx.mode = NOUVEAU_GRCTX_VALS; ctx.data = chan->ramin_grctx->gpuobj; nv50_grctx_init(&ctx); } else { nouveau_grctx_vals_load(dev, ctx); } nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); if ((dev_priv->chipset & 0xf0) == 0xa0) nv_wo32(dev, ctx, 0x00004/4, 0x00000000); else nv_wo32(dev, ctx, 0x0011c/4, 0x00000000); dev_priv->engine.instmem.finish_access(dev); return 0; }
/* cleans up all the fifos from file_priv */ void nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->engine; int i; NV_DEBUG(dev, "clearing FIFO enables from file_priv\n"); for (i = 0; i < engine->fifo.channels; i++) { struct nouveau_channel *chan = dev_priv->fifos[i]; if (chan && chan->file_priv == file_priv) nouveau_channel_free(chan); } }
static int nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data) { struct drm_nouveau_private *dev_priv = container_of(nb, struct drm_nouveau_private, engine.pm.acpi_nb); struct drm_device *dev = dev_priv->dev; struct acpi_bus_event *entry = (struct acpi_bus_event *)data; if (strcmp(entry->device_class, "ac_adapter") == 0) { bool ac = power_supply_is_system_supplied(); NV_DEBUG(dev, "power supply changed: %s\n", ac ? "AC" : "DC"); } return NOTIFY_OK; }