APIs to access the Management Complex (MC) hardware module of Freescale LS2 SoCs. This patch includes APIs to check the MC firmware version and to manipulate DPRC objects in the MC. Signed-off-by: J. German Rivera <German.Rivera@xxxxxxxxxxxxx> Signed-off-by: Stuart Yoder <stuart.yoder@xxxxxxxxxxxxx> --- Changes in v8: - Addressed comments from Greg Kroah-Hartman: * Moved files to drivers/staging to wait for child drivers of the fsl-mc bus to be posted upstream: drivers/bus/fsl-mc/dpmng-cmd.h -> drivers/staging/fsl-mc/bus/dpmng-cmd.h drivers/bus/fsl-mc/dpmng.c -> drivers/staging/fsl-mc/bus/dpmng.c drivers/bus/fsl-mc/dprc-cmd.h -> drivers/staging/fsl-mc/bus/dprc-cmd.h drivers/bus/fsl-mc/dprc.c -> drivers/staging/fsl-mc/bus/dprc.c drivers/bus/fsl-mc/mc-sys.c -> drivers/staging/fsl-mc/bus/mc-sys.c include/linux/fsl/dpmng.h -> drivers/staging/fsl-mc/include/dpmng.h include/linux/fsl/dprc.h -> drivers/staging/fsl-mc/include/dprc.h include/linux/fsl/mc-cmd.h -> drivers/staging/fsl-mc/include/mc-cmd.h include/linux/fsl/mc-sys.h -> drivers/staging/fsl-mc/include/mc-sys.h - Addressed comments from Alex Graf: * Removed leftover doxygen comments from mc-sys.h Changes in v6: - Upgraded MC flibs for MC firmware 0.5.3 - Fixed new checkpatch warnings Changes in v5: - Addressed comments from Alex Graf: * Removed unused variable in mc_send_command() * Renamed dprc_get_container_id() as dpmng_get_container_id() and moved corresponding code from dprc.[hc] to dpmng.[hc], as "get_container_id" is not really an operation on a DPRC object, but it is a general MC management operation. * Ensure that strings sent/received to/from the MC fw for DPRC commands are null-terminated. Changes in v4: - Addressed comments from Alex Graf: * Added file description for files that did not have one * Removed Marshalling/unmarshalling macros invoked in MC command wrapper functions, and instead do the marshalling/ unmarshalling directly in these functions. * Added type cast u32 in status range-check in mc_status_to_error() * Moved mc_write_command() and mc_read_response() inline function to mc_sys.c as they are only used in that file * Renamed u64_enc() as mc_enc() and u64_dec() as mc_dec() - Upgraded MC flibs for MC firmware 0.5 Changes in v3: - Addressed comment from Greg Kroah-Hartman: * Removed doxygen comments - Addressed comment from Scott Wood: * Replaced udelay() call with usleep_range() call in polling loop - Addressed comments from Kim Phillips: * Fixed license text in all files * Renamed files: drivers/bus/fsl-mc/fsl_dpmng_cmd.h -> drivers/bus/fsl-mc/dpmng-cmd.h drivers/bus/fsl-mc/fsl_dprc_cmd.h -> drivers/bus/fsl-mc/dprc-cmd.h drivers/bus/fsl-mc/fsl_mc_sys.c -> drivers/bus/fsl-mc/mc-sys.c include/linux/fsl_dpmng.h -> include/linux/fsl/dpmng.h include/linux/fsl_dprc.h -> include/linux/fsl/dprc.h include/linux/fsl_mc_cmd.h -> include/linux/fsl/mc-cmd.h include/linux/fsl_mc_sys.h -> include/linux/fsl/mc-sys.h * Changed dpmng_load_iop() to take the DMA address directly, instead of the image virtual address. * Removed if and WARN_ON that checks for NULL fsl_destroy_mc_io() * Removed locking from mc_send_command(). Now the caller of MC flib APIs is responsible for protecting concurrent accesses to the same MC portal. Changes in v2: - Addressed comment from Joe Perches: * Refactored logic to actively fail on err and proceed at the same indent level on success, for all functions in dprc.c and dpmng.c. - Addressed comments from Kim Phillips: * Fixed warning in mc_send_command * Changed serialization logic in mc_send_command() to only use spinlock_irqsave() when both threads and interrupt handlers concurrently access the same portal. * Changed switch to lookup table in mc_status_to_error() * Removed macros iowrite64(), ioread64(), ENOTSUP from fsl_mc_sys.h * Removed #ifdef side for FSL_MC_FIRMWARE in fsl_mc_cmd.h * Changed non-devm_ API calls to devm_ API calls and refactored fsl_create_mc_io()/fsl_destroy_mc_io() to simplify cleanup logic. - Addressed comments from Scott Wood: * Return -ENXIO instead of -EFAULT when ioremap_nocache() fails - Addressed comments from Alex Graf: * Added MAINTAINERS file entries for new files * Added dev param to fsl_create_mc_io(), to enable the use of devm_ APIs in this function and fsl_destroy_mc_io(). * Changed the value of the timeout for MC command completion to be a function of HZ instead of a hard-coded jiffies value. MAINTAINERS | 6 + drivers/staging/fsl-mc/TODO | 11 + drivers/staging/fsl-mc/bus/dpmng-cmd.h | 47 ++ drivers/staging/fsl-mc/bus/dpmng.c | 78 +++ drivers/staging/fsl-mc/bus/dprc-cmd.h | 84 +++ drivers/staging/fsl-mc/bus/dprc.c | 913 ++++++++++++++++++++++++++++++++ drivers/staging/fsl-mc/bus/mc-sys.c | 283 ++++++++++ drivers/staging/fsl-mc/include/dpmng.h | 80 +++ drivers/staging/fsl-mc/include/dprc.h | 801 ++++++++++++++++++++++++++++ drivers/staging/fsl-mc/include/mc-cmd.h | 113 ++++ drivers/staging/fsl-mc/include/mc-sys.h | 70 +++ 11 files changed, 2486 insertions(+) create mode 100644 drivers/staging/fsl-mc/TODO create mode 100644 drivers/staging/fsl-mc/bus/dpmng-cmd.h create mode 100644 drivers/staging/fsl-mc/bus/dpmng.c create mode 100644 drivers/staging/fsl-mc/bus/dprc-cmd.h create mode 100644 drivers/staging/fsl-mc/bus/dprc.c create mode 100644 drivers/staging/fsl-mc/bus/mc-sys.c create mode 100644 drivers/staging/fsl-mc/include/dpmng.h create mode 100644 drivers/staging/fsl-mc/include/dprc.h create mode 100644 drivers/staging/fsl-mc/include/mc-cmd.h create mode 100644 drivers/staging/fsl-mc/include/mc-sys.h diff --git a/MAINTAINERS b/MAINTAINERS index 42f686f..b3d0702 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4145,6 +4145,12 @@ F: sound/soc/fsl/fsl* F: sound/soc/fsl/imx* F: sound/soc/fsl/mpc8610_hpcd.c +FREESCALE QORIQ MANAGEMENT COMPLEX DRIVER +M: J. German Rivera <German.Rivera@xxxxxxxxxxxxx> +L: linux-kernel@xxxxxxxxxxxxxxx +S: Maintained +F: drivers/staging/fsl-mc/ + FREEVXFS FILESYSTEM M: Christoph Hellwig <hch@xxxxxxxxxxxxx> W: ftp://ftp.openlinux.org/pub/people/hch/vxfs diff --git a/drivers/staging/fsl-mc/TODO b/drivers/staging/fsl-mc/TODO new file mode 100644 index 0000000..5df2c74 --- /dev/null +++ b/drivers/staging/fsl-mc/TODO @@ -0,0 +1,11 @@ +* Add README file (with ASCII art) describing relationships between + DPAA2 objects and how combine them to make a NIC, an LS2 switch, etc. + +* Add at least one device driver for a DPAA2 object (child device of the + fsl-mc bus). + +Please send any patches to: +- Greg Kroah-Hartman <greg@xxxxxxxxx> +- German Rivera <german.rivera@xxxxxxxxxxxxx> +- devel@xxxxxxxxxxxxxxxxxxxx, +- linux-kernel@xxxxxxxxxxxxxxx diff --git a/drivers/staging/fsl-mc/bus/dpmng-cmd.h b/drivers/staging/fsl-mc/bus/dpmng-cmd.h new file mode 100644 index 0000000..ba8cfa9 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmng-cmd.h @@ -0,0 +1,47 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*************************************************************************//* + dpmng-cmd.h + + defines portal commands + + *//**************************************************************************/ + +#ifndef __FSL_DPMNG_CMD_H +#define __FSL_DPMNG_CMD_H + +/* Command IDs */ +#define DPMNG_CMDID_GET_CONT_ID 0x830 +#define DPMNG_CMDID_GET_VERSION 0x831 + +#endif /* __FSL_DPMNG_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dpmng.c b/drivers/staging/fsl-mc/bus/dpmng.c new file mode 100644 index 0000000..58328e8 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmng.c @@ -0,0 +1,78 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the above-listed copyright holders nor the +* names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* +* ALTERNATIVELY, this software may be distributed under the terms of the +* GNU General Public License ("GPL") as published by the Free Software +* Foundation, either version 2 of that License or (at your option) any +* later version. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +#include "../include/mc-sys.h" +#include "../include/mc-cmd.h" +#include "../include/dpmng.h" +#include "dpmng-cmd.h" + +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION, + MC_CMD_PRI_LOW, 0); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + mc_ver_info->revision = mc_dec(cmd.params[0], 0, 32); + mc_ver_info->major = mc_dec(cmd.params[0], 32, 32); + mc_ver_info->minor = mc_dec(cmd.params[1], 0, 32); + + return 0; +} + +int dpmng_get_container_id(struct fsl_mc_io *mc_io, int *container_id) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_CONT_ID, + MC_CMD_PRI_LOW, 0); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *container_id = mc_dec(cmd.params[0], 0, 32); + + return 0; +} + diff --git a/drivers/staging/fsl-mc/bus/dprc-cmd.h b/drivers/staging/fsl-mc/bus/dprc-cmd.h new file mode 100644 index 0000000..0920248 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dprc-cmd.h @@ -0,0 +1,84 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*************************************************************************//* + dprc-cmd.h + + defines dprc portal commands + + *//**************************************************************************/ + +#ifndef _FSL_DPRC_CMD_H +#define _FSL_DPRC_CMD_H + +/* DPRC Version */ +#define DPRC_VER_MAJOR 3 +#define DPRC_VER_MINOR 0 + +/* Command IDs */ +#define DPRC_CMDID_CLOSE 0x800 +#define DPRC_CMDID_OPEN 0x805 +#define DPRC_CMDID_CREATE 0x905 + +#define DPRC_CMDID_GET_ATTR 0x004 +#define DPRC_CMDID_RESET_CONT 0x005 + +#define DPRC_CMDID_SET_IRQ 0x010 +#define DPRC_CMDID_GET_IRQ 0x011 +#define DPRC_CMDID_SET_IRQ_ENABLE 0x012 +#define DPRC_CMDID_GET_IRQ_ENABLE 0x013 +#define DPRC_CMDID_SET_IRQ_MASK 0x014 +#define DPRC_CMDID_GET_IRQ_MASK 0x015 +#define DPRC_CMDID_GET_IRQ_STATUS 0x016 +#define DPRC_CMDID_CLEAR_IRQ_STATUS 0x017 + +#define DPRC_CMDID_CREATE_CONT 0x151 +#define DPRC_CMDID_DESTROY_CONT 0x152 +#define DPRC_CMDID_SET_RES_QUOTA 0x155 +#define DPRC_CMDID_GET_RES_QUOTA 0x156 +#define DPRC_CMDID_ASSIGN 0x157 +#define DPRC_CMDID_UNASSIGN 0x158 +#define DPRC_CMDID_GET_OBJ_COUNT 0x159 +#define DPRC_CMDID_GET_OBJ 0x15A +#define DPRC_CMDID_GET_RES_COUNT 0x15B +#define DPRC_CMDID_GET_RES_IDS 0x15C +#define DPRC_CMDID_GET_OBJ_REG 0x15E + +#define DPRC_CMDID_CONNECT 0x167 +#define DPRC_CMDID_DISCONNECT 0x168 +#define DPRC_CMDID_GET_POOL 0x169 +#define DPRC_CMDID_GET_POOL_COUNT 0x16A +#define DPRC_CMDID_GET_PORTAL_PADDR 0x16B + +#define DPRC_CMDID_GET_CONNECTION 0x16C + +#endif /* _FSL_DPRC_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dprc.c b/drivers/staging/fsl-mc/bus/dprc.c new file mode 100644 index 0000000..19b26e6 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dprc.c @@ -0,0 +1,913 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the above-listed copyright holders nor the +* names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* +* ALTERNATIVELY, this software may be distributed under the terms of the +* GNU General Public License ("GPL") as published by the Free Software +* Foundation, either version 2 of that License or (at your option) any +* later version. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +#include "../include/mc-sys.h" +#include "../include/mc-cmd.h" +#include "../include/dprc.h" +#include "dprc-cmd.h" + +int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, MC_CMD_PRI_LOW, + 0); + cmd.params[0] |= mc_enc(0, 32, container_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return 0; +} +EXPORT_SYMBOL(dprc_open); + +int dprc_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, MC_CMD_PRI_HIGH, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dprc_close); + +int dprc_create_container(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_cfg *cfg, + int *child_container_id, + uint64_t *child_portal_paddr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.params[0] |= mc_enc(32, 16, cfg->icid); + cmd.params[0] |= mc_enc(0, 32, cfg->options); + cmd.params[1] |= mc_enc(32, 32, cfg->portal_id); + + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CREATE_CONT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *child_container_id = mc_dec(cmd.params[1], 0, 32); + *child_portal_paddr = mc_dec(cmd.params[2], 0, 64); + + return 0; +} + +int dprc_destroy_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_DESTROY_CONT, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_reset_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + int *type, + uint64_t *irq_paddr, + uint32_t *irq_val, + int *user_irq_id) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *irq_val = mc_dec(cmd.params[0], 0, 32); + *irq_paddr = mc_dec(cmd.params[1], 0, 64); + *user_irq_id = mc_dec(cmd.params[2], 0, 32); + *type = mc_dec(cmd.params[2], 32, 32); + + return 0; +} + +int dprc_set_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint64_t irq_paddr, + uint32_t irq_val, + int user_irq_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd.params[0] |= mc_enc(0, 32, irq_val); + cmd.params[1] |= mc_enc(0, 64, irq_paddr); + cmd.params[2] |= mc_enc(0, 32, user_irq_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t *en) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_ENABLE, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *en = mc_dec(cmd.params[0], 0, 8); + + return 0; +} + +int dprc_set_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t en) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 8, en); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *mask) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_MASK, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *mask = mc_dec(cmd.params[0], 0, 32); + + return 0; +} + +int dprc_set_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t mask) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, mask); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *status) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *status = mc_dec(cmd.params[0], 0, 32); + + return 0; +} + +int dprc_clear_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t status) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, status); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_attributes *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR, + MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + attr->container_id = mc_dec(cmd.params[0], 0, 32); + attr->icid = mc_dec(cmd.params[0], 32, 16); + attr->options = mc_dec(cmd.params[1], 0, 32); + attr->portal_id = mc_dec(cmd.params[1], 32, 32); + attr->version.major = mc_dec(cmd.params[2], 0, 16); + attr->version.minor = mc_dec(cmd.params[2], 16, 16); + + return 0; +} + +int dprc_set_res_quota(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + char *type, + uint16_t quota) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_RES_QUOTA, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + cmd.params[0] |= mc_enc(32, 16, quota); + cmd.params[1] |= mc_enc(0, 8, type[0]); + cmd.params[1] |= mc_enc(8, 8, type[1]); + cmd.params[1] |= mc_enc(16, 8, type[2]); + cmd.params[1] |= mc_enc(24, 8, type[3]); + cmd.params[1] |= mc_enc(32, 8, type[4]); + cmd.params[1] |= mc_enc(40, 8, type[5]); + cmd.params[1] |= mc_enc(48, 8, type[6]); + cmd.params[1] |= mc_enc(56, 8, type[7]); + cmd.params[2] |= mc_enc(0, 8, type[8]); + cmd.params[2] |= mc_enc(8, 8, type[9]); + cmd.params[2] |= mc_enc(16, 8, type[10]); + cmd.params[2] |= mc_enc(24, 8, type[11]); + cmd.params[2] |= mc_enc(32, 8, type[12]); + cmd.params[2] |= mc_enc(40, 8, type[13]); + cmd.params[2] |= mc_enc(48, 8, type[14]); + cmd.params[2] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_res_quota(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + char *type, + uint16_t *quota) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_QUOTA, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + cmd.params[1] |= mc_enc(0, 8, type[0]); + cmd.params[1] |= mc_enc(8, 8, type[1]); + cmd.params[1] |= mc_enc(16, 8, type[2]); + cmd.params[1] |= mc_enc(24, 8, type[3]); + cmd.params[1] |= mc_enc(32, 8, type[4]); + cmd.params[1] |= mc_enc(40, 8, type[5]); + cmd.params[1] |= mc_enc(48, 8, type[6]); + cmd.params[1] |= mc_enc(56, 8, type[7]); + cmd.params[2] |= mc_enc(0, 8, type[8]); + cmd.params[2] |= mc_enc(8, 8, type[9]); + cmd.params[2] |= mc_enc(16, 8, type[10]); + cmd.params[2] |= mc_enc(24, 8, type[11]); + cmd.params[2] |= mc_enc(32, 8, type[12]); + cmd.params[2] |= mc_enc(40, 8, type[13]); + cmd.params[2] |= mc_enc(48, 8, type[14]); + cmd.params[2] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *quota = mc_dec(cmd.params[0], 32, 16); + + return 0; +} + +int dprc_assign(struct fsl_mc_io *mc_io, + uint16_t token, + int container_id, + struct dprc_res_req *res_req) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_ASSIGN, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, container_id); + cmd.params[0] |= mc_enc(32, 32, res_req->options); + cmd.params[1] |= mc_enc(0, 32, res_req->num); + cmd.params[1] |= mc_enc(32, 32, res_req->id_base_align); + cmd.params[2] |= mc_enc(0, 8, res_req->type[0]); + cmd.params[2] |= mc_enc(8, 8, res_req->type[1]); + cmd.params[2] |= mc_enc(16, 8, res_req->type[2]); + cmd.params[2] |= mc_enc(24, 8, res_req->type[3]); + cmd.params[2] |= mc_enc(32, 8, res_req->type[4]); + cmd.params[2] |= mc_enc(40, 8, res_req->type[5]); + cmd.params[2] |= mc_enc(48, 8, res_req->type[6]); + cmd.params[2] |= mc_enc(56, 8, res_req->type[7]); + cmd.params[3] |= mc_enc(0, 8, res_req->type[8]); + cmd.params[3] |= mc_enc(8, 8, res_req->type[9]); + cmd.params[3] |= mc_enc(16, 8, res_req->type[10]); + cmd.params[3] |= mc_enc(24, 8, res_req->type[11]); + cmd.params[3] |= mc_enc(32, 8, res_req->type[12]); + cmd.params[3] |= mc_enc(40, 8, res_req->type[13]); + cmd.params[3] |= mc_enc(48, 8, res_req->type[14]); + cmd.params[3] |= mc_enc(56, 8, res_req->type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_unassign(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + struct dprc_res_req *res_req) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_UNASSIGN, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + cmd.params[0] |= mc_enc(32, 32, res_req->options); + cmd.params[1] |= mc_enc(0, 32, res_req->num); + cmd.params[1] |= mc_enc(32, 32, res_req->id_base_align); + cmd.params[2] |= mc_enc(0, 8, res_req->type[0]); + cmd.params[2] |= mc_enc(8, 8, res_req->type[1]); + cmd.params[2] |= mc_enc(16, 8, res_req->type[2]); + cmd.params[2] |= mc_enc(24, 8, res_req->type[3]); + cmd.params[2] |= mc_enc(32, 8, res_req->type[4]); + cmd.params[2] |= mc_enc(40, 8, res_req->type[5]); + cmd.params[2] |= mc_enc(48, 8, res_req->type[6]); + cmd.params[2] |= mc_enc(56, 8, res_req->type[7]); + cmd.params[3] |= mc_enc(0, 8, res_req->type[8]); + cmd.params[3] |= mc_enc(8, 8, res_req->type[9]); + cmd.params[3] |= mc_enc(16, 8, res_req->type[10]); + cmd.params[3] |= mc_enc(24, 8, res_req->type[11]); + cmd.params[3] |= mc_enc(32, 8, res_req->type[12]); + cmd.params[3] |= mc_enc(40, 8, res_req->type[13]); + cmd.params[3] |= mc_enc(48, 8, res_req->type[14]); + cmd.params[3] |= mc_enc(56, 8, res_req->type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_pool_count(struct fsl_mc_io *mc_io, + uint16_t token, + int *pool_count) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL_COUNT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *pool_count = mc_dec(cmd.params[0], 0, 32); + + return 0; +} + +int dprc_get_pool(struct fsl_mc_io *mc_io, + uint16_t token, + int pool_index, + char *type) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, pool_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + type[0] = mc_dec(cmd.params[1], 0, 8); + type[1] = mc_dec(cmd.params[1], 8, 8); + type[2] = mc_dec(cmd.params[1], 16, 8); + type[3] = mc_dec(cmd.params[1], 24, 8); + type[4] = mc_dec(cmd.params[1], 32, 8); + type[5] = mc_dec(cmd.params[1], 40, 8); + type[6] = mc_dec(cmd.params[1], 48, 8); + type[7] = mc_dec(cmd.params[1], 56, 8); + type[8] = mc_dec(cmd.params[2], 0, 8); + type[9] = mc_dec(cmd.params[2], 8, 8); + type[10] = mc_dec(cmd.params[2], 16, 8); + type[11] = mc_dec(cmd.params[2], 24, 8); + type[12] = mc_dec(cmd.params[2], 32, 8); + type[13] = mc_dec(cmd.params[2], 40, 8); + type[14] = mc_dec(cmd.params[2], 48, 8); + type[15] = '\0'; + + return 0; +} + +int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *obj_count = mc_dec(cmd.params[0], 32, 32); + + return 0; +} +EXPORT_SYMBOL(dprc_get_obj_count); + +int dprc_get_obj(struct fsl_mc_io *mc_io, + uint16_t token, + int obj_index, + struct dprc_obj_desc *obj_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, obj_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + obj_desc->id = mc_dec(cmd.params[0], 32, 32); + obj_desc->vendor = mc_dec(cmd.params[1], 0, 16); + obj_desc->irq_count = mc_dec(cmd.params[1], 16, 8); + obj_desc->region_count = mc_dec(cmd.params[1], 24, 8); + obj_desc->state = mc_dec(cmd.params[1], 32, 32); + obj_desc->ver_major = mc_dec(cmd.params[2], 0, 16); + obj_desc->ver_minor = mc_dec(cmd.params[2], 16, 16); + obj_desc->type[0] = mc_dec(cmd.params[3], 0, 8); + obj_desc->type[1] = mc_dec(cmd.params[3], 8, 8); + obj_desc->type[2] = mc_dec(cmd.params[3], 16, 8); + obj_desc->type[3] = mc_dec(cmd.params[3], 24, 8); + obj_desc->type[4] = mc_dec(cmd.params[3], 32, 8); + obj_desc->type[5] = mc_dec(cmd.params[3], 40, 8); + obj_desc->type[6] = mc_dec(cmd.params[3], 48, 8); + obj_desc->type[7] = mc_dec(cmd.params[3], 56, 8); + obj_desc->type[8] = mc_dec(cmd.params[4], 0, 8); + obj_desc->type[9] = mc_dec(cmd.params[4], 8, 8); + obj_desc->type[10] = mc_dec(cmd.params[4], 16, 8); + obj_desc->type[11] = mc_dec(cmd.params[4], 24, 8); + obj_desc->type[12] = mc_dec(cmd.params[4], 32, 8); + obj_desc->type[13] = mc_dec(cmd.params[4], 40, 8); + obj_desc->type[14] = mc_dec(cmd.params[4], 48, 8); + obj_desc->type[15] = '\0'; + + return 0; +} +EXPORT_SYMBOL(dprc_get_obj); + +int dprc_get_res_count(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + int *res_count) +{ + struct mc_command cmd = { 0 }; + int err; + + *res_count = 0; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_COUNT, + MC_CMD_PRI_LOW, token); + cmd.params[1] |= mc_enc(0, 8, type[0]); + cmd.params[1] |= mc_enc(8, 8, type[1]); + cmd.params[1] |= mc_enc(16, 8, type[2]); + cmd.params[1] |= mc_enc(24, 8, type[3]); + cmd.params[1] |= mc_enc(32, 8, type[4]); + cmd.params[1] |= mc_enc(40, 8, type[5]); + cmd.params[1] |= mc_enc(48, 8, type[6]); + cmd.params[1] |= mc_enc(56, 8, type[7]); + cmd.params[2] |= mc_enc(0, 8, type[8]); + cmd.params[2] |= mc_enc(8, 8, type[9]); + cmd.params[2] |= mc_enc(16, 8, type[10]); + cmd.params[2] |= mc_enc(24, 8, type[11]); + cmd.params[2] |= mc_enc(32, 8, type[12]); + cmd.params[2] |= mc_enc(40, 8, type[13]); + cmd.params[2] |= mc_enc(48, 8, type[14]); + cmd.params[2] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *res_count = mc_dec(cmd.params[0], 0, 32); + + return 0; +} +EXPORT_SYMBOL(dprc_get_res_count); + +int dprc_get_res_ids(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + struct dprc_res_ids_range_desc *range_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_IDS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(42, 7, range_desc->iter_status); + cmd.params[1] |= mc_enc(0, 32, range_desc->base_id); + cmd.params[1] |= mc_enc(32, 32, range_desc->last_id); + cmd.params[2] |= mc_enc(0, 8, type[0]); + cmd.params[2] |= mc_enc(8, 8, type[1]); + cmd.params[2] |= mc_enc(16, 8, type[2]); + cmd.params[2] |= mc_enc(24, 8, type[3]); + cmd.params[2] |= mc_enc(32, 8, type[4]); + cmd.params[2] |= mc_enc(40, 8, type[5]); + cmd.params[2] |= mc_enc(48, 8, type[6]); + cmd.params[2] |= mc_enc(56, 8, type[7]); + cmd.params[3] |= mc_enc(0, 8, type[8]); + cmd.params[3] |= mc_enc(8, 8, type[9]); + cmd.params[3] |= mc_enc(16, 8, type[10]); + cmd.params[3] |= mc_enc(24, 8, type[11]); + cmd.params[3] |= mc_enc(32, 8, type[12]); + cmd.params[3] |= mc_enc(40, 8, type[13]); + cmd.params[3] |= mc_enc(48, 8, type[14]); + cmd.params[3] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + range_desc->iter_status = mc_dec(cmd.params[0], 42, 7); + range_desc->base_id = mc_dec(cmd.params[1], 0, 32); + range_desc->last_id = mc_dec(cmd.params[1], 32, 32); + + return 0; +} +EXPORT_SYMBOL(dprc_get_res_ids); + +int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, + uint16_t token, + int portal_id, + uint64_t *portal_addr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_PORTAL_PADDR, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, portal_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *portal_addr = mc_dec(cmd.params[1], 0, 64); + + return 0; +} +EXPORT_SYMBOL(dprc_get_portal_paddr); + +int dprc_get_obj_region(struct fsl_mc_io *mc_io, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t region_index, + struct dprc_region_desc *region_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, obj_id); + cmd.params[0] |= mc_enc(48, 8, region_index); + cmd.params[3] |= mc_enc(0, 8, obj_type[0]); + cmd.params[3] |= mc_enc(8, 8, obj_type[1]); + cmd.params[3] |= mc_enc(16, 8, obj_type[2]); + cmd.params[3] |= mc_enc(24, 8, obj_type[3]); + cmd.params[3] |= mc_enc(32, 8, obj_type[4]); + cmd.params[3] |= mc_enc(40, 8, obj_type[5]); + cmd.params[3] |= mc_enc(48, 8, obj_type[6]); + cmd.params[3] |= mc_enc(56, 8, obj_type[7]); + cmd.params[4] |= mc_enc(0, 8, obj_type[8]); + cmd.params[4] |= mc_enc(8, 8, obj_type[9]); + cmd.params[4] |= mc_enc(16, 8, obj_type[10]); + cmd.params[4] |= mc_enc(24, 8, obj_type[11]); + cmd.params[4] |= mc_enc(32, 8, obj_type[12]); + cmd.params[4] |= mc_enc(40, 8, obj_type[13]); + cmd.params[4] |= mc_enc(48, 8, obj_type[14]); + cmd.params[4] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + region_desc->base_paddr = mc_dec(cmd.params[1], 0, 64); + region_desc->size = mc_dec(cmd.params[2], 0, 32); + + return 0; +} +EXPORT_SYMBOL(dprc_get_obj_region); + +int dprc_connect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + const struct dprc_endpoint *endpoint2) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, endpoint1->id); + cmd.params[0] |= mc_enc(32, 32, endpoint1->interface_id); + cmd.params[1] |= mc_enc(0, 32, endpoint2->id); + cmd.params[1] |= mc_enc(32, 32, endpoint2->interface_id); + cmd.params[2] |= mc_enc(0, 8, endpoint1->type[0]); + cmd.params[2] |= mc_enc(8, 8, endpoint1->type[1]); + cmd.params[2] |= mc_enc(16, 8, endpoint1->type[2]); + cmd.params[2] |= mc_enc(24, 8, endpoint1->type[3]); + cmd.params[2] |= mc_enc(32, 8, endpoint1->type[4]); + cmd.params[2] |= mc_enc(40, 8, endpoint1->type[5]); + cmd.params[2] |= mc_enc(48, 8, endpoint1->type[6]); + cmd.params[2] |= mc_enc(56, 8, endpoint1->type[7]); + cmd.params[3] |= mc_enc(0, 8, endpoint1->type[8]); + cmd.params[3] |= mc_enc(8, 8, endpoint1->type[9]); + cmd.params[3] |= mc_enc(16, 8, endpoint1->type[10]); + cmd.params[3] |= mc_enc(24, 8, endpoint1->type[11]); + cmd.params[3] |= mc_enc(32, 8, endpoint1->type[12]); + cmd.params[3] |= mc_enc(40, 8, endpoint1->type[13]); + cmd.params[3] |= mc_enc(48, 8, endpoint1->type[14]); + cmd.params[3] |= mc_enc(56, 8, endpoint1->type[15]); + cmd.params[5] |= mc_enc(0, 8, endpoint2->type[0]); + cmd.params[5] |= mc_enc(8, 8, endpoint2->type[1]); + cmd.params[5] |= mc_enc(16, 8, endpoint2->type[2]); + cmd.params[5] |= mc_enc(24, 8, endpoint2->type[3]); + cmd.params[5] |= mc_enc(32, 8, endpoint2->type[4]); + cmd.params[5] |= mc_enc(40, 8, endpoint2->type[5]); + cmd.params[5] |= mc_enc(48, 8, endpoint2->type[6]); + cmd.params[5] |= mc_enc(56, 8, endpoint2->type[7]); + cmd.params[6] |= mc_enc(0, 8, endpoint2->type[8]); + cmd.params[6] |= mc_enc(8, 8, endpoint2->type[9]); + cmd.params[6] |= mc_enc(16, 8, endpoint2->type[10]); + cmd.params[6] |= mc_enc(24, 8, endpoint2->type[11]); + cmd.params[6] |= mc_enc(32, 8, endpoint2->type[12]); + cmd.params[6] |= mc_enc(40, 8, endpoint2->type[13]); + cmd.params[6] |= mc_enc(48, 8, endpoint2->type[14]); + cmd.params[6] |= mc_enc(56, 8, endpoint2->type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_disconnect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, endpoint->id); + cmd.params[0] |= mc_enc(32, 32, endpoint->interface_id); + cmd.params[1] |= mc_enc(0, 8, endpoint->type[0]); + cmd.params[1] |= mc_enc(8, 8, endpoint->type[1]); + cmd.params[1] |= mc_enc(16, 8, endpoint->type[2]); + cmd.params[1] |= mc_enc(24, 8, endpoint->type[3]); + cmd.params[1] |= mc_enc(32, 8, endpoint->type[4]); + cmd.params[1] |= mc_enc(40, 8, endpoint->type[5]); + cmd.params[1] |= mc_enc(48, 8, endpoint->type[6]); + cmd.params[1] |= mc_enc(56, 8, endpoint->type[7]); + cmd.params[2] |= mc_enc(0, 8, endpoint->type[8]); + cmd.params[2] |= mc_enc(8, 8, endpoint->type[9]); + cmd.params[2] |= mc_enc(16, 8, endpoint->type[10]); + cmd.params[2] |= mc_enc(24, 8, endpoint->type[11]); + cmd.params[2] |= mc_enc(32, 8, endpoint->type[12]); + cmd.params[2] |= mc_enc(40, 8, endpoint->type[13]); + cmd.params[2] |= mc_enc(48, 8, endpoint->type[14]); + cmd.params[2] |= mc_enc(56, 8, endpoint->type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_connection(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + struct dprc_endpoint *endpoint2, + int *state) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, endpoint1->id); + cmd.params[0] |= mc_enc(32, 32, endpoint1->interface_id); + cmd.params[1] |= mc_enc(0, 8, endpoint1->type[0]); + cmd.params[1] |= mc_enc(8, 8, endpoint1->type[1]); + cmd.params[1] |= mc_enc(16, 8, endpoint1->type[2]); + cmd.params[1] |= mc_enc(24, 8, endpoint1->type[3]); + cmd.params[1] |= mc_enc(32, 8, endpoint1->type[4]); + cmd.params[1] |= mc_enc(40, 8, endpoint1->type[5]); + cmd.params[1] |= mc_enc(48, 8, endpoint1->type[6]); + cmd.params[1] |= mc_enc(56, 8, endpoint1->type[7]); + cmd.params[2] |= mc_enc(0, 8, endpoint1->type[8]); + cmd.params[2] |= mc_enc(8, 8, endpoint1->type[9]); + cmd.params[2] |= mc_enc(16, 8, endpoint1->type[10]); + cmd.params[2] |= mc_enc(24, 8, endpoint1->type[11]); + cmd.params[2] |= mc_enc(32, 8, endpoint1->type[12]); + cmd.params[2] |= mc_enc(40, 8, endpoint1->type[13]); + cmd.params[2] |= mc_enc(48, 8, endpoint1->type[14]); + cmd.params[2] |= mc_enc(56, 8, endpoint1->type[15]); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + endpoint2->id = mc_dec(cmd.params[3], 0, 32); + endpoint2->interface_id = mc_dec(cmd.params[3], 32, 32); + endpoint2->type[0] = mc_dec(cmd.params[4], 0, 8); + endpoint2->type[1] = mc_dec(cmd.params[4], 8, 8); + endpoint2->type[2] = mc_dec(cmd.params[4], 16, 8); + endpoint2->type[3] = mc_dec(cmd.params[4], 24, 8); + endpoint2->type[4] = mc_dec(cmd.params[4], 32, 8); + endpoint2->type[5] = mc_dec(cmd.params[4], 40, 8); + endpoint2->type[6] = mc_dec(cmd.params[4], 48, 8); + endpoint2->type[7] = mc_dec(cmd.params[4], 56, 8); + endpoint2->type[8] = mc_dec(cmd.params[5], 0, 8); + endpoint2->type[9] = mc_dec(cmd.params[5], 8, 8); + endpoint2->type[10] = mc_dec(cmd.params[5], 16, 8); + endpoint2->type[11] = mc_dec(cmd.params[5], 24, 8); + endpoint2->type[12] = mc_dec(cmd.params[5], 32, 8); + endpoint2->type[13] = mc_dec(cmd.params[5], 40, 8); + endpoint2->type[14] = mc_dec(cmd.params[5], 48, 8); + endpoint2->type[15] = mc_dec(cmd.params[5], 56, 8); + *state = mc_dec(cmd.params[6], 0, 32); + + return 0; +} diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c new file mode 100644 index 0000000..85ca5f9 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/mc-sys.c @@ -0,0 +1,283 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. + * + * I/O services to send MC commands to the MC hardware + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "../include/mc-sys.h" +#include "../include/fsl/mc-cmd.h" +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/ioport.h> +#include <linux/device.h> + +/** + * Timeout in jiffies to wait for the completion of an MC command + */ +#define MC_CMD_COMPLETION_TIMEOUT_JIFFIES (HZ / 2) /* 500 ms */ + +/* + * usleep_range() min and max values used to throttle down polling + * iterations while waiting for MC command completion + */ +#define MC_CMD_COMPLETION_POLLING_MIN_SLEEP_USECS 10 +#define MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS 500 + +#define MC_CMD_HDR_READ_CMDID(_hdr) \ + ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S)) + +/** + * Creates an MC I/O object + * + * @dev: device to be associated with the MC I/O object + * @mc_portal_phys_addr: physical address of the MC portal to use + * @mc_portal_size: size in bytes of the MC portal + * @flags: flags for the new MC I/O object + * @new_mc_io: Area to return pointer to newly created MC I/O object + * + * Returns '0' on Success; Error code otherwise. + */ +int __must_check fsl_create_mc_io(struct device *dev, + phys_addr_t mc_portal_phys_addr, + uint32_t mc_portal_size, + uint32_t flags, struct fsl_mc_io **new_mc_io) +{ + struct fsl_mc_io *mc_io; + void __iomem *mc_portal_virt_addr; + struct resource *res; + + mc_io = devm_kzalloc(dev, sizeof(*mc_io), GFP_KERNEL); + if (!mc_io) + return -ENOMEM; + + mc_io->dev = dev; + mc_io->flags = flags; + mc_io->portal_phys_addr = mc_portal_phys_addr; + mc_io->portal_size = mc_portal_size; + res = devm_request_mem_region(dev, + mc_portal_phys_addr, + mc_portal_size, + "mc_portal"); + if (!res) { + dev_err(dev, + "devm_request_mem_region failed for MC portal %#llx\n", + mc_portal_phys_addr); + return -EBUSY; + } + + mc_portal_virt_addr = devm_ioremap_nocache(dev, + mc_portal_phys_addr, + mc_portal_size); + if (!mc_portal_virt_addr) { + dev_err(dev, + "devm_ioremap_nocache failed for MC portal %#llx\n", + mc_portal_phys_addr); + return -ENXIO; + } + + mc_io->portal_virt_addr = mc_portal_virt_addr; + *new_mc_io = mc_io; + return 0; +} +EXPORT_SYMBOL_GPL(fsl_create_mc_io); + +/** + * Destroys an MC I/O object + * + * @mc_io: MC I/O object to destroy + */ +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io) +{ + devm_iounmap(mc_io->dev, mc_io->portal_virt_addr); + devm_release_mem_region(mc_io->dev, + mc_io->portal_phys_addr, + mc_io->portal_size); + + mc_io->portal_virt_addr = NULL; + devm_kfree(mc_io->dev, mc_io); +} +EXPORT_SYMBOL_GPL(fsl_destroy_mc_io); + +static int mc_status_to_error(enum mc_cmd_status status) +{ + static const int mc_status_to_error_map[] = { + [MC_CMD_STATUS_OK] = 0, + [MC_CMD_STATUS_AUTH_ERR] = -EACCES, + [MC_CMD_STATUS_NO_PRIVILEGE] = -EPERM, + [MC_CMD_STATUS_DMA_ERR] = -EIO, + [MC_CMD_STATUS_CONFIG_ERR] = -ENXIO, + [MC_CMD_STATUS_TIMEOUT] = -ETIMEDOUT, + [MC_CMD_STATUS_NO_RESOURCE] = -ENAVAIL, + [MC_CMD_STATUS_NO_MEMORY] = -ENOMEM, + [MC_CMD_STATUS_BUSY] = -EBUSY, + [MC_CMD_STATUS_UNSUPPORTED_OP] = -ENOTSUPP, + [MC_CMD_STATUS_INVALID_STATE] = -ENODEV, + }; + + if (WARN_ON((u32)status >= ARRAY_SIZE(mc_status_to_error_map))) + return -EINVAL; + + return mc_status_to_error_map[status]; +} + +static const char *mc_status_to_string(enum mc_cmd_status status) +{ + static const char *const status_strings[] = { + [MC_CMD_STATUS_OK] = "Command completed successfully", + [MC_CMD_STATUS_READY] = "Command ready to be processed", + [MC_CMD_STATUS_AUTH_ERR] = "Authentication error", + [MC_CMD_STATUS_NO_PRIVILEGE] = "No privilege", + [MC_CMD_STATUS_DMA_ERR] = "DMA or I/O error", + [MC_CMD_STATUS_CONFIG_ERR] = "Configuration error", + [MC_CMD_STATUS_TIMEOUT] = "Operation timed out", + [MC_CMD_STATUS_NO_RESOURCE] = "No resources", + [MC_CMD_STATUS_NO_MEMORY] = "No memory available", + [MC_CMD_STATUS_BUSY] = "Device is busy", + [MC_CMD_STATUS_UNSUPPORTED_OP] = "Unsupported operation", + [MC_CMD_STATUS_INVALID_STATE] = "Invalid state" + }; + + if ((unsigned int)status >= ARRAY_SIZE(status_strings)) + return "Unknown MC error"; + + return status_strings[status]; +} + +/** + * mc_write_command - writes a command to a Management Complex (MC) portal + * + * @portal: pointer to an MC portal + * @cmd: pointer to a filled command + */ +static inline void mc_write_command(struct mc_command __iomem *portal, + struct mc_command *cmd) +{ + int i; + + /* copy command parameters into the portal */ + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++) + writeq(cmd->params[i], &portal->params[i]); + + /* submit the command by writing the header */ + writeq(cmd->header, &portal->header); +} + +/** + * mc_read_response - reads the response for the last MC command from a + * Management Complex (MC) portal + * + * @portal: pointer to an MC portal + * @resp: pointer to command response buffer + * + * Returns MC_CMD_STATUS_OK on Success; Error code otherwise. + */ +static inline enum mc_cmd_status mc_read_response(struct mc_command __iomem * + portal, + struct mc_command *resp) +{ + int i; + enum mc_cmd_status status; + + /* Copy command response header from MC portal: */ + resp->header = readq(&portal->header); + status = MC_CMD_HDR_READ_STATUS(resp->header); + if (status != MC_CMD_STATUS_OK) + return status; + + /* Copy command response data from MC portal: */ + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++) + resp->params[i] = readq(&portal->params[i]); + + return status; +} + +/** + * Sends an command to the MC device using the given MC I/O object + * + * @mc_io: MC I/O object to be used + * @cmd: command to be sent + * + * Returns '0' on Success; Error code otherwise. + * + * NOTE: This function cannot be invoked from from atomic contexts. + */ +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) +{ + enum mc_cmd_status status; + unsigned long jiffies_until_timeout = + jiffies + MC_CMD_COMPLETION_TIMEOUT_JIFFIES; + + /* + * Send command to the MC hardware: + */ + mc_write_command(mc_io->portal_virt_addr, cmd); + + /* + * Wait for response from the MC hardware: + */ + for (;;) { + status = mc_read_response(mc_io->portal_virt_addr, cmd); + if (status != MC_CMD_STATUS_READY) + break; + + /* + * TODO: When MC command completion interrupts are supported + * call wait function here instead of usleep_range() + */ + usleep_range(MC_CMD_COMPLETION_POLLING_MIN_SLEEP_USECS, + MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS); + + if (time_after_eq(jiffies, jiffies_until_timeout)) { + pr_debug("MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n", + mc_io->portal_phys_addr, + (unsigned int) + MC_CMD_HDR_READ_TOKEN(cmd->header), + (unsigned int) + MC_CMD_HDR_READ_CMDID(cmd->header)); + + return -ETIMEDOUT; + } + } + + if (status != MC_CMD_STATUS_OK) { + pr_debug("MC command failed: portal: %#llx, obj handle: %#x, command: %#x, status: %s (%#x)\n", + mc_io->portal_phys_addr, + (unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header), + (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header), + mc_status_to_string(status), + (unsigned int)status); + + return mc_status_to_error(status); + } + + return 0; +} +EXPORT_SYMBOL(mc_send_command); diff --git a/drivers/staging/fsl-mc/include/dpmng.h b/drivers/staging/fsl-mc/include/dpmng.h new file mode 100644 index 0000000..0fc0a57 --- /dev/null +++ b/drivers/staging/fsl-mc/include/dpmng.h @@ -0,0 +1,80 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_DPMNG_H +#define __FSL_DPMNG_H + +/* Management Complex General API + * Contains general API for the Management Complex firmware + */ + +struct fsl_mc_io; + +/** + * Management Complex firmware version information + */ +#define MC_VER_MAJOR 5 +#define MC_VER_MINOR 0 + +/** + * struct mc_versoin + * @major: Major version number: incremented on API compatibility changes + * @minor: Minor version number: incremented on API additions (that are + * backward compatible); reset when major version is incremented + * @revision: Internal revision number: incremented on implementation changes + * and/or bug fixes that have no impact on API + */ +struct mc_version { + uint32_t major; + uint32_t minor; + uint32_t revision; +}; + +/** + * mc_get_version() - Retrieves the Management Complex firmware + * version information + * @mc_io: Pointer to opaque I/O object + * @mc_ver_info: Returned version information structure + * + * Return: '0' on Success; Error code otherwise. + */ +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info); + +/** + * dpmng_get_container_id() - Get container ID associated with a given portal. + * @mc_io: Pointer to MC portal's I/O object + * @container_id: Requested container ID + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmng_get_container_id(struct fsl_mc_io *mc_io, int *container_id); + +#endif /* __FSL_DPMNG_H */ diff --git a/drivers/staging/fsl-mc/include/dprc.h b/drivers/staging/fsl-mc/include/dprc.h new file mode 100644 index 0000000..f1862a7 --- /dev/null +++ b/drivers/staging/fsl-mc/include/dprc.h @@ -0,0 +1,801 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_DPRC_H +#define _FSL_DPRC_H + +/* Data Path Resource Container API + * Contains DPRC API for managing and querying DPAA resources + */ + +struct fsl_mc_io; + +/** + * Set this value as the icid value in dprc_cfg structure when creating a + * container, in case the ICID is not selected by the user and should be + * allocated by the DPRC from the pool of ICIDs. + */ +#define DPRC_GET_ICID_FROM_POOL (uint16_t)(~(0)) + +/** + * Set this value as the portal_id value in dprc_cfg structure when creating a + * container, in case the portal ID is not specifically selected by the + * user and should be allocated by the DPRC from the pool of portal ids. + */ +#define DPRC_GET_PORTAL_ID_FROM_POOL (int)(~(0)) + +/** + * dprc_open() - Open DPRC object for use + * @mc_io: Pointer to MC portal's I/O object + * @container_id: Container ID to open + * @token: Returned token of DPRC object + * + * Return: '0' on Success; Error code otherwise. + * + * @warning Required before any operation on the object. + */ +int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token); + +/** + * dprc_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * Container general options + * + * These options may be selected at container creation by the container creator + * and can be retrieved using dprc_get_attributes() + */ + +/* Spawn Policy Option allowed - Indicates that the new container is allowed + * to spawn and have its own child containers. + */ +#define DPRC_CFG_OPT_SPAWN_ALLOWED 0x00000001 + +/* General Container allocation policy - Indicates that the new container is + * allowed to allocate requested resources from its parent container; if not + * set, the container is only allowed to use resources in its own pools; Note + * that this is a container's global policy, but the parent container may + * override it and set specific quota per resource type. + */ +#define DPRC_CFG_OPT_ALLOC_ALLOWED 0x00000002 + +/* Object initialization allowed - software context associated with this + * container is allowed to invoke object initialization operations. + */ +#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 + +/* Topology change allowed - software context associated with this + * container is allowed to invoke topology operations, such as attach/detach + * of network objects. + */ +#define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED 0x00000008 + +/* IOMMU bypass - indicates whether objects of this container are permitted + * to bypass the IOMMU. + */ +#define DPRC_CFG_OPT_IOMMU_BYPASS 0x00000010 + +/* AIOP - Indicates that container belongs to AIOP. */ +#define DPRC_CFG_OPT_AIOP 0x00000020 + +/** + * struct dprc_cfg - Container configuration options + * @icid: Container's ICID; if set to 'DPRC_GET_ICID_FROM_POOL', a free + * ICID value is allocated by the DPRC + * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free + * portal ID is allocated by the DPRC + * @options: Combination of 'DPRC_CFG_OPT_<X>' options + */ +struct dprc_cfg { + uint16_t icid; + int portal_id; + uint64_t options; +}; + +/** + * dprc_create_container() - Create child container + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @cfg: Child container configuration + * @child_container_id: Returned child container ID + * @child_portal_paddr: Returned base physical address of the + * child portal + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_create_container(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_cfg *cfg, + int *child_container_id, + uint64_t *child_portal_paddr); + +/** + * dprc_destroy_container() - Destroy child container. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id: ID of the container to destroy + * + * This function terminates the child container, so following this call the + * child container ID becomes invalid. + * + * Notes: + * - All resources and objects of the destroyed container are returned to the + * parent container or destroyed if were created be the destroyed container. + * - This function destroy all the child containers of the specified + * container prior to destroying the container itself. + * + * warning: Only the parent container is allowed to destroy a child policy + * Container 0 can't be destroyed + * + * Return: '0' on Success; Error code otherwise. + * + */ +int dprc_destroy_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id); + +/** + * dprc_reset_container - Reset child container. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id: ID of the container to reset + * + * In case a software context crashes or becomes non-responsive, the parent + * may wish to reset its resources container before the software context is + * restarted. + * + * This routine informs all objects assigned to the child container that the + * container is being reset, so they may perform any cleanup operations that are + * needed. All objects handles that were owned by the child container shall be + * closed. + * + * Note that such request may be submitted even if the child software context + * has not crashed, but the resulting object cleanup operations will not be + * aware of that. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_reset_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id); + +/* IRQ */ + +/* Number of dprc's IRQs */ +#define DPRC_NUM_OF_IRQS 1 + +/* Object irq events */ + +/* IRQ event - Indicates that a new object assigned to the container */ +#define DPRC_IRQ_EVENT_OBJ_ADDED 0x00000001 +/* IRQ event - Indicates that an object was unassigned from the container */ +#define DPRC_IRQ_EVENT_OBJ_REMOVED 0x00000002 +/* IRQ event - Indicates that resources assigned to the container */ +#define DPRC_IRQ_EVENT_RES_ADDED 0x00000004 +/* IRQ event - Indicates that resources unassigned from the container */ +#define DPRC_IRQ_EVENT_RES_REMOVED 0x00000008 +/* IRQ event - Indicates that one of the descendant containers that opened by + * this container is destroyed + */ +#define DPRC_IRQ_EVENT_CONTAINER_DESTROYED 0x00000010 + +/* IRQ event - Indicates that on one of the container's opened object is + * destroyed + */ +#define DPRC_IRQ_EVENT_OBJ_DESTROYED 0x00000020 + +/* Irq event - Indicates that object is created at the container */ +#define DPRC_IRQ_EVENT_OBJ_CREATED 0x00000040 + +/** + * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: Identifies the interrupt index to configure + * @irq_addr: Address that must be written to + * signal a message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: Returned a user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_set_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint64_t irq_addr, + uint32_t irq_val, + int user_irq_id); + +/** + * dprc_get_irq() - Get IRQ information from the DPRC. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @type: Returned interrupt type: 0 represents message interrupt + * type (both irq_addr and irq_val are valid) + * @irq_addr: Returned address that must be written to + * signal the message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: A user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + int *type, + uint64_t *irq_addr, + uint32_t *irq_val, + int *user_irq_id); + +/** + * dprc_set_irq_enable() - Set overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @en: Interrupt state - enable = 1, disable = 0 + * + * Allows GPP software to control when interrupts are generated. + * Each interrupt can have up to 32 causes. The enable/disable control's the + * overall interrupt state. if the interrupt is disabled no causes will cause + * an interrupt. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_set_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t en); + +/** + * dprc_get_irq_enable() - Get overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @en: Returned interrupt state - enable = 1, disable = 0 + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t *en); + +/** + * dprc_set_irq_mask() - Set interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @mask: event mask to trigger interrupt; + * each bit: + * 0 = ignore event + * 1 = consider event for asserting irq + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_set_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t mask); + +/** + * dprc_get_irq_mask() - Get interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @mask: Returned event mask to trigger interrupt + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *mask); + +/** + * dprc_get_irq_status() - Get the current status of any pending interrupts. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @status: Returned interrupts status - one bit per cause: + * 0 = no interrupt pending + * 1 = interrupt pending + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *status); + +/** + * dprc_clear_irq_status() - Clear a pending interrupt's status + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @status: bits to clear (W1C) - one bit per cause: + * 0 = don't change + * 1 = clear status bit + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_clear_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t status); + +/** + * struct dprc_attributes - Container attributes + * @container_id: Container's ID + * @icid: Container's ICID + * @portal_id: Container's portal ID + * @options: Container's options as set at container's creation + * @version: DPRC version + */ +struct dprc_attributes { + int container_id; + uint16_t icid; + int portal_id; + uint64_t options; + /** + * struct version - DPRC version + * @major: DPRC major version + * @minor: DPRC minor version + */ + struct { + uint16_t major; + uint16_t minor; + } version; +}; + +/** + * dprc_get_attributes() - Obtains container attributes + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @attributes Returned container attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_attributes *attributes); + +/** + * dprc_set_res_quota() - Set allocation policy for a specific resource/object + * type in a child container + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id: ID of the child container + * @type: Resource/object type + * @quota: Sets the maximum number of resources of the selected type + * that the child container is allowed to allocate from its parent; + * when quota is set to -1, the policy is the same as container's + * general policy. + * + * Allocation policy determines whether or not a container may allocate + * resources from its parent. Each container has a 'global' allocation policy + * that is set when the container is created. + * + * This function sets allocation policy for a specific resource type. + * The default policy for all resource types matches the container's 'global' + * allocation policy. + * + * Return: '0' on Success; Error code otherwise. + * + * @warning Only the parent container is allowed to change a child policy. + */ +int dprc_set_res_quota(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + char *type, + uint16_t quota); + +/** + * dprc_get_res_quota() - Gets the allocation policy of a specific + * resource/object type in a child container + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id; ID of the child container + * @type: resource/object type + * @quota: Returnes the maximum number of resources of the selected type + * that the child container is allowed to allocate from the parent; + * when quota is set to -1, the policy is the same as container's + * general policy. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_res_quota(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + char *type, + uint16_t *quota); + +/* Resource request options */ + +/* Explicit resource ID request - The requested objects/resources + * are explicit and sequential (in case of resources). + * The base ID is given at res_req at base_align field + */ +#define DPRC_RES_REQ_OPT_EXPLICIT 0x00000001 + +/* Aligned resources request - Relevant only for resources + * request (and not objects). Indicates that resources base ID should be + * sequential and aligned to the value given at dprc_res_req base_align field + */ +#define DPRC_RES_REQ_OPT_ALIGNED 0x00000002 + +/* Plugged Flag - Relevant only for object assignment request. + * Indicates that after all objects assigned. An interrupt will be invoked at + * the relevant GPP. The assigned object will be marked as plugged. + * plugged objects can't be assigned from their container + */ +#define DPRC_RES_REQ_OPT_PLUGGED 0x00000004 + +/** + * struct dprc_res_req - Resource request descriptor, to be used in assignment + * or un-assignment of resources and objects. + * @type: Resource/object type: Represent as a NULL terminated string. + * This string may received by using dprc_get_pool() to get resource + * type and dprc_get_obj() to get object type; + * Note: it is not possible to assign/un-assign DPRC objects + * @num: Number of resources + * @options: Request options: combination of DPRC_RES_REQ_OPT_ options + * @id_base_align: In case of explicit assignment (DPRC_RES_REQ_OPT_EXPLICIT + * is set at option), this field represents the required base ID + * for resource allocation; In case of aligned assignment + * (DPRC_RES_REQ_OPT_ALIGNED is set at option), this field + * indicates the required alignment for the resource ID(s) - + * use 0 if there is no alignment or explicit ID requirements + */ +struct dprc_res_req { + char type[16]; + uint32_t num; + uint32_t options; + int id_base_align; +}; + +/** + * dprc_assign() - Assigns objects or resource to a child container. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @container_id: ID of the child container + * @res_req: Describes the type and amount of resources to + * assign to the given container + * + * Assignment is usually done by a parent (this DPRC) to one of its child + * containers. + * + * According to the DPRC allocation policy, the assigned resources may be taken + * (allocated) from the container's ancestors, if not enough resources are + * available in the container itself. + * + * The type of assignment depends on the dprc_res_req options, as follows: + * - DPRC_RES_REQ_OPT_EXPLICIT: indicates that assigned resources should have + * the explicit base ID specified at the id_base_align field of res_req. + * - DPRC_RES_REQ_OPT_ALIGNED: indicates that the assigned resources should be + * aligned to the value given at id_base_align field of res_req. + * - DPRC_RES_REQ_OPT_PLUGGED: Relevant only for object assignment, + * and indicates that the object must be set to the plugged state. + * + * A container may use this function with its own ID in order to change a + * object state to plugged or unplugged. + * + * If IRQ information has been set in the child DPRC, it will signal an + * interrupt following every change in its object assignment. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_assign(struct fsl_mc_io *mc_io, + uint16_t token, + int container_id, + struct dprc_res_req *res_req); + +/** + * dprc_unassign() - Un-assigns objects or resources from a child container + * and moves them into this (parent) DPRC. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id: ID of the child container + * @res_req: Describes the type and amount of resources to un-assign from + * the child container + * + * Un-assignment of objects can succeed only if the object is not in the + * plugged or opened state. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_unassign(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + struct dprc_res_req *res_req); + +/** + * dprc_get_pool_count() - Get the number of dprc's pools + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @pool_count: Returned number of resource pools in the dprc + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_pool_count(struct fsl_mc_io *mc_io, + uint16_t token, + int *pool_count); + +/** + * dprc_get_pool() - Get the type (string) of a certain dprc's pool + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @pool_index; Index of the pool to be queried (< pool_count) + * @type: The type of the pool + * + * The pool types retrieved one by one by incrementing + * pool_index up to (not including) the value of pool_count returned + * from dprc_get_pool_count(). dprc_get_pool_count() must + * be called prior to dprc_get_pool(). + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_pool(struct fsl_mc_io *mc_io, + uint16_t token, + int pool_index, + char *type); + +/** + * dprc_get_obj_count() - Obtains the number of objects in the DPRC + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_count: Number of objects assigned to the DPRC + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count); + +/* Objects Attributes Flags */ + +/* Opened state - Indicates that an object is open by at least one owner */ +#define DPRC_OBJ_STATE_OPEN 0x00000001 +/* Plugged state - Indicates that the object is plugged */ +#define DPRC_OBJ_STATE_PLUGGED 0x00000002 + +/** + * struct dprc_obj_desc - Object descriptor, returned from dprc_get_obj() + * @type: Type of object: NULL terminated string + * @id: ID of logical object resource + * @vendor: Object vendor identifier + * @ver_major: Major version number + * @ver_minor: Minor version number + * @irq_count: Number of interrupts supported by the object + * @region_count: Number of mappable regions supported by the object + * @state: Object state: combination of DPRC_OBJ_STATE_ states + */ +struct dprc_obj_desc { + char type[16]; + int id; + uint16_t vendor; + uint16_t ver_major; + uint16_t ver_minor; + uint8_t irq_count; + uint8_t region_count; + uint32_t state; +}; + +/** + * dprc_get_obj() - Get general information on an object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_index: Index of the object to be queried (< obj_count) + * @obj_desc: Returns the requested object descriptor + * + * The object descriptors are retrieved one by one by incrementing + * obj_index up to (not including) the value of obj_count returned + * from dprc_get_obj_count(). dprc_get_obj_count() must + * be called prior to dprc_get_obj(). + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj(struct fsl_mc_io *mc_io, + uint16_t token, + int obj_index, + struct dprc_obj_desc *obj_desc); + +/** + * dprc_get_res_count() - Obtains the number of free resources that are assigned + * to this container, by pool type + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @type: pool type + * @res_count: Returned number of free resources of the given + * resource type that are assigned to this DPRC + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_res_count(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + int *res_count); + +/** + * enum dprc_iter_status - Iteration status + * @DPRC_ITER_STATUS_FIRST: Perform first iteration + * @DPRC_ITER_STATUS_MORE: Indicates more/next iteration is needed + * @DPRC_ITER_STATUS_LAST: Indicates last iteration + */ +enum dprc_iter_status { + DPRC_ITER_STATUS_FIRST = 0, + DPRC_ITER_STATUS_MORE = 1, + DPRC_ITER_STATUS_LAST = 2 +}; + +/** + * struct dprc_res_ids_range_desc - Resource ID range descriptor + * @base_id: Base resource ID of this range + * @last_id: Last resource ID of this range + * @iter_status: Iteration status - should be set to DPRC_ITER_STATUS_FIRST at + * first iteration; while the returned marker is DPRC_ITER_STATUS_MORE, + * additional iterations are needed, until the returned marker is + * DPRC_ITER_STATUS_LAST + */ +struct dprc_res_ids_range_desc { + int base_id; + int last_id; + enum dprc_iter_status iter_status; +}; + +/** + * dprc_get_res_ids() - Obtains IDs of free resources in the container + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @type: pool type + * @range_desc: range descriptor + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_res_ids(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + struct dprc_res_ids_range_desc *range_desc); + +/** + * dprc_get_portal_paddr() - Get the physical address of MC portals + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @portal_id: MC portal ID + * @portal_addr: The physical address of the MC portal ID + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, + uint16_t token, + int portal_id, + uint64_t *portal_addr); + +/** + * struct dprc_region_desc - Mappable region descriptor + * @base_paddr: Region base physical address + * @size: Region size (in bytes) + */ +struct dprc_region_desc { + uint64_t base_paddr; + uint32_t size; +}; + +/** + * dprc_get_obj_region() - Get region information for a specified object. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_type; Object type as returned in dprc_get_obj() + * @obj_id: Unique object instance as returned in dprc_get_obj() + * @region_index: The specific region to query + * @region_desc: Returns the requested region descriptor + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj_region(struct fsl_mc_io *mc_io, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t region_index, + struct dprc_region_desc *region_desc); + +/** + * struct dprc_endpoint - Endpoint description for link connect/disconnect + * operations + * @type: Endpoint object type: NULL terminated string + * @id: Endpoint object ID + * @interface_id: Interface ID; should be set for endpoints with multiple + * interfaces ("dpsw", "dpdmux"); for others, always set to 0 + */ +struct dprc_endpoint { + char type[16]; + int id; + int interface_id; +}; + +/** + * dprc_connect() - Connect two endpoints to create a network link between them + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @endpoint1: Endpoint 1 configuration parameters + * @endpoint2: Endpoint 2 configuration parameters + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_connect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + const struct dprc_endpoint *endpoint2); + +/** + * dprc_disconnect() - Disconnect one endpoint to remove its network connection + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @endpoint: Endpoint configuration parameters + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_disconnect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint); + +/** +* dprc_get_connection() - Get connected endpoint and link status if connection +* exists. +* @mc_io Pointer to MC portal's I/O object +* @token Token of DPRC object +* @endpoint1 Endpoint 1 configuration parameters +* @endpoint2 Returned endpoint 2 configuration parameters +* @state: Returned link state: 1 - link is up, 0 - link is down +* +* Return: '0' on Success; -ENAVAIL if connection does not exist. +*/ +int dprc_get_connection(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + struct dprc_endpoint *endpoint2, + int *state); + +#endif /* _FSL_DPRC_H */ + diff --git a/drivers/staging/fsl-mc/include/mc-cmd.h b/drivers/staging/fsl-mc/include/mc-cmd.h new file mode 100644 index 0000000..32501e0 --- /dev/null +++ b/drivers/staging/fsl-mc/include/mc-cmd.h @@ -0,0 +1,113 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_MC_CMD_H +#define __FSL_MC_CMD_H + +#define MC_CMD_NUM_OF_PARAMS 7 + +#define MAKE_UMASK64(_width) \ + ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : -1)) + +static inline uint64_t mc_enc(int lsoffset, int width, uint64_t val) +{ + return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset); +} + +static inline uint64_t mc_dec(uint64_t val, int lsoffset, int width) +{ + return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width)); +} + +struct mc_command { + uint64_t header; + uint64_t params[MC_CMD_NUM_OF_PARAMS]; +}; + +enum mc_cmd_status { + MC_CMD_STATUS_OK = 0x0, /* Completed successfully */ + MC_CMD_STATUS_READY = 0x1, /* Ready to be processed */ + MC_CMD_STATUS_AUTH_ERR = 0x3, /* Authentication error */ + MC_CMD_STATUS_NO_PRIVILEGE = 0x4, /* No privilege */ + MC_CMD_STATUS_DMA_ERR = 0x5, /* DMA or I/O error */ + MC_CMD_STATUS_CONFIG_ERR = 0x6, /* Configuration error */ + MC_CMD_STATUS_TIMEOUT = 0x7, /* Operation timed out */ + MC_CMD_STATUS_NO_RESOURCE = 0x8, /* No resources */ + MC_CMD_STATUS_NO_MEMORY = 0x9, /* No memory available */ + MC_CMD_STATUS_BUSY = 0xA, /* Device is busy */ + MC_CMD_STATUS_UNSUPPORTED_OP = 0xB, /* Unsupported operation */ + MC_CMD_STATUS_INVALID_STATE = 0xC /* Invalid state */ +}; + +#define MC_CMD_HDR_CMDID_O 52 /* Command ID field offset */ +#define MC_CMD_HDR_CMDID_S 12 /* Command ID field size */ +#define MC_CMD_HDR_TOKEN_O 38 /* Token field offset */ +#define MC_CMD_HDR_TOKEN_S 10 /* Token field size */ +#define MC_CMD_HDR_STATUS_O 16 /* Status field offset */ +#define MC_CMD_HDR_STATUS_S 8 /* Status field size*/ +#define MC_CMD_HDR_PRI_O 15 /* Priority field offset */ +#define MC_CMD_HDR_PRI_S 1 /* Priority field size */ + +#define MC_CMD_HDR_READ_STATUS(_hdr) \ + ((enum mc_cmd_status)mc_dec((_hdr), \ + MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S)) + +#define MC_CMD_HDR_READ_TOKEN(_hdr) \ + ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S)) + +#define MC_CMD_PRI_LOW 0 /* Low Priority command indication */ +#define MC_CMD_PRI_HIGH 1 /* High Priority command indication */ + +#define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \ + ((_ext)[_param] |= mc_enc((_offset), (_width), _arg)) + +#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \ + ((_cmd).params[_param] |= mc_enc((_offset), (_width), _arg)) + +#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \ + (_arg = (_type)mc_dec(_cmd.params[_param], (_offset), (_width))) + +static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id, + uint8_t priority, + uint16_t token) +{ + uint64_t hdr; + + hdr = mc_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id); + hdr |= mc_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token); + hdr |= mc_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority); + hdr |= mc_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S, + MC_CMD_STATUS_READY); + + return hdr; +} + +#endif /* __FSL_MC_CMD_H */ diff --git a/drivers/staging/fsl-mc/include/mc-sys.h b/drivers/staging/fsl-mc/include/mc-sys.h new file mode 100644 index 0000000..abfd6a2 --- /dev/null +++ b/drivers/staging/fsl-mc/include/mc-sys.h @@ -0,0 +1,70 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. + * + * Interface of the I/O services to send MC commands to the MC hardware + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_MC_SYS_H +#define _FSL_MC_SYS_H + +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/io.h> +#include <linux/dma-mapping.h> + +struct mc_command; + +/** + * struct fsl_mc_io - MC I/O object to be passed-in to mc_send_command() + * @dev: device associated with this Mc I/O object + * @flags: flags for mc_send_command() + * @portal_size: MC command portal size in bytes + * @portal_phys_addr: MC command portal physical address + * @portal_virt_addr: MC command portal virtual address + */ +struct fsl_mc_io { + struct device *dev; + uint32_t flags; + uint32_t portal_size; + phys_addr_t portal_phys_addr; + void __iomem *portal_virt_addr; +}; + +int __must_check fsl_create_mc_io(struct device *dev, + phys_addr_t mc_portal_phys_addr, + uint32_t mc_portal_size, + uint32_t flags, struct fsl_mc_io **new_mc_io); + +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io); + +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd); + +#endif /* _FSL_MC_SYS_H */ -- 2.3.0 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel