Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * SLIM core rproc driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2016 STMicroelectronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author: Peter Griffin <peter.griffin@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/remoteproc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/remoteproc/st_slim_rproc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "remoteproc_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) /* SLIM core registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define SLIM_ID_OFST		0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define SLIM_VER_OFST		0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define SLIM_EN_OFST		0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define SLIM_EN_RUN			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define SLIM_CLK_GATE_OFST	0xC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define SLIM_CLK_GATE_DIS		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define SLIM_CLK_GATE_RESET		BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define SLIM_SLIM_PC_OFST	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /* DMEM registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define SLIM_REV_ID_OFST	0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define SLIM_REV_ID_MIN_MASK		GENMASK(15, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define SLIM_REV_ID_MIN(id)		((id & SLIM_REV_ID_MIN_MASK) >> 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define SLIM_REV_ID_MAJ_MASK		GENMASK(23, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define SLIM_REV_ID_MAJ(id)		((id & SLIM_REV_ID_MAJ_MASK) >> 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) /* peripherals registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define SLIM_STBUS_SYNC_OFST	0xF88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define SLIM_STBUS_SYNC_DIS		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define SLIM_INT_SET_OFST	0xFD4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define SLIM_INT_CLR_OFST	0xFD8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define SLIM_INT_MASK_OFST	0xFDC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define SLIM_CMD_CLR_OFST	0xFC8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define SLIM_CMD_MASK_OFST	0xFCC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static const char *mem_names[ST_SLIM_MEM_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	[ST_SLIM_DMEM]	= "dmem",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	[ST_SLIM_IMEM]	= "imem",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static int slim_clk_get(struct st_slim_rproc *slim_rproc, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	int clk, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	for (clk = 0; clk < ST_SLIM_MAX_CLK; clk++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		slim_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		if (IS_ERR(slim_rproc->clks[clk])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			err = PTR_ERR(slim_rproc->clks[clk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			if (err == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 				goto err_put_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 			slim_rproc->clks[clk] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) err_put_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	while (--clk >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		clk_put(slim_rproc->clks[clk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static void slim_clk_disable(struct st_slim_rproc *slim_rproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	int clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	for (clk = 0; clk < ST_SLIM_MAX_CLK && slim_rproc->clks[clk]; clk++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		clk_disable_unprepare(slim_rproc->clks[clk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) static int slim_clk_enable(struct st_slim_rproc *slim_rproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	int clk, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	for (clk = 0; clk < ST_SLIM_MAX_CLK && slim_rproc->clks[clk]; clk++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		ret = clk_prepare_enable(slim_rproc->clks[clk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			goto err_disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) err_disable_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	while (--clk >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		clk_disable_unprepare(slim_rproc->clks[clk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  * Remoteproc slim specific device handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int slim_rproc_start(struct rproc *rproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	struct device *dev = &rproc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	struct st_slim_rproc *slim_rproc = rproc->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	unsigned long hw_id, hw_ver, fw_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	/* disable CPU pipeline clock & reset CPU pipeline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	val = SLIM_CLK_GATE_DIS | SLIM_CLK_GATE_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	writel(val, slim_rproc->slimcore + SLIM_CLK_GATE_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	/* disable SLIM core STBus sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	writel(SLIM_STBUS_SYNC_DIS, slim_rproc->peri + SLIM_STBUS_SYNC_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	/* enable cpu pipeline clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	writel(!SLIM_CLK_GATE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		slim_rproc->slimcore + SLIM_CLK_GATE_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	/* clear int & cmd mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	writel(~0U, slim_rproc->peri + SLIM_INT_CLR_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	writel(~0U, slim_rproc->peri + SLIM_CMD_CLR_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	/* enable all channels cmd & int */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	writel(~0U, slim_rproc->peri + SLIM_INT_MASK_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	writel(~0U, slim_rproc->peri + SLIM_CMD_MASK_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	/* enable cpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	writel(SLIM_EN_RUN, slim_rproc->slimcore + SLIM_EN_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	hw_id = readl_relaxed(slim_rproc->slimcore + SLIM_ID_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	hw_ver = readl_relaxed(slim_rproc->slimcore + SLIM_VER_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	fw_rev = readl(slim_rproc->mem[ST_SLIM_DMEM].cpu_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			SLIM_REV_ID_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	dev_info(dev, "fw rev:%ld.%ld on SLIM %ld.%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		 SLIM_REV_ID_MAJ(fw_rev), SLIM_REV_ID_MIN(fw_rev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		 hw_id, hw_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int slim_rproc_stop(struct rproc *rproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct st_slim_rproc *slim_rproc = rproc->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	/* mask all (cmd & int) channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	writel(0UL, slim_rproc->peri + SLIM_INT_MASK_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	writel(0UL, slim_rproc->peri + SLIM_CMD_MASK_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	/* disable cpu pipeline clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	writel(SLIM_CLK_GATE_DIS, slim_rproc->slimcore + SLIM_CLK_GATE_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	writel(!SLIM_EN_RUN, slim_rproc->slimcore + SLIM_EN_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	val = readl(slim_rproc->slimcore + SLIM_EN_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	if (val & SLIM_EN_RUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		dev_warn(&rproc->dev, "Failed to disable SLIM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	dev_dbg(&rproc->dev, "slim stopped\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static void *slim_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	struct st_slim_rproc *slim_rproc = rproc->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	void *va = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	for (i = 0; i < ST_SLIM_MEM_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		if (da != slim_rproc->mem[i].bus_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		if (len <= slim_rproc->mem[i].size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			/* __force to make sparse happy with type conversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			va = (__force void *)slim_rproc->mem[i].cpu_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	dev_dbg(&rproc->dev, "da = 0x%llx len = 0x%zx va = 0x%pK\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		da, len, va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	return va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static const struct rproc_ops slim_rproc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	.start		= slim_rproc_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	.stop		= slim_rproc_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	.da_to_va       = slim_rproc_da_to_va,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	.get_boot_addr	= rproc_elf_get_boot_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	.load		= rproc_elf_load_segments,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	.sanity_check	= rproc_elf_sanity_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * st_slim_rproc_alloc() - allocate and initialise slim rproc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * @pdev: Pointer to the platform_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * @fw_name: Name of firmware for rproc to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * Function for allocating and initialising a slim rproc for use by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * device drivers whose IP is based around the SLIM core. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * obtains and enables any clocks required by the SLIM core and also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  * ioremaps the various IO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  * Returns st_slim_rproc pointer or PTR_ERR() on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct st_slim_rproc *st_slim_rproc_alloc(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 				char *fw_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	struct st_slim_rproc *slim_rproc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	struct rproc *rproc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (!fw_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (!of_device_is_compatible(np, "st,slim-rproc"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	rproc = rproc_alloc(dev, np->name, &slim_rproc_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			fw_name, sizeof(*slim_rproc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (!rproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	rproc->has_iommu = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	slim_rproc = rproc->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	slim_rproc->rproc = rproc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	/* get imem and dmem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 						mem_names[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		slim_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		if (IS_ERR(slim_rproc->mem[i].cpu_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			err = PTR_ERR(slim_rproc->mem[i].cpu_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		slim_rproc->mem[i].bus_addr = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		slim_rproc->mem[i].size = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	slim_rproc->slimcore = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	if (IS_ERR(slim_rproc->slimcore)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		dev_err(&pdev->dev, "failed to ioremap slimcore IO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		err = PTR_ERR(slim_rproc->slimcore);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	slim_rproc->peri = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	if (IS_ERR(slim_rproc->peri)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		dev_err(&pdev->dev, "failed to ioremap peripherals IO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		err = PTR_ERR(slim_rproc->peri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	err = slim_clk_get(slim_rproc, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	err = slim_clk_enable(slim_rproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		dev_err(dev, "Failed to enable clocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		goto err_clk_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	/* Register as a remoteproc device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	err = rproc_add(rproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		dev_err(dev, "registration of slim remoteproc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		goto err_clk_dis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	return slim_rproc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) err_clk_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	slim_clk_disable(slim_rproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) err_clk_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	for (i = 0; i < ST_SLIM_MAX_CLK && slim_rproc->clks[i]; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		clk_put(slim_rproc->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	rproc_free(rproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) EXPORT_SYMBOL(st_slim_rproc_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)   * st_slim_rproc_put() - put slim rproc resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)   * @slim_rproc: Pointer to the st_slim_rproc struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)   *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)   * Function for calling respective _put() functions on slim_rproc resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)   *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) void st_slim_rproc_put(struct st_slim_rproc *slim_rproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	int clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (!slim_rproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	slim_clk_disable(slim_rproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	for (clk = 0; clk < ST_SLIM_MAX_CLK && slim_rproc->clks[clk]; clk++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		clk_put(slim_rproc->clks[clk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	rproc_del(slim_rproc->rproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	rproc_free(slim_rproc->rproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) EXPORT_SYMBOL(st_slim_rproc_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) MODULE_DESCRIPTION("STMicroelectronics SLIM core rproc driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) MODULE_LICENSE("GPL v2");