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:
Arnd Bergmann 2020-05-26 00:00:46 +02:00
commit 7b972f3830
6 changed files with 136 additions and 87 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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>

View file

@ -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 */

View file

@ -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>

View file

@ -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 */