[meta-xilinx] Zynq TTC usage by Linux

Mike Looijmans mike.looijmans at topic.nl
Mon Oct 24 23:16:39 PDT 2016


On 25-10-16 08:03, Edward Wingate wrote:
> On Sat, Oct 22, 2016 at 3:06 AM, Mike Looijmans <mike.looijmans at topic.nl> wrote:
>> One of the TTCs used to be used for clock source. This should still be the
>> case if you use dynamic clocks, because the ARM timer is fixed to the CPU
>> speed and does not handle frequency changes (though I think it should be
>> possible to fix this purely in software, no-one seems to care though).
>> The TTC can use the prescaler to adjust the timing when the CPU speed changes.
>> But if you use AMP, frequency scaling will affect both cores, so you
>> probably cannot use it anyway.
>
> Thanks for this information, Mike.  I'm probably not using dynamic
> clocks since I'm using both the global arm timer and AMP.  In what
> cases are dynamic clocks used?  Just for my information, how are they
> enabled?

Enabling frequency scaling in the kernel will make the CPU clock switch 
between 333 and 666 MHz on demand. This results in considerable power saving, 
and is transparent to the system.

>> For AMP, I assigned the TTC1 interrupts to the remoteproc. I also add GPIO
>> "hogs" for all GPIO signals it uses. That way, the AMP firmware doesn't need
>> to modify various race-condition prone registers.
>
> Could you explain about how GPIO hogs eliminate dealing with
> race-condition prone registers?  Which registers are prone to race
> conditions in the first place?

For example, to enable the GPIO output mode on MIO pin 0, you'd have to do 
this in bare metal code:

#define ZYNQ_GPIO_DIRM_0	0xE000A204
#define ZYNQ_GPIO_OEN_0		0xE000A208
unsigned int reg
reg = ioread((ZYNQ_GPIO_DIRM_0 + 0));
iowrite(addr, (ZYNQ_GPIO_OEN_0 + 0) | 0x1);
reg = ioread((ZYNQ_GPIO_DIRM_0 + 0));
iowrite(addr, (ZYNQ_GPIO_OEN_0 + 0) | 0x1);


If between reading and writing the registers, the other CPU does something 
similar (e.g. enable output on MIO 1) the result will be undefined.

Setting the GPIO value can be done race-free using the "MASK_DATA_0_LSW" 
register (writing 0xFFFE0001 to address 0xE000A000 will set GPIO 0 to "high" 
without interfering with the other CPU).


PS: My generic advice would be to stay away from AMP as far as you possibly 
can. There's hardly any advantage over letting the Linux kernel handle things, 
and the disadvantages are plentiful.


Kind regards,

Mike Looijmans
System Expert

TOPIC Products
Materiaalweg 4, NL-5681 RJ Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans at topicproducts.com
Website: www.topicproducts.com

Please consider the environment before printing this e-mail








More information about the meta-xilinx mailing list