From: Kumar Abhishek <[email protected]> BeagleLogic is implemented as a separate kernel module that binds and unbinds itself from pru_rproc at runtime.
Signed-off-by: Kumar Abhishek <[email protected]> --- drivers/remoteproc/beaglelogic_glue.h | 43 ++++++++++++++++ drivers/remoteproc/pru_rproc.c | 92 +++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 drivers/remoteproc/beaglelogic_glue.h diff --git a/drivers/remoteproc/beaglelogic_glue.h b/drivers/remoteproc/beaglelogic_glue.h new file mode 100644 index 0000000..ede6370 --- /dev/null +++ b/drivers/remoteproc/beaglelogic_glue.h @@ -0,0 +1,43 @@ +/* + * Include file for the BeagleLogic kernel module [glue code for pru_rproc + * + * Copyright (C) 2014 Kumar Abhishek <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef BEAGLELOGIC_GLUE_H_ +#define BEAGLELOGIC_GLUE_H_ + +/* IRQ requests handled by pru_rproc are rerouted to beaglelogic + * after a rename. + * + * Currently only two interrupts, buffer ready and cleanup after stop */ +#define BL_IRQ_BUFREADY 0 +#define BL_IRQ_CLEANUP 1 + +struct beaglelogic_glue { + /* Misc device descriptor */ + struct miscdevice miscdev; + + /* Imported functions */ + int (*downcall_idx)(int, u32, u32, u32, u32, u32, u32); + void __iomem *(*d_da_to_va)(int, u32); + int (*pru_start)(int); + void (*pru_request_stop)(void); + + /* Exported functions */ + int (*serve_irq)(int, void *); + + /* Core clock frequency: Required for configuring sample rates */ + u32 coreclockfreq; +}; + +/* Bind and unbind requests */ +extern int pruproc_beaglelogic_request_bind(struct beaglelogic_glue *g); +extern void pruproc_beaglelogic_request_unbind(void); + +#endif /* BEAGLELOGIC_KERNEL_H_ */ diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 7b7280d..ff8e541 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -34,6 +34,8 @@ #include "remoteproc_internal.h" +#include "beaglelogic_glue.h" + /* PRU_EVTOUT0 is halt (system call) */ /* maximum PRUs */ @@ -189,8 +191,13 @@ struct pruproc { int controller; u32 dc_ids[DC_PWM_MAX]; } pwm; + + struct beaglelogic_glue *beaglelogic; }; +/* For the BeagleLogic bindings */ +static struct pruproc *pp_bl; + /* global memory map (for am33xx) (almost the same as local) */ #define PRU_DATA_RAM0 0x00000 #define PRU_DATA_RAM1 0x02000 @@ -1794,6 +1801,11 @@ static irqreturn_t pru_handler(int irq, void *data) handled = 0; + /* Handle BeagleLogic interrupts (same as vrings) + * This takes precedence when BeagleLogic is enabled and bound */ + if (pst->vring == 1 && pp->beaglelogic) + return pp->beaglelogic->serve_irq(pru_idx, pp->beaglelogic); + /* we either handle a vring or not */ if (!pst->vring) { ret = pru_handle_syscall(ppc); @@ -2346,6 +2358,83 @@ static int pruproc_create_devices(struct pruproc *pp) return ret; } +/* BeagleLogic plugin code section */ + +/* Downcall wrapper */ +static int beaglelogic_pru_downcall(int pru_no, u32 nr, u32 arg0, u32 arg1, + u32 arg2, u32 arg3, u32 arg4) +{ + return pru_downcall_idx(pp_bl, pru_no, nr, arg0, + arg1, arg2, arg3, arg4); +} + +/* Request VA to remapped PRU memory area */ +static void * __iomem beaglelogic_pru_d_da_to_va(int idx, u32 daddr) +{ + return pru_d_da_to_va(pp_bl->pru_to_pruc[idx], daddr, NULL); +} + +/* Post-configuration, resume the PRU [reserved for a future FWrev] */ +static int beaglelogic_pru_start(int idx) +{ + /* u32 addr; */ + + /* TODO Attempt to start halted PRU, skip over HALT */ + /* + if (pru_is_halted(pp_bl->pru_to_pruc[idx], &addr)) { + return -1; + } + pru_resume(pp_bl->pru_to_pruc[idx], addr + 4); + */ + return 0; +} + +/* Signal the PRU Firmware to abort after the next buffer */ +static void beaglelogic_pru_request_stop(void) +{ + /* ARM -> PRU1 interrupt */ + u32 sysint = pp_bl->target_to_sysev[TARGET_ARM_TO_PRU_IDX(1)]; + + /* Raise interrupt */ + if (sysint < 32) + pintc_write_reg(pp_bl, PINTC_SRSR0, 1 << sysint); + else + pintc_write_reg(pp_bl, PINTC_SRSR1, 1 << (sysint - 32)); +} + +/* The BeagleLogic module requests attach to the remoteproc module here */ +int pruproc_beaglelogic_request_bind(struct beaglelogic_glue *g) +{ + if (pp_bl == NULL) + return -1; + + /* Export the fp's to BeagleLogic functions located in this module */ + g->downcall_idx = beaglelogic_pru_downcall; + g->d_da_to_va = beaglelogic_pru_d_da_to_va; + g->pru_request_stop = beaglelogic_pru_request_stop; + g->pru_start = beaglelogic_pru_start; + + g->coreclockfreq = pp_bl->clock_freq; + + pp_bl->beaglelogic = g; + + return 0; +} +EXPORT_SYMBOL(pruproc_beaglelogic_request_bind); + +void pruproc_beaglelogic_request_unbind(void) +{ + /* Invalidate our handle to the module exported functions */ + pp_bl->beaglelogic = NULL; +} +EXPORT_SYMBOL(pruproc_beaglelogic_request_unbind); + +static void pruproc_beaglelogic_init_bindings(struct pruproc *pp) +{ + pp_bl = pp; +} +/* End BeagleLogic Section */ + static int pruproc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -2787,6 +2876,9 @@ static int pruproc_probe(struct platform_device *pdev) /* creating devices */ pruproc_create_devices(pp); + /* init the BeagleLogic binding section */ + pruproc_beaglelogic_init_bindings(pp); + (void)pru_d_read_u32; (void)pru_i_write_u32; (void)pru_d_write_u32; -- 1.9.1 -- For more options, visit http://beagleboard.org/discuss --- You received this message because you are subscribed to the Google Groups "BeagleBoard" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
