<font size=2 face="sans-serif">Hi,</font>
<br>
<br><font size=2 face="sans-serif">I found current gma500 fbdev driver
does not support the virtual </font>
<br><font size=2 face="sans-serif">mapping for the fb pages, instead it
only uses stolen pages and </font>
<br><font size=2 face="sans-serif">supports high resolution console by
reducing the color depth. It </font>
<br><font size=2 face="sans-serif">works well with fbcon for high resolution
envirnment.</font>
<br>
<br><font size=2 face="sans-serif">However, other programs, such as plymouth(a
boot animation program) </font>
<br><font size=2 face="sans-serif">may also use fbdev driver to flush screen
in high resolution </font>
<br><font size=2 face="sans-serif">envirnment, in that case, reducing the
color depth will decrease the </font>
<br><font size=2 face="sans-serif">quality or result in other problem.
              </font>
<br>
<br><font size=2 face="sans-serif">Noticed that Alan's patch(commit </font>
<br><font size=2 face="sans-serif">dffc9ceb55695f121adc57dd1fde7304c3afe81e)
killed the virtual mapping </font>
<br><font size=2 face="sans-serif">support for short of vmap space. But
the vmalloc space(128M) should </font>
<br><font size=2 face="sans-serif">be enough for most high resolution envirnments.</font>
<br>
<br><font size=2 face="sans-serif">So I'm considering add the virual mapping
support for fbdev driver. </font>
<br><font size=2 face="sans-serif">The following patch has not done completely
yet, still having console </font>
<br><font size=2 face="sans-serif">flicking problem need to be solved.</font>
<br>
<br><font size=2 face="sans-serif">I'm not sure whether the patch will
be useful for others or if there</font>
<br><font size=2 face="sans-serif">is something I missed. Need your comments.</font>
<br>
<br><font size=2 face="sans-serif">Thanks.</font>
<br>
<br><font size=2 face="sans-serif">Signed-off-by: Jiang Biao<jiang.biao2@zte.com.cn></font>
<br>
<br><font size=2 face="sans-serif">---</font>
<br><font size=2 face="sans-serif"> drivers/gpu/drm/gma500/framebuffer.c
| 110 ++++++++++++++++++++++-------------</font>
<br><font size=2 face="sans-serif"> drivers/gpu/drm/gma500/framebuffer.h
|   2 +</font>
<br><font size=2 face="sans-serif"> 2 files changed, 73 insertions(+),
39 deletions(-)</font>
<br>
<br><font size=2 face="sans-serif">diff --git a/drivers/gpu/drm/gma500/framebuffer.c
b/drivers/gpu/drm/gma500/framebuffer.c</font>
<br><font size=2 face="sans-serif">index 0fcdce0..21f14df 100644</font>
<br><font size=2 face="sans-serif">--- a/drivers/gpu/drm/gma500/framebuffer.c</font>
<br><font size=2 face="sans-serif">+++ b/drivers/gpu/drm/gma500/framebuffer.c</font>
<br><font size=2 face="sans-serif">@@ -117,34 +117,43 @@ static int psbfb_vm_fault(struct
vm_area_struct *vma, struct vm_fault *vmf)</font>
<br><font size=2 face="sans-serif">         struct
psb_framebuffer *psbfb = vma->vm_private_data;</font>
<br><font size=2 face="sans-serif">         struct
drm_device *dev = psbfb->base.dev;</font>
<br><font size=2 face="sans-serif">         struct
drm_psb_private *dev_priv = dev->dev_private;</font>
<br><font size=2 face="sans-serif">-        int
page_num;</font>
<br><font size=2 face="sans-serif">-        int
i;</font>
<br><font size=2 face="sans-serif">-        unsigned
long address;</font>
<br><font size=2 face="sans-serif">         int
ret;</font>
<br><font size=2 face="sans-serif">         unsigned
long pfn;</font>
<br><font size=2 face="sans-serif">-        unsigned
long phys_addr = (unsigned long)dev_priv->stolen_base +</font>
<br><font size=2 face="sans-serif">-        
               
         psbfb->gtt->offset;</font>
