Help regarding programming for GPIOs on A13, without any linux kernel overhead

Started by Vinuthan, March 11, 2013, 02:49:44 PM

Previous topic - Next topic

olimex

how do you dump the key register?
as the kernel on Allwinner Android image toggle GPIOs at double speed, so we can see how AXI AHB APB clocks are initialized there
with no proper docs we can only assume that Allwinner setup their clocks correctly :)

crubille

 ;D                     ;D
    ;D               ;D
       ;D         ;D
          ;D   ;D
             ;D

So, I patch the linux kernel roughly and set the AHB divisor to 1,
compile,
reboot,


So PLL1 is at 1000 MHz, AXI at 333MHz
AHB was at 41.6 MHz and is now at 166 MHz
APB was at 20.8 MHz ans is now at 83,3 MHz



It look ok. I check the SYSCLKDIV is  was it should be.

Then i do some xenomai test:

first "echo 0 > /proc/xenomai/latency"  so there is no pre calibration of the delay.

xenomai task in user mode:
"latency -p 100" minimal time from 8.9 micro seconds to 4.0 micro seconds - more than twice
"latency -p 100" average time from 10.4 micro seconds to 4.8 micro seconds - more than twice

xenomai driver in kernel mode:
"latency -p 100 -t 2" minimal time from 4.58 micro seconds to 1.33 micro seconds - more than three times faster
"latency -p 100 -t 2" average time from 5.58 micro seconds to 1.77 micro seconds - more than three times faster

I check the usb and mmc access too:
"hdparm -tT /dev/uba"  throughput go from 18.2 to 18.7 - just a bit better
"hdparm -tT /dev/mmcblk0"  throughput go from 20.4 to 20.7 - not significant.

I copy a large file from my host to the A13 with "scp" and get 2.7MB/s - so ethernet is ok;

The display with VGA is OK.

The proc is not warmer.

Only one point: The patch is really ugly  :P



crubille

I patch the kernel to get the register state and all the modification of PLL (which are done from the code in this file).
Just a little line change the divisor for ABP.


Then, after booting just to:
"dmesg | grep PC-MSG"


Here is the patch (from kernel 3.4.24 )


pc@debian:~$ cat /usr/src/sysclk.patch
--- linux-sunxi-sunxi-3.4/arch/arm/mach-sun5i/clock/ccmu/ccm_sys_clk.c  2013-02-21 19:50:22.000000000 +0000
+++ linux-sunxi-sunxi-3.4-xenomai-prio_irq/arch/arm/mach-sun5i/clock/ccmu/ccm_sys_clk.c 2013-03-14 18:07:13.000000000 +0000
@@ -725,10 +725,12 @@
             /* delay 500us for pll be stably */
             __delay((rate >> 20) * 500 / 2);

