rk fb:add ioctl for hwc addr
authorhjc <hjc@rock-chips.com>
Wed, 10 Sep 2014 02:55:11 +0000 (10:55 +0800)
committerhjc <hjc@rock-chips.com>
Thu, 11 Sep 2014 03:36:57 +0000 (11:36 +0800)
drivers/video/rockchip/rk_fb.c
include/linux/rk_fb.h

index 1fe662f43978fc017d29d847b7919abc9b549d3a..c77094faa762fce975f4a6cfd85cc656540bb3cd 100755 (executable)
@@ -2394,6 +2394,7 @@ EXPORT_SYMBOL(rk_get_real_fps);
 #ifdef CONFIG_ROCKCHIP_IOMMU
 #define ION_MAX 10
 static struct ion_handle *ion_hanle[ION_MAX];
+static struct ion_handle *ion_hwc[1];
 #endif
 static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,
                       unsigned long arg)
@@ -2428,6 +2429,51 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,
        }
 
        switch (cmd) {
+       case RK_FBIOSET_HWC_ADDR:
+       {
+               u32 hwc_phy[1];
+               if (copy_from_user(hwc_phy, argp, 4))
+                       return -EFAULT;
+               if (!dev_drv->iommu_enabled) {
+                       fix->smem_start = hwc_phy[0];
+               } else {
+                       int usr_fd;
+                       struct ion_handle *hdl;
+                       ion_phys_addr_t phy_addr;
+                       size_t len;
+
+                       usr_fd = hwc_phy[0];
+                       if (!usr_fd) {
+                               fix->smem_start = 0;
+                               fix->mmio_start = 0;
+                               break;
+                       }
+
+                       if (ion_hwc[0] != 0) {
+                               ion_free(rk_fb->ion_client, ion_hwc[0]);
+                               ion_hwc[0] = 0;
+                       }
+
+                       hdl = ion_import_dma_buf(rk_fb->ion_client, usr_fd);
+                       if (IS_ERR(hdl)) {
+                               dev_err(info->dev, "failed to get hwc ion handle:%ld\n",
+                                       PTR_ERR(hdl));
+                               return -EFAULT;
+                       }
+
+                       ret = ion_map_iommu(dev_drv->dev, rk_fb->ion_client, hdl,
+                                               (unsigned long *)&phy_addr,
+                                               (unsigned long *)&len);
+                       if (ret < 0) {
+                               dev_err(info->dev, "ion map to get hwc phy addr failed");
+                               ion_free(rk_fb->ion_client, hdl);
+                               return -ENOMEM;
+                       }
+                       fix->smem_start = phy_addr;
+                       ion_hwc[0] = hdl;
+               }
+               break;
+       }
        case RK_FBIOSET_YUV_ADDR:
                {
                        u32 yuv_phy[2];
index f4a1c3785033a0bfc12e99f53c464aaf30c5e40b..883483e5d7368273d4031da0a5e4cc0ef0a2de31 100755 (executable)
@@ -54,6 +54,7 @@
 #define RK_FBIOGET_16OR32                              0X4621
 #define RK_FBIOGET_IDLEFBUff_16OR32                    0X4622
 #define RK_FBIOSET_COMPOSE_LAYER_COUNTS                0X4623
+#define RK_FBIOSET_HWC_ADDR                            0x4624
 
 #define RK_FBIOGET_DMABUF_FD                           0x5003
 #define RK_FBIOSET_DMABUF_FD                           0x5004