diff options
author | J. German Rivera <German.Rivera@freescale.com> | 2015-03-05 19:35:25 -0600 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-03-06 17:29:10 -0800 |
commit | 197f4d6a4a00915b29fa7ec71f8010b9c763e676 (patch) | |
tree | 74bcafca4e1aa0c0f8bae739771b8b91eeb8499a /drivers/staging/fsl-mc | |
parent | f2f2726b62f59424782516fd6d0d164892493ada (diff) |
staging: fsl-mc: fsl-mc object allocator driver
The fsl-mc object allocator driver manages "allocatable" fsl-mc
objects such as DPBPs, DPMCPs and DPCONs. It provides services to
other fsl-mc drivers to allocate/deallocate these types of objects.
Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/fsl-mc')
-rw-r--r-- | drivers/staging/fsl-mc/bus/Makefile | 6 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/bus/dpbp.c | 358 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 136 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/bus/dpmcp.c | 308 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/bus/dpmcp.h | 311 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/bus/dprc-driver.c | 104 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/bus/mc-allocator.c | 569 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/bus/mc-bus.c | 2 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/bus/mc-sys.c | 4 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/include/dpbp-cmd.h | 60 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/include/dpbp.h | 330 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/include/dpcon-cmd.h | 62 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/include/mc-private.h | 61 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/include/mc-sys.h | 6 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/include/mc.h | 65 |
15 files changed, 2366 insertions, 16 deletions
diff --git a/drivers/staging/fsl-mc/bus/Makefile b/drivers/staging/fsl-mc/bus/Makefile index 424e58e1ea7e..bd09fc8cf650 100644 --- a/drivers/staging/fsl-mc/bus/Makefile +++ b/drivers/staging/fsl-mc/bus/Makefile @@ -5,7 +5,8 @@ # # This file is released under the GPLv2 # -obj-$(CONFIG_FSL_MC_BUS) += mc-bus-driver.o +obj-$(CONFIG_FSL_MC_BUS) += mc-bus-driver.o \ + mc-allocator-driver.o mc-bus-driver-objs := mc-bus.o \ mc-sys.o \ @@ -13,3 +14,6 @@ mc-bus-driver-objs := mc-bus.o \ dpmng.o \ dprc-driver.o +mc-allocator-driver-objs := mc-allocator.o \ + dpmcp.o \ + dpbp.o diff --git a/drivers/staging/fsl-mc/bus/dpbp.c b/drivers/staging/fsl-mc/bus/dpbp.c new file mode 100644 index 000000000000..d99ab6d0bbb1 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpbp.c @@ -0,0 +1,358 @@ +/* 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/dpbp.h" +#include "../include/dpbp-cmd.h" + +int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN, + MC_CMD_PRI_LOW, 0); + cmd.params[0] |= mc_enc(0, 32, dpbp_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 err; +} +EXPORT_SYMBOL(dpbp_open); + +int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, MC_CMD_PRI_HIGH, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dpbp_close); + +int dpbp_create(struct fsl_mc_io *mc_io, + const struct dpbp_cfg *cfg, + uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + (void)(cfg); /* unused */ + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE, + MC_CMD_PRI_LOW, 0); + + /* 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; +} + +int dpbp_destroy(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dpbp_enable); + +int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dpbp_disable); + +int dpbp_is_enabled(struct fsl_mc_io *mc_io, uint16_t token, int *en) +{ + struct mc_command cmd = { 0 }; + int err; + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *en = (int)mc_dec(cmd.params[0], 0, 1); + + return 0; +} + +int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_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(DPBP_CMDID_SET_IRQ, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 8, irq_index); + cmd.params[0] |= mc_enc(32, 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 dpbp_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(DPBP_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 = (uint32_t)mc_dec(cmd.params[0], 0, 32); + *irq_paddr = (uint64_t)mc_dec(cmd.params[1], 0, 64); + *user_irq_id = (int)mc_dec(cmd.params[2], 0, 32); + *type = (int)mc_dec(cmd.params[2], 32, 32); + return 0; +} + +int dpbp_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(DPBP_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 dpbp_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(DPBP_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 = (uint8_t)mc_dec(cmd.params[0], 0, 8); + return 0; +} + +int dpbp_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(DPBP_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 dpbp_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(DPBP_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 = (uint32_t)mc_dec(cmd.params[0], 0, 32); + return 0; +} + +int dpbp_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(DPBP_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 = (uint32_t)mc_dec(cmd.params[0], 0, 32); + return 0; +} + +int dpbp_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(DPBP_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 dpbp_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpbp_attr *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_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->bpid = (uint16_t)mc_dec(cmd.params[0], 16, 16); + attr->id = (int)mc_dec(cmd.params[0], 32, 32); + attr->version.major = (uint16_t)mc_dec(cmd.params[1], 0, 16); + attr->version.minor = (uint16_t)mc_dec(cmd.params[1], 16, 16); + return 0; +} +EXPORT_SYMBOL(dpbp_get_attributes); diff --git a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h new file mode 100644 index 000000000000..57f326b60b76 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h @@ -0,0 +1,136 @@ +/* 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_DPMCP_CMD_H +#define _FSL_DPMCP_CMD_H + +/* DPMCP Version */ +#define DPMCP_VER_MAJOR 2 +#define DPMCP_VER_MINOR 0 + +/* Command IDs */ +#define DPMCP_CMDID_CLOSE 0x800 +#define DPMCP_CMDID_OPEN 0x80b +#define DPMCP_CMDID_CREATE 0x90b +#define DPMCP_CMDID_DESTROY 0x900 + +#define DPMCP_CMDID_GET_ATTR 0x004 +#define DPMCP_CMDID_RESET 0x005 + +#define DPMCP_CMDID_SET_IRQ 0x010 +#define DPMCP_CMDID_GET_IRQ 0x011 +#define DPMCP_CMDID_SET_IRQ_ENABLE 0x012 +#define DPMCP_CMDID_GET_IRQ_ENABLE 0x013 +#define DPMCP_CMDID_SET_IRQ_MASK 0x014 +#define DPMCP_CMDID_GET_IRQ_MASK 0x015 +#define DPMCP_CMDID_GET_IRQ_STATUS 0x016 +#define DPMCP_CMDID_CLEAR_IRQ_STATUS 0x017 + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_CREATE(cmd, cfg) \ + MC_CMD_OP(cmd, 0, 0, 32, int, cfg->portal_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_SET_IRQ(cmd, irq_index, irq_addr, irq_val, user_irq_id) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\ + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_val);\ + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_addr); \ + MC_CMD_OP(cmd, 2, 0, 32, int, user_irq_id); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_GET_IRQ(cmd, irq_index) \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_IRQ(cmd, type, irq_addr, irq_val, user_irq_id) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_val); \ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_addr); \ + MC_RSP_OP(cmd, 2, 0, 32, int, user_irq_id); \ + MC_RSP_OP(cmd, 2, 32, 32, int, type); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_SET_IRQ_ENABLE(cmd, irq_index, en) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, en); \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_GET_IRQ_ENABLE(cmd, irq_index) \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_IRQ_ENABLE(cmd, en) \ + MC_RSP_OP(cmd, 0, 0, 8, uint8_t, en) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask);\ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_GET_IRQ_MASK(cmd, irq_index) \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_IRQ_MASK(cmd, mask) \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_GET_IRQ_STATUS(cmd, irq_index) \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_IRQ_STATUS(cmd, status) \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_ATTRIBUTES(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\ + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\ + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\ +} while (0) + +#endif /* _FSL_DPMCP_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dpmcp.c b/drivers/staging/fsl-mc/bus/dpmcp.c new file mode 100644 index 000000000000..6b9da5b7fd00 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmcp.c @@ -0,0 +1,308 @@ +/* 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. + */ +#include "../include/mc-sys.h" +#include "../include/mc-cmd.h" +#include "dpmcp.h" +#include "dpmcp-cmd.h" + +int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_OPEN, + MC_CMD_PRI_LOW, 0); + cmd.params[0] |= mc_enc(0, 32, dpmcp_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 err; +} + +int dpmcp_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLOSE, MC_CMD_PRI_HIGH, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_create(struct fsl_mc_io *mc_io, + const struct dpmcp_cfg *cfg, + uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CREATE, + MC_CMD_PRI_LOW, 0); + cmd.params[0] |= mc_enc(0, 32, cfg->portal_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; +} + +int dpmcp_destroy(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_DESTROY, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_reset(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_RESET, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_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) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 8, irq_index); + cmd.params[0] |= mc_enc(32, 32, irq_val); + cmd.params[1] |= mc_enc(0, 64, irq_addr); + cmd.params[2] |= mc_enc(0, 32, user_irq_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_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) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_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 = (uint32_t)mc_dec(cmd.params[0], 0, 32); + *irq_addr = (uint64_t)mc_dec(cmd.params[1], 0, 64); + *user_irq_id = (int)mc_dec(cmd.params[2], 0, 32); + *type = (int)mc_dec(cmd.params[2], 32, 32); + return 0; +} + +int dpmcp_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(DPMCP_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 dpmcp_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(DPMCP_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 = (uint8_t)mc_dec(cmd.params[0], 0, 8); + return 0; +} + +int dpmcp_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(DPMCP_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 dpmcp_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(DPMCP_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 = (uint32_t)mc_dec(cmd.params[0], 0, 32); + return 0; +} + +int dpmcp_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(DPMCP_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 = (uint32_t)mc_dec(cmd.params[0], 0, 32); + return 0; +} + +int dpmcp_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(DPMCP_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 dpmcp_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpmcp_attr *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_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->id = (int)mc_dec(cmd.params[0], 32, 32); + attr->version.major = (uint16_t)mc_dec(cmd.params[1], 0, 16); + attr->version.minor = (uint16_t)mc_dec(cmd.params[1], 16, 16); + return 0; +} diff --git a/drivers/staging/fsl-mc/bus/dpmcp.h b/drivers/staging/fsl-mc/bus/dpmcp.h new file mode 100644 index 000000000000..5e7c21952ce5 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmcp.h @@ -0,0 +1,311 @@ +/* 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_DPMCP_H +#define __FSL_DPMCP_H + +/* Data Path Management Command Portal API + * Contains initialization APIs and runtime control APIs for DPMCP + */ + +struct fsl_mc_io; + +/** + * dpmcp_open() - Open a control session for the specified object. + * @mc_io: Pointer to MC portal's I/O object + * @dpmcp_id: DPMCP unique ID + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpmcp_create function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, uint16_t *token); + +/* Get portal ID from pool */ +#define DPMCP_GET_PORTAL_ID_FROM_POOL (-1) + +/** + * dpmcp_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP 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 dpmcp_close(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * struct dpmcp_cfg() - Structure representing DPMCP configuration + * @portal_id: Portal ID; 'DPMCP_GET_PORTAL_ID_FROM_POOL' to get the portal ID + * from pool + */ +struct dpmcp_cfg { + int portal_id; +}; + +/** + * dpmcp_create() - Create the DPMCP object. + * @mc_io: Pointer to MC portal's I/O object + * @cfg: Configuration structure + * @token: Returned token; use in subsequent API calls + * + * Create the DPMCP object, allocate required resources and + * perform required initialization. + * + * The object can be created either by declaring it in the + * DPL file, or by calling this function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent calls to + * this specific object. For objects that are created using the + * DPL file, call dpmcp_open function to get an authentication + * token first. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_create(struct fsl_mc_io *mc_io, + const struct dpmcp_cfg *cfg, + uint16_t *token); + +/** + * dpmcp_destroy() - Destroy the DPMCP object and release all its resources. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * + * Return: '0' on Success; error code otherwise. + */ +int dpmcp_destroy(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpmcp_reset() - Reset the DPMCP, returns the object to initial state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_reset(struct fsl_mc_io *mc_io, uint16_t token); + +/* IRQ */ +/*! + * @name dpmcp IRQ Index and Events + */ +#define DPMCP_IRQ_INDEX 0 +/*!< Irq index */ +#define DPMCP_IRQ_EVENT_CMD_DONE 0x00000001 +/*!< irq event - |