Commit 9966afca authored by Alessandro Rubini's avatar Alessandro Rubini

kernel: remove hardwired addresses, to support svec

This commit uses a non-constant i2c address so a multi-slot
carrier can be supported.  Also, all constant register offsets are
removed, because they are retrieved from SDB.  Unfortunately
this  doesn't yet support several cores with the same device ID.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent a01d16b1
......@@ -188,6 +188,13 @@ int fd_probe(struct fmc_device *fmc)
if (fd_show_sdb)
fmc_show_sdb_tree(fmc);
/* Now use SDB to find the base addresses */
fd->fd_regs_base =
fmc_find_sdb_device(fmc->sdb, 0xce42, 0xf19ede1a, NULL);
fd->fd_vic_base =
fmc_find_sdb_device(fmc->sdb, 0xce42, 0x00000013, NULL);
fd->fd_owregs_base = fd->fd_regs_base + 0x500;
spin_lock_init(&fd->lock);
fmc->mezzanine_data = fd;
fd->fmc = fmc;
......
......@@ -209,7 +209,7 @@ out:
else {
/* ack at this point, but may be redundant */
fmc->op->irq_ack(fmc);
fmc_writel(fmc, 0, FD_VIC_BASE + VIC_REG_EOIR);
fmc_writel(fmc, 0, fd->fd_vic_base + VIC_REG_EOIR);
}
}
......@@ -237,7 +237,7 @@ out_unexpected:
* up, entering the interrupt again and again
*/
fmc->op->irq_ack(fmc);
fmc_writel(fmc, 0, FD_VIC_BASE + VIC_REG_EOIR);
fmc_writel(fmc, 0, fd->fd_vic_base + VIC_REG_EOIR);
return IRQ_HANDLED;
}
......@@ -307,8 +307,8 @@ int fd_irq_init(struct fd_dev *fd)
/* 4us edge emulation timer (counts in 16ns steps) */
vic_ctl = VIC_CTL_EMU_EDGE | VIC_CTL_EMU_LEN_W(4000 / 16);
fmc_writel(fmc, vic_ctl | VIC_CTL_ENABLE | VIC_CTL_POL,
FD_VIC_BASE + VIC_REG_CTL);
fmc_writel(fmc, 1, FD_VIC_BASE + VIC_REG_IER);
fd->fd_vic_base + VIC_REG_CTL);
fmc_writel(fmc, 1, fd->fd_vic_base + VIC_REG_IER);
fmc->op->gpio_config(fmc, fd_gpio_on, ARRAY_SIZE(fd_gpio_on));
}
......@@ -328,9 +328,9 @@ void fd_irq_exit(struct fd_dev *fd)
} else {
/* disable interrupts: first carrier, than vic, then fd */
fmc->op->gpio_config(fmc, fd_gpio_off, ARRAY_SIZE(fd_gpio_off));
fmc_writel(fmc, 1, FD_VIC_BASE + VIC_REG_IDR);
fmc_writel(fmc, 1, fd->fd_vic_base + VIC_REG_IDR);
fd_writel(fd, ~0, FD_REG_EIC_IDR);
fmc_writel(fmc, VIC_CTL_POL, FD_VIC_BASE + VIC_REG_CTL);
fmc_writel(fmc, VIC_CTL_POL, fd->fd_vic_base + VIC_REG_CTL);
fmc->op->irq_free(fmc);
}
kfree(fd->sw_fifo.t);
......
......@@ -125,10 +125,6 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
# endif
#endif
#define FD_REGS_BASE 0x80000 /* sdb_find_device(cern, f19ede1a) */
#define FD_OWREGS_BASE (FD_REGS_BASE + 0x500)
#define FD_VIC_BASE 0x90000 /* sdb_find_device(cern, 00000013) */
struct fd_calib {
int64_t frr_poly[3]; /* SY89295 delay/temp poly coeffs */
uint32_t magic; /* magic ID: 0xf19ede1a */
......@@ -187,6 +183,9 @@ struct fd_sw_fifo {
struct fd_dev {
spinlock_t lock;
unsigned long flags;
int fd_regs_base; /* sdb_find_device(cern, f19ede1a) */
int fd_owregs_base; /* regs_base + 0x500 */
int fd_vic_base; /* sdb_find_device(cern, 00000013) */
struct fmc_device *fmc;
struct zio_device *zdev, *hwzdev;
struct timer_list fifo_timer;
......@@ -225,11 +224,11 @@ static inline void fd_split_pico(uint64_t pico,
static inline uint32_t fd_readl(struct fd_dev *fd, unsigned long reg)
{
return fmc_readl(fd->fmc, FD_REGS_BASE + reg);
return fmc_readl(fd->fmc, fd->fd_regs_base + reg);
}
static inline void fd_writel(struct fd_dev *fd, uint32_t v, unsigned long reg)
{
fmc_writel(fd->fmc, v, FD_REGS_BASE + reg);
fmc_writel(fd->fmc, v, fd->fd_regs_base + reg);
}
static inline void __check_chan(int x)
......
......@@ -22,8 +22,7 @@
#include "fine-delay.h"
#include "hw/fd_main_regs.h"
/* The eeprom is at address 0x50, and the structure lives at 6kB */
#define I2C_ADDR 0x50
/* The eeprom is geographically addressed, and the structure lives at 6kB */
#define I2C_OFFSET (6*1024)
/* At factory config time, it's possible to load a file and/or write eeprom */
......@@ -256,7 +255,7 @@ int fd_i2c_init(struct fd_dev *fd)
u8 buf[8];
int i;
fd_eeprom_read(fd, I2C_ADDR, I2C_OFFSET, buf, 8);
fd_eeprom_read(fd, fd->fmc->eeprom_addr, I2C_OFFSET, buf, 8);
printk("read: ");
for (i = 0; i < 8; i++)
printk("%02x%c", buf[i], i==7 ? '\n' : ' ');
......@@ -265,14 +264,15 @@ int fd_i2c_init(struct fd_dev *fd)
printk("write: ");
for (i = 0; i < 8; i++)
printk("%02x%c", buf[i], i==7 ? '\n' : ' ');
fd_eeprom_write(fd, I2C_ADDR, I2C_OFFSET, buf, 8);
fd_eeprom_write(fd, fd->fmc->eeprom_addr, I2C_OFFSET, buf, 8);
}
/* Retrieve and validate the calibration */
cal_ee = kzalloc(sizeof(*cal_ee), GFP_KERNEL);
if (!cal_ee)
return -ENOMEM;
i = fd_eeprom_read(fd, I2C_ADDR, I2C_OFFSET, cal_ee, sizeof(*cal_ee));
i = fd_eeprom_read(fd, fd->fmc->eeprom_addr, I2C_OFFSET,
cal_ee, sizeof(*cal_ee));
if (i != sizeof(*cal_ee)) {
pr_err("%s: cannot read_eeprom\n", __func__);
goto load;
......@@ -305,8 +305,8 @@ load:
cal_ee->version = 1;
if (calibration_save) {
i = fd_eeprom_write(fd, I2C_ADDR, I2C_OFFSET, cal_ee,
sizeof(*cal_ee));
i = fd_eeprom_write(fd, fd->fmc->eeprom_addr, I2C_OFFSET,
cal_ee, sizeof(*cal_ee));
if (i != sizeof(*cal_ee)) {
pr_err("%s: error in writing calibration to eeprom\n",
__func__);
......
......@@ -56,12 +56,12 @@
static void ow_writel(struct fd_dev *fd, uint32_t val, unsigned long reg)
{
fmc_writel(fd->fmc, val, FD_OWREGS_BASE + reg);
fmc_writel(fd->fmc, val, fd->fd_owregs_base + reg);
}
static uint32_t ow_readl(struct fd_dev *fd, unsigned long reg)
{
return fmc_readl(fd->fmc, FD_OWREGS_BASE + reg);
return fmc_readl(fd->fmc, fd->fd_owregs_base + reg);
}
static int ow_reset(struct fd_dev *fd, int port)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment