This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to make spi4 clock available ?

Hi,

I have tried for days to enable spi4_sclk on my EVMDM365... I may have forget to change a register. For now, I create the following sequence in the driver.c :

 

PINMUX4:19:18 to 01(GIO36 -> SPI4_CLK)

PUPDCTL1:4 to 0 (disable GIO36 IPD)

AUXEN has already been enabled !

This is the result the register change :

Changing PINMUX4
PINMUX4 = 51554555
PINMUX4 = 51564555
Changing PUPDCTL1
PUPDCTL1 = FA07FFFF
PUPDCTL1 = FA07FFEF

CKEN PLL1= 0x00000001
CKSTAT PLL1= 0x00000009

Then this clock passed through the CPLD :  "pSPI4_CLK_CONN    <= pSPI4_CLK;"

and should be on the pin B20 of the imager interface (EVM)... but there is nothing on this pin.

I have also try to switch on clockout1 with no result :

 

 

Does someone know why ?

This is my driver.c :

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/ioctl.h>
#include <mach/hardware.h>

#include <linux/io.h>

#include <asm/clkdev.h>
#include <mach/clock.h>

#include "user_clock.h"

#define MAJOR_VERSION           60
#define MINOR_VERSION           01

#define DAVINCI_PLL1_BASE 0x01c40800
#define DAVINCI_PLL2_BASE 0x01c40c00

#define SYSTEM_BASE       0x01C40000
#define PINMUX4          0x10

#define PLL2_OSCDIV1       0x124

#define PUPDCTL1       0x7C

#define CKSTAT           0x14C

#define OCSEL           0x104

#define PERI_CLKCTL       0x48

static struct clk *spi4_clk = 0;
static int user_clock_open (struct inode *inode, struct file *filp);
static int user_clock_release (struct inode *inode, struct file *filp);
static int spi4_clock_init(void);
static void spi4_clock_exit(void);
static void spi4_clock_enable(void);
static void spi4_clock_disable(void);
static int  spi4_clock_ioctl  (struct inode *inode, struct file *flip, unsigned int cmd, unsigned long args);


static struct file_operations spi4_clock_fops = {
                .open = user_clock_open,
        .ioctl = spi4_clock_ioctl,
                .release = user_clock_release,
};


static int user_clock_open (struct inode *inode, struct file *filp)
{
    return 0;
}    

/*****************************/

static int user_clock_release (struct inode *inode, struct file *filp)
{
    return 0;
}
    
/**************************/

static int spi4_clock_init(void)
{
      int result;
      result = register_chrdev(MAJOR_VERSION, "user_clock",&spi4_clock_fops);
      if (result < 0)
        {
             printk("<1>dv_spi: cannot obtain major number %d\n",MAJOR_VERSION);
             return result;
         }
    printk("spi4 clock modules enabled\n");
    return 0;
}

/**************************/

static void spi4_clock_exit(void)
{
    unregister_chrdev(MAJOR_VERSION, "user_clock");
    printk("spi4 clock module removed\n");
}

/******************************/

static void spi4_clock_enable(void)
{
     unsigned int ctrl=0;

    printk("Changing PINMUX4\n");
      ctrl = __raw_readl(IO_ADDRESS(SYSTEM_BASE) + PINMUX4);
        printk("PINMUX4 = %X\n",ctrl);
    ctrl = (ctrl & 0xFFF2FFFF) | 0x00040000;
    __raw_writel(ctrl,IO_ADDRESS(SYSTEM_BASE) + PINMUX4);
      ctrl = __raw_readl(IO_ADDRESS(SYSTEM_BASE) + PINMUX4);
        printk("PINMUX4 = %X\n",ctrl);

    printk("Changing PUPDCTL1\n");
    ctrl = __raw_readl(IO_ADDRESS(SYSTEM_BASE) + PUPDCTL1);
        printk("PUPDCTL1 = %X\n",ctrl);
    ctrl &= 0xFFFFFFEF;
    __raw_writel(ctrl,IO_ADDRESS(SYSTEM_BASE) + PUPDCTL1);
      ctrl = __raw_readl(IO_ADDRESS(SYSTEM_BASE) + PUPDCTL1);
        printk("PUPDCTL1 = %X\n",ctrl);
 }
}

/*****************************/
/*
static void spi4_clock_disable(void)
{
     spi4_clk = clk_get(NULL, "spi4");
     if(spi4_clk <= 0) printk("Error : could not get the clock\n");
     else clk_disable(spi4_clk);
}
*/
/******************************/

static int  spi4_clock_ioctl  (struct inode *inode, struct file *flip, unsigned int cmd, unsigned long args)
{
    switch (cmd) {
        case CLOCK_ENABLE:
           spi4_clock_enable();             
        break;
        
        case CLOCK_DISABLE:
       spi4_clock_disable();
        break;

        default:
            return -ENOTTY;
            break;
    }

    return 0;
}

MODULE_LICENSE("GPL");

module_init(spi4_clock_init);
module_exit(spi4_clock_exit);

 

and the program that called the driver :

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>


#include "user_clock.h"


static int clock_enable (void)
{
    int fd;
 
    fd = open("/dev/user_clock", O_RDWR);
    if (fd < 0) {
        printf("Failed to open device\n");
        return 1;
    }
 
    if (ioctl(fd, CLOCK_ENABLE) < 0) {
        printf("Failed to enable clock\n");
        return -1;
    }
    close(fd);
    return 0;
}



static int clock_disable (void)
{
    int fd;
 
    fd = open("/dev/user_clock", O_RDWR);
    if (fd < 0) {
        printf("Failed to open device\n");
        return 1;
    }
 
    if (ioctl(fd, CLOCK_DISABLE) < 0) {
        printf("Failed to enable clock\n");
        return -1;
    }
    close(fd);
    return 0;
}


int main (void)
{
    clock_enable();
//    udelay(10000000);
//    clock_disable();
}

 

Moreover, I tried to enable the clock with :

    int ret = 0;
    clk_spi4 = clk_get_sys("spi_davinci.4", NULL);
    if (IS_ERR(clk_spi4)) {
        ret = -ENODEV;
        printk("Can't find spi4 clock\n");
    }
    else
    {
    clk_enable(clk_spi4 );

 }

But, it is still not working... What should I change in the SPI4 registers ? At least, is it possible to have a 24Mhz-clock on the spi4_sclk without the other SPI4 signals ?

Otherwise, I tried to use clkout1 :

PERI_CLKCTL = 0x243F0FFC
PINMUX4 = 0x51554555
PINMUX4 = 0x51574555
CKEN PLL2= 0x00000000
CKEN PLL2= 0x00000002
OCSEL PLL2= 0x00000010
OCSEL PLL2= 0x00000000
PLL 2 OSCDIV1 = 0x00000000
PLL 2 OSCDIV1 = 0x00008001
CKSTAT PLL2= 0x0000000A

But nothing happened again ! What should I change ? The CPLD registers ?

Best regards,

Thibault

  • Hey guys,

    I found everything I need.

    In fact, it is impossible to create a 24MHz clock with SPI4_SCLK (see  Serial Peripheral Interface (SPI) Users Guide SPRUFH1.pdf) because Spi4_sclk frequency = Input_frequency / (RATIO + 1) and RATIO has to be > 1.And it is harder to enable SPI4_sclk than Clkout 1.

    Then I am now able to see clockout1 at 24 MHz on B18. I forgot to change the CPLD registers. In fact, I didn't know how to do that.

    Bye !