static int rotator_dst_set_addr(struct device *dev, struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id, enum drm_exynos_ipp_buf_type buf_type) { struct rot_context *rot = dev_get_drvdata(dev); dma_addr_t addr[EXYNOS_DRM_PLANAR_MAX]; u32 val, fmt, hsize, vsize; int i; /* Set current buf_id */ rot->cur_buf_id[EXYNOS_DRM_OPS_DST] = buf_id; switch (buf_type) { case IPP_BUF_ENQUEUE: /* Set address configuration */ for_each_ipp_planar(i) addr[i] = buf_info->base[i]; /* Get format */ fmt = rotator_reg_get_fmt(rot); if (!rotator_check_reg_fmt(fmt)) { DRM_ERROR("invalid format.\n"); return -EINVAL; } /* Re-set cb planar for NV12 format */ if ((fmt == ROT_CONTROL_FMT_YCBCR420_2P) && !addr[EXYNOS_DRM_PLANAR_CB]) { /* Get buf size */ val = rot_read(ROT_DST_BUF_SIZE); hsize = ROT_GET_BUF_SIZE_W(val); vsize = ROT_GET_BUF_SIZE_H(val); /* Set cb planar */ addr[EXYNOS_DRM_PLANAR_CB] = addr[EXYNOS_DRM_PLANAR_Y] + hsize * vsize; } for_each_ipp_planar(i) rot_write(addr[i], ROT_DST_BUF_ADDR(i)); break; case IPP_BUF_DEQUEUE: for_each_ipp_planar(i) rot_write(0x0, ROT_DST_BUF_ADDR(i)); break; default: /* Nothing to do */ break; } return 0; }
static void rotator_reg_set_dst_buf_addr(struct rot_context *rot, dma_addr_t addr, int i) { writel(addr, rot->regs + ROT_DST_BUF_ADDR(i)); }