brintos

brintos / linux-shallow public Read only

0
0
Text · 23.3 KiB · 8be3f63 Raw
808 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * TI K3 DSP Remote Processor(s) driver4 *5 * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/6 *	Suman Anna <s-anna@ti.com>7 */8 9#include <linux/io.h>10#include <linux/mailbox_client.h>11#include <linux/module.h>12#include <linux/of.h>13#include <linux/of_reserved_mem.h>14#include <linux/omap-mailbox.h>15#include <linux/platform_device.h>16#include <linux/remoteproc.h>17#include <linux/reset.h>18#include <linux/slab.h>19 20#include "omap_remoteproc.h"21#include "remoteproc_internal.h"22#include "ti_sci_proc.h"23 24#define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK	(SZ_16M - 1)25 26/**27 * struct k3_dsp_mem - internal memory structure28 * @cpu_addr: MPU virtual address of the memory region29 * @bus_addr: Bus address used to access the memory region30 * @dev_addr: Device address of the memory region from DSP view31 * @size: Size of the memory region32 */33struct k3_dsp_mem {34	void __iomem *cpu_addr;35	phys_addr_t bus_addr;36	u32 dev_addr;37	size_t size;38};39 40/**41 * struct k3_dsp_mem_data - memory definitions for a DSP42 * @name: name for this memory entry43 * @dev_addr: device address for the memory entry44 */45struct k3_dsp_mem_data {46	const char *name;47	const u32 dev_addr;48};49 50/**51 * struct k3_dsp_dev_data - device data structure for a DSP52 * @mems: pointer to memory definitions for a DSP53 * @num_mems: number of memory regions in @mems54 * @boot_align_addr: boot vector address alignment granularity55 * @uses_lreset: flag to denote the need for local reset management56 */57struct k3_dsp_dev_data {58	const struct k3_dsp_mem_data *mems;59	u32 num_mems;60	u32 boot_align_addr;61	bool uses_lreset;62};63 64/**65 * struct k3_dsp_rproc - k3 DSP remote processor driver structure66 * @dev: cached device pointer67 * @rproc: remoteproc device handle68 * @mem: internal memory regions data69 * @num_mems: number of internal memory regions70 * @rmem: reserved memory regions data71 * @num_rmems: number of reserved memory regions72 * @reset: reset control handle73 * @data: pointer to DSP-specific device data74 * @tsp: TI-SCI processor control handle75 * @ti_sci: TI-SCI handle76 * @ti_sci_id: TI-SCI device identifier77 * @mbox: mailbox channel handle78 * @client: mailbox client to request the mailbox channel79 */80struct k3_dsp_rproc {81	struct device *dev;82	struct rproc *rproc;83	struct k3_dsp_mem *mem;84	int num_mems;85	struct k3_dsp_mem *rmem;86	int num_rmems;87	struct reset_control *reset;88	const struct k3_dsp_dev_data *data;89	struct ti_sci_proc *tsp;90	const struct ti_sci_handle *ti_sci;91	u32 ti_sci_id;92	struct mbox_chan *mbox;93	struct mbox_client client;94};95 96/**97 * k3_dsp_rproc_mbox_callback() - inbound mailbox message handler98 * @client: mailbox client pointer used for requesting the mailbox channel99 * @data: mailbox payload100 *101 * This handler is invoked by the OMAP mailbox driver whenever a mailbox102 * message is received. Usually, the mailbox payload simply contains103 * the index of the virtqueue that is kicked by the remote processor,104 * and we let remoteproc core handle it.105 *106 * In addition to virtqueue indices, we also have some out-of-band values107 * that indicate different events. Those values are deliberately very108 * large so they don't coincide with virtqueue indices.109 */110static void k3_dsp_rproc_mbox_callback(struct mbox_client *client, void *data)111{112	struct k3_dsp_rproc *kproc = container_of(client, struct k3_dsp_rproc,113						  client);114	struct device *dev = kproc->rproc->dev.parent;115	const char *name = kproc->rproc->name;116	u32 msg = omap_mbox_message(data);117 118	/* Do not forward messages from a detached core */119	if (kproc->rproc->state == RPROC_DETACHED)120		return;121 122	dev_dbg(dev, "mbox msg: 0x%x\n", msg);123 124	switch (msg) {125	case RP_MBOX_CRASH:126		/*127		 * remoteproc detected an exception, but error recovery is not128		 * supported. So, just log this for now129		 */130		dev_err(dev, "K3 DSP rproc %s crashed\n", name);131		break;132	case RP_MBOX_ECHO_REPLY:133		dev_info(dev, "received echo reply from %s\n", name);134		break;135	default:136		/* silently handle all other valid messages */137		if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)138			return;139		if (msg > kproc->rproc->max_notifyid) {140			dev_dbg(dev, "dropping unknown message 0x%x", msg);141			return;142		}143		/* msg contains the index of the triggered vring */144		if (rproc_vq_interrupt(kproc->rproc, msg) == IRQ_NONE)145			dev_dbg(dev, "no message was found in vqid %d\n", msg);146	}147}148 149/*150 * Kick the remote processor to notify about pending unprocessed messages.151 * The vqid usage is not used and is inconsequential, as the kick is performed152 * through a simulated GPIO (a bit in an IPC interrupt-triggering register),153 * the remote processor is expected to process both its Tx and Rx virtqueues.154 */155static void k3_dsp_rproc_kick(struct rproc *rproc, int vqid)156{157	struct k3_dsp_rproc *kproc = rproc->priv;158	struct device *dev = rproc->dev.parent;159	mbox_msg_t msg = (mbox_msg_t)vqid;160	int ret;161 162	/* Do not forward messages to a detached core */163	if (kproc->rproc->state == RPROC_DETACHED)164		return;165 166	/* send the index of the triggered virtqueue in the mailbox payload */167	ret = mbox_send_message(kproc->mbox, (void *)msg);168	if (ret < 0)169		dev_err(dev, "failed to send mailbox message (%pe)\n",170			ERR_PTR(ret));171}172 173/* Put the DSP processor into reset */174static int k3_dsp_rproc_reset(struct k3_dsp_rproc *kproc)175{176	struct device *dev = kproc->dev;177	int ret;178 179	ret = reset_control_assert(kproc->reset);180	if (ret) {181		dev_err(dev, "local-reset assert failed (%pe)\n", ERR_PTR(ret));182		return ret;183	}184 185	if (kproc->data->uses_lreset)186		return ret;187 188	ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,189						    kproc->ti_sci_id);190	if (ret) {191		dev_err(dev, "module-reset assert failed (%pe)\n", ERR_PTR(ret));192		if (reset_control_deassert(kproc->reset))193			dev_warn(dev, "local-reset deassert back failed\n");194	}195 196	return ret;197}198 199/* Release the DSP processor from reset */200static int k3_dsp_rproc_release(struct k3_dsp_rproc *kproc)201{202	struct device *dev = kproc->dev;203	int ret;204 205	if (kproc->data->uses_lreset)206		goto lreset;207 208	ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,209						    kproc->ti_sci_id);210	if (ret) {211		dev_err(dev, "module-reset deassert failed (%pe)\n", ERR_PTR(ret));212		return ret;213	}214 215lreset:216	ret = reset_control_deassert(kproc->reset);217	if (ret) {218		dev_err(dev, "local-reset deassert failed, (%pe)\n", ERR_PTR(ret));219		if (kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,220							  kproc->ti_sci_id))221			dev_warn(dev, "module-reset assert back failed\n");222	}223 224	return ret;225}226 227static int k3_dsp_rproc_request_mbox(struct rproc *rproc)228{229	struct k3_dsp_rproc *kproc = rproc->priv;230	struct mbox_client *client = &kproc->client;231	struct device *dev = kproc->dev;232	int ret;233 234	client->dev = dev;235	client->tx_done = NULL;236	client->rx_callback = k3_dsp_rproc_mbox_callback;237	client->tx_block = false;238	client->knows_txdone = false;239 240	kproc->mbox = mbox_request_channel(client, 0);241	if (IS_ERR(kproc->mbox))242		return dev_err_probe(dev, PTR_ERR(kproc->mbox),243				     "mbox_request_channel failed\n");244 245	/*246	 * Ping the remote processor, this is only for sanity-sake for now;247	 * there is no functional effect whatsoever.248	 *249	 * Note that the reply will _not_ arrive immediately: this message250	 * will wait in the mailbox fifo until the remote processor is booted.251	 */252	ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST);253	if (ret < 0) {254		dev_err(dev, "mbox_send_message failed (%pe)\n", ERR_PTR(ret));255		mbox_free_channel(kproc->mbox);256		return ret;257	}258 259	return 0;260}261/*262 * The C66x DSP cores have a local reset that affects only the CPU, and a263 * generic module reset that powers on the device and allows the DSP internal264 * memories to be accessed while the local reset is asserted. This function is265 * used to release the global reset on C66x DSPs to allow loading into the DSP266 * internal RAMs. The .prepare() ops is invoked by remoteproc core before any267 * firmware loading, and is followed by the .start() ops after loading to268 * actually let the C66x DSP cores run. This callback is invoked only in269 * remoteproc mode.270 */271static int k3_dsp_rproc_prepare(struct rproc *rproc)272{273	struct k3_dsp_rproc *kproc = rproc->priv;274	struct device *dev = kproc->dev;275	int ret;276 277	ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,278						    kproc->ti_sci_id);279	if (ret)280		dev_err(dev, "module-reset deassert failed, cannot enable internal RAM loading (%pe)\n",281			ERR_PTR(ret));282 283	return ret;284}285 286/*287 * This function implements the .unprepare() ops and performs the complimentary288 * operations to that of the .prepare() ops. The function is used to assert the289 * global reset on applicable C66x cores. This completes the second portion of290 * powering down the C66x DSP cores. The cores themselves are only halted in the291 * .stop() callback through the local reset, and the .unprepare() ops is invoked292 * by the remoteproc core after the remoteproc is stopped to balance the global293 * reset. This callback is invoked only in remoteproc mode.294 */295static int k3_dsp_rproc_unprepare(struct rproc *rproc)296{297	struct k3_dsp_rproc *kproc = rproc->priv;298	struct device *dev = kproc->dev;299	int ret;300 301	ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,302						    kproc->ti_sci_id);303	if (ret)304		dev_err(dev, "module-reset assert failed (%pe)\n", ERR_PTR(ret));305 306	return ret;307}308 309/*310 * Power up the DSP remote processor.311 *312 * This function will be invoked only after the firmware for this rproc313 * was loaded, parsed successfully, and all of its resource requirements314 * were met. This callback is invoked only in remoteproc mode.315 */316static int k3_dsp_rproc_start(struct rproc *rproc)317{318	struct k3_dsp_rproc *kproc = rproc->priv;319	struct device *dev = kproc->dev;320	u32 boot_addr;321	int ret;322 323	boot_addr = rproc->bootaddr;324	if (boot_addr & (kproc->data->boot_align_addr - 1)) {325		dev_err(dev, "invalid boot address 0x%x, must be aligned on a 0x%x boundary\n",326			boot_addr, kproc->data->boot_align_addr);327		return -EINVAL;328	}329 330	dev_dbg(dev, "booting DSP core using boot addr = 0x%x\n", boot_addr);331	ret = ti_sci_proc_set_config(kproc->tsp, boot_addr, 0, 0);332	if (ret)333		return ret;334 335	ret = k3_dsp_rproc_release(kproc);336	if (ret)337		return ret;338 339	return 0;340}341 342/*343 * Stop the DSP remote processor.344 *345 * This function puts the DSP processor into reset, and finishes processing346 * of any pending messages. This callback is invoked only in remoteproc mode.347 */348static int k3_dsp_rproc_stop(struct rproc *rproc)349{350	struct k3_dsp_rproc *kproc = rproc->priv;351 352	k3_dsp_rproc_reset(kproc);353 354	return 0;355}356 357/*358 * Attach to a running DSP remote processor (IPC-only mode)359 *360 * This rproc attach callback is a NOP. The remote processor is already booted,361 * and all required resources have been acquired during probe routine, so there362 * is no need to issue any TI-SCI commands to boot the DSP core. This callback363 * is invoked only in IPC-only mode and exists because rproc_validate() checks364 * for its existence.365 */366static int k3_dsp_rproc_attach(struct rproc *rproc) { return 0; }367 368/*369 * Detach from a running DSP remote processor (IPC-only mode)370 *371 * This rproc detach callback is a NOP. The DSP core is not stopped and will be372 * left to continue to run its booted firmware. This callback is invoked only in373 * IPC-only mode and exists for sanity sake.374 */375static int k3_dsp_rproc_detach(struct rproc *rproc) { return 0; }376 377/*378 * This function implements the .get_loaded_rsc_table() callback and is used379 * to provide the resource table for a booted DSP in IPC-only mode. The K3 DSP380 * firmwares follow a design-by-contract approach and are expected to have the381 * resource table at the base of the DDR region reserved for firmware usage.382 * This provides flexibility for the remote processor to be booted by different383 * bootloaders that may or may not have the ability to publish the resource table384 * address and size through a DT property. This callback is invoked only in385 * IPC-only mode.386 */387static struct resource_table *k3_dsp_get_loaded_rsc_table(struct rproc *rproc,388							  size_t *rsc_table_sz)389{390	struct k3_dsp_rproc *kproc = rproc->priv;391	struct device *dev = kproc->dev;392 393	if (!kproc->rmem[0].cpu_addr) {394		dev_err(dev, "memory-region #1 does not exist, loaded rsc table can't be found");395		return ERR_PTR(-ENOMEM);396	}397 398	/*399	 * NOTE: The resource table size is currently hard-coded to a maximum400	 * of 256 bytes. The most common resource table usage for K3 firmwares401	 * is to only have the vdev resource entry and an optional trace entry.402	 * The exact size could be computed based on resource table address, but403	 * the hard-coded value suffices to support the IPC-only mode.404	 */405	*rsc_table_sz = 256;406	return (struct resource_table *)kproc->rmem[0].cpu_addr;407}408 409/*410 * Custom function to translate a DSP device address (internal RAMs only) to a411 * kernel virtual address.  The DSPs can access their RAMs at either an internal412 * address visible only from a DSP, or at the SoC-level bus address. Both these413 * addresses need to be looked through for translation. The translated addresses414 * can be used either by the remoteproc core for loading (when using kernel415 * remoteproc loader), or by any rpmsg bus drivers.416 */417static void *k3_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)418{419	struct k3_dsp_rproc *kproc = rproc->priv;420	void __iomem *va = NULL;421	phys_addr_t bus_addr;422	u32 dev_addr, offset;423	size_t size;424	int i;425 426	if (len == 0)427		return NULL;428 429	for (i = 0; i < kproc->num_mems; i++) {430		bus_addr = kproc->mem[i].bus_addr;431		dev_addr = kproc->mem[i].dev_addr;432		size = kproc->mem[i].size;433 434		if (da < KEYSTONE_RPROC_LOCAL_ADDRESS_MASK) {435			/* handle DSP-view addresses */436			if (da >= dev_addr &&437			    ((da + len) <= (dev_addr + size))) {438				offset = da - dev_addr;439				va = kproc->mem[i].cpu_addr + offset;440				return (__force void *)va;441			}442		} else {443			/* handle SoC-view addresses */444			if (da >= bus_addr &&445			    (da + len) <= (bus_addr + size)) {446				offset = da - bus_addr;447				va = kproc->mem[i].cpu_addr + offset;448				return (__force void *)va;449			}450		}451	}452 453	/* handle static DDR reserved memory regions */454	for (i = 0; i < kproc->num_rmems; i++) {455		dev_addr = kproc->rmem[i].dev_addr;456		size = kproc->rmem[i].size;457 458		if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {459			offset = da - dev_addr;460			va = kproc->rmem[i].cpu_addr + offset;461			return (__force void *)va;462		}463	}464 465	return NULL;466}467 468static const struct rproc_ops k3_dsp_rproc_ops = {469	.start		= k3_dsp_rproc_start,470	.stop		= k3_dsp_rproc_stop,471	.kick		= k3_dsp_rproc_kick,472	.da_to_va	= k3_dsp_rproc_da_to_va,473};474 475static int k3_dsp_rproc_of_get_memories(struct platform_device *pdev,476					struct k3_dsp_rproc *kproc)477{478	const struct k3_dsp_dev_data *data = kproc->data;479	struct device *dev = &pdev->dev;480	struct resource *res;481	int num_mems = 0;482	int i;483 484	num_mems = kproc->data->num_mems;485	kproc->mem = devm_kcalloc(kproc->dev, num_mems,486				  sizeof(*kproc->mem), GFP_KERNEL);487	if (!kproc->mem)488		return -ENOMEM;489 490	for (i = 0; i < num_mems; i++) {491		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,492						   data->mems[i].name);493		if (!res) {494			dev_err(dev, "found no memory resource for %s\n",495				data->mems[i].name);496			return -EINVAL;497		}498		if (!devm_request_mem_region(dev, res->start,499					     resource_size(res),500					     dev_name(dev))) {501			dev_err(dev, "could not request %s region for resource\n",502				data->mems[i].name);503			return -EBUSY;504		}505 506		kproc->mem[i].cpu_addr = devm_ioremap_wc(dev, res->start,507							 resource_size(res));508		if (!kproc->mem[i].cpu_addr) {509			dev_err(dev, "failed to map %s memory\n",510				data->mems[i].name);511			return -ENOMEM;512		}513		kproc->mem[i].bus_addr = res->start;514		kproc->mem[i].dev_addr = data->mems[i].dev_addr;515		kproc->mem[i].size = resource_size(res);516 517		dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %pK da 0x%x\n",518			data->mems[i].name, &kproc->mem[i].bus_addr,519			kproc->mem[i].size, kproc->mem[i].cpu_addr,520			kproc->mem[i].dev_addr);521	}522	kproc->num_mems = num_mems;523 524	return 0;525}526 527static void k3_dsp_mem_release(void *data)528{529	struct device *dev = data;530 531	of_reserved_mem_device_release(dev);532}533 534static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)535{536	struct device *dev = kproc->dev;537	struct device_node *np = dev->of_node;538	struct device_node *rmem_np;539	struct reserved_mem *rmem;540	int num_rmems;541	int ret, i;542 543	num_rmems = of_property_count_elems_of_size(np, "memory-region",544						    sizeof(phandle));545	if (num_rmems < 0) {546		dev_err(dev, "device does not reserved memory regions (%pe)\n",547			ERR_PTR(num_rmems));548		return -EINVAL;549	}550	if (num_rmems < 2) {551		dev_err(dev, "device needs at least two memory regions to be defined, num = %d\n",552			num_rmems);553		return -EINVAL;554	}555 556	/* use reserved memory region 0 for vring DMA allocations */557	ret = of_reserved_mem_device_init_by_idx(dev, np, 0);558	if (ret) {559		dev_err(dev, "device cannot initialize DMA pool (%pe)\n",560			ERR_PTR(ret));561		return ret;562	}563	ret = devm_add_action_or_reset(dev, k3_dsp_mem_release, dev);564	if (ret)565		return ret;566 567	num_rmems--;568	kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);569	if (!kproc->rmem)570		return -ENOMEM;571 572	/* use remaining reserved memory regions for static carveouts */573	for (i = 0; i < num_rmems; i++) {574		rmem_np = of_parse_phandle(np, "memory-region", i + 1);575		if (!rmem_np)576			return -EINVAL;577 578		rmem = of_reserved_mem_lookup(rmem_np);579		if (!rmem) {580			of_node_put(rmem_np);581			return -EINVAL;582		}583		of_node_put(rmem_np);584 585		kproc->rmem[i].bus_addr = rmem->base;586		/* 64-bit address regions currently not supported */587		kproc->rmem[i].dev_addr = (u32)rmem->base;588		kproc->rmem[i].size = rmem->size;589		kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);590		if (!kproc->rmem[i].cpu_addr) {591			dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",592				i + 1, &rmem->base, &rmem->size);593			return -ENOMEM;594		}595 596		dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",597			i + 1, &kproc->rmem[i].bus_addr,598			kproc->rmem[i].size, kproc->rmem[i].cpu_addr,599			kproc->rmem[i].dev_addr);600	}601	kproc->num_rmems = num_rmems;602 603	return 0;604}605 606static void k3_dsp_release_tsp(void *data)607{608	struct ti_sci_proc *tsp = data;609 610	ti_sci_proc_release(tsp);611}612 613static int k3_dsp_rproc_probe(struct platform_device *pdev)614{615	struct device *dev = &pdev->dev;616	struct device_node *np = dev->of_node;617	const struct k3_dsp_dev_data *data;618	struct k3_dsp_rproc *kproc;619	struct rproc *rproc;620	const char *fw_name;621	bool p_state = false;622	int ret = 0;623 624	data = of_device_get_match_data(dev);625	if (!data)626		return -ENODEV;627 628	ret = rproc_of_parse_firmware(dev, 0, &fw_name);629	if (ret)630		return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");631 632	rproc = devm_rproc_alloc(dev, dev_name(dev), &k3_dsp_rproc_ops,633				 fw_name, sizeof(*kproc));634	if (!rproc)635		return -ENOMEM;636 637	rproc->has_iommu = false;638	rproc->recovery_disabled = true;639	if (data->uses_lreset) {640		rproc->ops->prepare = k3_dsp_rproc_prepare;641		rproc->ops->unprepare = k3_dsp_rproc_unprepare;642	}643	kproc = rproc->priv;644	kproc->rproc = rproc;645	kproc->dev = dev;646	kproc->data = data;647 648	ret = k3_dsp_rproc_request_mbox(rproc);649	if (ret)650		return ret;651 652	kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");653	if (IS_ERR(kproc->ti_sci))654		return dev_err_probe(dev, PTR_ERR(kproc->ti_sci),655				     "failed to get ti-sci handle\n");656 657	ret = of_property_read_u32(np, "ti,sci-dev-id", &kproc->ti_sci_id);658	if (ret)659		return dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n");660 661	kproc->reset = devm_reset_control_get_exclusive(dev, NULL);662	if (IS_ERR(kproc->reset))663		return dev_err_probe(dev, PTR_ERR(kproc->reset),664				     "failed to get reset\n");665 666	kproc->tsp = ti_sci_proc_of_get_tsp(dev, kproc->ti_sci);667	if (IS_ERR(kproc->tsp))668		return dev_err_probe(dev, PTR_ERR(kproc->tsp),669				     "failed to construct ti-sci proc control\n");670 671	ret = ti_sci_proc_request(kproc->tsp);672	if (ret < 0) {673		dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");674		return ret;675	}676	ret = devm_add_action_or_reset(dev, k3_dsp_release_tsp, kproc->tsp);677	if (ret)678		return ret;679 680	ret = k3_dsp_rproc_of_get_memories(pdev, kproc);681	if (ret)682		return ret;683 684	ret = k3_dsp_reserved_mem_init(kproc);685	if (ret)686		return dev_err_probe(dev, ret, "reserved memory init failed\n");687 688	ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,689					       NULL, &p_state);690	if (ret)691		return dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");692 693	/* configure J721E devices for either remoteproc or IPC-only mode */694	if (p_state) {695		dev_info(dev, "configured DSP for IPC-only mode\n");696		rproc->state = RPROC_DETACHED;697		/* override rproc ops with only required IPC-only mode ops */698		rproc->ops->prepare = NULL;699		rproc->ops->unprepare = NULL;700		rproc->ops->start = NULL;701		rproc->ops->stop = NULL;702		rproc->ops->attach = k3_dsp_rproc_attach;703		rproc->ops->detach = k3_dsp_rproc_detach;704		rproc->ops->get_loaded_rsc_table = k3_dsp_get_loaded_rsc_table;705	} else {706		dev_info(dev, "configured DSP for remoteproc mode\n");707		/*708		 * ensure the DSP local reset is asserted to ensure the DSP709		 * doesn't execute bogus code in .prepare() when the module710		 * reset is released.711		 */712		if (data->uses_lreset) {713			ret = reset_control_status(kproc->reset);714			if (ret < 0) {715				return dev_err_probe(dev, ret, "failed to get reset status\n");716			} else if (ret == 0) {717				dev_warn(dev, "local reset is deasserted for device\n");718				k3_dsp_rproc_reset(kproc);719			}720		}721	}722 723	ret = devm_rproc_add(dev, rproc);724	if (ret)725		return dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");726 727	platform_set_drvdata(pdev, kproc);728 729	return 0;730}731 732static void k3_dsp_rproc_remove(struct platform_device *pdev)733{734	struct k3_dsp_rproc *kproc = platform_get_drvdata(pdev);735	struct rproc *rproc = kproc->rproc;736	struct device *dev = &pdev->dev;737	int ret;738 739	if (rproc->state == RPROC_ATTACHED) {740		ret = rproc_detach(rproc);741		if (ret)742			dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret));743	}744 745	mbox_free_channel(kproc->mbox);746}747 748static const struct k3_dsp_mem_data c66_mems[] = {749	{ .name = "l2sram", .dev_addr = 0x800000 },750	{ .name = "l1pram", .dev_addr = 0xe00000 },751	{ .name = "l1dram", .dev_addr = 0xf00000 },752};753 754/* C71x cores only have a L1P Cache, there are no L1P SRAMs */755static const struct k3_dsp_mem_data c71_mems[] = {756	{ .name = "l2sram", .dev_addr = 0x800000 },757	{ .name = "l1dram", .dev_addr = 0xe00000 },758};759 760static const struct k3_dsp_mem_data c7xv_mems[] = {761	{ .name = "l2sram", .dev_addr = 0x800000 },762};763 764static const struct k3_dsp_dev_data c66_data = {765	.mems = c66_mems,766	.num_mems = ARRAY_SIZE(c66_mems),767	.boot_align_addr = SZ_1K,768	.uses_lreset = true,769};770 771static const struct k3_dsp_dev_data c71_data = {772	.mems = c71_mems,773	.num_mems = ARRAY_SIZE(c71_mems),774	.boot_align_addr = SZ_2M,775	.uses_lreset = false,776};777 778static const struct k3_dsp_dev_data c7xv_data = {779	.mems = c7xv_mems,780	.num_mems = ARRAY_SIZE(c7xv_mems),781	.boot_align_addr = SZ_2M,782	.uses_lreset = false,783};784 785static const struct of_device_id k3_dsp_of_match[] = {786	{ .compatible = "ti,j721e-c66-dsp", .data = &c66_data, },787	{ .compatible = "ti,j721e-c71-dsp", .data = &c71_data, },788	{ .compatible = "ti,j721s2-c71-dsp", .data = &c71_data, },789	{ .compatible = "ti,am62a-c7xv-dsp", .data = &c7xv_data, },790	{ /* sentinel */ },791};792MODULE_DEVICE_TABLE(of, k3_dsp_of_match);793 794static struct platform_driver k3_dsp_rproc_driver = {795	.probe	= k3_dsp_rproc_probe,796	.remove_new = k3_dsp_rproc_remove,797	.driver	= {798		.name = "k3-dsp-rproc",799		.of_match_table = k3_dsp_of_match,800	},801};802 803module_platform_driver(k3_dsp_rproc_driver);804 805MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");806MODULE_LICENSE("GPL v2");807MODULE_DESCRIPTION("TI K3 DSP Remoteproc driver");808