Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'imx-drivers-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers

i.MX drivers change for 5.11:

- A series from Daniel Baluta to update imx-dsp driver and export
functions for on demand channel request/free.
- A number of patches to add power domains for i.MX8qxp DC0, LVDS1,
MIPI1 and JPEG subsystems.
- Add dummy functions for i.MX firmware drivers to avoid build failure
seen with COMPILE_TEST.

* tag 'imx-drivers-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux:
firmware: imx: scu-pd: Add some power domains support for i.MX8qxp MIPI1 subsystem
firmware: imx: scu-pd: Add main power domain support for i.MX8qxp LVDS1 subsystem
firmware: imx: scu-pd: Add video0/1 power domains support for i.MX8qxp DC0 subsystem
firmware: imx-dsp: Export functions to request/free channels
firmware: imx: Save channel name for further use
firmware: imx: Introduce imx_dsp_setup_channels
firmware: imx: scu-pd: Add power domains for imx-jpeg
firmware: imx: add dummy functions

Link: https://lore.kernel.org/r/20201202142717.9262-1-shawnguo@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+137 -20
+56 -20
drivers/firmware/imx/imx-dsp.c
··· 60 60 } 61 61 } 62 62 63 - static int imx_dsp_probe(struct platform_device *pdev) 63 + struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *dsp_ipc, int idx) 64 64 { 65 - struct device *dev = &pdev->dev; 66 - struct imx_dsp_ipc *dsp_ipc; 65 + struct imx_dsp_chan *dsp_chan; 66 + 67 + if (idx >= DSP_MU_CHAN_NUM) 68 + return ERR_PTR(-EINVAL); 69 + 70 + dsp_chan = &dsp_ipc->chans[idx]; 71 + dsp_chan->ch = mbox_request_channel_byname(&dsp_chan->cl, dsp_chan->name); 72 + return dsp_chan->ch; 73 + } 74 + EXPORT_SYMBOL(imx_dsp_request_channel); 75 + 76 + void imx_dsp_free_channel(struct imx_dsp_ipc *dsp_ipc, int idx) 77 + { 78 + struct imx_dsp_chan *dsp_chan; 79 + 80 + if (idx >= DSP_MU_CHAN_NUM) 81 + return; 82 + 83 + dsp_chan = &dsp_ipc->chans[idx]; 84 + mbox_free_channel(dsp_chan->ch); 85 + } 86 + EXPORT_SYMBOL(imx_dsp_free_channel); 87 + 88 + static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc) 89 + { 90 + struct device *dev = dsp_ipc->dev; 67 91 struct imx_dsp_chan *dsp_chan; 68 92 struct mbox_client *cl; 69 93 char *chan_name; 70 94 int ret; 71 95 int i, j; 72 - 73 - device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent); 74 - 75 - dsp_ipc = devm_kzalloc(dev, sizeof(*dsp_ipc), GFP_KERNEL); 76 - if (!dsp_ipc) 77 - return -ENOMEM; 78 96 79 97 for (i = 0; i < DSP_MU_CHAN_NUM; i++) { 80 98 if (i < 2) ··· 104 86 return -ENOMEM; 105 87 106 88 dsp_chan = &dsp_ipc->chans[i]; 89 + dsp_chan->name = chan_name; 107 90 cl = &dsp_chan->cl; 108 91 cl->dev = dev; 109 92 cl->tx_block = false; ··· 123 104 } 124 105 125 106 dev_dbg(dev, "request mbox chan %s\n", chan_name); 126 - /* chan_name is not used anymore by framework */ 127 - kfree(chan_name); 128 107 } 129 108 130 - dsp_ipc->dev = dev; 109 + return 0; 110 + out: 111 + for (j = 0; j < i; j++) { 112 + dsp_chan = &dsp_ipc->chans[j]; 113 + mbox_free_channel(dsp_chan->ch); 114 + kfree(dsp_chan->name); 115 + } 131 116 117 + return ret; 118 + } 119 + 120 + static int imx_dsp_probe(struct platform_device *pdev) 121 + { 122 + struct device *dev = &pdev->dev; 123 + struct imx_dsp_ipc *dsp_ipc; 124 + int ret; 125 + 126 + device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent); 127 + 128 + dsp_ipc = devm_kzalloc(dev, sizeof(*dsp_ipc), GFP_KERNEL); 129 + if (!dsp_ipc) 130 + return -ENOMEM; 131 + 132 + dsp_ipc->dev = dev; 132 133 dev_set_drvdata(dev, dsp_ipc); 134 + 135 + ret = imx_dsp_setup_channels(dsp_ipc); 136 + if (ret < 0) 137 + return ret; 133 138 134 139 dev_info(dev, "NXP i.MX DSP IPC initialized\n"); 135 140 136 141 return 0; 137 - out: 138 - kfree(chan_name); 139 - for (j = 0; j < i; j++) { 140 - dsp_chan = &dsp_ipc->chans[j]; 141 - mbox_free_channel(dsp_chan->ch); 142 - } 143 - 144 - return ret; 145 142 } 146 143 147 144 static int imx_dsp_remove(struct platform_device *pdev) ··· 171 136 for (i = 0; i < DSP_MU_CHAN_NUM; i++) { 172 137 dsp_chan = &dsp_ipc->chans[i]; 173 138 mbox_free_channel(dsp_chan->ch); 139 + kfree(dsp_chan->name); 174 140 } 175 141 176 142 return 0;
+12
drivers/firmware/imx/scu-pd.c
··· 160 160 { "mipi0-pwm0", IMX_SC_R_MIPI_0_PWM_0, 1, false, 0 }, 161 161 { "mipi0-i2c", IMX_SC_R_MIPI_0_I2C_0, 2, true, 0 }, 162 162 163 + { "mipi1", IMX_SC_R_MIPI_1, 1, false, 0 }, 164 + { "mipi1-pwm0", IMX_SC_R_MIPI_1_PWM_0, 1, false, 0 }, 165 + { "mipi1-i2c", IMX_SC_R_MIPI_1_I2C_0, 2, true, 0 }, 166 + 163 167 /* LVDS SS */ 164 168 { "lvds0", IMX_SC_R_LVDS_0, 1, false, 0 }, 169 + { "lvds1", IMX_SC_R_LVDS_1, 1, false, 0 }, 165 170 166 171 /* DC SS */ 167 172 { "dc0", IMX_SC_R_DC_0, 1, false, 0 }, 168 173 { "dc0-pll", IMX_SC_R_DC_0_PLL_0, 2, true, 0 }, 174 + { "dc0-video", IMX_SC_R_DC_0_VIDEO0, 2, true, 0 }, 169 175 170 176 /* CM40 SS */ 171 177 { "cm40-i2c", IMX_SC_R_M4_0_I2C, 1, false, 0 }, ··· 186 180 { "cm41-pid", IMX_SC_R_M4_1_PID0, 5, true, 0}, 187 181 { "cm41-mu-a1", IMX_SC_R_M4_1_MU_1A, 1, false, 0}, 188 182 { "cm41-lpuart", IMX_SC_R_M4_1_UART, 1, false, 0}, 183 + 184 + /* IMAGE SS */ 185 + { "img-jpegdec-mp", IMX_SC_R_MJPEG_DEC_MP, 1, false, 0 }, 186 + { "img-jpegdec-s0", IMX_SC_R_MJPEG_DEC_S0, 4, true, 0 }, 187 + { "img-jpegenc-mp", IMX_SC_R_MJPEG_ENC_MP, 1, false, 0 }, 188 + { "img-jpegenc-s0", IMX_SC_R_MJPEG_ENC_S0, 4, true, 0 }, 189 189 }; 190 190 191 191 static const struct imx_sc_pd_soc imx8qxp_scu_pd = {
+10
include/linux/firmware/imx/dsp.h
··· 55 55 56 56 int imx_dsp_ring_doorbell(struct imx_dsp_ipc *dsp, unsigned int chan_idx); 57 57 58 + struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *ipc, int idx); 59 + void imx_dsp_free_channel(struct imx_dsp_ipc *ipc, int idx); 60 + 58 61 #else 59 62 60 63 static inline int imx_dsp_ring_doorbell(struct imx_dsp_ipc *ipc, ··· 65 62 { 66 63 return -ENOTSUPP; 67 64 } 65 + 66 + struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *ipc, int idx) 67 + { 68 + return ERR_PTR(-EOPNOTSUPP); 69 + } 70 + 71 + void imx_dsp_free_channel(struct imx_dsp_ipc *ipc, int idx) { } 68 72 69 73 #endif 70 74 #endif /* _IMX_DSP_IPC_H */
+13
include/linux/firmware/imx/ipc.h
··· 34 34 uint8_t func; 35 35 }; 36 36 37 + #ifdef CONFIG_IMX_SCU 37 38 /* 38 39 * This is an function to send an RPC message over an IPC channel. 39 40 * It is called by client-side SCFW API function shims. ··· 56 55 * @return Returns an error code (0 = success, failed if < 0) 57 56 */ 58 57 int imx_scu_get_handle(struct imx_sc_ipc **ipc); 58 + #else 59 + static inline int imx_scu_call_rpc(struct imx_sc_ipc *ipc, void *msg, 60 + bool have_resp) 61 + { 62 + return -ENOTSUPP; 63 + } 64 + 65 + static inline int imx_scu_get_handle(struct imx_sc_ipc **ipc) 66 + { 67 + return -ENOTSUPP; 68 + } 69 + #endif 59 70 #endif /* _SC_IPC_H */
+27
include/linux/firmware/imx/sci.h
··· 16 16 #include <linux/firmware/imx/svc/pm.h> 17 17 #include <linux/firmware/imx/svc/rm.h> 18 18 19 + #if IS_ENABLED(CONFIG_IMX_SCU) 19 20 int imx_scu_enable_general_irq_channel(struct device *dev); 20 21 int imx_scu_irq_register_notifier(struct notifier_block *nb); 21 22 int imx_scu_irq_unregister_notifier(struct notifier_block *nb); 22 23 int imx_scu_irq_group_enable(u8 group, u32 mask, u8 enable); 23 24 int imx_scu_soc_init(struct device *dev); 25 + #else 26 + static inline int imx_scu_soc_init(struct device *dev) 27 + { 28 + return -ENOTSUPP; 29 + } 30 + 31 + static inline int imx_scu_enable_general_irq_channel(struct device *dev) 32 + { 33 + return -ENOTSUPP; 34 + } 35 + 36 + static inline int imx_scu_irq_register_notifier(struct notifier_block *nb) 37 + { 38 + return -ENOTSUPP; 39 + } 40 + 41 + static inline int imx_scu_irq_unregister_notifier(struct notifier_block *nb) 42 + { 43 + return -ENOTSUPP; 44 + } 45 + 46 + static inline int imx_scu_irq_group_enable(u8 group, u32 mask, u8 enable) 47 + { 48 + return -ENOTSUPP; 49 + } 50 + #endif 24 51 #endif /* _SC_SCI_H */
+19
include/linux/firmware/imx/svc/misc.h
··· 46 46 * Control Functions 47 47 */ 48 48 49 + #ifdef CONFIG_IMX_SCU 49 50 int imx_sc_misc_set_control(struct imx_sc_ipc *ipc, u32 resource, 50 51 u8 ctrl, u32 val); 51 52 ··· 55 54 56 55 int imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource, 57 56 bool enable, u64 phys_addr); 57 + #else 58 + static inline int imx_sc_misc_set_control(struct imx_sc_ipc *ipc, 59 + u32 resource, u8 ctrl, u32 val) 60 + { 61 + return -ENOTSUPP; 62 + } 58 63 64 + static inline int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, 65 + u32 resource, u8 ctrl, u32 *val) 66 + { 67 + return -ENOTSUPP; 68 + } 69 + 70 + static inline int imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource, 71 + bool enable, u64 phys_addr) 72 + { 73 + return -ENOTSUPP; 74 + } 75 + #endif 59 76 #endif /* _SC_MISC_API_H */