blob: d3eb957b2e4957f2dcbf3e7d4a5c8d1983f4dbda [file] [log] [blame]
Lokesh Vutlafdae32e2018-08-27 15:57:52 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
Lokesh Vutla247418b2019-06-07 19:25:59 +05303 * Texas Instruments' K3 ARM64 Remoteproc driver
Lokesh Vutlafdae32e2018-08-27 15:57:52 +05304 *
Nishanth Menoneaa39c62023-11-01 15:56:03 -05005 * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/
Lokesh Vutlafdae32e2018-08-27 15:57:52 +05306 * Lokesh Vutla <lokeshvutla@ti.com>
7 *
8 */
9
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053010#include <dm.h>
11#include <remoteproc.h>
12#include <errno.h>
13#include <clk.h>
14#include <reset.h>
15#include <asm/io.h>
16#include <power-domain.h>
Simon Glass9bc15642020-02-03 07:36:16 -070017#include <dm/device_compat.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070018#include <linux/err.h>
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053019#include <linux/soc/ti/ti_sci_protocol.h>
Lokesh Vutla142611f2019-06-07 19:25:58 +053020#include "ti_sci_proc.h"
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053021
22#define INVALID_ID 0xffff
23
24#define GTC_CNTCR_REG 0x0
Nishanth Menonf26b45c2021-01-06 13:20:32 -060025#define GTC_CNTFID0_REG 0x20
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053026#define GTC_CNTR_EN 0x3
27
28/**
Lokesh Vutla247418b2019-06-07 19:25:59 +053029 * struct k3_arm64_privdata - Structure representing Remote processor data.
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053030 * @rproc_pwrdmn: rproc power domain data
31 * @rproc_rst: rproc reset control data
32 * @sci: Pointer to TISCI handle
Lokesh Vutla142611f2019-06-07 19:25:58 +053033 * @tsp: TISCI processor control helper structure
Nishanth Menonf26b45c2021-01-06 13:20:32 -060034 * @gtc_clk: GTC clock description
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053035 * @gtc_base: Timer base address.
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053036 */
Lokesh Vutla247418b2019-06-07 19:25:59 +053037struct k3_arm64_privdata {
Manorit Chawdhrya62bd8c2023-04-14 09:48:00 +053038 bool has_cluster_node;
39 struct power_domain cluster_pwrdmn;
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053040 struct power_domain rproc_pwrdmn;
41 struct power_domain gtc_pwrdmn;
42 struct reset_ctl rproc_rst;
Lokesh Vutla142611f2019-06-07 19:25:58 +053043 struct ti_sci_proc tsp;
Nishanth Menonf26b45c2021-01-06 13:20:32 -060044 struct clk gtc_clk;
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053045 void *gtc_base;
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053046};
47
48/**
Lokesh Vutla247418b2019-06-07 19:25:59 +053049 * k3_arm64_load() - Load up the Remote processor image
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053050 * @dev: rproc device pointer
51 * @addr: Address at which image is available
52 * @size: size of the image
53 *
54 * Return: 0 if all goes good, else appropriate error message.
55 */
Lokesh Vutla247418b2019-06-07 19:25:59 +053056static int k3_arm64_load(struct udevice *dev, ulong addr, ulong size)
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053057{
Lokesh Vutla247418b2019-06-07 19:25:59 +053058 struct k3_arm64_privdata *rproc = dev_get_priv(dev);
Manorit Chawdhrya62bd8c2023-04-14 09:48:00 +053059 ulong gtc_rate;
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053060 int ret;
61
62 dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size);
63
64 /* request for the processor */
Lokesh Vutla142611f2019-06-07 19:25:58 +053065 ret = ti_sci_proc_request(&rproc->tsp);
66 if (ret)
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053067 return ret;
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053068
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053069 ret = power_domain_on(&rproc->gtc_pwrdmn);
70 if (ret) {
Manorit Chawdhrya62bd8c2023-04-14 09:48:00 +053071 dev_err(dev, "power_domain_on(&rproc->gtc_pwrdmn) failed: %d\n",
72 ret);
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053073 return ret;
74 }
75
Nishanth Menonf26b45c2021-01-06 13:20:32 -060076 gtc_rate = clk_get_rate(&rproc->gtc_clk);
77 dev_dbg(dev, "GTC RATE= %d\n", (u32) gtc_rate);
78 /* Store the clock frequency down for GTC users to pick up */
79 writel((u32)gtc_rate, rproc->gtc_base + GTC_CNTFID0_REG);
80
Lokesh Vutlafdae32e2018-08-27 15:57:52 +053081 /* Enable the timer before starting remote core */
82 writel(GTC_CNTR_EN, rproc->gtc_base + GTC_CNTCR_REG);
83
84 /*
85 * Setting the right clock frequency would have taken care by
86 * assigned-clock-rates during the device probe. So no need to
87 * set the frequency again here.
88 */
Manorit Chawdhrya62bd8c2023-04-14 09:48:00 +053089 if (rproc->has_cluster_node) {
90 ret = power_domain_on(&rproc->cluster_pwrdmn);
91 if (ret) {
92 dev_err(dev,
93 "power_domain_on(&rproc->cluster_pwrdmn) failed: %d\n",
94 ret);
95 return ret;
96 }
97 }
98
99 return ti_sci_proc_set_config(&rproc->tsp, addr, 0, 0);
100}
101
102/**
103 * k3_arm64_start() - Start the remote processor
104 * @dev: rproc device pointer
105 *
106 * Return: 0 if all went ok, else return appropriate error
107 */
108static int k3_arm64_start(struct udevice *dev)
109{
110 struct k3_arm64_privdata *rproc = dev_get_priv(dev);
111 int ret;
112
113 dev_dbg(dev, "%s\n", __func__);
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530114 ret = power_domain_on(&rproc->rproc_pwrdmn);
115 if (ret) {
Manorit Chawdhrya62bd8c2023-04-14 09:48:00 +0530116 dev_err(dev,
117 "power_domain_on(&rproc->rproc_pwrdmn) failed: %d\n",
118 ret);
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530119 return ret;
120 }
121
Lokesh Vutla142611f2019-06-07 19:25:58 +0530122 return ti_sci_proc_release(&rproc->tsp);
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530123}
124
125/**
Lokesh Vutla247418b2019-06-07 19:25:59 +0530126 * k3_arm64_init() - Initialize the remote processor
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530127 * @dev: rproc device pointer
128 *
129 * Return: 0 if all went ok, else return appropriate error
130 */
Lokesh Vutla247418b2019-06-07 19:25:59 +0530131static int k3_arm64_init(struct udevice *dev)
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530132{
133 dev_dbg(dev, "%s\n", __func__);
134
135 /* Enable the module */
136 dev_dbg(dev, "%s: rproc successfully initialized\n", __func__);
137
138 return 0;
139}
140
Lokesh Vutla247418b2019-06-07 19:25:59 +0530141static const struct dm_rproc_ops k3_arm64_ops = {
142 .init = k3_arm64_init,
143 .load = k3_arm64_load,
144 .start = k3_arm64_start,
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530145};
146
Lokesh Vutla142611f2019-06-07 19:25:58 +0530147static int ti_sci_proc_of_to_priv(struct udevice *dev, struct ti_sci_proc *tsp)
148{
149 dev_dbg(dev, "%s\n", __func__);
150
151 tsp->sci = ti_sci_get_by_phandle(dev, "ti,sci");
152 if (IS_ERR(tsp->sci)) {
153 dev_err(dev, "ti_sci get failed: %ld\n", PTR_ERR(tsp->sci));
154 return PTR_ERR(tsp->sci);
155 }
156
157 tsp->proc_id = dev_read_u32_default(dev, "ti,sci-proc-id", INVALID_ID);
158 if (tsp->proc_id == INVALID_ID) {
159 dev_err(dev, "proc id not populated\n");
160 return -ENOENT;
161 }
162 tsp->host_id = dev_read_u32_default(dev, "ti,sci-host-id", INVALID_ID);
163 tsp->ops = &tsp->sci->ops.proc_ops;
164
165 return 0;
166}
167
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530168/**
169 * k3_of_to_priv() - generate private data from device tree
170 * @dev: corresponding k3 remote processor device
171 * @priv: pointer to driver specific private data
172 *
173 * Return: 0 if all goes good, else appropriate error message.
174 */
Lokesh Vutla247418b2019-06-07 19:25:59 +0530175static int k3_arm64_of_to_priv(struct udevice *dev,
176 struct k3_arm64_privdata *rproc)
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530177{
178 int ret;
179
180 dev_dbg(dev, "%s\n", __func__);
181
Manorit Chawdhrya62bd8c2023-04-14 09:48:00 +0530182 /* Cluster needs to be powered on if firewalls are being configured */
183 rproc->has_cluster_node = true;
184 ret = power_domain_get_by_index(dev, &rproc->cluster_pwrdmn, 2);
185 if (ret) {
186 dev_dbg(dev, "warning: power_domain_get_cluster() failed: %d\n", ret);
187 rproc->has_cluster_node = false;
188 }
189
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530190 ret = power_domain_get_by_index(dev, &rproc->rproc_pwrdmn, 1);
191 if (ret) {
Manorit Chawdhrya62bd8c2023-04-14 09:48:00 +0530192 dev_err(dev, "power_domain_get_rproc() failed: %d\n", ret);
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530193 return ret;
194 }
195
196 ret = power_domain_get_by_index(dev, &rproc->gtc_pwrdmn, 0);
197 if (ret) {
198 dev_err(dev, "power_domain_get() failed: %d\n", ret);
199 return ret;
200 }
201
Nishanth Menonf26b45c2021-01-06 13:20:32 -0600202 ret = clk_get_by_index(dev, 0, &rproc->gtc_clk);
203 if (ret) {
204 dev_err(dev, "clk_get failed: %d\n", ret);
205 return ret;
206 }
207
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530208 ret = reset_get_by_index(dev, 0, &rproc->rproc_rst);
209 if (ret) {
210 dev_err(dev, "reset_get() failed: %d\n", ret);
211 return ret;
212 }
213
Lokesh Vutla142611f2019-06-07 19:25:58 +0530214 ret = ti_sci_proc_of_to_priv(dev, &rproc->tsp);
215 if (ret)
216 return ret;
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530217
218 rproc->gtc_base = dev_read_addr_ptr(dev);
219 if (!rproc->gtc_base) {
220 dev_err(dev, "Get address failed\n");
221 return -ENODEV;
222 }
223
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530224 return 0;
225}
226
227/**
Lokesh Vutla247418b2019-06-07 19:25:59 +0530228 * k3_arm64_probe() - Basic probe
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530229 * @dev: corresponding k3 remote processor device
230 *
231 * Return: 0 if all goes good, else appropriate error message.
232 */
Lokesh Vutla247418b2019-06-07 19:25:59 +0530233static int k3_arm64_probe(struct udevice *dev)
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530234{
Lokesh Vutla247418b2019-06-07 19:25:59 +0530235 struct k3_arm64_privdata *priv;
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530236 int ret;
237
238 dev_dbg(dev, "%s\n", __func__);
239
240 priv = dev_get_priv(dev);
241
Lokesh Vutla247418b2019-06-07 19:25:59 +0530242 ret = k3_arm64_of_to_priv(dev, priv);
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530243 if (ret) {
244 dev_dbg(dev, "%s: Probe failed with error %d\n", __func__, ret);
245 return ret;
246 }
247
248 dev_dbg(dev, "Remoteproc successfully probed\n");
249
250 return 0;
251}
252
Lokesh Vutla247418b2019-06-07 19:25:59 +0530253static const struct udevice_id k3_arm64_ids[] = {
254 { .compatible = "ti,am654-arm64"},
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530255 { .compatible = "ti,am654-rproc"},
256 {}
257};
258
Lokesh Vutla247418b2019-06-07 19:25:59 +0530259U_BOOT_DRIVER(k3_arm64) = {
260 .name = "k3_arm64",
261 .of_match = k3_arm64_ids,
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530262 .id = UCLASS_REMOTEPROC,
Lokesh Vutla247418b2019-06-07 19:25:59 +0530263 .ops = &k3_arm64_ops,
264 .probe = k3_arm64_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700265 .priv_auto = sizeof(struct k3_arm64_privdata),
Lokesh Vutla01cfdf72019-09-27 13:48:13 +0530266 .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
Lokesh Vutlafdae32e2018-08-27 15:57:52 +0530267};