static unsigned int nouveau_vga_set_decode(void *priv, bool state) { struct nvif_device *device = &nouveau_drm(priv)->device; if (device->info.family == NV_DEVICE_INFO_V0_CURIE && device->info.chipset >= 0x4c) nvif_wr32(device, 0x088060, state); else if (device->info.chipset >= 0x40) nvif_wr32(device, 0x088054, state); else nvif_wr32(device, 0x001854, state); if (state) return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; else return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; }
static int nv40_set_intensity(struct backlight_device *bd) { struct nouveau_encoder *nv_encoder = bl_get_data(bd); struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); struct nvif_object *device = &drm->client.device.object; int val = bd->props.brightness; int reg = nvif_rd32(device, NV40_PMC_BACKLIGHT); nvif_wr32(device, NV40_PMC_BACKLIGHT, (val << 16) | (reg & ~NV40_PMC_BACKLIGHT_MASK)); return 0; }
static int nv50_set_intensity(struct backlight_device *bd) { struct nouveau_encoder *nv_encoder = bl_get_data(bd); struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); struct nvif_object *device = &drm->client.device.object; int or = ffs(nv_encoder->dcb->or) - 1; u32 div = 1025; u32 val = (bd->props.brightness * div) / 100; nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or), NV50_PDISP_SOR_PWM_CTL_NEW | val); return 0; }
static int nva3_set_intensity(struct backlight_device *bd) { struct nouveau_encoder *nv_encoder = bl_get_data(bd); struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); struct nvif_object *device = &drm->client.device.object; int or = ffs(nv_encoder->dcb->or) - 1; u32 div, val; div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or)); val = (bd->props.brightness * div) / 100; if (div) { nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or), val | NV50_PDISP_SOR_PWM_CTL_NEW | NVA3_PDISP_SOR_PWM_CTL_UNK); return 0; } return -EINVAL; }
void nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length) { struct nvif_user *user = &chan->drm->client.device.user; struct nouveau_bo *pb = chan->push.buffer; int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; BUG_ON(chan->dma.ib_free < 1); nouveau_bo_wr32(pb, ip++, lower_32_bits(offset)); nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8); chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; mb(); /* Flush writes. */ nouveau_bo_rd32(pb, 0); nvif_wr32(&chan->user, 0x8c, chan->dma.ib_put); if (user->func && user->func->doorbell) user->func->doorbell(user, chan->chid); chan->dma.ib_free--; }