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