+#if defined(CONFIG_ROCKCHIP_RGA) || defined(CONFIG_ROCKCHIP_RGA2)
+static int get_rga_format(int fmt)
+{
+ int rga_fmt = 0;
+
+ switch (fmt) {
+ case XBGR888:
+ rga_fmt = RK_FORMAT_RGBX_8888;
+ break;
+ case ABGR888:
+ rga_fmt = RK_FORMAT_RGBA_8888;
+ break;
+ case ARGB888:
+ rga_fmt = RK_FORMAT_BGRA_8888;
+ break;
+ case RGB888:
+ rga_fmt = RK_FORMAT_RGB_888;
+ break;
+ case RGB565:
+ rga_fmt = RK_FORMAT_RGB_565;
+ break;
+ case YUV422:
+ rga_fmt = RK_FORMAT_YCbCr_422_SP;
+ break;
+ case YUV420:
+ rga_fmt = RK_FORMAT_YCbCr_420_SP;
+ break;
+ default:
+ rga_fmt = RK_FORMAT_RGBA_8888;
+ break;
+ }
+
+ return rga_fmt;
+}
+
+static void rga_win_check(struct rk_lcdc_win *dst_win,
+ struct rk_lcdc_win *src_win)
+{
+ int align32 = 4;
+
+ align32 -= 1;
+ /*width and height must be aligned by 32 bit */
+ if ((src_win->area[0].xact & align32) != 0)
+ src_win->area[0].xact =
+ (src_win->area[0].xact + align32) & (~align32);
+ if ((src_win->area[0].yact & align32) != 0)
+ src_win->area[0].yact =
+ (src_win->area[0].yact + align32) & (~align32);
+ if (src_win->area[0].xvir < src_win->area[0].xact)
+ src_win->area[0].xvir = src_win->area[0].xact;
+ if (src_win->area[0].yvir < src_win->area[0].yact)
+ src_win->area[0].yvir = src_win->area[0].yact;
+
+ if ((dst_win->area[0].xact & align32) != 0)
+ dst_win->area[0].xact =
+ (dst_win->area[0].xact + align32) & (~align32);
+ if ((dst_win->area[0].yact & align32) != 0)
+ dst_win->area[0].yact =
+ (dst_win->area[0].yact + align32) & (~align32);
+ if (dst_win->area[0].xvir < dst_win->area[0].xact)
+ dst_win->area[0].xvir = dst_win->area[0].xact;
+ if (dst_win->area[0].yvir < dst_win->area[0].yact)
+ dst_win->area[0].yvir = dst_win->area[0].yact;
+}
+
+static void win_copy_by_rga(struct rk_lcdc_win *dst_win,
+ struct rk_lcdc_win *src_win, u16 orientation)
+{
+ struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
+ struct rga_req Rga_Request;
+ long ret = 0;
+ /* int fd = 0; */
+
+ memset(&Rga_Request, 0, sizeof(Rga_Request));
+ rga_win_check(dst_win, src_win);
+
+ switch (orientation) {
+ case ROTATE_90:
+ Rga_Request.rotate_mode = 1;
+ Rga_Request.sina = 65536;
+ Rga_Request.cosa = 0;
+ Rga_Request.dst.act_w = dst_win->area[0].yact;
+ Rga_Request.dst.act_h = dst_win->area[0].xact;
+ Rga_Request.dst.x_offset = dst_win->area[0].xact - 1;
+ Rga_Request.dst.y_offset = 0;
+ break;
+ case ROTATE_180:
+ Rga_Request.rotate_mode = 1;
+ Rga_Request.sina = 0;
+ Rga_Request.cosa = -65536;
+ Rga_Request.dst.act_w = dst_win->area[0].xact;
+ Rga_Request.dst.act_h = dst_win->area[0].yact;
+ Rga_Request.dst.x_offset = dst_win->area[0].xact - 1;
+ Rga_Request.dst.y_offset = dst_win->area[0].yact - 1;
+ break;
+ case ROTATE_270:
+ Rga_Request.rotate_mode = 1;
+ Rga_Request.sina = -65536;
+ Rga_Request.cosa = 0;
+ Rga_Request.dst.act_w = dst_win->area[0].yact;
+ Rga_Request.dst.act_h = dst_win->area[0].xact;
+ Rga_Request.dst.x_offset = dst_win->area[0].xact - 1;
+ Rga_Request.dst.y_offset = dst_win->area[0].yact - 1;
+ break;
+ default:
+ Rga_Request.rotate_mode = 0;
+ Rga_Request.dst.act_w = dst_win->area[0].xact;
+ Rga_Request.dst.act_h = dst_win->area[0].yact;
+ Rga_Request.dst.x_offset = dst_win->area[0].xact - 1;
+ Rga_Request.dst.y_offset = dst_win->area[0].yact - 1;
+ break;
+ }
+
+#if defined(CONFIG_ROCKCHIP_RGA)
+ Rga_Request.src.yrgb_addr =
+ src_win->area[0].smem_start + src_win->area[0].y_offset;
+ Rga_Request.src.uv_addr = 0;
+ Rga_Request.src.v_addr = 0;
+
+ dst_win->area[0].smem_start =
+ rk_fb->fb[rk_fb->num_fb >> 1]->fix.smem_start;
+ Rga_Request.dst.yrgb_addr =
+ dst_win->area[0].smem_start + dst_win->area[0].y_offset;
+ Rga_Request.dst.uv_addr = 0;
+ Rga_Request.dst.v_addr = 0;
+#elif defined(CONFIG_ROCKCHIP_RGA2)
+/*
+ fd = ion_share_dma_buf_fd(rk_fb->ion_client, src_win->area[0].ion_hdl);
+ Rga_Request.src.yrgb_addr = fd;
+ fd = ion_share_dma_buf_fd(rk_fb->ion_client, dst_win->area[0].ion_hdl);
+ Rga_Request.dst.yrgb_addr = fd;
+*/
+ Rga_Request.src.yrgb_addr = 0;
+ Rga_Request.src.uv_addr =
+ src_win->area[0].smem_start + src_win->area[0].y_offset;
+ Rga_Request.src.v_addr = 0;
+
+ dst_win->area[0].smem_start =
+ rk_fb->fb[rk_fb->num_fb >> 1]->fix.smem_start;
+ Rga_Request.dst.yrgb_addr = 0;
+ Rga_Request.dst.uv_addr =
+ dst_win->area[0].smem_start + dst_win->area[0].y_offset;
+ Rga_Request.dst.v_addr = 0;
+#endif
+
+ Rga_Request.src.vir_w = src_win->area[0].xvir;
+ Rga_Request.src.vir_h = src_win->area[0].yvir;
+ Rga_Request.src.format = get_rga_format(src_win->format);
+ Rga_Request.src.act_w = src_win->area[0].xact;
+ Rga_Request.src.act_h = src_win->area[0].yact;
+ Rga_Request.src.x_offset = 0;
+ Rga_Request.src.y_offset = 0;
+
+ Rga_Request.dst.vir_w = dst_win->area[0].xvir;
+ Rga_Request.dst.vir_h = dst_win->area[0].yvir;
+ Rga_Request.dst.format = get_rga_format(dst_win->format);
+
+ Rga_Request.clip.xmin = 0;
+ Rga_Request.clip.xmax = dst_win->area[0].xact - 1;
+ Rga_Request.clip.ymin = 0;
+ Rga_Request.clip.ymax = dst_win->area[0].yact - 1;
+ Rga_Request.scale_mode = 0;
+#if defined(CONFIG_ROCKCHIP_IOMMU)
+ Rga_Request.mmu_info.mmu_en = 1; /* TODO Modify for use mmu */
+ Rga_Request.mmu_info.mmu_flag = 1;
+#else
+ Rga_Request.mmu_info.mmu_en = 0;
+ Rga_Request.mmu_info.mmu_flag = 0;
+#endif
+
+ ret = rga_ioctl_kernel(&Rga_Request);
+}
+
+/*
+ * This function is used for copying fb by RGA Module
+ * RGA only support copy RGB to RGB
+ * RGA2 support copy RGB to RGB and YUV to YUV
+ */
+static void fb_copy_by_rga(struct fb_info *dst_info, struct fb_info *src_info,
+ int yrgb_offset)
+{
+ struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)src_info->par;
+ struct rk_lcdc_driver *ext_dev_drv =
+ (struct rk_lcdc_driver *)dst_info->par;
+ int win_id = 0, ext_win_id;
+ struct rk_lcdc_win *src_win, *dst_win;
+
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, src_info->fix.id);
+ src_win = dev_drv->win[win_id];
+
+ ext_win_id =
+ ext_dev_drv->ops->fb_get_win_id(ext_dev_drv, dst_info->fix.id);
+ dst_win = ext_dev_drv->win[ext_win_id];
+
+ win_copy_by_rga(dst_win, src_win, ext_dev_drv->rotate_mode);
+}
+
+#endif