Lines Matching full:npe
23 #include <linux/soc/ixp4xx/npe.h>
45 /* NPE exec status (read) and command (write) */
85 #define ECS_INSTRUCT_REG 0x11 /* NPE Instruction Register */
98 /* NPE watchpoint_fifo register bit */
101 /* NPE messaging_status register bit definitions */
111 /* NPE messaging_control register bit definitions */
117 /* NPE mailbox_status value for reset */
120 #define NPE_A_FIRMWARE "NPE-A"
121 #define NPE_B_FIRMWARE "NPE-B"
122 #define NPE_C_FIRMWARE "NPE-C"
126 #define print_npe(pri, npe, fmt, ...) \ argument
127 printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__)
130 #define debug_msg(npe, fmt, ...) \ argument
131 print_npe(KERN_DEBUG, npe, fmt, ## __VA_ARGS__)
133 #define debug_msg(npe, fmt, ...) argument
154 static struct npe npe_tab[NPE_COUNT] = {
164 int npe_running(struct npe *npe) in npe_running() argument
166 return (__raw_readl(&npe->regs->exec_status_cmd) & STAT_RUN) != 0; in npe_running()
169 static void npe_cmd_write(struct npe *npe, u32 addr, int cmd, u32 data) in npe_cmd_write() argument
171 __raw_writel(data, &npe->regs->exec_data); in npe_cmd_write()
172 __raw_writel(addr, &npe->regs->exec_addr); in npe_cmd_write()
173 __raw_writel(cmd, &npe->regs->exec_status_cmd); in npe_cmd_write()
176 static u32 npe_cmd_read(struct npe *npe, u32 addr, int cmd) in npe_cmd_read() argument
178 __raw_writel(addr, &npe->regs->exec_addr); in npe_cmd_read()
179 __raw_writel(cmd, &npe->regs->exec_status_cmd); in npe_cmd_read()
180 /* Iintroduce extra read cycles after issuing read command to NPE in npe_cmd_read()
181 so that we read the register after the NPE has updated it. in npe_cmd_read()
182 This is to overcome race condition between XScale and NPE */ in npe_cmd_read()
183 __raw_readl(&npe->regs->exec_data); in npe_cmd_read()
184 __raw_readl(&npe->regs->exec_data); in npe_cmd_read()
185 return __raw_readl(&npe->regs->exec_data); in npe_cmd_read()
188 static void npe_clear_active(struct npe *npe, u32 reg) in npe_clear_active() argument
190 u32 val = npe_cmd_read(npe, reg, CMD_RD_ECS_REG); in npe_clear_active()
191 npe_cmd_write(npe, reg, CMD_WR_ECS_REG, val & ~ECS_REG_0_ACTIVE); in npe_clear_active()
194 static void npe_start(struct npe *npe) in npe_start() argument
197 npe_clear_active(npe, ECS_PRI_1_CTXT_REG_0); in npe_start()
198 npe_clear_active(npe, ECS_PRI_2_CTXT_REG_0); in npe_start()
199 npe_clear_active(npe, ECS_DBG_CTXT_REG_0); in npe_start()
201 __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); in npe_start()
202 __raw_writel(CMD_NPE_START, &npe->regs->exec_status_cmd); in npe_start()
205 static void npe_stop(struct npe *npe) in npe_stop() argument
207 __raw_writel(CMD_NPE_STOP, &npe->regs->exec_status_cmd); in npe_stop()
208 __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); /*FIXME?*/ in npe_stop()
211 static int __must_check npe_debug_instr(struct npe *npe, u32 instr, u32 ctx, in npe_debug_instr() argument
218 npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG, in npe_debug_instr()
226 npe_cmd_write(npe, ECS_DBG_CTXT_REG_1, CMD_WR_ECS_REG, in npe_debug_instr()
231 __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); in npe_debug_instr()
233 /* load NPE instruction into the instruction register */ in npe_debug_instr()
234 npe_cmd_write(npe, ECS_INSTRUCT_REG, CMD_WR_ECS_REG, instr); in npe_debug_instr()
236 /* we need this value later to wait for completion of NPE execution in npe_debug_instr()
238 wc = __raw_readl(&npe->regs->watch_count); in npe_debug_instr()
241 __raw_writel(CMD_NPE_STEP, &npe->regs->exec_status_cmd); in npe_debug_instr()
243 /* Watch Count register increments when NPE completes an instruction */ in npe_debug_instr()
245 if (wc != __raw_readl(&npe->regs->watch_count)) in npe_debug_instr()
250 print_npe(KERN_ERR, npe, "reset: npe_debug_instr(): timeout\n"); in npe_debug_instr()
254 static int __must_check npe_logical_reg_write8(struct npe *npe, u32 addr, in npe_logical_reg_write8() argument
257 /* here we build the NPE assembler instruction: mov8 d0, #0 */ in npe_logical_reg_write8()
262 return npe_debug_instr(npe, instr, ctx, 1); /* execute it */ in npe_logical_reg_write8()
265 static int __must_check npe_logical_reg_write16(struct npe *npe, u32 addr, in npe_logical_reg_write16() argument
268 /* here we build the NPE assembler instruction: mov16 d0, #0 */ in npe_logical_reg_write16()
273 return npe_debug_instr(npe, instr, ctx, 1); /* execute it */ in npe_logical_reg_write16()
276 static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr, in npe_logical_reg_write32() argument
280 if (npe_logical_reg_write16(npe, addr, val >> 16, ctx)) in npe_logical_reg_write32()
282 return npe_logical_reg_write16(npe, addr + 2, val & 0xFFFF, ctx); in npe_logical_reg_write32()
285 static int npe_reset(struct npe *npe) in npe_reset() argument
290 ctl = (__raw_readl(&npe->regs->messaging_control) | 0x3F000000) & in npe_reset()
294 __raw_writel(ctl & 0x3F00FFFF, &npe->regs->messaging_control); in npe_reset()
298 exec_count = __raw_readl(&npe->regs->exec_count); in npe_reset()
299 __raw_writel(0, &npe->regs->exec_count); in npe_reset()
302 ctx_reg2 = npe_cmd_read(npe, ECS_DBG_CTXT_REG_2, CMD_RD_ECS_REG); in npe_reset()
303 npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2 | in npe_reset()
307 while (__raw_readl(&npe->regs->watchpoint_fifo) & WFIFO_VALID) in npe_reset()
309 while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE) in npe_reset()
311 print_npe(KERN_DEBUG, npe, "npe_reset: read FIFO = 0x%X\n", in npe_reset()
312 __raw_readl(&npe->regs->in_out_fifo)); in npe_reset()
314 while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE) in npe_reset()
315 /* step execution of the NPE intruction to read inFIFO using in npe_reset()
317 if (npe_debug_instr(npe, INSTR_RD_FIFO, 0, 0)) in npe_reset()
321 __raw_writel(RESET_MBOX_STAT, &npe->regs->mailbox_status); in npe_reset()
322 /* from NPE side */ in npe_reset()
323 if (npe_debug_instr(npe, INSTR_RESET_MBOX, 0, 0)) in npe_reset()
326 /* Reset the physical registers in the NPE register file */ in npe_reset()
328 if (npe_logical_reg_write16(npe, NPE_REGMAP, val >> 1, 0)) in npe_reset()
331 if (npe_logical_reg_write32(npe, (val & 1) * 4, 0, 0)) in npe_reset()
338 for Background ECS, to set where NPE starts executing code */ in npe_reset()
339 val = npe_cmd_read(npe, ECS_BG_CTXT_REG_0, CMD_RD_ECS_REG); in npe_reset()
342 npe_cmd_write(npe, ECS_BG_CTXT_REG_0, CMD_WR_ECS_REG, val); in npe_reset()
347 if (npe_logical_reg_write8(npe, NPE_STEVT, 0x80, i)) in npe_reset()
349 if (npe_logical_reg_write16(npe, NPE_STARTPC, 0, i)) in npe_reset()
353 if (npe_logical_reg_write16(npe, NPE_REGMAP, 0x820, i)) in npe_reset()
355 if (npe_logical_reg_write8(npe, NPE_CINDEX, 0, i)) in npe_reset()
361 npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG, 0); in npe_reset()
363 __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); in npe_reset()
365 __raw_writel(exec_count, &npe->regs->exec_count); in npe_reset()
366 npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2); in npe_reset()
370 npe_cmd_write(npe, ecs_reset[val].reg, CMD_WR_ECS_REG, in npe_reset()
374 __raw_writel(CMD_CLR_PROFILE_CNT, &npe->regs->exec_status_cmd); in npe_reset()
376 __raw_writel(0, &npe->regs->exec_count); in npe_reset()
377 __raw_writel(0, &npe->regs->action_points[0]); in npe_reset()
378 __raw_writel(0, &npe->regs->action_points[1]); in npe_reset()
379 __raw_writel(0, &npe->regs->action_points[2]); in npe_reset()
380 __raw_writel(0, &npe->regs->action_points[3]); in npe_reset()
381 __raw_writel(0, &npe->regs->watch_count); in npe_reset()
384 /* reset the NPE */ in npe_reset()
386 ~(IXP4XX_FEATURE_RESET_NPEA << npe->id)); in npe_reset()
389 (IXP4XX_FEATURE_RESET_NPEA << npe->id)); in npe_reset()
392 (IXP4XX_FEATURE_RESET_NPEA << npe->id)) in npe_reset()
393 break; /* NPE is back alive */ in npe_reset()
399 npe_stop(npe); in npe_reset()
401 /* restore NPE configuration bus Control Register - parity settings */ in npe_reset()
402 __raw_writel(ctl, &npe->regs->messaging_control); in npe_reset()
407 int npe_send_message(struct npe *npe, const void *msg, const char *what) in npe_send_message() argument
412 debug_msg(npe, "Trying to send message %s [%08X:%08X]\n", in npe_send_message()
415 if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE) { in npe_send_message()
416 debug_msg(npe, "NPE input FIFO not empty\n"); in npe_send_message()
420 __raw_writel(send[0], &npe->regs->in_out_fifo); in npe_send_message()
422 if (!(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNF)) { in npe_send_message()
423 debug_msg(npe, "NPE input FIFO full\n"); in npe_send_message()
427 __raw_writel(send[1], &npe->regs->in_out_fifo); in npe_send_message()
430 (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)) { in npe_send_message()
436 debug_msg(npe, "Timeout sending message\n"); in npe_send_message()
441 debug_msg(npe, "Sending a message took %i cycles\n", cycles); in npe_send_message()
446 int npe_recv_message(struct npe *npe, void *msg, const char *what) in npe_recv_message() argument
451 debug_msg(npe, "Trying to receive message %s\n", what); in npe_recv_message()
454 if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE) { in npe_recv_message()
455 recv[cnt++] = __raw_readl(&npe->regs->in_out_fifo); in npe_recv_message()
466 debug_msg(npe, "Received [%08X]\n", recv[0]); in npe_recv_message()
469 debug_msg(npe, "Received [%08X:%08X]\n", recv[0], recv[1]); in npe_recv_message()
474 debug_msg(npe, "Timeout waiting for message\n"); in npe_recv_message()
479 debug_msg(npe, "Receiving a message took %i cycles\n", cycles); in npe_recv_message()
484 int npe_send_recv_message(struct npe *npe, void *msg, const char *what) in npe_send_recv_message() argument
489 if ((result = npe_send_message(npe, msg, what)) != 0) in npe_send_recv_message()
491 if ((result = npe_recv_message(npe, recv, what)) != 0) in npe_send_recv_message()
495 debug_msg(npe, "Message %s: unexpected message received\n", in npe_send_recv_message()
503 int npe_load_firmware(struct npe *npe, const char *name, struct device *dev) in npe_load_firmware() argument
536 print_npe(KERN_ERR, npe, "incomplete firmware file\n"); in npe_load_firmware()
542 print_npe(KERN_DEBUG, npe, "firmware: %08X %08X %08X (0x%X bytes)\n", in npe_load_firmware()
550 print_npe(KERN_ERR, npe, "bad firmware file magic: 0x%X\n", in npe_load_firmware()
555 print_npe(KERN_ERR, npe, in npe_load_firmware()
559 if (((image->id >> 24) & 0xF /* NPE ID */) != npe->id) { in npe_load_firmware()
560 print_npe(KERN_ERR, npe, "firmware file NPE ID mismatch\n"); in npe_load_firmware()
568 print_npe(KERN_INFO, npe, "IXP43x/IXP46x firmware ignored on " in npe_load_firmware()
573 if (npe_running(npe)) { in npe_load_firmware()
574 print_npe(KERN_INFO, npe, "unable to load firmware, NPE is " in npe_load_firmware()
580 npe_stop(npe); in npe_load_firmware()
581 npe_reset(npe); in npe_load_firmware()
584 print_npe(KERN_INFO, npe, "firmware functionality 0x%X, " in npe_load_firmware()
589 if (!npe->id) in npe_load_firmware()
604 print_npe(KERN_INFO, npe, "firmware EOF block marker not " in npe_load_firmware()
610 print_npe(KERN_DEBUG, npe, "%i firmware blocks found\n", blocks); in npe_load_firmware()
617 print_npe(KERN_INFO, npe, "invalid offset 0x%X of " in npe_load_firmware()
632 print_npe(KERN_INFO, npe, "invalid firmware block #%i " in npe_load_firmware()
637 print_npe(KERN_INFO, npe, "firmware block #%i doesn't " in npe_load_firmware()
646 npe_cmd_write(npe, cb->npe_addr + j, cmd, cb->data[j]); in npe_load_firmware()
649 npe_start(npe); in npe_load_firmware()
650 if (!npe_running(npe)) in npe_load_firmware()
651 print_npe(KERN_ERR, npe, "unable to start\n"); in npe_load_firmware()
656 print_npe(KERN_INFO, npe, "firmware block #%i doesn't fit in NPE " in npe_load_firmware()
666 struct npe *npe_request(unsigned id) in npe_request()
675 void npe_release(struct npe *npe) in npe_release() argument
688 struct npe *npe = &npe_tab[i]; in ixp4xx_npe_probe() local
696 dev_info(dev, "NPE%d at %pR not available\n", in ixp4xx_npe_probe()
698 continue; /* NPE already disabled or not present */ in ixp4xx_npe_probe()
700 npe->regs = devm_ioremap_resource(dev, res); in ixp4xx_npe_probe()
701 if (IS_ERR(npe->regs)) in ixp4xx_npe_probe()
702 return PTR_ERR(npe->regs); in ixp4xx_npe_probe()
704 if (npe_reset(npe)) { in ixp4xx_npe_probe()
705 dev_info(dev, "NPE%d at %pR does not reset\n", in ixp4xx_npe_probe()
709 npe->valid = 1; in ixp4xx_npe_probe()
710 dev_info(dev, "NPE%d at %pR registered\n", i, res); in ixp4xx_npe_probe()
745 .name = "ixp4xx-npe",