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) ...@@ -188,6 +188,13 @@ int fd_probe(struct fmc_device *fmc)
if (fd_show_sdb) if (fd_show_sdb)
fmc_show_sdb_tree(fmc); 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); spin_lock_init(&fd->lock);
fmc->mezzanine_data = fd; fmc->mezzanine_data = fd;
fd->fmc = fmc; fd->fmc = fmc;
......
...@@ -209,7 +209,7 @@ out: ...@@ -209,7 +209,7 @@ out:
else { else {
/* ack at this point, but may be redundant */ /* ack at this point, but may be redundant */
fmc->op->irq_ack(fmc); 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: ...@@ -237,7 +237,7 @@ out_unexpected:
* up, entering the interrupt again and again * up, entering the interrupt again and again
*/ */
fmc->op->irq_ack(fmc); 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; return IRQ_HANDLED;
} }
...@@ -307,8 +307,8 @@ int fd_irq_init(struct fd_dev *fd) ...@@ -307,8 +307,8 @@ int fd_irq_init(struct fd_dev *fd)
/* 4us edge emulation timer (counts in 16ns steps) */ /* 4us edge emulation timer (counts in 16ns steps) */
vic_ctl = VIC_CTL_EMU_EDGE | VIC_CTL_EMU_LEN_W(4000 / 16); vic_ctl = VIC_CTL_EMU_EDGE | VIC_CTL_EMU_LEN_W(4000 / 16);
fmc_writel(fmc, vic_ctl | VIC_CTL_ENABLE | VIC_CTL_POL, fmc_writel(fmc, vic_ctl | VIC_CTL_ENABLE | VIC_CTL_POL,
FD_VIC_BASE + VIC_REG_CTL); fd->fd_vic_base + VIC_REG_CTL);
fmc_writel(fmc, 1, FD_VIC_BASE + VIC_REG_IER); fmc_writel(fmc, 1, fd->fd_vic_base + VIC_REG_IER);
fmc->op->gpio_config(fmc, fd_gpio_on, ARRAY_SIZE(fd_gpio_on)); 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) ...@@ -328,9 +328,9 @@ void fd_irq_exit(struct fd_dev *fd)
} else { } else {
/* disable interrupts: first carrier, than vic, then fd */ /* disable interrupts: first carrier, than vic, then fd */
fmc->op->gpio_config(fmc, fd_gpio_off, ARRAY_SIZE(fd_gpio_off)); 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); 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); fmc->op->irq_free(fmc);
} }
kfree(fd->sw_fifo.t); kfree(fd->sw_fifo.t);
......
...@@ -125,10 +125,6 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) ...@@ -125,10 +125,6 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
# endif # endif
#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 { struct fd_calib {
int64_t frr_poly[3]; /* SY89295 delay/temp poly coeffs */ int64_t frr_poly[3]; /* SY89295 delay/temp poly coeffs */
uint32_t magic; /* magic ID: 0xf19ede1a */ uint32_t magic; /* magic ID: 0xf19ede1a */
...@@ -187,6 +183,9 @@ struct fd_sw_fifo { ...@@ -187,6 +183,9 @@ struct fd_sw_fifo {
struct fd_dev { struct fd_dev {
spinlock_t lock; spinlock_t lock;
unsigned long flags; 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 fmc_device *fmc;
struct zio_device *zdev, *hwzdev; struct zio_device *zdev, *hwzdev;
struct timer_list fifo_timer; struct timer_list fifo_timer;
...@@ -225,11 +224,11 @@ static inline void fd_split_pico(uint64_t pico, ...@@ -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) 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) 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) static inline void __check_chan(int x)
......
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
#include "fine-delay.h" #include "fine-delay.h"
#include "hw/fd_main_regs.h" #include "hw/fd_main_regs.h"
/* The eeprom is at address 0x50, and the structure lives at 6kB */ /* The eeprom is geographically addressed, and the structure lives at 6kB */
#define I2C_ADDR 0x50
#define I2C_OFFSET (6*1024) #define I2C_OFFSET (6*1024)
/* At factory config time, it's possible to load a file and/or write eeprom */ /* 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) ...@@ -256,7 +255,7 @@ int fd_i2c_init(struct fd_dev *fd)
u8 buf[8]; u8 buf[8];
int i; 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: "); printk("read: ");
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
printk("%02x%c", buf[i], i==7 ? '\n' : ' '); printk("%02x%c", buf[i], i==7 ? '\n' : ' ');
...@@ -265,14 +264,15 @@ int fd_i2c_init(struct fd_dev *fd) ...@@ -265,14 +264,15 @@ int fd_i2c_init(struct fd_dev *fd)
printk("write: "); printk("write: ");
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
printk("%02x%c", buf[i], i==7 ? '\n' : ' '); 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 */ /* Retrieve and validate the calibration */
cal_ee = kzalloc(sizeof(*cal_ee), GFP_KERNEL); cal_ee = kzalloc(sizeof(*cal_ee), GFP_KERNEL);
if (!cal_ee) if (!cal_ee)
return -ENOMEM; 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)) { if (i != sizeof(*cal_ee)) {
pr_err("%s: cannot read_eeprom\n", __func__); pr_err("%s: cannot read_eeprom\n", __func__);
goto load; goto load;
...@@ -305,8 +305,8 @@ load: ...@@ -305,8 +305,8 @@ load:
cal_ee->version = 1; cal_ee->version = 1;
if (calibration_save) { if (calibration_save) {
i = fd_eeprom_write(fd, I2C_ADDR, I2C_OFFSET, cal_ee, i = fd_eeprom_write(fd, fd->fmc->eeprom_addr, I2C_OFFSET,
sizeof(*cal_ee)); cal_ee, sizeof(*cal_ee));
if (i != sizeof(*cal_ee)) { if (i != sizeof(*cal_ee)) {
pr_err("%s: error in writing calibration to eeprom\n", pr_err("%s: error in writing calibration to eeprom\n",
__func__); __func__);
......
...@@ -56,12 +56,12 @@ ...@@ -56,12 +56,12 @@
static void ow_writel(struct fd_dev *fd, uint32_t val, unsigned long reg) 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) 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) 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