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

RE: [microblaze-uclinux] VGA controller in Microblaze



Hi Pablo,

 here is the code you need to add, first the definition of the device structure:

static struct platform_device xilinxfb_device={
	.name = "xilinxfb",				\
	.id = 0,					\
	.num_resources = 1,				\
	.resource = (struct resource[]) {		\
		{					\
			.start	= CONFIG_XILINX_TFT_0_SPLB_BASEADDR,	\
			.end	= CONFIG_XILINX_TFT_0_SPLB_HIGHADDR,	\
			.flags	= IORESOURCE_IO			\
		}							\
	}						\

};

In the driver initialization function you must register the device with 'platform_device_register' function:

static int __init
xilinxfb_init(void)
{
	int rc;
	rc = xilinxfb_of_register();
	if (rc)
		return rc;

	rc = platform_driver_register(&xilinxfb_platform_driver);
	if (rc)
		xilinxfb_of_unregister();
	
	platform_device_register(&xilinxfb_device); /* Device initialization */

	return rc;
}

I hope this work for you.

Regards,

 Inaki



-----Mensaje original-----
De: owner-microblaze-uclinux@xxxxxxxxxxxxxx en nombre de pcolodron@xxxxxxxx
Enviado el: lun 30/03/2009 14:58
Para: microblaze-uclinux@xxxxxxxxxxxxxx
Asunto: Re: [microblaze-uclinux] VGA controller in Microblaze
 
Hi John,

Thanks for your help, it helped me to understand better how to work  
with new devices and drivers. As you told me, I created a file  
xilinxfb.c in arch/microblaze/platform/common, which content is:

#include <linux/autoconf.h>
#include <linux/init.h>
#include <linux/resource.h>
#include <linux/xilinx_devices.h>

/* Fake definitions of IRQ channels for XGPIOs that don't actually have one.
    This is not super clean, but it does allow us to use a generic
    platform_device initialiser macro - see below */

#ifndef CONFIG_XILINX_TFT_0_IRQ
#define CONFIG_XILINX_TFT_0_IRQ -1L
#endif

#ifndef CONFIG_XILINX_TFT_1_IRQ
#define CONFIG_XILINX_TFT_1_IRQ -1L
#endif

#ifndef CONFIG_XILINX_TFT_2_IRQ
#define CONFIG_XILINX_TFT_2_IRQ -1L
#endif

#ifndef CONFIG_XILINX_TFT_3_IRQ
#define CONFIG_XILINX_TFT_3_IRQ -1L
#endif

#ifndef CONFIG_XILINX_TFT_4_IRQ
#define CONFIG_XILINX_TFT_4_IRQ -1L
#endif

#ifndef CONFIG_XILINX_TFT_5_IRQ
#define CONFIG_XILINX_TFT_5_IRQ -1L
#endif

/* Generic XGPIO platform_device initialiser macro.  Sinec we can nets #ifdef
    conditionals inside macros, we have two resources for each device, but in
    non-IRQ peripherals, the resource type is set to zero, otherwise it's
    IORESOURCE_IRQ as expected.  The kernel will just ignore zero-flagged
    resources.  We waste a small number of bytes - c'est la vie*/
#define XILINX_FB_PLATFORM_INITIALISER(n) \
{								\
	.name = "xilinxfb",					\
	.id = (n),						\
	.dev.platform_data = 0,					\
	.num_resources = 2,					\
	.resource = (struct resource[]) {			\
		{						\
			.start	= CONFIG_XILINX_TFT_##n##_SPLB_BASEADDR,	\
			.end	= CONFIG_XILINX_TFT_##n##_SPLB_HIGHADDR,	\
			.flags	= IORESOURCE_IO,			\
		},							\
		{							\
			.start	= CONFIG_XILINX_TFT_##n##_IRQ,		\
			.end    = CONFIG_XILINX_TFT_##n##_IRQ,		\
			.flags  = IORESOURCE_IRQ,			\
		},							\
	},								\
}

