Clive Levinson
2004-08-30 16:36:33 UTC
Hi,
I have been stuck for a few days trying to map physical memory
in my framebuffer driver using the nopage handler on a strongArm
running V2.4.18.
The hardware is physically at address 0x2C000000, iotable_init()
maps it to 0XF1000000.
Within my driver, writing directly to 0XF1000000 will set pixels
on the screen. However for, a user application that calls mmap
to map the framebuffer, I use the following in my mmap handler::
io_remap_page_range(vma->vm_start, 0x2c000000,
vma->vm_end - vma->vm_start,
vma->vm_page_prot)
This is remapping to the actual physical address, and seems
to work correctly. The user level application then is able to write
to the framebuffer return by mmap and have it appear on screen.
My first point of confusion, is what is the relationship between
the physical address at 0x2C000000, and the 0XF1000000 ?
However, the real problem is that my hardware has banked memory,
mapping in the mmap, I can only write to the first 64K of the
framebuffer. I decided to get around this by using a nopage handler,
so that I can handle the bank switching.
This is basically what I have:
static struct vm_operations_struct myfb_vm_ops = {
nopage: myfb_nopage,
};
static int myfb_mmap(struct fb_info *info,
struct file *file,
struct vm_area_struct *vma)
{
vma->vm_flags = vma->vm_flags|VM_IO|VM_RESERVED;
vma->vm_ops = &myfb_vm_ops;
return 0;
}
static struct page * myfb_nopage(struct vm_area_struct * vma,
unsigned long address,
int unused)
{
pte_t pte;
//ignore the address offset at this point, assume it is the
//same as vma->vm_start
//pte=mk_pte_phys( 0x2c000000, PAGE_SHARED); //Generates an error
pte=mk_pte_phys( 0xf1000000, PAGE_SHARED); //No error
pageptr=pte_page( pte );
get_page( pageptr );
return pageptr;
}
If I use mk_pte_phys( 0x2c000000, PAGE_SHARED), I get an internal
error. If use pte=mk_pte_phys( 0xf1000000, PAGE_SHARED), it
satisfies the page request, however, the write is not happening to the
actual framebuffer, I am not sure where it is going.
Any suggestions or tips please?
Thanks,
Clive
-------------------------------------------------------------------
Subscription options: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/armlinux/mlfaq.php
Etiquette: http://www.arm.linux.org.uk/armlinux/mletiquette.php
I have been stuck for a few days trying to map physical memory
in my framebuffer driver using the nopage handler on a strongArm
running V2.4.18.
The hardware is physically at address 0x2C000000, iotable_init()
maps it to 0XF1000000.
Within my driver, writing directly to 0XF1000000 will set pixels
on the screen. However for, a user application that calls mmap
to map the framebuffer, I use the following in my mmap handler::
io_remap_page_range(vma->vm_start, 0x2c000000,
vma->vm_end - vma->vm_start,
vma->vm_page_prot)
This is remapping to the actual physical address, and seems
to work correctly. The user level application then is able to write
to the framebuffer return by mmap and have it appear on screen.
My first point of confusion, is what is the relationship between
the physical address at 0x2C000000, and the 0XF1000000 ?
However, the real problem is that my hardware has banked memory,
mapping in the mmap, I can only write to the first 64K of the
framebuffer. I decided to get around this by using a nopage handler,
so that I can handle the bank switching.
This is basically what I have:
static struct vm_operations_struct myfb_vm_ops = {
nopage: myfb_nopage,
};
static int myfb_mmap(struct fb_info *info,
struct file *file,
struct vm_area_struct *vma)
{
vma->vm_flags = vma->vm_flags|VM_IO|VM_RESERVED;
vma->vm_ops = &myfb_vm_ops;
return 0;
}
static struct page * myfb_nopage(struct vm_area_struct * vma,
unsigned long address,
int unused)
{
pte_t pte;
//ignore the address offset at this point, assume it is the
//same as vma->vm_start
//pte=mk_pte_phys( 0x2c000000, PAGE_SHARED); //Generates an error
pte=mk_pte_phys( 0xf1000000, PAGE_SHARED); //No error
pageptr=pte_page( pte );
get_page( pageptr );
return pageptr;
}
If I use mk_pte_phys( 0x2c000000, PAGE_SHARED), I get an internal
error. If use pte=mk_pte_phys( 0xf1000000, PAGE_SHARED), it
satisfies the page request, however, the write is not happening to the
actual framebuffer, I am not sure where it is going.
Any suggestions or tips please?
Thanks,
Clive
-------------------------------------------------------------------
Subscription options: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/armlinux/mlfaq.php
Etiquette: http://www.arm.linux.org.uk/armlinux/mletiquette.php