i.MX drivers update for 5.8:
- Optimize imx-scu driver to use one TX and one RX instead of four for talking to SCU. - Fix one possible message header corruption where the response is longer than the request. - Move System Control defines into dt-bindings header, so that DT can use them as well. - A couple of small fixups. -----BEGIN PGP SIGNATURE----- iQFIBAABCgAyFiEEFmJXigPl4LoGSz08UFdYWoewfM4FAl7IeuUUHHNoYXduZ3Vv QGtlcm5lbC5vcmcACgkQUFdYWoewfM5CpAf/VV2krqXlgTXA1Ppl+ivdGkx9ntwo dVtZYNr65Z1iqp6yujW7cH/qulXfkaFanwDptq9ulBkG6uiyV06GCtBxpp3VhNOB 60uaS8RsieYmCz3e8j4kZkMCBthpD72wt0DxF1TlJu2d/cWfsM4/bMbrx0qYiT0V J5FqcGH0xbe+E5YITdoPQbNxEig49q2P6BhkNLQelVQtVgM0lwSpDX3WRpCizch4 bbKSVYudV/rGGPM7ZYM53N+ngwKZurRbIf7br1QgA4ZlQxdCtADB6IRd2RsfrC8P 4BizRONfh46ogrnb9/P951RZu9H7VFRkTurnXdU+NcFK8HPYDGQmm7P2SQ== =cJwM -----END PGP SIGNATURE----- Merge tag 'imx-drivers-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers i.MX drivers update for 5.8: - Optimize imx-scu driver to use one TX and one RX instead of four for talking to SCU. - Fix one possible message header corruption where the response is longer than the request. - Move System Control defines into dt-bindings header, so that DT can use them as well. - A couple of small fixups. * tag 'imx-drivers-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux: firmware: imx: scu: Fix possible memory leak in imx_scu_probe() dt-bindings: firmware: imx: Add more system controls and PM clock types dt-bindings: firmware: imx: Move system control into dt-binding headfile firmware: imx: scu: Fix corruption of header firmware: imx-scu: Support one TX and one RX soc: imx8m: No need to put node when of_find_compatible_node() failed Link: https://lore.kernel.org/r/20200523032516.11016-1-shawnguo@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
7b972f3830
|
@ -8,7 +8,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/firmware/imx/types.h>
|
||||
#include <linux/firmware/imx/ipc.h>
|
||||
#include <linux/firmware/imx/sci.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
@ -38,6 +37,7 @@ struct imx_sc_ipc {
|
|||
struct device *dev;
|
||||
struct mutex lock;
|
||||
struct completion done;
|
||||
bool fast_ipc;
|
||||
|
||||
/* temporarily store the SCU msg */
|
||||
u32 *msg;
|
||||
|
@ -115,6 +115,7 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
|
|||
struct imx_sc_ipc *sc_ipc = sc_chan->sc_ipc;
|
||||
struct imx_sc_rpc_msg *hdr;
|
||||
u32 *data = msg;
|
||||
int i;
|
||||
|
||||
if (!sc_ipc->msg) {
|
||||
dev_warn(sc_ipc->dev, "unexpected rx idx %d 0x%08x, ignore!\n",
|
||||
|
@ -122,6 +123,19 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
|
|||
return;
|
||||
}
|
||||
|
||||
if (sc_ipc->fast_ipc) {
|
||||
hdr = msg;
|
||||
sc_ipc->rx_size = hdr->size;
|
||||
sc_ipc->msg[0] = *data++;
|
||||
|
||||
for (i = 1; i < sc_ipc->rx_size; i++)
|
||||
sc_ipc->msg[i] = *data++;
|
||||
|
||||
complete(&sc_ipc->done);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sc_chan->idx == 0) {
|
||||
hdr = msg;
|
||||
sc_ipc->rx_size = hdr->size;
|
||||
|
@ -143,20 +157,22 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
|
|||
|
||||
static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
|
||||
{
|
||||
struct imx_sc_rpc_msg *hdr = msg;
|
||||
struct imx_sc_rpc_msg hdr = *(struct imx_sc_rpc_msg *)msg;
|
||||
struct imx_sc_chan *sc_chan;
|
||||
u32 *data = msg;
|
||||
int ret;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
/* Check size */
|
||||
if (hdr->size > IMX_SC_RPC_MAX_MSG)
|
||||
if (hdr.size > IMX_SC_RPC_MAX_MSG)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr->svc,
|
||||
hdr->func, hdr->size);
|
||||
dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr.svc,
|
||||
hdr.func, hdr.size);
|
||||
|
||||
for (i = 0; i < hdr->size; i++) {
|
||||
size = sc_ipc->fast_ipc ? 1 : hdr.size;
|
||||
for (i = 0; i < size; i++) {
|
||||
sc_chan = &sc_ipc->chans[i % 4];
|
||||
|
||||
/*
|
||||
|
@ -168,8 +184,10 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
|
|||
* Wait for tx_done before every send to ensure that no
|
||||
* queueing happens at the mailbox channel level.
|
||||
*/
|
||||
wait_for_completion(&sc_chan->tx_done);
|
||||
reinit_completion(&sc_chan->tx_done);
|
||||
if (!sc_ipc->fast_ipc) {
|
||||
wait_for_completion(&sc_chan->tx_done);
|
||||
reinit_completion(&sc_chan->tx_done);
|
||||
}
|
||||
|
||||
ret = mbox_send_message(sc_chan->ch, &data[i]);
|
||||
if (ret < 0)
|
||||
|
@ -246,6 +264,8 @@ static int imx_scu_probe(struct platform_device *pdev)
|
|||
struct imx_sc_chan *sc_chan;
|
||||
struct mbox_client *cl;
|
||||
char *chan_name;
|
||||
struct of_phandle_args args;
|
||||
int num_channel;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
@ -253,11 +273,20 @@ static int imx_scu_probe(struct platform_device *pdev)
|
|||
if (!sc_ipc)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < SCU_MU_CHAN_NUM; i++) {
|
||||
if (i < 4)
|
||||
ret = of_parse_phandle_with_args(pdev->dev.of_node, "mboxes",
|
||||
"#mbox-cells", 0, &args);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sc_ipc->fast_ipc = of_device_is_compatible(args.np, "fsl,imx8-mu-scu");
|
||||
|
||||
num_channel = sc_ipc->fast_ipc ? 2 : SCU_MU_CHAN_NUM;
|
||||
for (i = 0; i < num_channel; i++) {
|
||||
if (i < num_channel / 2)
|
||||
chan_name = kasprintf(GFP_KERNEL, "tx%d", i);
|
||||
else
|
||||
chan_name = kasprintf(GFP_KERNEL, "rx%d", i - 4);
|
||||
chan_name = kasprintf(GFP_KERNEL, "rx%d",
|
||||
i - num_channel / 2);
|
||||
|
||||
if (!chan_name)
|
||||
return -ENOMEM;
|
||||
|
@ -269,19 +298,22 @@ static int imx_scu_probe(struct platform_device *pdev)
|
|||
cl->knows_txdone = true;
|
||||
cl->rx_callback = imx_scu_rx_callback;
|
||||
|
||||
/* Initial tx_done completion as "done" */
|
||||
cl->tx_done = imx_scu_tx_done;
|
||||
init_completion(&sc_chan->tx_done);
|
||||
complete(&sc_chan->tx_done);
|
||||
if (!sc_ipc->fast_ipc) {
|
||||
/* Initial tx_done completion as "done" */
|
||||
cl->tx_done = imx_scu_tx_done;
|
||||
init_completion(&sc_chan->tx_done);
|
||||
complete(&sc_chan->tx_done);
|
||||
}
|
||||
|
||||
sc_chan->sc_ipc = sc_ipc;
|
||||
sc_chan->idx = i % 4;
|
||||
sc_chan->idx = i % (num_channel / 2);
|
||||
sc_chan->ch = mbox_request_channel_byname(cl, chan_name);
|
||||
if (IS_ERR(sc_chan->ch)) {
|
||||
ret = PTR_ERR(sc_chan->ch);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to request mbox chan %s ret %d\n",
|
||||
chan_name, ret);
|
||||
kfree(chan_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,11 +53,11 @@ static u32 __init imx8mq_soc_revision(void)
|
|||
struct device_node *np;
|
||||
void __iomem *ocotp_base;
|
||||
u32 magic;
|
||||
u32 rev = 0;
|
||||
u32 rev;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
|
||||
if (!np)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
ocotp_base = of_iomap(np, 0);
|
||||
WARN_ON(!ocotp_base);
|
||||
|
@ -78,9 +78,8 @@ static u32 __init imx8mq_soc_revision(void)
|
|||
soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
|
||||
|
||||
iounmap(ocotp_base);
|
||||
|
||||
out:
|
||||
of_node_put(np);
|
||||
|
||||
return rev;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
* Copyright 2018-2020 NXP.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/firmware/imx/sci.h>
|
||||
#include <linux/firmware/imx/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
|
|
@ -547,4 +547,88 @@
|
|||
#define IMX_SC_R_ATTESTATION 545
|
||||
#define IMX_SC_R_LAST 546
|
||||
|
||||
/*
|
||||
* Defines for SC PM CLK
|
||||
*/
|
||||
#define IMX_SC_PM_CLK_SLV_BUS 0 /* Slave bus clock */
|
||||
#define IMX_SC_PM_CLK_MST_BUS 1 /* Master bus clock */
|
||||
#define IMX_SC_PM_CLK_PER 2 /* Peripheral clock */
|
||||
#define IMX_SC_PM_CLK_PHY 3 /* Phy clock */
|
||||
#define IMX_SC_PM_CLK_MISC 4 /* Misc clock */
|
||||
#define IMX_SC_PM_CLK_MISC0 0 /* Misc 0 clock */
|
||||
#define IMX_SC_PM_CLK_MISC1 1 /* Misc 1 clock */
|
||||
#define IMX_SC_PM_CLK_MISC2 2 /* Misc 2 clock */
|
||||
#define IMX_SC_PM_CLK_MISC3 3 /* Misc 3 clock */
|
||||
#define IMX_SC_PM_CLK_MISC4 4 /* Misc 4 clock */
|
||||
#define IMX_SC_PM_CLK_CPU 2 /* CPU clock */
|
||||
#define IMX_SC_PM_CLK_PLL 4 /* PLL */
|
||||
#define IMX_SC_PM_CLK_BYPASS 4 /* Bypass clock */
|
||||
|
||||
/*
|
||||
* Defines for SC CONTROL
|
||||
*/
|
||||
#define IMX_SC_C_TEMP 0
|
||||
#define IMX_SC_C_TEMP_HI 1
|
||||
#define IMX_SC_C_TEMP_LOW 2
|
||||
#define IMX_SC_C_PXL_LINK_MST1_ADDR 3
|
||||
#define IMX_SC_C_PXL_LINK_MST2_ADDR 4
|
||||
#define IMX_SC_C_PXL_LINK_MST_ENB 5
|
||||
#define IMX_SC_C_PXL_LINK_MST1_ENB 6
|
||||
#define IMX_SC_C_PXL_LINK_MST2_ENB 7
|
||||
#define IMX_SC_C_PXL_LINK_SLV1_ADDR 8
|
||||
#define IMX_SC_C_PXL_LINK_SLV2_ADDR 9
|
||||
#define IMX_SC_C_PXL_LINK_MST_VLD 10
|
||||
#define IMX_SC_C_PXL_LINK_MST1_VLD 11
|
||||
#define IMX_SC_C_PXL_LINK_MST2_VLD 12
|
||||
#define IMX_SC_C_SINGLE_MODE 13
|
||||
#define IMX_SC_C_ID 14
|
||||
#define IMX_SC_C_PXL_CLK_POLARITY 15
|
||||
#define IMX_SC_C_LINESTATE 16
|
||||
#define IMX_SC_C_PCIE_G_RST 17
|
||||
#define IMX_SC_C_PCIE_BUTTON_RST 18
|
||||
#define IMX_SC_C_PCIE_PERST 19
|
||||
#define IMX_SC_C_PHY_RESET 20
|
||||
#define IMX_SC_C_PXL_LINK_RATE_CORRECTION 21
|
||||
#define IMX_SC_C_PANIC 22
|
||||
#define IMX_SC_C_PRIORITY_GROUP 23
|
||||
#define IMX_SC_C_TXCLK 24
|
||||
#define IMX_SC_C_CLKDIV 25
|
||||
#define IMX_SC_C_DISABLE_50 26
|
||||
#define IMX_SC_C_DISABLE_125 27
|
||||
#define IMX_SC_C_SEL_125 28
|
||||
#define IMX_SC_C_MODE 29
|
||||
#define IMX_SC_C_SYNC_CTRL0 30
|
||||
#define IMX_SC_C_KACHUNK_CNT 31
|
||||
#define IMX_SC_C_KACHUNK_SEL 32
|
||||
#define IMX_SC_C_SYNC_CTRL1 33
|
||||
#define IMX_SC_C_DPI_RESET 34
|
||||
#define IMX_SC_C_MIPI_RESET 35
|
||||
#define IMX_SC_C_DUAL_MODE 36
|
||||
#define IMX_SC_C_VOLTAGE 37
|
||||
#define IMX_SC_C_PXL_LINK_SEL 38
|
||||
#define IMX_SC_C_OFS_SEL 39
|
||||
#define IMX_SC_C_OFS_AUDIO 40
|
||||
#define IMX_SC_C_OFS_PERIPH 41
|
||||
#define IMX_SC_C_OFS_IRQ 42
|
||||
#define IMX_SC_C_RST0 43
|
||||
#define IMX_SC_C_RST1 44
|
||||
#define IMX_SC_C_SEL0 45
|
||||
#define IMX_SC_C_CALIB0 46
|
||||
#define IMX_SC_C_CALIB1 47
|
||||
#define IMX_SC_C_CALIB2 48
|
||||
#define IMX_SC_C_IPG_DEBUG 49
|
||||
#define IMX_SC_C_IPG_DOZE 50
|
||||
#define IMX_SC_C_IPG_WAIT 51
|
||||
#define IMX_SC_C_IPG_STOP 52
|
||||
#define IMX_SC_C_IPG_STOP_MODE 53
|
||||
#define IMX_SC_C_IPG_STOP_ACK 54
|
||||
#define IMX_SC_C_SYNC_CTRL 55
|
||||
#define IMX_SC_C_OFS_AUDIO_ALT 56
|
||||
#define IMX_SC_C_DSP_BYP 57
|
||||
#define IMX_SC_C_CLK_GEN_EN 58
|
||||
#define IMX_SC_C_INTF_SEL 59
|
||||
#define IMX_SC_C_RXC_DLY 60
|
||||
#define IMX_SC_C_TIMER_SEL 61
|
||||
#define IMX_SC_C_LAST 62
|
||||
|
||||
#endif /* __DT_BINDINGS_RSCRC_IMX_H */
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#define _SC_SCI_H
|
||||
|
||||
#include <linux/firmware/imx/ipc.h>
|
||||
#include <linux/firmware/imx/types.h>
|
||||
|
||||
#include <linux/firmware/imx/svc/misc.h>
|
||||
#include <linux/firmware/imx/svc/pm.h>
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017~2018 NXP
|
||||
*
|
||||
* Header file containing types used across multiple service APIs.
|
||||
*/
|
||||
|
||||
#ifndef _SC_TYPES_H
|
||||
#define _SC_TYPES_H
|
||||
|
||||
/*
|
||||
* This type is used to indicate a control.
|
||||
*/
|
||||
enum imx_sc_ctrl {
|
||||
IMX_SC_C_TEMP = 0,
|
||||
IMX_SC_C_TEMP_HI = 1,
|
||||
IMX_SC_C_TEMP_LOW = 2,
|
||||
IMX_SC_C_PXL_LINK_MST1_ADDR = 3,
|
||||
IMX_SC_C_PXL_LINK_MST2_ADDR = 4,
|
||||
IMX_SC_C_PXL_LINK_MST_ENB = 5,
|
||||
IMX_SC_C_PXL_LINK_MST1_ENB = 6,
|
||||
IMX_SC_C_PXL_LINK_MST2_ENB = 7,
|
||||
IMX_SC_C_PXL_LINK_SLV1_ADDR = 8,
|
||||
IMX_SC_C_PXL_LINK_SLV2_ADDR = 9,
|
||||
IMX_SC_C_PXL_LINK_MST_VLD = 10,
|
||||
IMX_SC_C_PXL_LINK_MST1_VLD = 11,
|
||||
IMX_SC_C_PXL_LINK_MST2_VLD = 12,
|
||||
IMX_SC_C_SINGLE_MODE = 13,
|
||||
IMX_SC_C_ID = 14,
|
||||
IMX_SC_C_PXL_CLK_POLARITY = 15,
|
||||
IMX_SC_C_LINESTATE = 16,
|
||||
IMX_SC_C_PCIE_G_RST = 17,
|
||||
IMX_SC_C_PCIE_BUTTON_RST = 18,
|
||||
IMX_SC_C_PCIE_PERST = 19,
|
||||
IMX_SC_C_PHY_RESET = 20,
|
||||
IMX_SC_C_PXL_LINK_RATE_CORRECTION = 21,
|
||||
IMX_SC_C_PANIC = 22,
|
||||
IMX_SC_C_PRIORITY_GROUP = 23,
|
||||
IMX_SC_C_TXCLK = 24,
|
||||
IMX_SC_C_CLKDIV = 25,
|
||||
IMX_SC_C_DISABLE_50 = 26,
|
||||
IMX_SC_C_DISABLE_125 = 27,
|
||||
IMX_SC_C_SEL_125 = 28,
|
||||
IMX_SC_C_MODE = 29,
|
||||
IMX_SC_C_SYNC_CTRL0 = 30,
|
||||
IMX_SC_C_KACHUNK_CNT = 31,
|
||||
IMX_SC_C_KACHUNK_SEL = 32,
|
||||
IMX_SC_C_SYNC_CTRL1 = 33,
|
||||
IMX_SC_C_DPI_RESET = 34,
|
||||
IMX_SC_C_MIPI_RESET = 35,
|
||||
IMX_SC_C_DUAL_MODE = 36,
|
||||
IMX_SC_C_VOLTAGE = 37,
|
||||
IMX_SC_C_PXL_LINK_SEL = 38,
|
||||
IMX_SC_C_OFS_SEL = 39,
|
||||
IMX_SC_C_OFS_AUDIO = 40,
|
||||
IMX_SC_C_OFS_PERIPH = 41,
|
||||
IMX_SC_C_OFS_IRQ = 42,
|
||||
IMX_SC_C_RST0 = 43,
|
||||
IMX_SC_C_RST1 = 44,
|
||||
IMX_SC_C_SEL0 = 45,
|
||||
IMX_SC_C_LAST
|
||||
};
|
||||
|
||||
#endif /* _SC_TYPES_H */
|
Loading…
Reference in New Issue