forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'imx6sx_mu' into rpmsglite-imx
This branch is the PR zephyrproject-rtos#8527 which was not upstreamed yet.
- Loading branch information
Showing
19 changed files
with
1,276 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
zephyr_library() | ||
|
||
zephyr_library_sources_ifdef(CONFIG_IPM_MCUX ipm_mcux.c) | ||
zephyr_library_sources_ifdef(CONFIG_IPM_IMX ipm_imx.c) | ||
zephyr_library_sources_ifdef(CONFIG_IPM_QUARK_SE ipm_quark_se.c) | ||
|
||
zephyr_library_sources_ifdef(CONFIG_USERSPACE ipm_handlers.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
/* | ||
* Copyright (c) 2018, NXP | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <errno.h> | ||
#include <string.h> | ||
#include <device.h> | ||
#include <soc.h> | ||
#include <ipm.h> | ||
#include <mu_imx.h> | ||
|
||
#define MU(config) ((MU_Type *)config->base) | ||
|
||
#if ((CONFIG_IPM_IMX_MAX_DATA_SIZE % 4) != 0) | ||
#error CONFIG_IPM_IMX_MAX_DATA_SIZE is invalid | ||
#endif | ||
|
||
#define IMX_IPM_DATA_REGS (CONFIG_IPM_IMX_MAX_DATA_SIZE / 4) | ||
|
||
struct imx_mu_config { | ||
MU_Type *base; | ||
void (*irq_config_func)(struct device *dev); | ||
}; | ||
|
||
struct imx_mu_data { | ||
ipm_callback_t callback; | ||
void *callback_ctx; | ||
}; | ||
|
||
static void imx_mu_isr(void *arg) | ||
{ | ||
struct device *dev = (struct device *)arg; | ||
const struct imx_mu_config *config = dev->config->config_info; | ||
MU_Type *base = MU(config); | ||
struct imx_mu_data *data = dev->driver_data; | ||
u32_t data32[IMX_IPM_DATA_REGS]; | ||
u32_t status_reg; | ||
s32_t id; | ||
s32_t i; | ||
bool all_registers_full; | ||
|
||
status_reg = base->SR >>= MU_SR_RFn_SHIFT; | ||
|
||
for (id = CONFIG_IPM_IMX_MAX_ID_VAL; id >= 0; id--) { | ||
if (status_reg & 0x1U) { | ||
/* | ||
* Check if all receive registers are full. If not, | ||
* it is violation of the protocol (status register | ||
* are set earlier than all receive registers). | ||
* Do not read any of the registers in such situation. | ||
*/ | ||
all_registers_full = true; | ||
for (i = 0; i < IMX_IPM_DATA_REGS; i++) { | ||
if (!MU_IsRxFull(base, | ||
(id * IMX_IPM_DATA_REGS) + i)) { | ||
all_registers_full = false; | ||
break; | ||
} | ||
} | ||
if (all_registers_full) { | ||
for (i = 0; i < IMX_IPM_DATA_REGS; i++) { | ||
MU_ReceiveMsg(base, | ||
(id * IMX_IPM_DATA_REGS) + i, | ||
&data32[i]); | ||
} | ||
|
||
if (data->callback) { | ||
data->callback(data->callback_ctx, | ||
(u32_t)id, | ||
&data32[0]); | ||
} | ||
} | ||
} | ||
status_reg >>= IMX_IPM_DATA_REGS; | ||
} | ||
|
||
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F | ||
* Store immediate overlapping exception return operation | ||
* might vector to incorrect interrupt | ||
*/ | ||
#if defined __CORTEX_M && (__CORTEX_M == 4U) | ||
__DSB(); | ||
#endif | ||
} | ||
|
||
static int imx_mu_ipm_send(struct device *dev, int wait, u32_t id, | ||
const void *data, int size) | ||
{ | ||
const struct imx_mu_config *config = dev->config->config_info; | ||
MU_Type *base = MU(config); | ||
u32_t data32[IMX_IPM_DATA_REGS]; | ||
mu_status_t status; | ||
int i; | ||
|
||
if (id > CONFIG_IPM_IMX_MAX_ID_VAL) { | ||
return -EINVAL; | ||
} | ||
|
||
if (size > CONFIG_IPM_IMX_MAX_DATA_SIZE) { | ||
return -EMSGSIZE; | ||
} | ||
|
||
/* Actual message is passing using 32 bits registers */ | ||
memcpy(data32, data, size); | ||
|
||
for (i = 0; i < IMX_IPM_DATA_REGS; i++) { | ||
status = MU_TrySendMsg(base, id * IMX_IPM_DATA_REGS + i, | ||
data32[i]); | ||
if (status == kStatus_MU_TxNotEmpty) { | ||
return -EBUSY; | ||
} | ||
} | ||
|
||
if (wait) { | ||
while (!MU_IsTxEmpty(base, | ||
(id * IMX_IPM_DATA_REGS) + IMX_IPM_DATA_REGS - 1)) { | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int imx_mu_ipm_max_data_size_get(struct device *dev) | ||
{ | ||
ARG_UNUSED(dev); | ||
|
||
return CONFIG_IPM_IMX_MAX_DATA_SIZE; | ||
} | ||
|
||
static u32_t imx_mu_ipm_max_id_val_get(struct device *dev) | ||
{ | ||
ARG_UNUSED(dev); | ||
|
||
return CONFIG_IPM_IMX_MAX_ID_VAL; | ||
} | ||
|
||
static void imx_mu_ipm_register_callback(struct device *dev, | ||
ipm_callback_t cb, | ||
void *context) | ||
{ | ||
struct imx_mu_data *driver_data = dev->driver_data; | ||
|
||
driver_data->callback = cb; | ||
driver_data->callback_ctx = context; | ||
} | ||
|
||
static int imx_mu_ipm_set_enabled(struct device *dev, int enable) | ||
{ | ||
const struct imx_mu_config *config = dev->config->config_info; | ||
MU_Type *base = MU(config); | ||
|
||
#if CONFIG_IPM_IMX_MAX_DATA_SIZE_4 | ||
if (enable) { | ||
MU_EnableRxFullInt(base, 0U); | ||
MU_EnableRxFullInt(base, 1U); | ||
MU_EnableRxFullInt(base, 2U); | ||
MU_EnableRxFullInt(base, 3U); | ||
} else { | ||
MU_DisableRxFullInt(base, 0U); | ||
MU_DisableRxFullInt(base, 1U); | ||
MU_DisableRxFullInt(base, 2U); | ||
MU_DisableRxFullInt(base, 3U); | ||
} | ||
#elif CONFIG_IPM_IMX_MAX_DATA_SIZE_8 | ||
if (enable) { | ||
MU_EnableRxFullInt(base, 1U); | ||
MU_EnableRxFullInt(base, 3U); | ||
} else { | ||
MU_DisableRxFullInt(base, 1U); | ||
MU_DisableRxFullInt(base, 3U); | ||
} | ||
#elif CONFIG_IPM_IMX_MAX_DATA_SIZE_16 | ||
if (enable) { | ||
MU_EnableRxFullInt(base, 3U); | ||
} else { | ||
MU_DisableRxFullInt(base, 3U); | ||
} | ||
#else | ||
#error "CONFIG_IPM_IMX_MAX_DATA_SIZE_n is not set" | ||
#endif | ||
|
||
return 0; | ||
} | ||
|
||
static int imx_mu_init(struct device *dev) | ||
{ | ||
const struct imx_mu_config *config = dev->config->config_info; | ||
|
||
MU_Init(MU(config)); | ||
config->irq_config_func(dev); | ||
|
||
return 0; | ||
} | ||
|
||
static const struct ipm_driver_api imx_mu_driver_api = { | ||
.send = imx_mu_ipm_send, | ||
.register_callback = imx_mu_ipm_register_callback, | ||
.max_data_size_get = imx_mu_ipm_max_data_size_get, | ||
.max_id_val_get = imx_mu_ipm_max_id_val_get, | ||
.set_enabled = imx_mu_ipm_set_enabled | ||
}; | ||
|
||
/* Config MU */ | ||
|
||
static void imx_mu_config_func_b(struct device *dev); | ||
|
||
static const struct imx_mu_config imx_mu_b_config = { | ||
.base = (MU_Type *)CONFIG_IPM_IMX_MU_B_BASE_ADDRESS, | ||
.irq_config_func = imx_mu_config_func_b, | ||
}; | ||
|
||
static struct imx_mu_data imx_mu_b_data; | ||
|
||
DEVICE_AND_API_INIT(mu_b, CONFIG_IPM_IMX_MU_B_NAME, | ||
&imx_mu_init, | ||
&imx_mu_b_data, &imx_mu_b_config, | ||
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, | ||
&imx_mu_driver_api); | ||
|
||
static void imx_mu_config_func_b(struct device *dev) | ||
{ | ||
IRQ_CONNECT(CONFIG_IPM_IMX_MU_B_IRQ, | ||
CONFIG_IPM_IMX_MU_B_IRQ_PRI, | ||
imx_mu_isr, DEVICE_GET(mu_b), 0); | ||
|
||
irq_enable(CONFIG_IPM_IMX_MU_B_IRQ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# | ||
# Copyright (c) 2018, NXP | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
--- | ||
title: IMX MESSAGING UNIT | ||
id: nxp,imx-mu | ||
version: 0.1 | ||
|
||
description: > | ||
This binding gives a base representation of the i.MX Messaging Unit | ||
properties: | ||
compatible: | ||
type: string | ||
category: required | ||
description: compatible strings | ||
constraint: "nxp,imx-mu" | ||
|
||
reg: | ||
type: array | ||
description: mmio register space | ||
generation: define | ||
category: required | ||
|
||
interrupts: | ||
type: array | ||
category: required | ||
description: required interrupts | ||
generation: define | ||
|
||
label: | ||
type: string | ||
category: required | ||
description: Human readable string describing the device (used by Zephyr for API name) | ||
generation: define | ||
|
||
rdc: | ||
type: int | ||
category: required | ||
description: Set the RDC permission for this peripheral | ||
generation: define | ||
|
||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
cmake_minimum_required(VERSION 3.8.2) | ||
|
||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) | ||
project(NONE) | ||
|
||
target_include_directories(app PRIVATE $ENV{ZEPHYR_BASE}/drivers) | ||
target_sources(app PRIVATE src/main.c) |
Oops, something went wrong.