Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple VME FMC Carrier SVEC - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Simple VME FMC Carrier SVEC - Software
Commits
94674ffb
Commit
94674ffb
authored
Aug 29, 2013
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel: added sysfs-based VME configuration
parent
73372076
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
891 additions
and
298 deletions
+891
-298
Makefile
kernel/Makefile
+1
-0
svec-drv.c
kernel/svec-drv.c
+418
-150
svec-fmc.c
kernel/svec-fmc.c
+46
-57
svec-i2c.c
kernel/svec-i2c.c
+21
-22
svec-sysfs.c
kernel/svec-sysfs.c
+335
-43
svec.h
kernel/svec.h
+70
-26
No files found.
kernel/Makefile
View file @
94674ffb
...
...
@@ -25,6 +25,7 @@ svec-objs := svec-drv.o
svec-objs
+=
svec-sysfs.o
svec-objs
+=
svec-fmc.o
svec-objs
+=
svec-i2c.o
svec-objs
+=
svec-irq.o
all
:
modules
...
...
kernel/svec-drv.c
View file @
94674ffb
This diff is collapsed.
Click to expand it.
kernel/svec-fmc.c
View file @
94674ffb
...
...
@@ -12,7 +12,6 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/fmc-sdb.h>
#include <linux/jhash.h>
#include "svec.h"
static
int
svec_show_sdb
;
...
...
@@ -40,7 +39,6 @@ static int svec_reprogram(struct fmc_device *fmc, struct fmc_driver *drv,
const
struct
firmware
*
fw
;
struct
svec_dev
*
svec
=
fmc
->
carrier_data
;
struct
device
*
dev
=
fmc
->
hwdev
;
uint32_t
fw_hash
;
int
ret
=
0
;
/* If no firmware filename is provided, load default */
...
...
@@ -70,28 +68,17 @@ static int svec_reprogram(struct fmc_device *fmc, struct fmc_driver *drv,
}
fmc_free_sdb_tree
(
fmc
);
/* Hash firmware bitstream */
fw_hash
=
jhash
(
fw
->
data
,
fw
->
size
,
0
);
if
(
fw_hash
==
svec
->
fw_hash
)
{
dev_info
(
dev
,
"card already programmed with
\"
%s
\"
[%x]
\n
"
,
gw
,
fw_hash
);
goto
out
;
}
/* load the firmware */
ret
=
svec_load_fpga
(
svec
,
fw
->
data
,
fw
->
size
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
dev_err
(
dev
,
"error %i programming firmware
\"
%s
\"\n
"
,
ret
,
gw
);
goto
out
;
}
/* configure and activate function 0 */
dev_info
(
fmc
->
hwdev
,
"svec-fmc: setup fa0
\n
"
);
svec_setup_csr_fa0
(
svec
->
map
[
MAP_CR_CSR
]
->
kernel_va
,
svec
->
vmebase
,
svec
->
vector
,
svec
->
level
);
/* Configure & activate CSR functions depending on chosen AM */
svec_setup_csr
(
svec
);
/* Store firmware hash to avoid reprogram */
svec
->
fw_hash
=
fw_hash
;
out:
out:
release_firmware
(
fw
);
if
(
ret
<
0
)
dev_err
(
dev
,
"svec reprogram failed while loading %s
\n
"
,
gw
);
...
...
@@ -103,28 +90,12 @@ static int svec_validate(struct fmc_device *fmc, struct fmc_driver *drv)
return
0
;
/* everyhing is valid */
}
static
int
svec_irq_request
(
struct
fmc_device
*
fmc
,
irq_handler_t
handler
,
char
*
name
,
int
flags
)
{
return
0
;
}
static
void
svec_irq_ack
(
struct
fmc_device
*
fmc
)
{
}
static
int
svec_irq_free
(
struct
fmc_device
*
fmc
)
{
return
0
;
}
static
int
svec_gpio_config
(
struct
fmc_device
*
fmc
,
struct
fmc_gpio
*
gpio
,
int
ngpio
)
{
return
0
;
}
static
int
svec_read_ee
(
struct
fmc_device
*
fmc
,
int
pos
,
void
*
data
,
int
len
)
{
if
(
!
(
fmc
->
flags
&
FMC_DEVICE_HAS_GOLDEN
))
...
...
@@ -166,7 +137,7 @@ static int check_golden(struct fmc_device *fmc)
dev_err
(
svec
->
dev
,
"Bad SDB magic: 0x%08x
\n
"
,
magic
);
return
-
ENODEV
;
}
if
(
(
ret
=
fmc_scan_sdb_tree
(
fmc
,
0x0
))
<
0
)
if
((
ret
=
fmc_scan_sdb_tree
(
fmc
,
0x0
))
<
0
)
return
-
ENODEV
;
vendor
=
fmc_readl
(
fmc
,
0x5c
);
...
...
@@ -194,8 +165,7 @@ int svec_fmc_prepare(struct svec_dev *svec, unsigned int fmc_slot)
fmc
=
kzalloc
(
sizeof
(
*
fmc
),
GFP_KERNEL
);
if
(
!
fmc
)
{
dev_err
(
svec
->
dev
,
"cannot allocate fmc slot %d
\n
"
,
fmc_slot
);
dev_err
(
svec
->
dev
,
"cannot allocate fmc slot %d
\n
"
,
fmc_slot
);
return
-
ENOMEM
;
}
...
...
@@ -206,19 +176,27 @@ int svec_fmc_prepare(struct svec_dev *svec, unsigned int fmc_slot)
fmc
->
fpga_base
=
svec
->
map
[
MAP_REG
]
->
kernel_va
;
fmc
->
irq
=
0
;
/*TO-DO
*/
fmc
->
irq
=
0
;
/*TO-DO
*/
fmc
->
op
=
&
svec_fmc_operations
;
fmc
->
hwdev
=
svec
->
dev
;
/* for messages */
fmc
->
slot_id
=
fmc_slot
;
fmc
->
device_id
=
(
svec
->
slot
<<
6
)
|
fmc_slot
;
fmc
->
eeprom_addr
=
0x50
+
2
*
fmc_slot
;
fmc
->
memlen
=
0x100000
;
fmc
->
memlen
=
svec
->
cfg_cur
.
vme_size
;
/* check golden integrity */
/* FIXME: this uses fmc_scan_sdb_tree and de-allocation
* could be wrong at second reprogramming, as it is called
* n times, one per slot */
ret
=
svec_load_golden
(
svec
);
if
(
ret
)
{
dev_err
(
svec
->
dev
,
"Cannot load golden bitstream: %d
\n
"
,
ret
);
kfree
(
fmc
);
return
ret
;
}
ret
=
check_golden
(
fmc
);
if
(
ret
)
{
dev_err
(
svec
->
dev
,
"Bad golden, error %d
\n
"
,
ret
);
...
...
@@ -246,8 +224,9 @@ int svec_fmc_create(struct svec_dev *svec)
int
error
=
0
;
/* fmc structures filling */
for
(
i
=
0
;
i
<
svec
->
fmcs_n
;
i
++
)
{
for
(
i
=
0
;
i
<
svec
->
fmcs_n
;
i
++
)
{
error
=
svec_fmc_prepare
(
svec
,
i
);
if
(
error
)
goto
failed
;
}
...
...
@@ -263,7 +242,14 @@ int svec_fmc_create(struct svec_dev *svec)
*/
dev_info
(
svec
->
dev
,
"fmc devices registered
\n
"
);
failed:
return
0
;
failed:
for
(
i
=
0
;
i
<
svec
->
fmcs_n
;
i
++
)
if
(
svec
->
fmcs
[
i
])
kfree
(
svec
->
fmcs
[
i
]);
/* FIXME: free fmc allocations. */
return
error
;
...
...
@@ -271,7 +257,10 @@ failed:
void
svec_fmc_destroy
(
struct
svec_dev
*
svec
)
{
if
(
!
svec
->
fmcs
[
0
])
return
;
fmc_device_unregister_n
(
svec
->
fmcs
,
svec
->
fmcs_n
);
dev_info
(
svec
->
dev
,
"%d fmc devices unregistered
\n
"
,
svec
->
fmcs_n
);
dev_info
(
svec
->
dev
,
"%d fmc devices unregistered
\n
"
,
svec
->
fmcs_n
);
}
kernel/svec-i2c.c
View file @
94674ffb
...
...
@@ -51,7 +51,7 @@ static inline int mezzanine_present(struct fmc_device *fmc)
uint32_t
presence
;
presence
=
fmc_readl
(
fmc
,
GLD_I2C_CORE_BASE
+
GLD_REG_CSR
);
presence
=
GLD_CSR_FMC_PRESENT_R
(
presence
)
&
(
1
<<
fmc
->
slot_id
);
presence
=
GLD_CSR_FMC_PRESENT_R
(
presence
)
&
(
1
<<
fmc
->
slot_id
);
return
presence
;
}
...
...
@@ -62,7 +62,7 @@ static void dumpstruct(char *name, void *ptr, int size)
unsigned
char
*
p
=
ptr
;
printk
(
"%s: (size 0x%x)
\n
"
,
name
,
size
);
for
(
i
=
0
;
i
<
size
;
)
{
for
(
i
=
0
;
i
<
size
;)
{
printk
(
"%02x"
,
p
[
i
]);
i
++
;
printk
(
i
&
3
?
" "
:
i
&
0xf
?
" "
:
"
\n
"
);
...
...
@@ -116,7 +116,7 @@ int mi2c_put_byte(struct fmc_device *fmc, int data)
int
i
;
int
ack
;
for
(
i
=
0
;
i
<
8
;
i
++
,
data
<<=
1
)
{
for
(
i
=
0
;
i
<
8
;
i
++
,
data
<<=
1
)
{
set_sda
(
fmc
,
data
&
0x80
);
set_scl
(
fmc
,
1
);
set_scl
(
fmc
,
0
);
...
...
@@ -154,7 +154,7 @@ int mi2c_get_byte(struct fmc_device *fmc, unsigned char *data, int sendack)
set_scl
(
fmc
,
0
);
set_sda
(
fmc
,
0
);
*
data
=
indata
;
*
data
=
indata
;
return
0
;
}
...
...
@@ -167,9 +167,9 @@ void mi2c_init(struct fmc_device *fmc)
void
mi2c_scan
(
struct
fmc_device
*
fmc
)
{
int
i
;
for
(
i
=
0
;
i
<
256
;
i
+=
2
)
{
for
(
i
=
0
;
i
<
256
;
i
+=
2
)
{
mi2c_start
(
fmc
);
if
(
!
mi2c_put_byte
(
fmc
,
i
))
if
(
!
mi2c_put_byte
(
fmc
,
i
))
pr_info
(
"%s: Found i2c device at 0x%x
\n
"
,
KBUILD_MODNAME
,
i
>>
1
);
mi2c_stop
(
fmc
);
...
...
@@ -185,7 +185,7 @@ int svec_eeprom_read(struct fmc_device *fmc, uint32_t offset,
int
i2c_addr
=
fmc
->
eeprom_addr
;
mi2c_start
(
fmc
);
if
(
mi2c_put_byte
(
fmc
,
i2c_addr
<<
1
)
<
0
)
{
if
(
mi2c_put_byte
(
fmc
,
i2c_addr
<<
1
)
<
0
)
{
mi2c_stop
(
fmc
);
return
-
EIO
;
}
...
...
@@ -210,7 +210,7 @@ int svec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
const
uint8_t
*
buf8
=
buf
;
int
i2c_addr
=
fmc
->
eeprom_addr
;
for
(
i
=
0
;
i
<
size
;
i
++
)
{
for
(
i
=
0
;
i
<
size
;
i
++
)
{
mi2c_start
(
fmc
);
if
(
mi2c_put_byte
(
fmc
,
i2c_addr
<<
1
)
<
0
)
{
...
...
@@ -227,7 +227,7 @@ int svec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
mi2c_start
(
fmc
);
busy
=
mi2c_put_byte
(
fmc
,
i2c_addr
<<
1
);
mi2c_stop
(
fmc
);
}
while
(
busy
);
}
while
(
busy
);
}
return
size
;
}
...
...
@@ -273,4 +273,3 @@ void svec_i2c_exit(struct fmc_device *fmc)
fmc
->
eeprom
=
NULL
;
fmc
->
eeprom_len
=
0
;
}
kernel/svec-sysfs.c
View file @
94674ffb
This diff is collapsed.
Click to expand it.
kernel/svec.h
View file @
94674ffb
...
...
@@ -15,7 +15,16 @@
#include "vmebus.h"
#define SVEC_MAX_DEVICES 32
#define SVEC_MAX_FIRMWARE_SIZE 0x400000
#define SVEC_DEFAULT_IDX { [0 ... (SVEC_MAX_DEVICES-1)] = -1 }
#define SVEC_DEFAULT_VME_AM { [0 ... (SVEC_MAX_DEVICES-1)] = 0x39 }
#define SVEC_DEFAULT_VME_SIZE { [0 ... (SVEC_MAX_DEVICES-1)] = 0x100000 }
#define SVEC_DEFAULT_IRQ_LEVEL { [0 ... (SVEC_MAX_DEVICES-1)] = 0x2 }
#define SVEC_UNINITIALIZED_VME_BASE { [0 ... (SVEC_MAX_DEVICES-1)] = 0xffffffff }
#define SVEC_UNINITIALIZED_IRQ_VECTOR { [0 ... (SVEC_MAX_DEVICES-1)] = -1 }
#define SVEC_IRQ_LEVEL 2
#define SVEC_N_SLOTS 2
#define SVEC_BASE_LOADER 0x70000
...
...
@@ -29,44 +38,62 @@
enum
svec_map_win
{
MAP_CR_CSR
=
0
,
/* CR/CSR */
MAP_REG
/* A32
space */
MAP_REG
/* A32/A24/A16
space */
};
struct
svec_config
{
int
configured
;
uint32_t
vme_base
;
int
vme_am
;
uint32_t
vme_size
;
uint32_t
vic_base
;
int
interrupt_vector
;
int
interrupt_level
;
int
use_vic
;
int
use_fmc
;
};
#define SVEC_FLAG_FMCS_REGISTERED 0
#define SVEC_FLAG_IRQS_REQUESTED 1
#define SVEC_FLAG_BOOTLOADER_ACTIVE 2
/* Our device structure */
struct
svec_dev
{
int
lun
;
int
slot
;
uint32_t
vmebase
;
int
vector
;
int
level
;
unsigned
long
flags
;
char
*
fw_name
;
struct
device
*
dev
;
char
driver
[
16
];
char
description
[
80
];
uint32_t
fw_hash
;
struct
vme_mapping
*
map
[
2
];
struct
svec_config
cfg_cur
,
cfg_new
;
/* struct work_struct work; */
unsigned
long
irqcount
;
struct
fmc_device
*
fmcs
[
SVEC_N_SLOTS
];
/* FMC devices */
int
fmcs_n
;
/* Number of FMC devices */
int
irq_count
;
/* for mezzanine use too */
uint32_t
vme_raw_addr
;
/* VME address for raw VME I/O through vme_addr/vme_data attributes */
};
/* Functions and data in svec-vme.c */
extern
int
svec_is_bootloader_active
(
struct
svec_dev
*
svec
);
extern
int
svec_bootloader_unlock
(
struct
svec_dev
*
svec
);
extern
int
svec_bootloader_unlock
(
struct
svec_dev
*
svec
);
extern
int
svec_load_fpga
(
struct
svec_dev
*
svec
,
const
void
*
data
,
int
size
);
extern
int
svec_load_fpga_file
(
struct
svec_dev
*
svec
,
const
char
*
name
);
extern
void
svec_setup_csr_fa0
(
void
*
base
,
u32
vme
,
unsigned
vector
,
unsigned
level
);
extern
void
svec_setup_csr_fa0
(
struct
svec_dev
*
svec
);
extern
int
svec_unmap_window
(
struct
svec_dev
*
svec
,
enum
svec_map_win
map_type
);
extern
int
svec_map_window
(
struct
svec_dev
*
svec
,
enum
svec_map_win
map_type
);
extern
int
svec_map_window
(
struct
svec_dev
*
svec
,
enum
svec_map_win
map_type
);
extern
char
*
svec_fw_name
;
extern
int
spec_use_msi
;
/* Functions in svec-fmc.c, used by svec-vme.c */
extern
int
svec_fmc_create
(
struct
svec_dev
*
svec
);
...
...
@@ -82,6 +109,7 @@ extern int svec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
/* SVEC CSR offsets */
#define FUN0ADER 0x7FF63
#define FUN1ADER 0x7FF73
#define INT_LEVEL 0x7ff5b
#define INTVECTOR 0x7ff5f
#define WB_32_64 0x7ff33
...
...
@@ -96,4 +124,20 @@ extern int svec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
extern
int
svec_create_sysfs_files
(
struct
svec_dev
*
card
);
extern
void
svec_remove_sysfs_files
(
struct
svec_dev
*
card
);
int
svec_dma_write
(
struct
svec_dev
*
svec
,
uint32_t
addr
,
int
am
,
size_t
size
,
void
*
buf
,
int
is_fifo
);
int
svec_dma_read
(
struct
svec_dev
*
svec
,
uint32_t
addr
,
int
am
,
size_t
size
,
void
*
buf
,
int
is_fifo
);
int
svec_irq_request
(
struct
fmc_device
*
fmc
,
irq_handler_t
handler
,
char
*
name
,
int
flags
);
void
svec_irq_ack
(
struct
fmc_device
*
fmc
);
int
svec_irq_free
(
struct
fmc_device
*
fmc
);
int
svec_reconfigure
(
struct
svec_dev
*
svec
);
int
svec_setup_csr
(
struct
svec_dev
*
svec
);
int
svec_validate_configuration
(
struct
device
*
pdev
,
struct
svec_config
*
cfg
);
int
svec_load_golden
(
struct
svec_dev
*
svec
);
#endif
/* __SVEC_H__ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment