File Index
Files and directories
Sign in
FILE

ti_k3_m4_remoteproc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/remoteproc/ti_k3_m4_remoteproc.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * TI K3 Cortex-M4 Remote Processor(s) driver
  4 *
  5 * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
  6 *	Hari Nagalla <hnagalla@ti.com>
  7 */
  8
  9#include <linux/io.h>
 10#include <linux/mailbox_client.h>
 11#include <linux/module.h>
 12#include <linux/of_address.h>
 13#include <linux/of_reserved_mem.h>
 14#include <linux/platform_device.h>
 15#include <linux/remoteproc.h>
 16#include <linux/reset.h>
 17#include <linux/slab.h>
 18
 19#include "omap_remoteproc.h"
 20#include "remoteproc_internal.h"
 21#include "ti_sci_proc.h"
 22#include "ti_k3_common.h"
 23
 24static const struct rproc_ops k3_m4_rproc_ops = {
 25	.prepare = k3_rproc_prepare,
 26	.unprepare = k3_rproc_unprepare,
 27	.start = k3_rproc_start,
 28	.stop = k3_rproc_stop,
 29	.attach = k3_rproc_attach,
 30	.detach = k3_rproc_detach,
 31	.kick = k3_rproc_kick,
 32	.da_to_va = k3_rproc_da_to_va,
 33	.get_loaded_rsc_table = k3_get_loaded_rsc_table,
 34};
 35
 36static int k3_m4_rproc_probe(struct platform_device *pdev)
 37{
 38	const struct k3_rproc_dev_data *data;
 39	struct device *dev = &pdev->dev;
 40	struct k3_rproc *kproc;
 41	struct rproc *rproc;
 42	const char *fw_name;
 43	bool r_state = false;
 44	bool p_state = false;
 45	int ret;
 46
 47	data = of_device_get_match_data(dev);
 48	if (!data)
 49		return -ENODEV;
 50
 51	ret = rproc_of_parse_firmware(dev, 0, &fw_name);
 52	if (ret)
 53		return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");
 54
 55	rproc = devm_rproc_alloc(dev, dev_name(dev), &k3_m4_rproc_ops, fw_name,
 56				 sizeof(*kproc));
 57	if (!rproc)
 58		return -ENOMEM;
 59
 60	rproc->has_iommu = false;
 61	rproc->recovery_disabled = true;
 62	kproc = rproc->priv;
 63	kproc->dev = dev;
 64	kproc->rproc = rproc;
 65	kproc->data = data;
 66	platform_set_drvdata(pdev, rproc);
 67
 68	kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
 69	if (IS_ERR(kproc->ti_sci))
 70		return dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
 71				     "failed to get ti-sci handle\n");
 72
 73	ret = of_property_read_u32(dev->of_node, "ti,sci-dev-id", &kproc->ti_sci_id);
 74	if (ret)
 75		return dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n");
 76
 77	kproc->reset = devm_reset_control_get_exclusive(dev, NULL);
 78	if (IS_ERR(kproc->reset))
 79		return dev_err_probe(dev, PTR_ERR(kproc->reset), "failed to get reset\n");
 80
 81	kproc->tsp = ti_sci_proc_of_get_tsp(dev, kproc->ti_sci);
 82	if (IS_ERR(kproc->tsp))
 83		return dev_err_probe(dev, PTR_ERR(kproc->tsp),
 84				     "failed to construct ti-sci proc control\n");
 85
 86	ret = ti_sci_proc_request(kproc->tsp);
 87	if (ret < 0)
 88		return dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
 89	ret = devm_add_action_or_reset(dev, k3_release_tsp, kproc->tsp);
 90	if (ret)
 91		return ret;
 92
 93	ret = k3_rproc_of_get_memories(pdev, kproc);
 94	if (ret)
 95		return ret;
 96
 97	ret = k3_reserved_mem_init(kproc);
 98	if (ret)
 99		return dev_err_probe(dev, ret, "reserved memory init failed\n");
100
101	ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
102					       &r_state, &p_state);
103	if (ret)
104		return dev_err_probe(dev, ret,
105				     "failed to get initial state, mode cannot be determined\n");
106
107	/* configure devices for either remoteproc or IPC-only mode */
108	if (p_state) {
109		rproc->state = RPROC_DETACHED;
110		dev_info(dev, "configured M4F for IPC-only mode\n");
111	} else {
112		dev_info(dev, "configured M4F for remoteproc mode\n");
113	}
114
115	ret = k3_rproc_request_mbox(rproc);
116	if (ret)
117		return ret;
118
119	ret = devm_rproc_add(dev, rproc);
120	if (ret)
121		return dev_err_probe(dev, ret,
122				     "failed to register device with remoteproc core\n");
123
124	return 0;
125}
126
127static const struct k3_rproc_mem_data am64_m4_mems[] = {
128	{ .name = "iram", .dev_addr = 0x0 },
129	{ .name = "dram", .dev_addr = 0x30000 },
130};
131
132static const struct k3_rproc_dev_data am64_m4_data = {
133	.mems = am64_m4_mems,
134	.num_mems = ARRAY_SIZE(am64_m4_mems),
135	.boot_align_addr = SZ_1K,
136	.uses_lreset = true,
137};
138
139static const struct of_device_id k3_m4_of_match[] = {
140	{ .compatible = "ti,am64-m4fss", .data = &am64_m4_data, },
141	{ /* sentinel */ },
142};
143MODULE_DEVICE_TABLE(of, k3_m4_of_match);
144
145static struct platform_driver k3_m4_rproc_driver = {
146	.probe	= k3_m4_rproc_probe,
147	.driver	= {
148		.name = "k3-m4-rproc",
149		.of_match_table = k3_m4_of_match,
150	},
151};
152module_platform_driver(k3_m4_rproc_driver);
153
154MODULE_AUTHOR("Hari Nagalla <hnagalla@ti.com>");
155MODULE_DESCRIPTION("TI K3 M4 Remoteproc driver");
156MODULE_LICENSE("GPL");
~/ Read-only file preview.