+printk(KERN_NOTICE "PC-MSG set PLL1 rate : %lld \n", rate);
             return 0;
         }
         case AW_SYS_CLK_PLL2:
         {
+printk(KERN_NOTICE "PC-MSG set PLL2 rate : %lld \n", rate);
             if(rate == 22579200)
             {
                 /* chip is version B, FactorN=79, PreDiv=21, PostDiv=4,
@@ -759,6 +761,7 @@
         }
         case AW_SYS_CLK_PLL2X8:
         {
+printk(KERN_NOTICE "PC-MSG set PLL2x8 rate : %lld \n", rate);
             if((sys_clk_get_rate(AW_SYS_CLK_PLL2) == 24576000) && (rate == 24576000 * 18))
             {
                 return 0;
@@ -773,6 +776,13 @@
         }
         case AW_SYS_CLK_PLL3:
         {
+printk(KERN_NOTICE "PC-MSG SysClkDiv AXI %d - AHB %d - APB %d -- SRC-CPU %d - SRC-AHB %d\n",
+       aw_ccu_reg->SysClkDiv.AXIClkDiv ,
+       aw_ccu_reg->SysClkDiv.AHBClkDiv ,
+       aw_ccu_reg->SysClkDiv.APB0ClkDiv ,
+       aw_ccu_reg->SysClkDiv.AC328ClkSrc ,
+       aw_ccu_reg->SysClkDiv.AHBClkSel );
+printk(KERN_NOTICE "PC-MSG set PLL3 rate : %lld \n", rate);
             if((rate < 9*3000000) || (rate > (127*3000000)))
             {
                 CCU_ERR("Rate(%lld) is invalid when set PLL3 rate!\n", rate);
@@ -798,6 +808,7 @@
         }
         case AW_SYS_CLK_PLL3X2:
         {
+printk(KERN_NOTICE "PC-MSG set PLL3x2 rate : %lld \n", rate);
             if(rate == (sys_clk_get_rate(AW_SYS_CLK_PLL3) << 1))
             {
                 return 0;
@@ -808,6 +819,9 @@
         {
             struct core_pll_factor_t    factor;
             __u32   tmpDly = ccu_clk_uldiv(sys_clk_get_rate(AW_SYS_CLK_CPU), 1000000) * 200;
+printk(KERN_NOTICE "PC-MSG set PLL4 rate : %lld \n", rate);
+
+ aw_ccu_reg->SysClkDiv.AHBClkDiv = 1 ;// PC-MSG - PATCH SAUVAGE !!

             ccm_clk_get_pll_para(&factor, rate);

@@ -824,7 +838,7 @@
         case AW_SYS_CLK_PLL5:
         {
             __s32   tmpFactorN, tmpFactorK;
-
+printk(KERN_NOTICE "PC-MSG set PLL5 rate : %lld \n", rate);
             if(rate < 240000000)
             {
                 CCU_ERR("Rate(%lld) is invalid when set PLL5 rate!\n", rate);
@@ -865,7 +879,7 @@
         {
             __u32   tmpFactorM;
             __s64   tmpPLL5;
-
+printk(KERN_NOTICE "PC-MSG set PLL5M rate : %lld \n", rate);
             tmpPLL5 = sys_clk_get_rate(AW_SYS_CLK_PLL5);
             if((rate > tmpPLL5) || (tmpPLL5 > rate*4))
             {
@@ -880,6 +894,7 @@
         }
         case AW_SYS_CLK_PLL5P:
         {
+printk(KERN_NOTICE "PC-MSG set PLL5P rate : %lld \n", rate);
             __s32   tmpFactorP = -1;
             __s64   tmpPLL5 = sys_clk_get_rate(AW_SYS_CLK_PLL5);

@@ -898,6 +913,8 @@
         {
             __s32   tmpFactorN, tmpFactorK;

+printk(KERN_NOTICE "PC-MSG set PLL6 rate : %lld \n", rate);
+
             if(rate <= 600000000)
                 tmpFactorK = 0;
             else if(rate <= 1200000000)
@@ -925,6 +942,8 @@
             __s64   tmpPLL6 = sys_clk_get_rate(AW_SYS_CLK_PLL6);
             __s32   tmpFactorM = ccu_clk_uldiv(tmpPLL6, rate*6);

+printk(KERN_NOTICE "PC-MSG set PLL6M rate : %lld \n", rate);
+
             tmpFactorM = tmpFactorM ? tmpFactorM : 1;
             aw_ccu_reg->Pll6Ctl.FactorM = tmpFactorM - 1;
             return 0;
@@ -936,6 +955,7 @@
         }
         case AW_SYS_CLK_PLL7:
         {
+printk(KERN_NOTICE "PC-MSG set PLL7 rate : %lld \n", rate);
             if((rate < 9*3000000) || (rate > (127*3000000)))
             {
                 CCU_ERR("Rate(%lld) is invalid when set PLL7 rate!\n", rate);
@@ -961,6 +981,7 @@
         }
         case AW_SYS_CLK_PLL7X2:
         {
+printk(KERN_NOTICE "PC-MSG set PLL7x2 rate : %lld \n", rate);
             if(rate == (sys_clk_get_rate(AW_SYS_CLK_PLL7) << 1))
             {
                 return 0;
@@ -969,6 +990,7 @@
         }
         case AW_SYS_CLK_200M:
         {
+printk(KERN_NOTICE "PC-MSG set CLK_200M rate : %lld \n", rate);
             if(rate == 200000000)
             {
                 return 0;
@@ -981,6 +1003,7 @@
         case AW_SYS_CLK_CPU:
         {
             __s64   tmpRate = sys_clk_get_rate(sys_clk_get_parent(AW_SYS_CLK_CPU));
+printk(KERN_NOTICE "PC-MSG set CLK_CPU rate : %lld \n", rate);

             if(rate != tmpRate)
             {
@@ -996,6 +1019,7 @@
         case AW_SYS_CLK_AXI:
         {
             __s32   tmpDiv = ccu_clk_uldiv(sys_clk_get_rate(AW_SYS_CLK_CPU) + (rate - 1), rate);
+printk(KERN_NOTICE "PC-MSG set CLK_AXI rate : %lld \n", rate);
             if(tmpDiv > 4)
             {
                 CCU_ERR("Rate(%lld) is invalid when set axi rate\n", rate);
@@ -1009,7 +1033,7 @@
         case AW_SYS_CLK_AHB:
         {
             __s32   tmpVal = -1, tmpDiv = ccu_clk_uldiv(sys_clk_get_rate(AW_SYS_CLK_AXI) + (rate - 1), rate);
-
+printk(KERN_NOTICE "PC-MSG set CLK_AHB rate : %lld \n", rate);
             if(tmpDiv > 8)
             {
                 CCU_ERR("Rate(%lld) is invalid for set AHB rate!\n", rate);
@@ -1024,7 +1048,7 @@
         case AW_SYS_CLK_APB0:
         {
             __s32   tmpVal = -1, tmpDiv = ccu_clk_uldiv(sys_clk_get_rate(AW_SYS_CLK_AHB) + (rate - 1), rate);
-
+printk(KERN_NOTICE "PC-MSG set CLK_APB0 rate : %lld \n", rate);
             if(tmpDiv > 8)
             {
                 CCU_ERR("Rate(%lld) is invalid for set APB0 rate!\n", rate);
@@ -1040,6 +1064,7 @@
         {
             __s64   tmpRate = sys_clk_get_rate(sys_clk_get_parent(AW_SYS_CLK_APB1));
             __s32   tmpDivP, tmpDivM;
+printk(KERN_NOTICE "PC-MSG set CLK_APB1 rate : %lld \n", rate);

             if(tmpRate < rate)
             {