int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, struct drm_framebuffer *fb, struct drm_display_mode *mode, struct exynos_drm_crtc_pos *pos) { struct exynos_drm_gem_buf *buffer; unsigned int actual_w; unsigned int actual_h; int nr = exynos_drm_format_num_buffers(fb->pixel_format); int i; for (i = 0; i < nr; i++) { buffer = exynos_drm_fb_buffer(fb, i); if (!buffer) { DRM_LOG_KMS("buffer is null\n"); return -EFAULT; } overlay->dma_addr[i] = buffer->dma_addr; overlay->vaddr[i] = buffer->kvaddr; DRM_DEBUG_KMS("buffer: %d, vaddr = 0x%lx, dma_addr = 0x%lx\n", i, (unsigned long)overlay->vaddr[i], (unsigned long)overlay->dma_addr[i]); } actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w); actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h); /* set drm framebuffer data. */ overlay->fb_x = pos->fb_x; overlay->fb_y = pos->fb_y; overlay->fb_width = fb->width; overlay->fb_height = fb->height; overlay->src_width = pos->src_w; overlay->src_height = pos->src_h; overlay->bpp = fb->bits_per_pixel; overlay->pitch = fb->pitches[0]; overlay->pixel_format = fb->pixel_format; /* set overlay range to be displayed. */ overlay->crtc_x = pos->crtc_x; overlay->crtc_y = pos->crtc_y; overlay->crtc_width = actual_w; overlay->crtc_height = actual_h; /* set drm mode data. */ overlay->mode_width = mode->hdisplay; overlay->mode_height = mode->vdisplay; overlay->refresh = mode->vrefresh; overlay->scan_flag = mode->flags; DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)", overlay->crtc_x, overlay->crtc_y, overlay->crtc_width, overlay->crtc_height); return 0; }
static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, struct drm_framebuffer *fb) { struct fb_info *fbi = helper->fbdev; struct drm_device *dev = helper->dev; struct exynos_drm_gem_buf *buffer; unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3); unsigned long offset; drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height); /* RGB formats use only one buffer */ buffer = exynos_drm_fb_buffer(fb, 0); if (!buffer) { DRM_DEBUG_KMS("buffer is null.\n"); return -EFAULT; } /* map pages with kernel virtual space. */ if (!buffer->kvaddr) { if (is_drm_iommu_supported(dev)) { unsigned int nr_pages = buffer->size >> PAGE_SHIFT; buffer->kvaddr = (void __iomem *) vmap(buffer->pages, nr_pages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); } else { phys_addr_t dma_addr = buffer->dma_addr; if (dma_addr) buffer->kvaddr = (void __iomem *)phys_to_virt(dma_addr); else buffer->kvaddr = (void __iomem *)NULL; } if (!buffer->kvaddr) { DRM_ERROR("failed to map pages to kernel space.\n"); return -EIO; } }