<br><font size=2 face="sans-serif">-</font>
<br><font size=2 face="sans-serif">-        page_num
= (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;</font>
<br><font size=2 face="sans-serif">-        address
= (unsigned long)vmf->virtual_address - (vmf->pgoff << PAGE_SHIFT);</font>
<br><font size=2 face="sans-serif">-</font>
<br><font size=2 face="sans-serif">-        vma->vm_page_prot
= pgprot_noncached(vma->vm_page_prot);</font>
<br><font size=2 face="sans-serif">-</font>
<br><font size=2 face="sans-serif">-        for
(i = 0; i < page_num; i++) {</font>
<br><font size=2 face="sans-serif">-        
       pfn = (phys_addr >> PAGE_SHIFT);</font>
<br><font size=2 face="sans-serif">-</font>
<br><font size=2 face="sans-serif">-        
       ret = vm_insert_mixed(vma, address,</font>
<br><font size=2 face="sans-serif">-        
               
       __pfn_to_pfn_t(pfn, PFN_DEV));</font>
<br><font size=2 face="sans-serif">-        
       if (unlikely((ret == -EBUSY) || (ret
!= 0 && i > 0)))</font>
<br><font size=2 face="sans-serif">-        
               break;</font>
<br><font size=2 face="sans-serif">-        
       else if (unlikely(ret != 0)) {</font>
<br><font size=2 face="sans-serif">-        
               ret
= (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;</font>
<br><font size=2 face="sans-serif">-        
               return
ret;</font>
<br><font size=2 face="sans-serif">+        struct
gtt_range *r;</font>
<br><font size=2 face="sans-serif">+        pgoff_t
page_offset;</font>
<br><font size=2 face="sans-serif">+        r
= psbfb->gtt;</font>
<br><font size=2 face="sans-serif">+</font>
<br><font size=2 face="sans-serif">+        mutex_lock(&dev->struct_mutex);</font>
<br><font size=2 face="sans-serif">+        if
(r->mmapping == 0) {</font>
<br><font size=2 face="sans-serif">+        
       ret = psb_gtt_pin(r);</font>
<br><font size=2 face="sans-serif">+        
       if (ret < 0) {</font>
<br><font size=2 face="sans-serif">+          
             goto fail;</font>
<br><font size=2 face="sans-serif">         
       }</font>
<br><font size=2 face="sans-serif">-        
       address += PAGE_SIZE;</font>
<br><font size=2 face="sans-serif">-        
       phys_addr += PAGE_SIZE;</font>
<br><font size=2 face="sans-serif">+        
       r->mmapping = 1;</font>
<br><font size=2 face="sans-serif">+        }</font>
<br><font size=2 face="sans-serif">+</font>
<br><font size=2 face="sans-serif">+        page_offset
= ((unsigned long) vmf->virtual_address - vma->vm_start)</font>
<br><font size=2 face="sans-serif">+        
               
       >> PAGE_SHIFT;</font>
<br><font size=2 face="sans-serif">+</font>
<br><font size=2 face="sans-serif">+        if
(r->stolen)</font>
<br><font size=2 face="sans-serif">+        
       pfn = (dev_priv->stolen_base + r->offset)
>> PAGE_SHIFT;</font>
<br><font size=2 face="sans-serif">+        else</font>
<br><font size=2 face="sans-serif">+        
       pfn = page_to_pfn(r->pages[page_offset]);</font>
<br><font size=2 face="sans-serif">+</font>
<br><font size=2 face="sans-serif">+        ret
= vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);</font>
<br><font size=2 face="sans-serif">+</font>
<br><font size=2 face="sans-serif">+fail:</font>
<br><font size=2 face="sans-serif">+        mutex_unlock(&dev->struct_mutex);</font>
<br><font size=2 face="sans-serif">+        switch
(ret) {</font>
<br><font size=2 face="sans-serif">+        case
0:</font>
<br><font size=2 face="sans-serif">+        case
-ERESTARTSYS:</font>
<br><font size=2 face="sans-serif">+        case
-EINTR:</font>
<br><font size=2 face="sans-serif">+        
       return VM_FAULT_NOPAGE;</font>
<br><font size=2 face="sans-serif">+        case
-ENOMEM:</font>
<br><font size=2 face="sans-serif">+        
       return VM_FAULT_OOM;</font>
<br><font size=2 face="sans-serif">+        default:</font>
<br><font size=2 face="sans-serif">+        
       return VM_FAULT_SIGBUS;</font>
<br><font size=2 face="sans-serif">         }</font>
<br><font size=2 face="sans-serif">-        return
VM_FAULT_NOPAGE;</font>
<br><font size=2 face="sans-serif"> }</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif"> static void psbfb_vm_open(struct
vm_area_struct *vma)</font>
<br><font size=2 face="sans-serif">@@ -180,7 +189,7 @@ static int psbfb_mmap(struct
fb_info *info, struct vm_area_struct *vma)</font>
<br><font size=2 face="sans-serif">         
*/</font>
<br><font size=2 face="sans-serif">         vma->vm_ops
= &psbfb_vm_ops;</font>
<br><font size=2 face="sans-serif">         vma->vm_private_data
= (void *)psbfb;</font>
<br><font size=2 face="sans-serif">-        vma->vm_flags
|= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;</font>
<br><font size=2 face="sans-serif">+        vma->vm_flags
|= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;</font>
<br><font size=2 face="sans-serif">         return
0;</font>
<br><font size=2 face="sans-serif"> }</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">@@ -317,7 +326,17 @@ static struct gtt_range
*psbfb_alloc(struct drm_device *dev, int aligned_size)</font>
<br><font size=2 face="sans-serif">         
       drm_gem_private_object_init(dev, &backing->gem,
aligned_size);</font>
<br><font size=2 face="sans-serif">         
       return backing;</font>
<br><font size=2 face="sans-serif">         }</font>
<br><font size=2 face="sans-serif">-        return
NULL;</font>
<br><font size=2 face="sans-serif">+        /*
Next try using GEM host memory */</font>
<br><font size=2 face="sans-serif">+        backing
= psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0, PAGE_SIZE);</font>
<br><font size=2 face="sans-serif">+        if (backing
== NULL)</font>
<br><font size=2 face="sans-serif">+          
     return NULL;</font>
<br><font size=2 face="sans-serif">+</font>
<br><font size=2 face="sans-serif">+        /* Now
back it with an object */</font>
<br><font size=2 face="sans-serif">+        if (drm_gem_object_init(dev,
&backing->gem, aligned_size) != 0) {</font>
<br><font size=2 face="sans-serif">+          
     psb_gtt_free_range(dev, backing);</font>
<br><font size=2 face="sans-serif">+          
     return NULL;</font>
<br><font size=2 face="sans-serif">+        }</font>
<br><font size=2 face="sans-serif">+        return
backing;</font>
<br><font size=2 face="sans-serif"> }</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif"> /**</font>
<br><font size=2 face="sans-serif">@@ -397,7 +416,8 @@ static int psbfb_create(struct
psb_fbdev *fbdev,</font>
<br><font size=2 face="sans-serif">         
               return
-ENOMEM;</font>
<br><font size=2 face="sans-serif">         }</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">-        memset(dev_priv->vram_addr
+ backing->offset, 0, size);</font>
<br><font size=2 face="sans-serif">+        if
(backing->stolen)</font>
<br><font size=2 face="sans-serif">+        
       memset(dev_priv->vram_addr + backing->offset,
0, size);</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">         info
= drm_fb_helper_alloc_fbi(&fbdev->psb_fb_helper);</font>
<br><font size=2 face="sans-serif">         if
(IS_ERR(info)) {</font>
<br><font size=2 face="sans-serif">@@ -434,8 +454,20 @@ static int psbfb_create(struct
psb_fbdev *fbdev,</font>
<br><font size=2 face="sans-serif">         info->fix.ywrapstep
= gtt_roll;</font>
<br><font size=2 face="sans-serif">         info->fix.ypanstep
= 0;</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">-        /*
Accessed stolen memory directly */</font>
<br><font size=2 face="sans-serif">-        info->screen_base
= dev_priv->vram_addr + backing->offset;</font>
<br><font size=2 face="sans-serif">+        if
(backing->stolen) {</font>
<br><font size=2 face="sans-serif">+        
       info->screen_base = dev_priv->vram_addr
+ backing->offset;</font>
<br><font size=2 face="sans-serif">+        }
else {</font>
<br><font size=2 face="sans-serif">+        
       psb_gtt_pin(backing);</font>
<br><font size=2 face="sans-serif">+        
       backing->mapping = 1;</font>
<br><font size=2 face="sans-serif">+        
       info->screen_base = vm_map_ram(backing->pages,
backing->npage, -1, PAGE_KERNEL);</font>
<br><font size=2 face="sans-serif">+        
       if (info->screen_base == NULL) {</font>
<br><font size=2 face="sans-serif">+        
               ret
= -ENOMEM;</font>
<br><font size=2 face="sans-serif">+        
               goto
err_free_range;</font>
<br><font size=2 face="sans-serif">+        
       }</font>
<br><font size=2 face="sans-serif">+        
       psbfb->vm_map = 1;</font>
<br><font size=2 face="sans-serif">+        </font>
<br><font size=2 face="sans-serif">+        }</font>
<br><font size=2 face="sans-serif">+</font>
<br><font size=2 face="sans-serif">         info->screen_size
= size;</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">         if
(dev_priv->gtt.stolen_size) {</font>
<br><font size=2 face="sans-serif">@@ -458,7 +490,10 @@ static int psbfb_create(struct
psb_fbdev *fbdev,</font>
<br><font size=2 face="sans-serif"> err_release:</font>
<br><font size=2 face="sans-serif">         drm_fb_helper_release_fbi(&fbdev->psb_fb_helper);</font>
<br><font size=2 face="sans-serif"> err_free_range:</font>
<br><font size=2 face="sans-serif">-        psb_gtt_free_range(dev,
backing);</font>
<br><font size=2 face="sans-serif">+        if
(backing->stolen)</font>
<br><font size=2 face="sans-serif">+        
       psb_gtt_free_range(dev, backing);</font>
<br><font size=2 face="sans-serif">+        else
if(psbfb->vm_map)</font>
<br><font size=2 face="sans-serif">+        
       vm_unmap_ram(info->screen_base, backing->npage);</font>
<br><font size=2 face="sans-serif">         return
ret;</font>
<br><font size=2 face="sans-serif"> }</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">@@ -523,15 +558,6 @@ static int psbfb_probe(struct
drm_fb_helper *helper,</font>
<br><font size=2 face="sans-serif">         if
(bytespp == 3)        /* no 24bit packed */</font>
<br><font size=2 face="sans-serif">         
       bytespp = 4;</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">-        /*
If the mode will not fit in 32bit then switch to 16bit to get</font>
<br><font size=2 face="sans-serif">-        
  a console on full resolution. The X mode setting server will</font>
<br><font size=2 face="sans-serif">-        
  allocate its own 32bit GEM framebuffer */</font>
<br><font size=2 face="sans-serif">-        if
(ALIGN(sizes->fb_width * bytespp, 64) * sizes->fb_height ></font>
<br><font size=2 face="sans-serif">-        
               dev_priv->vram_stolen_size)
{</font>
<br><font size=2 face="sans-serif">-          
     sizes->surface_bpp = 16;</font>
<br><font size=2 face="sans-serif">-          
     sizes->surface_depth = 16;</font>
<br><font size=2 face="sans-serif">-        }</font>
<br><font size=2 face="sans-serif">-</font>
<br><font size=2 face="sans-serif">         return
psbfb_create(psb_fbdev, sizes);</font>
<br><font size=2 face="sans-serif"> }</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">@@ -545,6 +571,12 @@ static int psb_fbdev_destroy(struct
drm_device *dev, struct psb_fbdev *fbdev)</font>
<br><font size=2 face="sans-serif"> {</font>
<br><font size=2 face="sans-serif">         struct
psb_framebuffer *psbfb = &fbdev->pfb;</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">+        info
= fbdev->psb_fb_helper.fbdev;</font>
<br><font size=2 face="sans-serif">+        if
(psbfb->vm_map) {</font>
<br><font size=2 face="sans-serif">+        
       vm_unmap_ram(info->screen_base, psbfb->gtt->npage);</font>
<br><font size=2 face="sans-serif">+        
       psb_gtt_unpin(psbfb->gtt);</font>
<br><font size=2 face="sans-serif">+        }</font>
<br><font size=2 face="sans-serif">+</font>
<br><font size=2 face="sans-serif">         drm_fb_helper_unregister_fbi(&fbdev->psb_fb_helper);</font>
<br><font size=2 face="sans-serif">         drm_fb_helper_release_fbi(&fbdev->psb_fb_helper);</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">diff --git a/drivers/gpu/drm/gma500/framebuffer.h
b/drivers/gpu/drm/gma500/framebuffer.h</font>
<br><font size=2 face="sans-serif">index 395f20b..50b384e 100644</font>
<br><font size=2 face="sans-serif">--- a/drivers/gpu/drm/gma500/framebuffer.h</font>
<br><font size=2 face="sans-serif">+++ b/drivers/gpu/drm/gma500/framebuffer.h</font>
<br><font size=2 face="sans-serif">@@ -32,6 +32,8 @@ struct psb_framebuffer
{</font>
<br><font size=2 face="sans-serif">         struct
address_space *addr_space;</font>
<br><font size=2 face="sans-serif">         struct
fb_info *fbdev;</font>
<br><font size=2 face="sans-serif">         struct
gtt_range *gtt;</font>
<br><font size=2 face="sans-serif">+        bool
vm_map;</font>
<br><font size=2 face="sans-serif">+</font>
<br><font size=2 face="sans-serif"> };</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif"> struct psb_fbdev {</font>
<br><font size=2 face="sans-serif">-- </font>
<br><font size=2 face="sans-serif">2.1.0</font>