<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>