#if defined(CONFIG_ION_ROCKCHIP)
#include <linux/rockchip_ion.h>
-#ifdef USE_ION_MMU
#include <linux/rockchip/iovmm.h>
#include <linux/rockchip/sysmmu.h>
#include <linux/dma-buf.h>
#endif
-#endif
#define H_USE_FENCE 1
static int hdmi_switch_complete;
static struct platform_device *fb_pdev;
EXPORT_SYMBOL(video_data_to_mirroring);
#endif
+struct rk_fb_reg_win_data g_reg_win_data[4];
+static int g_first_buf = 1;
static struct rk_fb_trsm_ops *trsm_lvds_ops;
static struct rk_fb_trsm_ops *trsm_edp_ops;
printk("error waiting on fence\n");
}
-#ifdef USE_ION_MMU
-static unsigned int rk_fb_map_ion_handle(struct fb_info *info,
- struct rk_fb_reg_area_data *reg_area_data,
- struct ion_handle *ion_handle,struct dma_buf *buf)
-{
- struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
- reg_area_data->dma_buf = buf;
- reg_area_data->attachment =
- dma_buf_attach(reg_area_data->dma_buf, dev_drv->dev);
- if (IS_ERR_OR_NULL(reg_area_data->attachment)) {
- dev_err(dev_drv->dev, "dma_buf_attach() failed: %ld\n",
- PTR_ERR(reg_area_data->attachment));
- goto err_buf_map_attach;
- }
-
- reg_area_data->sg_table = dma_buf_map_attachment(reg_area_data->attachment,
- DMA_BIDIRECTIONAL);
- if (IS_ERR_OR_NULL(reg_area_data->sg_table)) {
- dev_err(dev_drv->dev, "dma_buf_map_attachment() failed: %ld\n",
- PTR_ERR(reg_area_data->sg_table));
- goto err_buf_map_attachment;
- }
-
- reg_area_data->dma_addr = iovmm_map(dev_drv->dev, reg_area_data->sg_table->sgl, 0,
- buf->size);
- if (!reg_area_data->dma_addr || IS_ERR_VALUE(reg_area_data->dma_addr)) {
- dev_err(dev_drv->dev, "iovmm_map() failed: %d\n", reg_area_data->dma_addr);
- goto err_iovmm_map;
- }
- reg_area_data->ion_handle = ion_handle;
- return reg_area_data->dma_buf->size;
-
-err_iovmm_map:
- dma_buf_unmap_attachment(reg_area_data->attachment,
- reg_area_data->sg_table,DMA_BIDIRECTIONAL);
-err_buf_map_attachment:
- dma_buf_detach(buf, reg_area_data->attachment);
-err_buf_map_attach:
- return 0;
-}
-
+#ifdef CONFIG_ROCKCHIP_IOMMU
int rk_fb_sysmmu_fault_handler(struct device *dev,
enum rk_sysmmu_inttype itype, unsigned long pgtable_base,
- unsigned long fault_addr,unsigned int statu)
+ unsigned long fault_addr,unsigned int status)
{
- /*struct fb_info *fbi = dev_get_drvdata(dev);
+ struct fb_info *fbi = dev_get_drvdata(dev);
struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)fbi->par;
pr_err("PAGE FAULT occurred at 0x%lx (Page table base: 0x%lx),status=%d\n",
- fault_addr, pgtable_base,statu);
+ fault_addr, pgtable_base,status);
dev_drv->ops->dump_reg(dev_drv);
pr_err("Generating Kernel OOPS... because it is unrecoverable.\n");
- BUG();*/
+ BUG();
return 0;
}
int i,index_buf;
struct rk_fb_reg_area_data *area_data;
struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
-#ifdef H_USE_FENCE
- for(i=0;i<RK_WIN_MAX_AREA;i++){
- if(reg_win_data->reg_area_data[i].acq_fence)
- sync_fence_put(reg_win_data->reg_area_data[i].acq_fence);
- }
-#endif
+
for(i=0;i<reg_win_data->area_num;i++){
area_data = ®_win_data->reg_area_data[i];
index_buf = area_data->index_buf;
-#ifdef USE_ION_MMU
- iovmm_unmap(dev,area_data->dma_addr);
- dma_buf_unmap_attachment(area_data->attachment, area_data->sg_table,
- DMA_BIDIRECTIONAL);
- dma_buf_detach(area_data->dma_buf, area_data->attachment);
- dma_buf_put(area_data->dma_buf);
-#endif
+ #ifdef CONFIG_ROCKCHIP_IOMMU
+ ion_unmap_iommu(dev, rk_fb->ion_client, area_data->ion_handle);
+ #endif
if(area_data->ion_handle != NULL)
ion_free(rk_fb->ion_client, area_data->ion_handle);
}
}
-
static void rk_fb_update_reg(struct rk_lcdc_driver * dev_drv,struct rk_fb_reg_data *regs)
{
int i,j,ret=0;
#ifdef H_USE_FENCE
sw_sync_timeline_inc(dev_drv->timeline, 1);
#endif
+ if(!g_first_buf){
+ for(i=0;i<regs->win_num;i++){
+ rk_fb_free_dma_buf(dev_drv->dev,&g_reg_win_data[i]);
+ }
+ }
for(i=0;i<regs->win_num;i++){
- rk_fb_free_dma_buf(dev_drv->dev,®s->reg_win_data[i]);
+ memcpy(&g_reg_win_data[i], &(regs->reg_win_data[i]), sizeof(struct rk_fb_reg_win_data));
}
+ g_first_buf = 0;
+
if (dev_drv->wait_fs == 1)
kfree(regs);
}
u16 uv_x_off,uv_y_off,uv_y_act;
u8 is_pic_yuv=0;
u8 ppixel_a=0,global_a=0;
-#ifdef USE_ION_MMU
- struct dma_buf *buf;
-#else
ion_phys_addr_t phy_addr;
-#endif
+
reg_win_data->reg_area_data[0].smem_start = -1;
reg_win_data->area_num = 0;
if(win_par->area_par[0].phy_addr == 0){
}
reg_win_data->area_num++;
reg_win_data->reg_area_data[i].ion_handle = hdl;
- #ifndef USE_ION_MMU
+ #ifndef CONFIG_ROCKCHIP_IOMMU
ion_phys(rk_fb->ion_client, hdl, &phy_addr, &len);
- reg_win_data->reg_area_data[i].smem_start = phy_addr;
#else
- buf = ion_share_dma_buf(rk_fb->ion_client, hdl);
- if (IS_ERR_OR_NULL(buf)) {
- dev_err(info->dev, "ion_share_dma_buf() failed\n");
- goto err_share_dma_buf;
- }
- rk_fb_map_ion_handle(info,®_win_data->reg_area_data[i],hdl,buf);
- reg_win_data->reg_area_data[i].smem_start =
- reg_win_data->reg_area_data[i].dma_addr;
+ ion_map_iommu(dev_drv->dev, rk_fb->ion_client, hdl,
+ (unsigned long *)&phy_addr, (unsigned long *)&len);
#endif
+ reg_win_data->reg_area_data[i].smem_start = phy_addr;
reg_win_data->area_buf_num++;
reg_win_data->reg_area_data[i].index_buf = 1;
}
}
}
return 0;
-#ifdef USE_ION_MMU
+#ifdef CONFIG_ROCKCHIP_IOMMU
err_share_dma_buf:
ion_free(rk_fb->ion_client, hdl);
return -ENOMEM;
return 0;
}
+static int rk_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
+ int win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
+ struct rk_lcdc_win *win;
+ win = dev_drv->win[win_id];
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return dma_buf_mmap(win->area[0].dma_buf, vma, 0);
+}
+
static struct fb_ops fb_ops = {
.owner = THIS_MODULE,
.fb_open = rk_fb_open,
#if defined(CONFIG_ION_ROCKCHIP)
struct ion_handle *handle;
ion_phys_addr_t phy_addr;
-#ifdef USE_ION_MMU
- struct dma_buf *buf;
-#else
size_t len;
-#endif
#endif
win_id = dev_drv->ops->fb_get_win_id(dev_drv, fbi->fix.id);
if (win_id < 0)
dev_err(fbi->device, "failed to ion_alloc:%ld\n",PTR_ERR(handle));
return -ENOMEM;
}
+ win->area[0].dma_buf = ion_share_dma_buf(rk_fb->ion_client, handle);
+ if (IS_ERR_OR_NULL(win->area[0].dma_buf)) {
+ printk("ion_share_dma_buf() failed\n");
+ goto err_share_dma_buf;
+ }
win->area[0].ion_hdl = handle;
fbi->screen_base = ion_map_kernel(rk_fb->ion_client, handle);
-#ifndef USE_ION_MMU
- ion_phys(rk_fb->ion_client, handle, &phy_addr, &len);
- fbi->fix.smem_start = phy_addr;
- fbi->fix.smem_len = len;
- printk(KERN_INFO "alloc_buffer:ion_phy_addr=0x%lx\n",phy_addr);
+#ifndef CONFIG_ROCKCHIP_IOMMU
+ ion_phys(rk_fb->ion_client, handle, &phy_addr, &len);
#else
- buf = ion_share_dma_buf(rk_fb->ion_client, handle);
- if (IS_ERR_OR_NULL(buf)) {
- dev_err(fbi->device, "ion_share_dma_buf() failed\n");
- goto err_share_dma_buf;
- }
- rk_fb_map_ion_handle(fbi,&dev_drv->reg_area_data,handle,buf);
- fbi->fix.smem_start = dev_drv->reg_area_data.dma_addr;
- fbi->fix.smem_len = buf->size;
- printk(KERN_INFO "alloc_buffer:kernel_vir_addr=0x%x,mmu_vir_addr=0x%x,len=0x%x\n",
- fbi->screen_base,fbi->fix.smem_start,fbi->fix.smem_len);
+ ion_phys(rk_fb->ion_client, handle, &phy_addr, &len);
+ printk("ion_phys: %x,%x\n", phy_addr, len);
+ ion_map_iommu(dev_drv->dev, rk_fb->ion_client, handle,
+ (unsigned long *)&phy_addr, (unsigned long *)&len);
+ printk("%s: ion_map_iommu: %x,%x\n", __func__, phy_addr, len);
#endif
-
+ fbi->fix.smem_start = phy_addr;
+ fbi->fix.smem_len = len;
+ printk(KERN_INFO "alloc_buffer:ion_phy_addr=0x%lx\n",phy_addr);
#else
dma_addr_t fb_mem_phys;
void *fb_mem_virt;
}
return ret;
-#ifdef USE_ION_MMU
+
err_share_dma_buf:
ion_free(rk_fb->ion_client, handle);
return -ENOMEM;
-#endif
+
}
static int rk_release_fb_buffer(struct fb_info *fbi)
struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
struct fb_info *fbi;
int i = 0, ret = 0, index = 0;
- #ifdef USE_ION_MMU
+ #ifdef CONFIG_ROCKCHIP_IOMMU
struct device *mmu_dev = NULL;
#endif
if (rk_fb->num_lcdc == RK30_MAX_LCDC_SUPPORT)
fbi->var.width = dev_drv->cur_screen->width;
fbi->var.height = dev_drv->cur_screen->height;
fbi->var.pixclock = dev_drv->pixclock;
+#ifdef CONFIG_ROCKCHIP_IOMMU
+ fb_ops.fb_mmap = rk_fb_mmap;
+#endif
fbi->fbops = &fb_ops;
fbi->flags = FBINFO_FLAG_DEFAULT;
fbi->pseudo_palette = dev_drv->win[i]->pseudo_pal;
if (i == 0){ /* only alloc memory for main fb*/
- #ifdef USE_ION_MMU
- mmu_dev =
- rockchip_get_sysmmu_device_by_compatible(dev_drv->mmu_dts_name);
- platform_set_sysmmu(mmu_dev, dev_drv->dev);
- /*rockchip_sysmmu_set_fault_handler(dev_drv->dev,
- rk_fb_sysmmu_fault_handler);*/
- iovmm_activate(dev_drv->dev);
+ #ifdef CONFIG_ROCKCHIP_IOMMU
+ mmu_dev = rockchip_get_sysmmu_device_by_compatible("iommu,vopl_mmu");
+ if (mmu_dev) {
+ platform_set_sysmmu(mmu_dev, dev_drv->dev);
+ rockchip_sysmmu_set_fault_handler(dev_drv->dev, rk_fb_sysmmu_fault_handler);
+ iovmm_activate(dev_drv->dev);
+ }
#endif
rk_fb_alloc_buffer(fbi, rk_fb->num_fb);
}