21 #include <linux/kernel.h>
22 #include <linux/module.h>
29 #define MAX_RETRIES 1000
30 #define NPE_42X_DATA_SIZE 0x800
31 #define NPE_46X_DATA_SIZE 0x1000
32 #define NPE_A_42X_INSTR_SIZE 0x1000
33 #define NPE_B_AND_C_42X_INSTR_SIZE 0x800
34 #define NPE_46X_INSTR_SIZE 0x1000
35 #define REGS_SIZE 0x1000
37 #define NPE_PHYS_REG 32
39 #define FW_MAGIC 0xFEEDF00D
40 #define FW_BLOCK_TYPE_INSTR 0x0
41 #define FW_BLOCK_TYPE_DATA 0x1
42 #define FW_BLOCK_TYPE_EOF 0xF
45 #define CMD_NPE_STEP 0x01
46 #define CMD_NPE_START 0x02
47 #define CMD_NPE_STOP 0x03
48 #define CMD_NPE_CLR_PIPE 0x04
49 #define CMD_CLR_PROFILE_CNT 0x0C
50 #define CMD_RD_INS_MEM 0x10
51 #define CMD_WR_INS_MEM 0x11
52 #define CMD_RD_DATA_MEM 0x12
53 #define CMD_WR_DATA_MEM 0x13
54 #define CMD_RD_ECS_REG 0x14
55 #define CMD_WR_ECS_REG 0x15
57 #define STAT_RUN 0x80000000
58 #define STAT_STOP 0x40000000
59 #define STAT_CLEAR 0x20000000
60 #define STAT_ECS_K 0x00800000
62 #define NPE_STEVT 0x1B
63 #define NPE_STARTPC 0x1C
64 #define NPE_REGMAP 0x1E
65 #define NPE_CINDEX 0x1F
67 #define INSTR_WR_REG_SHORT 0x0000C000
68 #define INSTR_WR_REG_BYTE 0x00004000
69 #define INSTR_RD_FIFO 0x0F888220
70 #define INSTR_RESET_MBOX 0x0FAC8210
72 #define ECS_BG_CTXT_REG_0 0x00
73 #define ECS_BG_CTXT_REG_1 0x01
74 #define ECS_BG_CTXT_REG_2 0x02
75 #define ECS_PRI_1_CTXT_REG_0 0x04
76 #define ECS_PRI_1_CTXT_REG_1 0x05
77 #define ECS_PRI_1_CTXT_REG_2 0x06
78 #define ECS_PRI_2_CTXT_REG_0 0x08
79 #define ECS_PRI_2_CTXT_REG_1 0x09
80 #define ECS_PRI_2_CTXT_REG_2 0x0A
81 #define ECS_DBG_CTXT_REG_0 0x0C
82 #define ECS_DBG_CTXT_REG_1 0x0D
83 #define ECS_DBG_CTXT_REG_2 0x0E
84 #define ECS_INSTRUCT_REG 0x11
86 #define ECS_REG_0_ACTIVE 0x80000000
87 #define ECS_REG_0_NEXTPC_MASK 0x1FFF0000
88 #define ECS_REG_0_LDUR_BITS 8
89 #define ECS_REG_0_LDUR_MASK 0x00000700
90 #define ECS_REG_1_CCTXT_BITS 16
91 #define ECS_REG_1_CCTXT_MASK 0x000F0000
92 #define ECS_REG_1_SELCTXT_BITS 0
93 #define ECS_REG_1_SELCTXT_MASK 0x0000000F
94 #define ECS_DBG_REG_2_IF 0x00100000
95 #define ECS_DBG_REG_2_IE 0x00080000
98 #define WFIFO_VALID 0x80000000
101 #define MSGSTAT_OFNE 0x00010000
102 #define MSGSTAT_IFNF 0x00020000
103 #define MSGSTAT_OFNF 0x00040000
104 #define MSGSTAT_IFNE 0x00080000
105 #define MSGSTAT_MBINT 0x00100000
106 #define MSGSTAT_IFINT 0x00200000
107 #define MSGSTAT_OFINT 0x00400000
108 #define MSGSTAT_WFINT 0x00800000
111 #define MSGCTL_OUT_FIFO 0x00010000
112 #define MSGCTL_IN_FIFO 0x00020000
113 #define MSGCTL_OUT_FIFO_WRITE 0x01000000
114 #define MSGCTL_IN_FIFO_WRITE 0x02000000
117 #define RESET_MBOX_STAT 0x0000F0F0
119 #define NPE_A_FIRMWARE "NPE-A"
120 #define NPE_B_FIRMWARE "NPE-B"
121 #define NPE_C_FIRMWARE "NPE-C"
125 #define print_npe(pri, npe, fmt, ...) \
126 printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__)
129 #define debug_msg(npe, fmt, ...) \
130 print_npe(KERN_DEBUG, npe, fmt, ## __VA_ARGS__)
132 #define debug_msg(npe, fmt, ...)
199 static void npe_start(
struct npe *
npe)
210 static void npe_stop(
struct npe *
npe)
266 (val & ~0x1F) << (18 - 5);
267 return npe_debug_instr(npe, instr, ctx, 1);
270 static int __must_check npe_logical_reg_write16(
struct npe *npe,
u32 addr,
277 (val & ~0x1F) << (18 - 5);
278 return npe_debug_instr(npe, instr, ctx, 1);
281 static int __must_check npe_logical_reg_write32(
struct npe *npe,
u32 addr,
285 if (npe_logical_reg_write16(npe, addr, val >> 16, ctx))
287 return npe_logical_reg_write16(npe, addr + 2, val & 0xFFFF, ctx);
290 static int npe_reset(
struct npe *npe)
333 if (npe_logical_reg_write16(npe,
NPE_REGMAP, val >> 1, 0))
336 if (npe_logical_reg_write32(npe, (val & 1) * 4, 0, 0))
349 for (i = 0; i < 16; i++) {
352 if (npe_logical_reg_write8(npe,
NPE_STEVT, 0x80, i))
354 if (npe_logical_reg_write16(npe,
NPE_STARTPC, 0, i))
358 if (npe_logical_reg_write16(npe,
NPE_REGMAP, 0x820, i))
360 if (npe_logical_reg_write8(npe,
NPE_CINDEX, 0, i))
374 for (val = 0; val <
ARRAY_SIZE(ecs_reset); val++)
388 val = ixp4xx_read_feature_bits();
390 ixp4xx_write_feature_bits(val &
393 ixp4xx_write_feature_bits(val |
396 if (ixp4xx_read_feature_bits() &
401 if (i == MAX_RETRIES)
417 debug_msg(npe,
"Trying to send message %s [%08X:%08X]\n",
418 what, send[0], send[1]);
421 debug_msg(npe,
"NPE input FIFO not empty\n");
434 while ((cycles < MAX_RETRIES) &&
440 if (cycles == MAX_RETRIES) {
441 debug_msg(npe,
"Timeout sending message\n");
446 debug_msg(npe,
"Sending a message took %i cycles\n", cycles);
454 int cycles = 0,
cnt = 0;
456 debug_msg(npe,
"Trying to receive message %s\n", what);
458 while (cycles < MAX_RETRIES) {
471 debug_msg(npe,
"Received [%08X]\n", recv[0]);
474 debug_msg(npe,
"Received [%08X:%08X]\n", recv[0], recv[1]);
478 if (cycles == MAX_RETRIES) {
479 debug_msg(npe,
"Timeout waiting for message\n");
484 debug_msg(npe,
"Receiving a message took %i cycles\n", cycles);
499 if ((recv[0] != send[0]) || (recv[1] != send[1])) {
500 debug_msg(npe,
"Message %s: unexpected message received\n",
523 struct dl_block blocks[0];
527 struct dl_codeblock {
540 if (fw_entry->
size <
sizeof(
struct dl_image)) {
544 image = (
struct dl_image*)fw_entry->
data;
559 if ((
image->size * 4 +
sizeof(
struct dl_image)) != fw_entry->
size) {
561 "inconsistent size of firmware file\n");
564 if (((
image->id >> 24) & 0xF ) != npe->
id) {
569 for (i = 0; i <
image->size; i++)
580 "already running\n");
590 "revision 0x%X:%X\n", (
image->id >> 16) & 0xFF,
604 for (blocks = 0; blocks *
sizeof(
struct dl_block) / 4 < image->size;
608 if (blocks *
sizeof(
struct dl_block) / 4 >= image->size) {
618 table_end = blocks *
sizeof(
struct dl_block) / 4 + 1 ;
619 for (i = 0,
blk = image->blocks; i < blocks; i++,
blk++) {
620 if (
blk->offset > image->size -
sizeof(
struct dl_codeblock) / 4
621 ||
blk->offset < table_end) {
623 "firmware block #%i\n",
blk->offset, i);
627 cb = (
struct dl_codeblock*)&image->data[
blk->offset];
629 if (
cb->npe_addr +
cb->
size > instr_size)
633 if (
cb->npe_addr +
cb->
size > data_size)
638 "type 0x%X\n", i,
blk->type);
641 if (
blk->offset +
sizeof(*
cb) / 4 +
cb->
size > image->size) {
643 "fit in firmware image: type %c, start 0x%X,"
650 for (j = 0; j <
cb->
size; j++)
651 npe_cmd_write(npe,
cb->npe_addr + j, cmd,
cb->data[j]);
662 "memory: type %c, start 0x%X, length 0x%X\n", i,
674 if (npe_tab[
id].
valid)
686 static int __init npe_init_module(
void)
692 struct npe *npe = &npe_tab[
i];
693 if (!(ixp4xx_read_feature_bits() &
700 "failed to request memory region\n");
715 static void __exit npe_cleanup_module(
void)
721 npe_reset(&npe_tab[i]);