Re: [Linux-fbdev-devel] How to mmap a shadow framebuffer in virtual memory

2007-02-06 Thread Bernardo Innocenti

Bernardo Innocenti wrote:


I still couldn't solve my problem, but thanks for helping.

The way you map memory in ps3fb_mmap() is basically the same.
In my case, memory is allocated with __get_free_pages() instead
of being at an absolute physical address, but I can't see how
it could make any difference.


A few weeks ago I found the solution, which I report here to help
people who are googling for the same problem.

consistent_alloc() performed all the required magic to allocate
a contiguous buffer in phisical memory:

-   if (!(fb_info.shadow = (void *)__get_free_pages(GFP_KERNEL, 
OLED_MEMORDER))
+   if (!(fb_info.shadow = consistent_alloc(GFP_KERNEL, 
PAGE_ALIGN(OLED_MEMSIZE),
+   &fb_info.shadow_phys, PTE_BUFFERABLE))


The complete patch set is here, just in case:

  http://www.develer.com/patches/linux/pending/

--
  // Bernardo Innocenti - Develer S.r.l., R&D dept.
\X/  http://www.develer.com/

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Linux-fbdev-devel] How to mmap a shadow framebuffer in virtual memory

2007-01-14 Thread Bernardo Innocenti
Geert Uytterhoeven wrote:

> It's known to work for the PS3 frame buffer device driver, which copies the
> virtual frame buffer to the GPU on every vsync. Check out ps3fb_mmap() in
> http://www.kernel.org/git/?p=linux/kernel/git/geoff/ps3-linux.git;a=blob_plain;f=drivers/video/ps3fb.c;hb=HEAD

I still couldn't solve my problem, but thanks for helping.

The way you map memory in ps3fb_mmap() is basically the same.
In my case, memory is allocated with __get_free_pages() instead
of being at an absolute physical address, but I can't see how
it could make any difference.

-- 
   // Bernardo Innocenti - Develer S.r.l., R&D dept.
 \X/  http://www.develer.com/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Linux-fbdev-devel] How to mmap a shadow framebuffer in virtual memory

2007-01-14 Thread Geert Uytterhoeven
On Sun, 14 Jan 2007, Bernardo Innocenti wrote:
> This is driving me crazy.  I wrote this custom fb driver for an
> organic LED display for an embedded ARM system.
> 
> The display is connected trough an I2C bus, therefore the display
> buffer is not memory mapped.
> 
> Anyway, I want to support mmap() and my driver allocates shadow
> buffer with __get_free_pages() which gets periodically copied
> to the display by a thread. This is unlike most fb drivers which
> just point smem_start to the phisical address of their framebuffer.
> 
> >From user space, opening /dev/fb0 and writing to it works just
> fine.  mmap()'ing the file and writing to it does not have any
> effect.
> 
> Writing the phisical address in smem_start and letting the
> fbgen code do the rest didn't seem to work, so I reimplemented
> the fb_mmap hook.
> 
> I don't feel confident with the Linux VM, so I tried several
> strategies to allocate the shadow buffer, including vmalloc()
> and kmalloc().
> 
> The virtual framebuffer (vfb) also uses vmalloc() but crashes
> calling processes because it confuses physical and virtual
> addresses, or so it seems.
> 
> Maybe it's just my kernel or my platform... does anybody use
> a similar technique?  Can anybody point me to known-good code
> that approximates my needs?

It's known to work for the PS3 frame buffer device driver, which copies the
virtual frame buffer to the GPU on every vsync. Check out ps3fb_mmap() in
http://www.kernel.org/git/?p=linux/kernel/git/geoff/ps3-linux.git;a=blob_plain;f=drivers/video/ps3fb.c;hb=HEAD

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- Sony Network and Software Technology Center Europe (NSCE)
[EMAIL PROTECTED] --- The Corporate Village, Da Vincilaan 7-D1
Voice +32-2-7008453 Fax +32-2-7008622  B-1935 Zaventem, Belgium
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


How to mmap a shadow framebuffer in virtual memory

2007-01-13 Thread Bernardo Innocenti
Hello,

This is driving me crazy.  I wrote this custom fb driver for an
organic LED display for an embedded ARM system.

The display is connected trough an I2C bus, therefore the display
buffer is not memory mapped.

Anyway, I want to support mmap() and my driver allocates shadow
buffer with __get_free_pages() which gets periodically copied
to the display by a thread. This is unlike most fb drivers which
just point smem_start to the phisical address of their framebuffer.

>From user space, opening /dev/fb0 and writing to it works just
fine.  mmap()'ing the file and writing to it does not have any
effect.

Writing the phisical address in smem_start and letting the
fbgen code do the rest didn't seem to work, so I reimplemented
the fb_mmap hook.

I don't feel confident with the Linux VM, so I tried several
strategies to allocate the shadow buffer, including vmalloc()
and kmalloc().

The virtual framebuffer (vfb) also uses vmalloc() but crashes
calling processes because it confuses physical and virtual
addresses, or so it seems.

Maybe it's just my kernel or my platform... does anybody use
a similar technique?  Can anybody point me to known-good code
that approximates my needs?

If you want to review the code below, look for the allocation in
oledfb_init() and usage in oledfb_mmap().  This code runs on
2.4.19-rmk7 because I can't upgrade to a newer kernel on this
target.



/*
 * linux/drivers/video/oledfb.c -- STV8102 OLED frame buffer device
 *
 * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
 * Author: Bernardo Innocenti <[EMAIL PROTECTED]>
 * Author: Stefano Fedrigo <[EMAIL PROTECTED]>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 

/* Define to either 0 or 1 */
#define OLED_DEBUG  1

/* Driver name used in several places */
#define OLED_NAME "oledfb"

/* Fully qualified driver name for users */
#define OLED_FRIENDLY_NAME "STV8102 OLED"

/* Dimensions in pixels */
#define OLED_WIDTH  128
#define OLED_HEIGHT 33

/* Dimensions in millimeters */
#define OLED_WIDTH_MM  55
#define OLED_HEIGHT_MM 14

/* Size of an horizontal line in bytes */
#define OLED_WIDTH_BYTES  ((OLED_WIDTH + 7) / 8)

/* Framebuffer size in bytes */
#define OLED_MEMSIZE (OLED_WIDTH_BYTES * OLED_HEIGHT)

#define OLED_MEMORDER (get_order(PAGE_ALIGN(OLED_MEMSIZE)))

/* OLED refresh delay in milliseconds */
#define OLED_REFRESH_DELAY 300
#define OLED_REFRESH_JIFFIES ((OLED_REFRESH_DELAY * HZ)/1000)

/* Set to 1 to enable an X11-like backfilling pattern */
#define OLED_BACKFILL_PATTERN 0

/* I2C address of the OLED command/data registers */
#define I2C_DRIVERID_STV8102_CMD  0x3C
#define I2C_DRIVERID_STV8102_DATA 0x3D

/* Use a kernel thread to refresh the OLED periodically */
#define CONFIG_OLED_REFRESH_THREAD 1

/* BROKEN: i2c code sleeps in timer context */
#define CONFIG_OLED_REFRESH_TIMER 0


#define OLED_CMD_XSTART   0x00 /* address in lower 4 bits */
#define OLED_CMD_YSTART   0x40 /* address in lower 4 bits */
#define OLED_CMD_DISPON   0xAF
#define OLED_CMD_DISPOFF  0xAE
#define OLED_CMD_MOVE 0x80 /* effects in lower 4 bits */
#define OLED_CMD_HSPEED   0x90 /* speed in lower 3 bits */
#define OLED_CMD_VSPEED   0x98 /* speed in lower 3 bits */
#define OLED_CMD_HMIN 0xC0
#define OLED_CMD_HMAX 0xC2
#define OLED_CMD_VMIN 0xC6
#define OLED_CMD_VMAX 0xC8

/* Missing utility macros */
#define countof(x) (sizeof(x) / sizeof(x[0]))
#ifndef bool
#   define bool  int
#   define false 0
#   define true  1
#endif

#if OLED_DEBUG == 1
#define OLED_TRACE printk(KERN_DEBUG "%s:%s()\n", OLED_NAME, 
__FUNCTION__)
#define OLED_TRACEMSG(msg,...) printk(KERN_DEBUG "%s:%s(): " msg "\n", \
OLED_NAME, __FUNCTION__, ## __VA_ARGS__)
#elif OLED_DEBUG == 0
#define OLED_TRACE do {} while (0)
#define OLED_TRACEMSG(msg,...)
#else
#error Define OLED_DEBUG to either 0 or 1
#endif


struct oledfb_info {
struct fb_info_gen gen;

/* Shadow buffer for the memory mapped framebuffer */
uint8_t *shadow;

/* Second copy of shadow buffer for optimized refesh */
uint8_t *shadow2;

/* Physical address of shadow buffer as required by fbmem */
unsigned long shadow_phys;

/* I2C client we talk to for OLED command register read/write */
struct i2c_client i2c_cmd;

/* I2C client we talk to for OLED data register write */
struct i2c_client i2c_data;

bool screensaver_running;

atomic_t open_cnt;

#if CONFIG_OLED_REFRESH_THREAD
int thread_pid;

/* Used to tell our refresh thread to quit asap */
/*bool*/ int quitting;

struct