2007-12-28 04:13:09 Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49070 Hi,
Today, another problem
On my bf537 board, I need to manage an LQ043 equivalent display. Thus my idea is to start from the lq035 driver. I don't want to start with the LQ043 driver for BF548 because the EPPI is really different of the BF537 PPI.
The first step for me is to compile the lq035 as is, and have it working on my board, to see the different signals on the oscilloscope (with my display not connected). After that I would be able to begin to modify the driver.
What I done this morning follow :
- Modify the linux-2.6.x/drivers/video/Kconfig file to be not dependent of i2c :
tristate "SHARP LQ035 TFT LCD on uClinux (BF537 STAMP)"
# depends on FB && ( BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI
depends on FB && ( BF534 || BF536 || BF537)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD
attached to a BF537.
- Modify bf537-lq035.c to erase all i2c parts
- Compile the kernel with the lq035 driver as module. The compilation is OK.
- Test the kernel + driver :
root:~> insmod /lib/modules/2.6.22.15-ADI-2007R2-pre-svn/kernel/drivers/video/cfbcopyarea.ko
root:~> insmod /lib/modules/2.6.22.15-ADI-2007R2-pre-svn/kernel/drivers/video/cfbfillrect.ko
root:~> insmod /lib/modules/2.6.22.15-ADI-2007R2-pre-svn/kernel/drivers/video/cfbimgblt.ko
root:~> insmod /lib/modules/2.6.22.15-ADI-2007R2-pre-svn/kernel/drivers/video/backlight/lcd.ko
root:~> insmod /lib/modules/2.6.22.15-ADI-2007R2-pre-svn/kernel/drivers/video/backlight/backlight.ko
root:~> insmod /lib/modules/2.6.22.15-ADI-2007R2-pre-svn/kernel/drivers/video/bf537-lq035.ko
bf537-lq035: FrameBuffer initializing...<6>Done.
Until here, everything is OK. But at this step, I have no signal on the timer outputs. Yet, my PPICLK is very clean, because directly connected to the CLKBUF pin. I have a10Mhz quartz, thus I have a very clean 10Mhz signal on the PPICLK.
If I look in /dev, the fb0 device is here after the modules are inserted :
root:~> ls -l /dev/fb0
brw-rw---- 1 root root 29, 0 Jan 1 00:00 /dev/fb0
So I tought that we need to open the fb device to start ppi+timers and have signal on the timers outputs.
Thus I try this command line, which works perfectly on my laptop (and print some pixel in the top left of the screen) :
root:~> echo "zkjbfjzehfjzhefjzhefkjhzekjfhzejfh" > /dev/fb0
/dev/fb0: cannot create
Another command, which works on my laptop and give me the framebuffer data :
root:~> cat /dev/fb0
/dev/fb0: cannot create
It's incredible, I am not lucky or what !?? It's exactly the same error than for my audio codec when I try to open the dev/dsp device !! I think these errors are linked, what do you think about that ?
Do I have a kernel misconfiguration somewhere ? It's true I have removed a lot of thing to have a small uclinux image (I am under 2Mo), do you think I have removed something which can explain this behavior ?
Regards,
Cyril
TranslateQuoteReplyEditDelete
2007-12-28 04:40:19 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49071 I saw in the source it's normal than I have no signal on the timer output. Everything is initialized when the function bfin_lq035_fb_open() is called.
I put a printk debug message at the beginning of this function, and this function is never called when I try to open the /dev/fb0 device with the echo or cat command !!
Does this precision can help you to find where can be my problem ?
Regards,
Cyril
TranslateQuoteReplyEditDelete
2007-12-28 05:45:45 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49073 I done a grep -R "cannot create" * in the linux src directory, and studied all the results, to see where come from this message. It's incredible, no source code prints this message !! All the "cannot create" message I can find are alway followed by something. In my case, the message "cannot create" is alone !
It's really incredible what happen to me !! I also searched this string in the user applications in romsfs/, it's the same, this message never come alone.
I begin to become crazy !! :))
Regards,
Cyril
TranslateQuoteReplyEditDelete
2007-12-28 06:43:32 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Mike Frysinger (UNITED STATES)
Message: 49084 the error message isnt coming from the kernel, so it wouldnt make sense for it to be in the kernel tree
the error message is coming from busybox's shell ... it failed to create the output for a redirection, so if you look in the busybox source code for the shell (msh.c), you'll find the place which is emitting that error
however, you should get the same exact error from doing an open() and write() in a C file, so that'll be easier for you to debug
QuoteReplyEditDelete
2007-12-28 08:27:43 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49085 Hi Mike,
I will write a small program which just do an open() on the /dev/fb0.
But I am pretty sure the bfin_lq035_fb_open() will not be called, as when I try to access it from the shell with echo or cat.
If I validate this point (because my debug message in this function will never appear), I really don't know the problem can come from.
It's very incredible because I work with the last trunk and my kernel / board has nothing special !!
For now I call the timers and ppi configuration in the init of the module. So I can begin to work on the port without open the framebuffer from userspace. In the framebuffer initialisation to 0xFFFF, I just set the first pixel of the screen to 0x0000. It permit to me to see everything on the oscilloscope, and I will be able to verify if the screen display me the first pixel as blank....
Regards,
Cyril
TranslateQuoteReplyEditDelete
2007-12-28 08:57:11 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Mike Frysinger (UNITED STATES)
Message: 49087 doing open(/dev/fb0) is exactly the same as doing 'echo > /dev/fb0' ... they both use the open function
if your open() function isnt being called, it sounds like the device node isnt being registered properly with the drivers filesystem ops
QuoteReplyEditDelete
2007-12-28 10:05:59 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49089 How it can be possible, I am working on the last trunk ?
TranslateQuoteReplyEditDelete
2007-12-28 14:10:51 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49095 I am happy, because I have successfully ported the driver to my LQ043 equivalent.
In the init function of the driver, I launch timers + dma, and I initialised the framebuffer memory to print blank pixels in the 4 angles of the screen. After some hour, it works. With the CLKBUF as clock for the PPICLK, it's really perfect, I can put my finger on the display signals, even PPICLK, nothing happen, the display is stable.
When the code will be cleaned, how proceed to send you the LQ043 driver for BF537 and add it in the trunk ?
Tomorrow I will try to understand why I have the error when opening /dev/fb0 from userspace.
Regards,
Cyril
TranslateQuoteReplyEditDelete
2007-12-28 14:29:25 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Bill Fassler (UNITED STATES)
Message: 49096 I am very interested in seeing your driver, side from acceptance in the dist. Could you please attach it to an email directly to me?
Thanks,
Bill
QuoteReplyEditDelete
2007-12-28 15:14:57 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49098 I clean it and attach it to this topic tomorrow
Cyril
TranslateQuoteReplyEditDelete
2007-12-29 03:00:56 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Mike Frysinger (UNITED STATES)
Message: 49103 post it to our patch tracker ... see if we cant get it unified with the existing lq drivers
QuoteReplyEditDelete
2007-12-29 03:43:29 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49105 No I think it will be not clean to unify it with existing lq driver.
As the LQ043 driver just has a vertical and a horizontal synchro, it is very different of the lq035, and easier, because it just use timer 0 and 1.
I don't know how works other TFT screen, but I think we can have a bf5xx_generic_tft.c instead of bf5xx-lq043.c.
Because with just 2 synchro, the code is easy and can be adapted easily on other TFT display (which works with 2 synchro only too).
With this idea, it become possible to configure the tftp parameters (resolution, horizontal back/front porsh, vertical back/front porsh, vertical pulse width, horizontal pulse witdh...) in the board file.
What do you think about that ?
Regards,
Cyril
TranslateQuoteReplyEditDelete
2007-12-29 05:54:14 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49107 Bill, I attached my code.
Your comments are welcome.
Cyril
bf537-lq043.c
TranslateQuoteReplyEditDelete
2007-12-29 07:03:26 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49109 I wrote a simple program to open the framebuffer :
int main ( int nbargs, char** args )
{
int fd;
fd = open( "/dev/fb0", O_RDWR );
if ( fd < 0 )
{ printf( "Impossible d'ouvrir, errno = %d\n", errno );
return -1;
}
close( fd );
return( 0 );
}
On my laptop it works, on the board :
root:~> ./framebuffer
Impossible d'ouvrir, errno = 6
errno 6 corresponds to : No such device or address
it's incredible, /dev/fb0 is here !!
root:~> ls -l /dev/fb0
brw-rw---- 1 root root 29, 0 Jan 1 00:00 /dev/fb0
Anyone has an idea ? Where begin to search the problem come from ?
I am pretty sure it's the same problem for my audio codec, because it's the same message. Thus the problem should come from the kernel, but where...and why !?
Regards,
Cyril
TranslateQuoteReplyEditDelete
2007-12-29 07:57:18 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49110 I found the problem : I have activated the General setup / Create deprecated sysfs files option, and now it works, I can successfully open, read and write on /dev/fb0.
When some day ago I deleted kernel functionnalities to have a small image size, I never thought this option will cause me problem because it was specified as deprecated...
Anyone can explain me why we can't open some device is this option is not enabled ?
Now I need to re-test my audio codec, I am pretty sure it will work too...
Regards,
Cyril
TranslateQuoteReplyEditDelete
2007-12-29 10:27:59 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49111 It's great, nano-X, naowm, jpgview, ... work well.
I just see a strange behavior. When the framebuffer is opened and something is displayed, an offset of the iomage occur when I launch a ftp transfer.
It seems the ppi dma miss pixels in the frame buffer.
TranslateQuoteReplyEditDelete
2008-01-04 06:49:16 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Lars Weber Rasmussen (DENMARK)
Message: 49252 You need to give the DMA controller higher priority to external bus accesses than the BF core.
QuoteReplyEditDelete
2008-01-04 11:27:12 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49262 In fact I verified, but it's already the case. The Blackfin processor option / EBIU_AMGCTL Global control / DMA has priority over core for ext. accesses option is checked.
Or there is another DMA which occur and which perturb the PPI DMA ?
The offset on the screen appear when there is a network communication. For example I see the problem when I launch an ftp transfer, or when I do a ping -s 2000 192.168.1.1 for example.
My network is based on a spectrum CF wifi card, connected on /AMS4, which is used in PIO mode + interrupt.
Thus there is no DMA for the CF card layer, but maybe there is DMA for some memory copy ?
Regards,
Cyril
TranslateQuoteReplyEditDelete
2008-01-04 13:48:57 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Robin Getz (UNITED STATES)
Message: 49271 Cyril:
My guess is that this has nothing to do with it.
But this is the first time I saw your network was a CF card....
I think I can describe the problem - and 2 alternative solutions:
The CF network driver uses the macros insw, insb, insl to read data from the card. These are architectures specific libs, defined in include/asm/io.h
extern void insb(unsigned long port, void *addr, unsigned long count);
extern void insw(unsigned long port, void *addr, unsigned long count);
extern void insl(unsigned long port, void *addr, unsigned long count);
extern void insl_16(unsigned long port, void *addr, unsigned long count);
It also defines:
#define ioread8_rep(a,d,c) insb(a,d,c)
#define ioread16_rep(a,d,c) insw(a,d,c)
#define ioread32_rep(a,d,c) insl(a,d,c)
So the driver might be using those as well.
On the Blackfin, those are defined in linux-2.6.x/arch/blackfin/lib/ins.S - let's look at the word (16-bit) version:
ENTRY(_insw)
P0 = R0; /* P0 = port */
cli R3;
P1 = R1; /* P1 = address */
P2 = R2; /* P2 = count */
SSYNC;
LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
.Lword_loop_s: R0 = W[P0];
W[P1++] = R0;
NOP;
.Lword_loop_e: NOP;
sti R3;
RTS;
ENDPROC(_insw)
One of the key things to note is the cli/sti which turns interrupts off during these reads. This is cause reads on the Blackfin are interruptable - they are done early in the pipeline, before the execute phase.
What this means is that a read (R0 = W[P0];) could be moving through the pipeline; the read stage of the pipeline is hit, the read gets issues on the external bus, before the read instruction can move to the execute stage of the pipeline, an async interrupt happens - and the pipeline is flushed. The interupt does its thing, and then returns. The read is re-issued (the value was not written to R0), and needs to be read again.
So what happens external to the core, is there are two reads issued, but the core really only sees one.
So we can not have interrupts enabled during reads of devices like FIFOs (like on a CF Networking card).
What we do, (to try to make the overhead as low as possible) is turn off interrupts, read all the values, and then turn them back on again. However, if you have a slow device, which moves alot of data at once (like an ethernet packet, on CF), this will cause other interrupts to be late.
You need to try something like:
ENTRY(_insw)
P0 = R0; /* P0 = port */
P1 = R1; /* P1 = address */
P2 = R2; /* P2 = count */
SSYNC(R3);
LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
.Lword_loop_s:
CLI R3; NOP; NOP; NOP;
R0 = W[P0];
STI R3;
W[P1++] = R0;
NOP;
.Lword_loop_e: NOP;
RTS;
ENDPROC(_insw)
CLI needs to be padded with 3 nops to make up for the 3 pipeline stages between the execute (where CLI commits) and the read stage, where things can be speculativliy issued on the bus.
This will need to be changed for all functions. Let me kniw if that helps.
This should make ethernet run a little slower, but make other interrupts more responsive.
The alternative is to re-write the network driver, so that the packet transfer uses the dma_outsb, dma_outsw, dma_outsl functions - since they are not speculative accesses, and can not be clobbered/cancelled/re-issued, they don't turn interrupts off, and things should work better. However, there is more overhead of setting up and managing dma.
-Robin
QuoteReplyEditDelete
2008-01-05 10:26:53 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49294 Robin,
Thank you very much for your very clear explanations.
For now I believe I will not change anything, because in fact I use the CF wifi card for development purpose only, to download new kernel, download new kernel modules, and so on. In the final product, no CF card will be connected, or it will be in some month/year, to connect a bluetooth CF card.
But what you tell me makes me think that I have an usb controller connected on async bus (/ams1), and a nand flash (/ams0). For the nand flash accesses, if I have the same behavior it's not really important because the nand flash accesses only occur if I need to write a new uImage into it. And this write will be done after boot before I launch my lq043 driver and my user application.
But if the same behavior happen with the USB controller it's a problem because the usb will be used during normal operation of the board ( to play mp3).
My controller is an ISP1160, can you tell me if I will have the same behavior ?
Best regards,
Cyril
TranslateQuoteReplyEditDelete
2008-01-06 22:44:56 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Robin Getz (UNITED STATES)
Message: 49307 Cyril:
rgetz@imhotep:~/blackfin/trunk/uClinux-dist/linux-2.6.x> grep ISP1160 $(find ./drivers/usb/ -name Kconfig)
./drivers/usb/host/Kconfig: The ISP1160 and ISP1161 chips are USB host controllers. Enable this
says that the ISP1160 is defined in that file. If you look at it:
rgetz@imhotep:~/blackfin/trunk/uClinux-dist/linux-2.6.x> less drivers/usb/host/Kconfig
config USB_ISP116X_HCD
tristate "ISP116X HCD support"
You can see what it is set by, and then look at the Makefile to look at the exact source file.
rgetz@imhotep:~/blackfin/trunk/uClinux-dist/linux-2.6.x> less drivers/usb/host/Makefile
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
From looking at the source:
rgetz@imhotep:~/blackfin/trunk/uClinux-dist/linux-2.6.x> less drivers/usb/host/isp116x-hcd.c
You should notice that the reads are in 4 functions:
isp116x_raw_read_data16()
isp116x_read_data16()
isp116x_read_reg16()
isp116x_read_reg32()
There are all defined in drivers/usb/host/isp116x.h, as either __raw_readw(), readw().
in include/asm/io.h :
#define __raw_readw readw
and
static inline unsigned short readw(const volatile void __iomem *addr)
{
unsigned int val;
int tmp;
__asm__ __volatile__ ("cli %1;\n\t"
"NOP; NOP; SSYNC;\n\t"
"%0 = w [%2] (z);\n\t"
"sti %1;\n\t"
: "=d"(val), "=d"(tmp): "a"(addr)
);
return (unsigned short) val;
}
So, no - you should not have any trouble with the USB, because the way the driver was written was it reads one word at a time. - so interrupts will only be turned off for a very short time.
-Robin
QuoteReplyEditDelete
2008-01-07 12:10:40 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Michael Hennerich (GERMANY)
Message: 49324
Try to reduce the ASYNC bus timing to a minimum - of the bank you connected the controller.
-Michael
QuoteReplyEditDelete
2008-01-09 11:11:03 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49404 Hi Robin and Michael.
I saw what you said Robin, but I wasn't sure.
For the USB part, I already have reduced the async bus timing.
Today I have the display mounted on the board, I make some test and I give you the result.
Regards,
Cyril
TranslateQuoteReplyEditDelete
2008-01-09 11:51:09 Re: Write LQ043 driver for BF537 with bf537-lq035.c as base
Cyril HAENEL (FRANCE)
Message: 49407 Goods news,
It seems Robin is right, usb transfers doesn't cause the lcd offset :
I have jpegview displaying a jpeg, mp3play playing a file in local filesystem, 2 usb stick mounted, with copy of a big directory from on usb stick to another.
Everything is OK, "top" command give me mp3play at 23%, and cp at 6% cpu usage.
The only problem I have is that I am not able to properly shutdown the display when the framebuffer is released. In the release function, I set the DISP_ON input of the screen to 0, release the associed GPIO port (which certainly become an input, but I have a pull down resistor), and stop the PPI dma and timers.
But the display is not correctly stopped, and very strange behavior appear on the screen. I think it's not very dangerous for the display, but it's not very beautiful for eyes...
I made test, and to cleanly stop the display, it seems I need to sert DISP_ON at lowlevel, but wait for a complete frame to be done before stop the H and V synchros.
Thus my question is : it is possible to do a usleep in a kernel module or something like that ? I yes, in the release function I can set my DISP_ON to low level, wait for 50ms for exemple, and then shutdown PPI and timers (and then H and V synchro).
Regards,
Cyril