0

I am looking at the exynos4_bus.c driver that is used with devfreq power management to try to develop a similar driver for a peripheral on the a Zynq SoC. The method I'm concerned about is this one:

static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp)
{
        ...
        __raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
        ...

}

It seems to me that raw_writel is writing to the Exynos clock register the frequency that it should run at. This register is defined in arch/arm/mach-exynos/include/mach/regs-clock.h. I am now looking at arch\arm\mach-zynq\include\mach\zynq_soc.h to try to find something equivalent for the Zynq setup, but there are quite a few clocks that are being defined, so I'm not sure which is the one I should be setting. Can anyone help?

stu
  • 58
  • 7
John Roberts
  • 5,885
  • 21
  • 70
  • 124
  • 3
    The poster is using `git clone git://git.xilinx.com/linux-xlnx.git`, and not the kernel mainline from www.kernel.org See [Xilinx Zynq machine directory](http://git.xilinx.com/?p=linux-xlnx.git;a=tree;f=arch/arm/mach-zynq;hb=HEAD) The files cited do not exist in v3.8. – artless noise Mar 24 '13 at 14:59
  • 2
    You're right. I apologize for not mentioning this. I did not know they differed so extensively. – John Roberts Mar 24 '13 at 19:01
  • That ok, were all human. Nice you confirmed it. Btw, this is a hard question to answer. You need to get someone with knowledge of this chip. Does Xilinx make a data sheet available? That might be helpful. I haven't used any of there embedded core stuff, just straight FPGA or ASIC. Looks pretty cool. – artless noise Mar 24 '13 at 22:44

2 Answers2

1

Zynq uses the kernel clock framework.

Include the declaration:

#include <linux/clk.h>

Get a handle on the clock you want, by name:

struct clk *fclk = clk_get_sys("FPGA0", NULL);
long requested_rate = 125000000;

Find the nearest supported frequency:

long actual_rate = clk_round_rate(fclk, requested_rate);

Then set the clock rate:

 int status;
    if ((status = clk_set_rate(fclk, actual_rate))) {
        printk(KERN_INFO "[%s:%d] err\n", __FUNCTION__, __LINE__);
        return status;
    }
Jamey Hicks
  • 2,340
  • 1
  • 14
  • 20
0

You can change the Zynq FCLK directly by its register. The easiest way to test it is to write to the address directly using devmem from busybox.

The name of the register is FPGA0_CLK_CTRL for the FCLK_CLK0 Zynq output. A possible solution to get the address is opening SDK and open the ps7_init.html and search the register.

Bit 0-7 selects the clock source (0x00 for IO_PLL, 0x20 ARM_PLL, 0x30 DDR_PLL)

Bit 8-15 is the first divisor

Bit 16-19 is reserved

Bit 20-25 is the second divisor

Example: for my Zynq-7000 I want to have 28MHz so I have DIV0=36, DIV1=1 and want to use the IO_PLL.You can get the values in the Zynq block by setting the corresponding FCLK in the Clock Configuration section and look in the Advanced Clocking tab. The command to set this in Linux would be "devmem 0xF8000170 32 0x002401".

akira hinoshiro
  • 393
  • 2
  • 15