// dev.platform_data se define como 0. En el archivo  
.../drivers/video/xilinxfb.c se utiliza un platform_data por defecto  
que define de la resolucion de la pantalla 640x480. Si aquí definimos  
un platform_data, utiliza estos para aplicar la resolución y si no lo  
definimos utiliza los que vienen por defecto.
// num_resources lo definimos igual a 2, así lo hace el resto de los  
drivers en esta carpeta excepto xgpio (parece que este parámetro  
depende de si hay interrupciones?).
// Será necesario definir la direccion donde se encuentra el  
framebuffer? (parece que no, debería buscarla usando baseaddr).

static struct platform_device xilinx_fb_device[]= {
#ifdef CONFIG_XILINX_TFT_0_INSTANCE
XILINX_FB_PLATFORM_INITIALISER(0),
#endif
#ifdef CONFIG_XILINX_TFT_1_INSTANCE
XILINX_FB_PLATFORM_INITIALISER(1),
#endif
#ifdef CONFIG_XILINX_TFT_2_INSTANCE
XILINX_FB_PLATFORM_INITIALISER(2),
#endif
#ifdef CONFIG_XILINX_TFT_3_INSTANCE
XILINX_FB_PLATFORM_INITIALISER(3),
#endif
#ifdef CONFIG_XILINX_TFT_4_INSTANCE
XILINX_FB_PLATFORM_INITIALISER(4),
#endif
#ifdef CONFIG_XILINX_TFT_5_INSTANCE
XILINX_FB_PLATFORM_INITIALISER(5),
#endif
};

static int __init xilinx_fb_platform_init(void)
{
	int i;

	for(i=0;i<ARRAY_SIZE(xilinx_fb_device); i++)
		platform_device_register(&xilinx_fb_device[i]);

	return 0;
}

device_initcall(xilinx_fb_platform_init);


As a result, now I have a xilinxfb device:

     # ls /sys/bus/platform/devices/
     i8042          uartlite.0     xilinx_gpio.0  xilinx_gpio.1  xilinxfb.0

However this device is not assigned to fb0. I receive the following  
message when booting the board:

xilinxfb xilinxfb.0: regs: phys=86e00000, virt=86e00000
xilinxfb xilinxfb.0: fb: phys=8fc00000, virt=8fc00000, size=1e0000

However there are no messages about the framebuffer. Moreover, when I  
try to see the I/O memory space I obtain the following:

     # cat /proc/iomem
     81400000-8140ffff : xilinx_gpio.0
       81400000-8140ffff : xilinx_gpio
     81420000-8142ffff : xilinx_gpio.1
       81420000-8142ffff : xilinx_gpio
     84000000-8400ffff : uartlite.0
       84000000-8400000f : uartlite
     86e00000-86e00007 : xilinxfb

As you can see, there is no memory assigned to xilinxfb.o. I am surely  
missing some steps when creating the framebuffer but I am not able to  
see where is the error. Do you have any hint about what I am not doing  
right?

Thanks a lot for your kind help John.

Regards,

Pablo Colodron



John Williams escribió:
> Hi Pablo,
>
> On Wed, Mar 25, 2009 at 8:50 PM,  <pcolodron@xxxxxxxx> wrote:
>> Hi Inaki,
>>
>> That is what I was checking just right now :) I have found out that although
>> it enters in function 'platform_driver_register', it does not enter in
>> function 'xilinxfb_platform_probe', which is the one that initialize the
>> framebuffer. I don't know why this happens but I'll try to figure it out...
>> Thanks a lot for your help Inaki. I'll let you know my progress.
>
> The problem is that you have not registered a platform device - that
> is the kernel doesn't know you have a xilinx_fb device in the system,
> so it never calls the _probe() function.
>
> To do this, look in arch/microblaze/platform/common - you need to
> create a file called xilinxfb.c here.  Link it in to the Makefile of
> this directory.
>
> This code must create a platform_device structure, and then call
> platform_device_register() on that object.
>
> There are other examples in this same directory for other devices -
> e.g. xilinx_spi.c.  The pattern should be clear.
>
> Regards,
>
> John
> ___________________________
> microblaze-uclinux mailing list
> microblaze-uclinux@xxxxxxxxxxxxxx
> Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
> Mailing List Archive :  
> http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/
>
>



___________________________
microblaze-uclinux mailing list
microblaze-uclinux@xxxxxxxxxxxxxx
Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
Mailing List Archive : http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/


<<winmail.dat>>