/* Fetch and adjust GPU GET pointer * * Returns: * value >= 0, the adjusted GET pointer * -EINVAL if GET pointer currently outside main push buffer * -EBUSY if timeout exceeded */ static inline int READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) { uint64_t val; val = nvif_rd32(&chan->user, chan->user_get); if (chan->user_get_hi) val |= (uint64_t)nvif_rd32(&chan->user, chan->user_get_hi) << 32; /* reset counter as long as GET is still advancing, this is * to avoid misdetecting a GPU lockup if the GPU happens to * just be processing an operation that takes a long time */ if (val != *prev_get) { *prev_get = val; *timeout = 0; } if ((++*timeout & 0xff) == 0) { udelay(1); if (*timeout > 100000) return -EBUSY; } if (val < chan->push.addr || val > chan->push.addr + (chan->dma.max << 2)) return -EINVAL; return (val - chan->push.addr) >> 2; }
static int nv50_dma_push_wait(struct nouveau_channel *chan, int count) { uint32_t cnt = 0, prev_get = 0; while (chan->dma.ib_free < count) { uint32_t get = nvif_rd32(&chan->user, 0x88); if (get != prev_get) { prev_get = get; cnt = 0; } if ((++cnt & 0xff) == 0) { DRM_UDELAY(1); if (cnt > 100000) return -EBUSY; } chan->dma.ib_free = get - chan->dma.ib_put; if (chan->dma.ib_free <= 0) chan->dma.ib_free += chan->dma.ib_max; } return 0; }
static int nva3_get_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 = nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(or)); val &= NVA3_PDISP_SOR_PWM_CTL_VAL; if (div && div >= val) return ((val * 100) + (div / 2)) / div; return 100; }
static int nv40_get_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 = (nvif_rd32(device, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK) >> 16; return val; }
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 nv40_backlight_init(struct nouveau_encoder *encoder, struct backlight_properties *props, const struct backlight_ops **ops) { struct nouveau_drm *drm = nouveau_drm(encoder->base.base.dev); struct nvif_object *device = &drm->client.device.object; if (!(nvif_rd32(device, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)) return -ENODEV; props->type = BACKLIGHT_RAW; props->max_brightness = 31; *ops = &nv40_bl_ops; return 0; }
static int nouveau_debugfs_strap_peek(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct nouveau_drm *drm = nouveau_drm(node->minor->dev); int ret; ret = pm_runtime_get_sync(drm->dev->dev); if (ret < 0 && ret != -EACCES) return ret; seq_printf(m, "0x%08x\n", nvif_rd32(&drm->client.device.object, 0x101000)); pm_runtime_mark_last_busy(drm->dev->dev); pm_runtime_put_autosuspend(drm->dev->dev); 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; }
static int nv50_backlight_init(struct nouveau_encoder *nv_encoder, struct backlight_properties *props, const struct backlight_ops **ops) { struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); struct nvif_object *device = &drm->client.device.object; if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(ffs(nv_encoder->dcb->or) - 1))) return -ENODEV; if (drm->client.device.info.chipset <= 0xa0 || drm->client.device.info.chipset == 0xaa || drm->client.device.info.chipset == 0xac) *ops = &nv50_bl_ops; else *ops = &nva3_bl_ops; props->type = BACKLIGHT_RAW; props->max_brightness = 100; return 0; }
u32 nv10_fence_read(struct nouveau_channel *chan) { return nvif_rd32(&chan->user, 0x0048); }