For IMX53, VGA output can be support only from DI1, so only DI1 pins can be used for VGA IOMUX.
As default, the freescale BSP used DI1_PIN7 and DI1_PIN8 for VGA HSYNC and VSYNC, but all the DI pins are configurable, so it is OK for the customer to use DI1_PIN4 as the VGA HSYNC.
Except the IOMUX setting, BSP code should be updated for such modification.
WinCE code modification (In file bspdisplay.cpp):
Modify code from:
#define DI_COUNTER_BASECLK 0
#define DI_COUNTER_IHSYNC 1
#define DI_COUNTER_OHSYNC 2
#define DI_COUNTER_OVSYNC 3
#define DI_COUNTER_ALINE 4
#define DI_COUNTER_ACLOCK 5
#define DI_COUNTER_VGA_HSYNC 7
#define DI_COUNTER_VGA_VSYNC 8
#define DI_TVE_WAVEFORM 6
To
#define DI_COUNTER_BASECLK 0
#define DI_COUNTER_IHSYNC 1
#define DI_COUNTER_OHSYNC 2
#define DI_COUNTER_OVSYNC 3
#define DI_COUNTER_ALINE 5
#define DI_COUNTER_ACLOCK 6
#define DI_COUNTER_VGA_HSYNC 4
#define DI_COUNTER_VGA_VSYNC 8
#define DI_TVE_WAVEFORM 7
Note: When one waveform needs base on another waveform, then its DI_PIN/DI_COUNT number must be bigger than the based one. For example, the VSYNC signal always needs base on the HSYNC signal, so the DI_PIN/DI_COUNT number of VSYNC must be bigger than the number of HSYNC.
For Linux code (ipu_disp.c):
Original Attachment has been moved to: ipu_disp_old.c.zip
Original Attachment has been moved to: ipu_disp_new.c.zip
I have modified the code as you have suggested (and as Florent Auger has suggested in this discussion) but still don't have proper video. I have proper sync signals on the pins I wanted, but the video looks wrong.
DI_TVE_WAVEFORM is only used in WinCE code, the above sample code modification are two versions, one for WinCE and one for Linux.
That code was verified on real board, I can measure clock on DI1_PIN4, but I haven't connected it to real monitor, because the hardware doesn't support it.
For the reset code on DI_PIN6 "__raw_writel(0, DI_SW_GEN0(disp, 6));", I think they should be removed. Maybe this code caused you have no clock on external PINs.
Hi Qiang,
Thanks for the information. Some questions and comments, though:
It would be helpful if your code (and the driver code in general) used the above defines instead of just the numbers. The code is full of unexplained magic numbers, which makes it hard to make changes in one place.
Compare the existing code:
/* Setup active data waveform to sync with DC */
_ipu_di_sync_config(ipu, disp, 4, 0, DI_SYNC_HSYNC,
v_sync_width + v_start_width, DI_SYNC_HSYNC, height,
DI_SYNC_VSYNC, 0, DI_SYNC_NONE,
DI_SYNC_NONE, 0, 0);
_ipu_di_sync_config(ipu, disp, 5, 0, DI_SYNC_CLK,
h_sync_width + h_start_width, DI_SYNC_CLK,
width, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0,
0);
with the code using the above defines:
/* Setup active data waveform to sync with DC */
_ipu_di_sync_config(disp, DI_COUNTER_ALINE, 0, DI_SYNC_HSYNC,
v_sync_width + v_start_width, DI_SYNC_HSYNC, height,
DI_SYNC_VSYNC, 0, DI_SYNC_NONE,
DI_SYNC_NONE, 0, 0);
_ipu_di_sync_config(disp, DI_COUNTER_ACLOCK, 0, DI_SYNC_CLK,
h_sync_width + h_start_width, DI_SYNC_CLK,
width, DI_COUNTER_ALINE, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0);
What does the DI_TVE_WAVEFORM define do? I don't see any references to it in the Linux code.
Does the above ipu_disp_new.c code actually work?
For instance, I see code in ipu_disp_new.c like:
/* reset all unused counters */
__raw_writel(0, DI_SW_GEN0(disp, 6));
__raw_writel(0, DI_SW_GEN1(disp, 6));
and then a few lines later:
reg = __raw_readl(DI_STP_REP(disp, 6));
reg &= 0x0000FFFF;
__raw_writel(reg, DI_STP_REP(disp, 6));
Won't this code reset the counter by zeroing the IPU_DI1_SW_GEN0_6, IPU_DI1_SW_GEN1_6, and (the top half of the) IPU_DI1_STP_REP_3 registers?
But if we're using counter #6 as DI_COUNTER_ACLOCK this won't work, will it?
Again, if the code had read something like:
/* reset all unused counters */
__raw_writel(0, DI_SW_GEN0(disp, DI_COUNTER_UNUSED1));
__raw_writel(0, DI_SW_GEN1(disp, DI_COUNTER_UNUSED1));
It would have been easier to catch this problem and to change it.
Like Paul, I want to move both DI_COUNTER_VGA_HSYNC and DI_COUNTER_VGA_VSYNC to other pins because of the conflicts with EIM pins.
In my case, I can use pins 4 and 6.
But I don't know where in the template microcode the counter references must be changed.
Hi Paul, yes, you use EIM_OE and EIM_RW for NAND, but you also need use other DI pins (DI1_PIN1 ~ DI1_PIN6) as the VGA VSYNC and HSYNC in hardware, and you need update the software code too.
The DI pins (DI1_PIN1 ~ DI1_PIN8) will align with DI wave gen 1 ~ 8, in default Freescale BSP, for VGA mode, the wave gen will used as followed:
wave gen 1 (Align with DI1_PIN1): internal HSYNC waveform
wave gen 2 (Align with DI1_PIN2): external HSYNC waveform
wave gen 3 (Align with DI1_PIN3): external VSYNC waveform
wave gen 4 (Align with DI1_PIN4): active lines waveform
wave gen 5 (Align with DI1_PIN5): active clock waveform
wave gen 6 (Align with DI1_PIN6): not used
wave gen 7 (Align with DI1_PIN7): VGA delay HSYNC waveform
wave gen 8 (Align with DI1_PIN8): VGA delay VSYNC waveform
And for VGA output, only VGA delay HSYNC and VSYNC need external DI pins, other signals are only internal signal, and no real DI pins need be used. So you can config the VGA HSYNC and VSYNC to other DI pins and update the software setting.
Hi Qiang, Thank you for the post, but I had a question. I am using the EIM_OE and EIM_RW pins for my NAND interface, but would like to use the VGA port as well. However, EIM_OE -> DI1_PIN7 and EIM_RW -> DI1_PIN8. From your post, you say that I can just change the mapping in the code and the hardware/driver should have no issue with this (the VGA will work, and the EIM_OR/RW signals will be usable by my memory/NAND device)?