I created a Linux driver for the VIU3 module on SOM Colibri VF61.
This requires an external video encoder type ADV7180.
The driver intercepts the interrupt number 64 (described on VYBRID RM REV8)
to synchronize the software on half-frame and PAL signals in order to properly configure the DMA address for recording in ram.
On the linux kernel 3.0.15 and the Colibri_VF_LinuxImageV2.1Beta3_20140318 image the interrupt is generated while
on the kernel 4.1.15 and Colibri_VF_LinuxConsoleImageV2.5_20151216 image the interrupt is not generated.
What is the solution for this issue?
Can you share the device tree change to the 4.1.15 kernel and atleast the probe function of the concerned driver meant for 4.1.15? Is the pinmultiplexing correct?
The device tree entry for VIU3 should be something as below:
+ viu3: viu3@400c9000 {
+ compatible = "fsl,vf610-viu";
+ reg = <0x400c9000 0x1000>;
+ interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_VIU>;
+ clock-names = "viu";
+ status = "disabled";
+ };
In device trees we use the NVIC interrupt ID. This can be found on Table 3.1 of Vybrid Technical Reference Manual.
I don’t use dtb node for this driver, I wrote the configuration for all resources I needed inside the code
but first I have disabled all devices that were not needed.
I attach the contents of my dts file
/dts-v1/;
#include “vf610-colibri.dtsi”
#include “vf-colibri-eval-v3.dtsi”
/ {
model = “Toradex Colibri VF61 on Colibri Evaluation Board”;
compatible = “toradex,vf610-colibri_vf61-on-eval”, “toradex,vf610-colibri_vf61”, “fsl,vf610”;
};
&esdhc1 {
pinctrl-names = “default”;
pinctrl-0 = <&pinctrl_esdhc1>;
bus-width = <4>;
status = “okay”;
};
&dcu0 {
status = “disabled”;
};
&bl {
status = “disabled”;
};
&pwm0 {
status = “disabled”;
};
&pwm1 {
status = “disabled”;
};
&uart1 {
status = “okay”;
};
&uart3 {
status = “disabled”;
};
&uart4 {
status = “disabled”;
};
&uart5 {
status = “disabled”;
};
&sai0 {
status = “disabled”;
};
&sai2 {
status = “disabled”;
};
&usbdev0 {
status = “disabled”;
};
&usbh1 {
status = “disabled”;
};
&usbmisc0 {
status = “disabled”;
};
&usbmisc1 {
status = “disabled”;
};
&usbphy0 {
status = “disabled”;
};
&usbphy1 {
status = “disabled”;
};
&i2c0 {
status = “okay”;
/* M41T0M6 real time clock on carrier board */
rtc: m41t0m6@68 {
compatible = "st,m41t00";
reg = <0x68>;
};
};
and thi is my hardware initialization code
static int init_hardware(void)
{
unsigned long val;
//Enable VIU clock; CCM_CCGR8[CG137] AIPS1-Slot73
val = get_register(0x4006B060);
val |= 0x000C0000;
set_register(0x4006B060, val);
//Pad configurations
val = 0x06 << 20; //Mux mode to video_in0
val |= 0x07 << 6; //DSE Drive Strength Field = 20 Ohm
val |= 0x01; //IBE Input Buffer Enable Field = Enabled
set_register(IOMUXC_PTC0, val); //VIU_DATA0, NOT USED, PUT TO GROUND
set_register(IOMUXC_PTC1, val); //VIU_DATA1, NOT USED, PUT TO GROUND
set_register(IOMUXC_PTC2, val); //VIU_DATA2
set_register(IOMUXC_PTC3, val); //VIU_DATA3
set_register(IOMUXC_PTC4, val); //VIU_DATA4
set_register(IOMUXC_PTC5, val); //VIU_DATA5
set_register(IOMUXC_PTC6, val); //VIU_DATA6
set_register(IOMUXC_PTC7, val); //VIU_DATA7
set_register(IOMUXC_PTC8, val); //VIU_DATA8
set_register(IOMUXC_PTB18, val); //VIU_DATA9
//VIU mux configured to get video signal from digital bus
clear_regbit(SRC_MISC2, 9);
clear_regbit(SRC_MISC2, 8);
val = 0x01 << 20; //Mux mode PIX_CLK of instance: video_in0
val |= 0x07 << 6; //DSE Drive Strength Field = 20 Ohm
val |= 0x01; //IBE Input Buffer Enable Field = Enabled
set_register(IOMUXC_PTA7, val); //VIU_PIX_CLK
set_register(IOMUXC_VIDEO_IN0_IPP_IND_PIX_CLK_SELECT_INPUT, 0x00000001);
return 0;
}
I highly recommend to use device tree at least for the standard stuff (registers, interrupts and clocks), it is so much easier and cleaner! Otherwise, you have to violate the architecture in order to get access to the required modules, and also need to understand all the modules yourself.
I guess that is exactly where the problem also is in your current approach: For interrupts, you not only need to setup GIC correctly, but in Vybrid there is also the MSCM interrupt router, which needs to route the interrupt to the A5’s GIC controller… I don’t see code which handels either of this.
You might find the attached patches helpful. They take care of enabling the clock and pinmux along with the correct device tree entry for the VIU peripheral. Patches are based off on top of latest 4.1-next branch.
Thanks Stefan, thanks Sanchayan, I’ll try your suggestions as soon as I can, I know it will cost me to rewrite a part of the driver.