Re: [PATCH 2/2] sm501fb.c: support mmap on PPC440SPe/PPC440EPx

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 26/05/10 18:57, Anatolij Gustschin wrote:
> Add driver specific mmap function to be able to mmap
> frame buffer on PPC440SPe/PPC440EPx platforms. This
> is needed because mmaping of the 36-bit physical
> address of the frame buffer or MMIO is not supported
> in generic fb_mmap().

Surely this is something we should be fixing in the
main fb layer?

> Signed-off-by: Anatolij Gustschin <agust@xxxxxxx>
> Cc: Ben Dooks <ben@xxxxxxxxxxxx>
> Cc: Simtec Linux Team <linux@xxxxxxxxxxxx>
> ---
>  drivers/video/sm501fb.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 52 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
> index 0b59112..9cdc298 100644
> --- a/drivers/video/sm501fb.c
> +++ b/drivers/video/sm501fb.c
> @@ -1426,6 +1426,52 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec
>  	writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
>  }
>  
> +#if defined(CONFIG_440EPX) || defined(CONFIG_440SPe)
> +static int sm501fb_mmap(struct fb_info *info,
> +			struct vm_area_struct *vma)
> +{
> +	struct sm501fb_par *par = info->par;
> +	struct sm501fb_info *fbi = par->info;
> +	unsigned long long start;
> +	unsigned long len, off, map_off;
> +
> +	off = vma->vm_pgoff << PAGE_SHIFT;
> +	/*
> +	 * Get 36-bit base address of the frame buffer memory.
> +	 * Since it was previously truncated while assigning to
> +	 * fix.smem_start, we retrieve correct address here.
> +	 */
> +	start = (fbi->fbmem_res->start & 0xf00000000ULL) +
> +		info->fix.smem_start;
> +	len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
> +
> +	if (off >= len) {
> +		/* memory mapped io */
> +		off -= len;
> +		if (info->var.accel_flags)
> +			return -EINVAL;
> +		start = fbi->regs_res->start;
> +		len = PAGE_ALIGN((start & ~PAGE_MASK) +
> +				 resource_size(fbi->regs_res));
> +	}
> +
> +	start &= PAGE_MASK;
> +	if ((vma->vm_end - vma->vm_start + off) > len)
> +		return -EINVAL;
> +
> +	map_off = (unsigned long)((off + start) >> PAGE_SHIFT);
> +	vma->vm_pgoff = map_off;
> +
> +	vma->vm_flags |= VM_IO | VM_RESERVED;
> +	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> +	if (io_remap_pfn_range(vma, vma->vm_start, map_off,
> +			       vma->vm_end - vma->vm_start,
> +			       vma->vm_page_prot))
> +		return -EAGAIN;
> +
> +	return 0;
> +}
> +#endif
>  
>  static struct fb_ops sm501fb_ops_crt = {
>  	.owner		= THIS_MODULE,
> @@ -1439,6 +1485,9 @@ static struct fb_ops sm501fb_ops_crt = {
>  	.fb_copyarea	= sm501fb_copyarea,
>  	.fb_imageblit	= cfb_imageblit,
>  	.fb_sync	= sm501fb_sync,
> +#if defined(CONFIG_440EPX) || defined(CONFIG_440SPe)
> +	.fb_mmap	= sm501fb_mmap,
> +#endif
>  };
>  
>  static struct fb_ops sm501fb_ops_pnl = {
> @@ -1453,6 +1502,9 @@ static struct fb_ops sm501fb_ops_pnl = {
>  	.fb_copyarea	= sm501fb_copyarea,
>  	.fb_imageblit	= cfb_imageblit,
>  	.fb_sync	= sm501fb_sync,
> +#if defined(CONFIG_440EPX) || defined(CONFIG_440SPe)
> +	.fb_mmap	= sm501fb_mmap,
> +#endif
>  };
>  
>  /* sm501_init_cursor

--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Tourism]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux