Commit b2cdf162 authored by Aurelio Colosimo's avatar Aurelio Colosimo

update from wrpc-sw, commit 82fd420e: new files

Included all arch-spec related sources, even if they are not used now.
parent f8eb98c3
#include "board.h"
#include "syscon.h"
#define DNA_DATA 1
#define DNA_CLK 4
#define DNA_SHIFT 3
#define DNA_READ 2
void dna_read(uint32_t *lo, uint32_t *hi)
{
uint64_t dna = 0;
int i;
gpio_out(DNA_DATA, 0);
delay(10);
gpio_out(DNA_CLK, 0);
delay(10);
gpio_out(DNA_READ, 1);
delay(10);
gpio_out(DNA_SHIFT, 0);
delay(10);
delay(10);
gpio_out(DNA_CLK, 1);
delay(10);
if(gpio_in(DNA_DATA)) dna |= 1;
delay(10);
gpio_out(DNA_CLK, 0);
delay(10);
gpio_out(DNA_READ, 0);
gpio_out(DNA_SHIFT, 1);
delay(10);
for(i=0;i<57;i++)
{
dna <<= 1;
delay(10);
delay(10);
gpio_out(DNA_CLK, 1);
delay(10);
if(gpio_in(DNA_DATA)) dna |= 1;
delay(10);
gpio_out(DNA_CLK, 0);
delay(10);
}
*hi = (uint32_t) (dna >> 32);
*lo = (uint32_t) dna;
}
#include "types.h"
#include "i2c.h"
#include "eeprom.h"
#include "board.h"
#include "syscon.h"
/*
* The SFP section is placed somewhere inside FMC EEPROM and it really does not
* matter where (can be a binary data inside the Board Info section but can be
* placed also outside the FMC standardized EEPROM structure. The only requirement
* is that it starts with 0xdeadbeef pattern. The structure of SFP section is:
*
* --------------------------------
* | 0xdeadbeef (4B) | count (4B) |
* -------------------------------------------------------------------------------
* | SFP(1) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) |
* -------------------------------------------------------------------------------
* | SFP(2) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) |
* -------------------------------------------------------------------------------
* | (....) | (....) | (....) | (....) |
* -------------------------------------------------------------------------------
* | SFP(count) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) |
* -------------------------------------------------------------------------------
* | checksum (1B) |
* -----------------
*
* Fields description:
* count - how many SFPs are described in the list (binary)
* SFP(n) part number - SFP PN as read from SFP's EEPROM (e.g. AXGE-1254-0531)
* (16 ascii chars)
* checksum - low order 8 bits of the sum of all bytes starting from
* _count_ (without 0xdeadbeef)
*
*/
int eeprom_read(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size)
{
int i;
unsigned char c;
mi2c_start(i2cif);
if(mi2c_put_byte(i2cif, i2c_addr << 1) < 0)
{
mi2c_stop(i2cif);
return -1;
}
mi2c_put_byte(i2cif, (offset>>8) & 0xff);
mi2c_put_byte(i2cif, offset & 0xff);
mi2c_repeat_start(i2cif);
mi2c_put_byte(i2cif, (i2c_addr << 1) | 1);
for(i=0; i<size-1; ++i)
{
mi2c_get_byte(i2cif, &c, 0);
*buf++ = c;
}
mi2c_get_byte(i2cif, &c, 1);
*buf++ = c;
mi2c_stop(i2cif);
return size;
}
//int eeprom_write(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size)
//{
// int i, busy;
//
// for(i=0;i<size;i++)
// {
// mi2c_start(i2cif);
//
// if(mi2c_put_byte(i2cif, i2c_addr << 1) < 0)
// {
// mi2c_stop(i2cif);
// return -1;
// }
// mi2c_put_byte(i2cif, (offset >> 8) & 0xff);
// mi2c_put_byte(i2cif, offset & 0xff);
// mi2c_put_byte(i2cif, *buf++);
// offset++;
// mi2c_stop(i2cif);
//
// do /* wait until the chip becomes ready */
// {
// mi2c_start(i2cif);
// busy = mi2c_put_byte(i2cif, i2c_addr << 1);
// mi2c_stop(i2cif);
// } while(busy);
//
// }
// return size;
//}
int32_t eeprom_sfp_section(uint8_t i2cif, uint8_t i2c_addr, size_t size, uint16_t *section_sz)
{
uint8_t c, match;
uint16_t i;
uint32_t sfp_pattern = SFP_SECTION_PATTERN;
match = 0x00;
*section_sz = 0x0000;
mi2c_start(i2cif);
if(mi2c_put_byte(i2cif, i2c_addr << 1) != 0)
{
mi2c_stop(i2cif);
return -1;
}
mi2c_put_byte(i2cif, 0x00);
mi2c_put_byte(i2cif, 0x00);
mi2c_repeat_start(i2cif);
mi2c_put_byte(i2cif, (i2c_addr << 1) | 1);
for(i=0; i<size-1; ++i)
{
mi2c_get_byte(i2cif, &c, 0);
if(match==0x0f)
{
*section_sz = ((uint16_t)c ) << 8;
match |= 0x10;
}
else if(match==0x1f)
{
*section_sz |= ((uint16_t)c ) & 0xff;
match |= 0x20;
}
else if( c== (uint8_t)(sfp_pattern>>24) )
match = 0x01;
else if( c== (uint8_t)((sfp_pattern>>16)&0xff) )
match |= 0x02;
else if( c== (uint8_t)((sfp_pattern>>8)&0xff) )
match |= 0x04;
else if( c== (uint8_t)(sfp_pattern&0xff) )
match |= 0x08;
else
match = 0x00;
if(match == 0x3f)
{
mi2c_get_byte(i2cif, &c, 1);
mi2c_stop(i2cif);
return i+1; //first address of first SFP in the list
}
}
mi2c_get_byte(i2cif, &c, 1);
mi2c_stop(i2cif);
return 0;
}
int8_t eeprom_get_sfpinfo(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, struct s_sfpinfo *sfpinfo, uint16_t section_sz)
{
uint8_t *buf;
uint32_t i;
uint8_t checksum, sum;
buf = (uint8_t *)sfpinfo;
eeprom_read(i2cif, i2c_addr, offset, buf, section_sz * sizeof(struct s_sfpinfo));
//read checksum
eeprom_read(i2cif, i2c_addr, offset+section_sz*sizeof(struct s_sfpinfo), &checksum, 1);
//count checksum
sum = (uint8_t) (section_sz>>8 & 0xff);
sum = (uint8_t) ((uint16_t) sum + (section_sz & 0xff)) & 0xff;
for(i=0; i<section_sz*sizeof(struct s_sfpinfo); ++i)
sum = (uint8_t) ((uint16_t)sum + *(buf+i)) & 0xff;
if(sum == checksum)
{
mprintf("%s: checksum match\n", __FUNCTION__);
return 0;
}
else
{
mprintf("%s: checksum error, %x | %x\n", __FUNCTION__, sum, checksum);
return -1;
}
}
int8_t access_eeprom(char *sfp_pn, int32_t *alpha, int32_t *deltaTx, int32_t *deltaRx)
{
uint16_t i;
uint8_t j;
uint16_t sfp_sz;
int32_t sfp_adr;
struct s_sfpinfo sfpinfo[SFPINFO_MAX];
mi2c_init(WRPC_FMC_I2C);
sfp_adr = eeprom_sfp_section(WRPC_FMC_I2C, FMC_EEPROM_ADR, 64*1024, &sfp_sz);
if(sfp_adr == -1)
{
mprintf("FMC EEPROM not found\n");
return -1;
}
else if(sfp_sz > SFPINFO_MAX)
{
//Ooops, there are too many of them, print warning
mprintf("! Warning ! too many SFP entries (%d)\n", sfp_sz);
sfp_sz = SFPINFO_MAX;
}
else if(sfp_sz == 0)
{
mprintf("EEPROM: could no find SFP section, staring with defaults\n");
return -1;
}
mprintf("EEPROM: found SFP section at %d size %d\n", (uint32_t)sfp_adr, (uint32_t)sfp_sz);
if( eeprom_get_sfpinfo(WRPC_FMC_I2C, FMC_EEPROM_ADR, sfp_adr, sfpinfo, sfp_sz))
{
mprintf("EEPROM ERROR\n");
return -1;
}
for(i=0; i<sfp_sz; ++i)
{
for(j=0; j<16; ++j)
{
if(sfp_pn[j] != sfpinfo[i].pn[j])
break;
}
if( j==16 ) //which means sfp_pn = sfpinfo[i].pn
{
mprintf("match SFP%d: pn=", i+1);
for(j=0; j<16; ++j)
mprintf("%c", sfpinfo[i].pn[j]);
//mprintf(" alpha=%x deltaTx=%x deltaRx=%x\n", sfpinfo[i].alpha, sfpinfo[i].deltaTx, sfpinfo[i].deltaRx);
*alpha = sfpinfo[i].alpha;
*deltaTx = sfpinfo[i].deltaTx;
*deltaRx = sfpinfo[i].deltaRx;
}
}
return 0;
}
#include <stdio.h>
#include "board.h"
#define R_CSR 0x0
#define R_CDR 0x4
#define CSR_DAT_MSK (1<<0)
#define CSR_RST_MSK (1<<1)
#define CSR_OVD_MSK (1<<2)
#define CSR_CYC_MSK (1<<3)
#define CSR_PWR_MSK (1<<4)
#define CSR_IRQ_MSK (1<<6)
#define CSR_IEN_MSK (1<<7)
#define CSR_SEL_OFS 8
#define CSR_SEL_MSK (0xF<<8)
#define CSR_POWER_OFS 16
#define CSR_POWER_MSK (0xFFFF<<16)
#define CDR_NOR_MSK (0xFFFF<<0)
#define CDR_OVD_OFS 16
#define CDR_OVD_MSK (0xFFFF<<16)
#define CLK_DIV_NOR 175 //clock divider for normal mode
#define CLK_DIV_OVD 124/2 //clock divider for overdrive mode
static inline void ow_writel(uint32_t reg, uint32_t data)
{
*(volatile uint32_t *) (BASE_ONEWIRE + reg) = data;
}
static inline uint32_t ow_readl(uint32_t reg)
{
return *(volatile uint32_t *)(BASE_ONEWIRE + reg);
}
void ow_init()
{
//set clock dividers for normal and overdrive mode
ow_writel( R_CDR, ((CLK_DIV_NOR & CDR_NOR_MSK) | (( CLK_DIV_OVD << CDR_OVD_OFS) & CDR_OVD_MSK)) );
}
static uint32_t ow_reset(uint32_t port)
{
uint32_t reg, data;
data = ( (port<<CSR_SEL_OFS) & CSR_SEL_MSK) |
CSR_CYC_MSK | CSR_RST_MSK; //start cycle, rst pulse request
ow_writel(R_CSR, data);
//wait until cycle done
while(ow_readl(R_CSR) & CSR_CYC_MSK);
reg = ow_readl(R_CSR);
return ~reg & CSR_DAT_MSK;
}
static uint32_t slot(uint32_t port, uint32_t bit)
{
uint32_t data, reg;
data = ( (port<<CSR_SEL_OFS) & CSR_SEL_MSK) |
CSR_CYC_MSK | (bit & CSR_DAT_MSK); //start cycle, write bit
ow_writel(R_CSR, data);
//wait until cycle done
while( ow_readl(R_CSR) & CSR_CYC_MSK );
reg = ow_readl(R_CSR);
return reg & CSR_DAT_MSK;
}
static inline uint32_t ow_read_bit(uint32_t port) { return slot(port, 0x1); }
static inline uint32_t ow_write_bit(uint32_t port, uint32_t bit) { return slot(port, bit); }
uint8_t ow_read_byte(uint32_t port)
{
uint32_t data = 0, i;
for(i=0;i<8;i++)
data |= ow_read_bit(port) << i;
return (uint8_t)data;
}
int8_t ow_write_byte(uint32_t port, uint32_t byte)
{
uint32_t data = 0;
uint8_t i;
uint32_t byte_old = byte;
for (i=0;i<8;i++)
{
data |= ow_write_bit(port, (byte & 0x1)) << i;
byte >>= 1;
}
return byte_old == data ? 0 : -1;
}
int ow_write_block(int port, uint8_t *block, int len)
{
uint32_t i;
for(i=0;i<len;i++)
*block++ = ow_write_byte(port, *block);
return 0;
}
int ow_read_block(int port, uint8_t *block, int len)
{
uint32_t i;
for(i=0;i<len;i++)
*block++ = ow_read_byte(port);
return 0;
}
#define ROM_SEARCH 0xF0
#define ROM_READ 0x33
#define ROM_MATCH 0x55
#define ROM_SKIP 0xCC
#define ROM_ALARM_SEARCH 0xEC
#define CONVERT_TEMP 0x44
#define WRITE_SCRATCHPAD 0x4E
#define READ_SCRATCHPAD 0xBE
#define COPY_SCRATCHPAD 0x48
#define RECALL_EEPROM 0xB8
#define READ_POWER_SUPPLY 0xB4
static uint8_t ds18x_id [8];
int8_t ds18x_read_serial(uint8_t *id)
{
uint8_t i;
if(!ow_reset(0))
return -1;
if(ow_write_byte(0, ROM_READ) < 0)
return -1;
for(i=0;i<8;i++)
{
*id = ow_read_byte(0);
id++;
}
return 0;
}
static int8_t ds18x_access(uint8_t *id)
{
int i;
if(!ow_reset(0))
return -1;
if(ow_write_byte(0, ROM_MATCH) < 0)
return -1;
for(i=0;i<8;i++)
if(ow_write_byte(0, id[i]) < 0)
return -1;
return 0;
}
int8_t ds18x_read_temp(uint8_t *id, int *temp_r)
{
int i, temp;
uint8_t data[9];
if(ds18x_access(id) < 0)
return -1;
ow_write_byte(0, READ_SCRATCHPAD);
for(i=0;i<9;i++) data[i] = ow_read_byte(0);
temp = ((int)data[1] << 8) | ((int)data[0]);
if(temp & 0x1000)
temp = -0x10000 + temp;
ds18x_access(id);
ow_write_byte(0, CONVERT_TEMP);
if(temp_r) *temp_r = temp;
return 0;
}
int ds18x_init()
{
ow_init();
if(ds18x_read_serial(ds18x_id) < 0)
return -1;
return ds18x_read_temp(ds18x_id, NULL);
}
/* SFP Detection / managenent functions */
#include <stdio.h>
#include <inttypes.h>
#include "syscon.h"
#include "i2c.h"
#include "sfp.h"
int sfp_present()
{
return !gpio_in(GPIO_SFP_DET);
}
int sfp_read_part_id(char *part_id)
{
int i;
uint8_t data, sum;
mi2c_init(WRPC_SFP_I2C);
mi2c_start(WRPC_SFP_I2C);
mi2c_put_byte(WRPC_SFP_I2C, 0xA0);
mi2c_put_byte(WRPC_SFP_I2C, 0x00);
mi2c_repeat_start(WRPC_SFP_I2C);
mi2c_put_byte(WRPC_SFP_I2C, 0xA1);
mi2c_get_byte(WRPC_SFP_I2C, &data, 1);
mi2c_stop(WRPC_SFP_I2C);
sum = data;
mi2c_start(WRPC_SFP_I2C);
mi2c_put_byte(WRPC_SFP_I2C, 0xA1);
for(i=1; i<63; ++i)
{
mi2c_get_byte(WRPC_SFP_I2C, &data, 0);
sum = (uint8_t) ((uint16_t)sum + data) & 0xff;
if(i>=40 && i<=55) //Part Number
part_id[i-40] = data;
}
mi2c_get_byte(WRPC_SFP_I2C, &data, 1); //final word, checksum
mi2c_stop(WRPC_SFP_I2C);
if(sum == data)
return 0;
return -1;
}
#ifndef __EEPROM_H
#define __EEPROM_H
#define SFP_SECTION_PATTERN 0xdeadbeef
#define SFPINFO_MAX 4
__attribute__ ((packed)) struct s_sfpinfo
{
char pn[16];
int32_t alpha;
int32_t deltaTx;
int32_t deltaRx;
};
int eeprom_read(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size);
int eeprom_write(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size);
int32_t eeprom_sfp_section(uint8_t i2cif, uint8_t i2c_addr, size_t size, uint16_t *section_sz);
int8_t eeprom_get_sfpinfo(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, struct s_sfpinfo *sfpinfo, uint16_t section_sz);
int8_t access_eeprom(char *sfp_pn, int32_t *alpha, int32_t *deltaTx, int32_t *deltaRx);
#endif
#ifndef __I2C_H
#define __I2C_H
void mi2c_init(uint8_t i2cif);
void mi2c_start(uint8_t i2cif);
void mi2c_repeat_start(uint8_t i2cif);
void mi2c_stop(uint8_t i2cif);
void mi2c_get_byte(uint8_t i2cif, unsigned char *data, uint8_t last);
unsigned char mi2c_put_byte(uint8_t i2cif, unsigned char data);
void mi2c_delay();
//void mi2c_scan(uint8_t i2cif);
#endif
#ifndef __IRQ_H
#define __IRQ_H
static inline void clear_irq()
{
unsigned int val = 1;
asm volatile ("wcsr ip, %0"::"r"(val));
}
void disable_irq();
void enable_irq();
#endif
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
void ow_init();
uint32_t ow_reset(uint32_t port);
uint8_t ow_read_byte(uint32_t port);
int8_t ow_write_byte(uint32_t port, uint32_t byte);
int ow_write_block(int port, uint8_t *block, int len);
int ow_read_block(int port, uint8_t *block, int len);
int8_t ds18x_read_serial(uint8_t *id);
int8_t ds18x_read_temp(uint8_t *id, int *temp_r);
int ds18x_init();
#endif
/* SFP Detection / management functions */
#ifndef __SFP_H
#define __SFP_H
#include <stdint.h>
struct sfp_info {
char part_no[16];
int32_t delta_tx, delta_rx, alpha;
};
/* Returns 1 if there's a SFP transceiver inserted in the socket. */
int sfp_present();
/* Reads the part ID of the SFP from its configuration EEPROM */
int sfp_read_part_id(char *part_id);
/* SFP Database functions */
/* Adds an SFP to the DB */
int sfp_db_add(struct sfp_info *sinfo);
/* Searches for an SFP matching its' part_id */
struct sfp_info *sfp_db_lookup(const char *part_id);
struct sfp_info *sfp_db_get(int i);
void sfp_db_clear();
#endif
#ifndef __TIMER_H
#define __TIMER_H
#include "types.h"
#define TICS_PER_SECOND 1000
uint32_t timer_get_tics();
void timer_delay(uint32_t how_long);
#endif
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