1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2018, NVIDIA CORPORATION. 4 */ 5 6 #include <linux/genalloc.h> 7 #include <linux/io.h> 8 #include <linux/mailbox_client.h> 9 #include <linux/of_reserved_mem.h> 10 #include <linux/platform_device.h> 11 12 #include <soc/tegra/bpmp.h> 13 #include <soc/tegra/bpmp-abi.h> 14 #include <soc/tegra/ivc.h> 15 16 #include "bpmp-private.h" 17 18 struct tegra186_bpmp { 19 struct tegra_bpmp *parent; 20 21 struct { 22 struct gen_pool *pool; 23 union { 24 void __iomem *sram; 25 void *dram; 26 }; 27 dma_addr_t phys; 28 } tx, rx; 29 30 struct { 31 struct mbox_client client; 32 struct mbox_chan *channel; 33 } mbox; 34 }; 35 36 static inline struct tegra_bpmp * 37 mbox_client_to_bpmp(struct mbox_client *client) 38 { 39 struct tegra186_bpmp *priv; 40 41 priv = container_of(client, struct tegra186_bpmp, mbox.client); 42 43 return priv->parent; 44 } 45 46 static bool tegra186_bpmp_is_message_ready(struct tegra_bpmp_channel *channel) 47 { 48 int err; 49 50 err = tegra_ivc_read_get_next_frame(channel->ivc, &channel->ib); 51 if (err) { 52 iosys_map_clear(&channel->ib); 53 return false; 54 } 55 56 return true; 57 } 58 59 static bool tegra186_bpmp_is_channel_free(struct tegra_bpmp_channel *channel) 60 { 61 int err; 62 63 err = tegra_ivc_write_get_next_frame(channel->ivc, &channel->ob); 64 if (err) { 65 iosys_map_clear(&channel->ob); 66 return false; 67 } 68 69 return true; 70 } 71 72 static int tegra186_bpmp_ack_message(struct tegra_bpmp_channel *channel) 73 { 74 return tegra_ivc_read_advance(channel->ivc); 75 } 76 77 static int tegra186_bpmp_post_message(struct tegra_bpmp_channel *channel) 78 { 79 return tegra_ivc_write_advance(channel->ivc); 80 } 81 82 static int tegra186_bpmp_ring_doorbell(struct tegra_bpmp *bpmp) 83 { 84 struct tegra186_bpmp *priv = bpmp->priv; 85 int err; 86 87 err = mbox_send_message(priv->mbox.channel, NULL); 88 if (err < 0) 89 return err; 90 91 mbox_client_txdone(priv->mbox.channel, 0); 92 93 return 0; 94 } 95 96 static void tegra186_bpmp_ivc_notify(struct tegra_ivc *ivc, void *data) 97 { 98 struct tegra_bpmp *bpmp = data; 99 struct tegra186_bpmp *priv = bpmp->priv; 100 101 if (WARN_ON(priv->mbox.channel == NULL)) 102 return; 103 104 tegra186_bpmp_ring_doorbell(bpmp); 105 } 106 107 static int tegra186_bpmp_channel_init(struct tegra_bpmp_channel *channel, 108 struct tegra_bpmp *bpmp, 109 unsigned int index) 110 { 111 struct tegra186_bpmp *priv = bpmp->priv; 112 size_t message_size, queue_size; 113 struct iosys_map rx, tx; 114 unsigned int offset; 115 int err; 116 117 channel->ivc = devm_kzalloc(bpmp->dev, sizeof(*channel->ivc), 118 GFP_KERNEL); 119 if (!channel->ivc) 120 return -ENOMEM; 121 122 message_size = tegra_ivc_align(MSG_MIN_SZ); 123 queue_size = tegra_ivc_total_queue_size(message_size); 124 offset = queue_size * index; 125 126 if (priv->rx.pool) { 127 iosys_map_set_vaddr_iomem(&rx, priv->rx.sram + offset); 128 iosys_map_set_vaddr_iomem(&tx, priv->tx.sram + offset); 129 } else { 130 iosys_map_set_vaddr(&rx, priv->rx.dram + offset); 131 iosys_map_set_vaddr(&tx, priv->tx.dram + offset); 132 } 133 134 err = tegra_ivc_init(channel->ivc, NULL, &rx, priv->rx.phys + offset, &tx, 135 priv->tx.phys + offset, 1, message_size, tegra186_bpmp_ivc_notify, 136 bpmp); 137 if (err < 0) { 138 dev_err(bpmp->dev, "failed to setup IVC for channel %u: %d\n", 139 index, err); 140 return err; 141 } 142 143 init_completion(&channel->completion); 144 channel->bpmp = bpmp; 145 146 return 0; 147 } 148 149 static void tegra186_bpmp_channel_reset(struct tegra_bpmp_channel *channel) 150 { 151 /* reset the channel state */ 152 tegra_ivc_reset(channel->ivc); 153 154 /* sync the channel state with BPMP */ 155 while (tegra_ivc_notified(channel->ivc)) 156 ; 157 } 158 159 static void tegra186_bpmp_channel_cleanup(struct tegra_bpmp_channel *channel) 160 { 161 tegra_ivc_cleanup(channel->ivc); 162 } 163 164 static void mbox_handle_rx(struct mbox_client *client, void *data) 165 { 166 struct tegra_bpmp *bpmp = mbox_client_to_bpmp(client); 167 168 tegra_bpmp_handle_rx(bpmp); 169 } 170 171 static void tegra186_bpmp_teardown_channels(struct tegra_bpmp *bpmp) 172 { 173 struct tegra186_bpmp *priv = bpmp->priv; 174 unsigned int i; 175 176 for (i = 0; i < bpmp->threaded.count; i++) { 177 if (!bpmp->threaded_channels[i].bpmp) 178 continue; 179 180 tegra186_bpmp_channel_cleanup(&bpmp->threaded_channels[i]); 181 } 182 183 tegra186_bpmp_channel_cleanup(bpmp->rx_channel); 184 tegra186_bpmp_channel_cleanup(bpmp->tx_channel); 185 186 if (priv->tx.pool) { 187 gen_pool_free(priv->tx.pool, (unsigned long)priv->tx.sram, 4096); 188 gen_pool_free(priv->rx.pool, (unsigned long)priv->rx.sram, 4096); 189 } 190 } 191 192 static int tegra186_bpmp_dram_init(struct tegra_bpmp *bpmp) 193 { 194 struct tegra186_bpmp *priv = bpmp->priv; 195 struct resource res; 196 size_t size; 197 int err; 198 199 err = of_reserved_mem_region_to_resource(bpmp->dev->of_node, 0, &res); 200 if (err < 0) { 201 dev_warn(bpmp->dev, "failed to parse memory region: %d\n", err); 202 return err; 203 } 204 205 size = resource_size(&res); 206 207 if (size < SZ_8K) { 208 dev_warn(bpmp->dev, "DRAM region must be larger than 8 KiB\n"); 209 return -EINVAL; 210 } 211 212 priv->tx.phys = res.start; 213 priv->rx.phys = res.start + SZ_4K; 214 215 priv->tx.dram = devm_memremap(bpmp->dev, priv->tx.phys, size, 216 MEMREMAP_WC); 217 if (IS_ERR(priv->tx.dram)) { 218 err = PTR_ERR(priv->tx.dram); 219 dev_warn(bpmp->dev, "failed to map DRAM region: %d\n", err); 220 return err; 221 } 222 223 priv->rx.dram = priv->tx.dram + SZ_4K; 224 225 return 0; 226 } 227 228 static int tegra186_bpmp_sram_init(struct tegra_bpmp *bpmp) 229 { 230 struct tegra186_bpmp *priv = bpmp->priv; 231 int err; 232 233 priv->tx.pool = of_gen_pool_get(bpmp->dev->of_node, "shmem", 0); 234 if (!priv->tx.pool) { 235 dev_err(bpmp->dev, "TX shmem pool not found\n"); 236 return -EPROBE_DEFER; 237 } 238 239 priv->tx.sram = (void __iomem *)gen_pool_dma_alloc(priv->tx.pool, 4096, 240 &priv->tx.phys); 241 if (!priv->tx.sram) { 242 dev_err(bpmp->dev, "failed to allocate from TX pool\n"); 243 return -ENOMEM; 244 } 245 246 priv->rx.pool = of_gen_pool_get(bpmp->dev->of_node, "shmem", 1); 247 if (!priv->rx.pool) { 248 dev_err(bpmp->dev, "RX shmem pool not found\n"); 249 err = -EPROBE_DEFER; 250 goto free_tx; 251 } 252 253 priv->rx.sram = (void __iomem *)gen_pool_dma_alloc(priv->rx.pool, 4096, 254 &priv->rx.phys); 255 if (!priv->rx.sram) { 256 dev_err(bpmp->dev, "failed to allocate from RX pool\n"); 257 err = -ENOMEM; 258 goto free_tx; 259 } 260 261 return 0; 262 263 free_tx: 264 gen_pool_free(priv->tx.pool, (unsigned long)priv->tx.sram, 4096); 265 266 return err; 267 } 268 269 static int tegra186_bpmp_setup_channels(struct tegra_bpmp *bpmp) 270 { 271 unsigned int i; 272 int err; 273 274 err = tegra186_bpmp_dram_init(bpmp); 275 if (err == -ENODEV) { 276 err = tegra186_bpmp_sram_init(bpmp); 277 if (err < 0) 278 return err; 279 } 280 281 err = tegra186_bpmp_channel_init(bpmp->tx_channel, bpmp, 282 bpmp->soc->channels.cpu_tx.offset); 283 if (err < 0) 284 return err; 285 286 err = tegra186_bpmp_channel_init(bpmp->rx_channel, bpmp, 287 bpmp->soc->channels.cpu_rx.offset); 288 if (err < 0) { 289 tegra186_bpmp_channel_cleanup(bpmp->tx_channel); 290 return err; 291 } 292 293 for (i = 0; i < bpmp->threaded.count; i++) { 294 unsigned int index = bpmp->soc->channels.thread.offset + i; 295 296 err = tegra186_bpmp_channel_init(&bpmp->threaded_channels[i], 297 bpmp, index); 298 if (err < 0) 299 break; 300 } 301 302 if (err < 0) 303 tegra186_bpmp_teardown_channels(bpmp); 304 305 return err; 306 } 307 308 static void tegra186_bpmp_reset_channels(struct tegra_bpmp *bpmp) 309 { 310 unsigned int i; 311 312 /* reset message channels */ 313 tegra186_bpmp_channel_reset(bpmp->tx_channel); 314 tegra186_bpmp_channel_reset(bpmp->rx_channel); 315 316 for (i = 0; i < bpmp->threaded.count; i++) 317 tegra186_bpmp_channel_reset(&bpmp->threaded_channels[i]); 318 } 319 320 static int tegra186_bpmp_init(struct tegra_bpmp *bpmp) 321 { 322 struct tegra186_bpmp *priv; 323 int err; 324 325 priv = devm_kzalloc(bpmp->dev, sizeof(*priv), GFP_KERNEL); 326 if (!priv) 327 return -ENOMEM; 328 329 priv->parent = bpmp; 330 bpmp->priv = priv; 331 332 err = tegra186_bpmp_setup_channels(bpmp); 333 if (err < 0) 334 return err; 335 336 /* mbox registration */ 337 priv->mbox.client.dev = bpmp->dev; 338 priv->mbox.client.rx_callback = mbox_handle_rx; 339 priv->mbox.client.tx_block = false; 340 priv->mbox.client.knows_txdone = false; 341 342 priv->mbox.channel = mbox_request_channel(&priv->mbox.client, 0); 343 if (IS_ERR(priv->mbox.channel)) { 344 err = PTR_ERR(priv->mbox.channel); 345 dev_err(bpmp->dev, "failed to get HSP mailbox: %d\n", err); 346 tegra186_bpmp_teardown_channels(bpmp); 347 return err; 348 } 349 350 tegra186_bpmp_reset_channels(bpmp); 351 352 return 0; 353 } 354 355 static void tegra186_bpmp_deinit(struct tegra_bpmp *bpmp) 356 { 357 struct tegra186_bpmp *priv = bpmp->priv; 358 359 mbox_free_channel(priv->mbox.channel); 360 361 tegra186_bpmp_teardown_channels(bpmp); 362 } 363 364 static int tegra186_bpmp_resume(struct tegra_bpmp *bpmp) 365 { 366 tegra186_bpmp_reset_channels(bpmp); 367 368 return 0; 369 } 370 371 const struct tegra_bpmp_ops tegra186_bpmp_ops = { 372 .init = tegra186_bpmp_init, 373 .deinit = tegra186_bpmp_deinit, 374 .is_response_ready = tegra186_bpmp_is_message_ready, 375 .is_request_ready = tegra186_bpmp_is_message_ready, 376 .ack_response = tegra186_bpmp_ack_message, 377 .ack_request = tegra186_bpmp_ack_message, 378 .is_response_channel_free = tegra186_bpmp_is_channel_free, 379 .is_request_channel_free = tegra186_bpmp_is_channel_free, 380 .post_response = tegra186_bpmp_post_message, 381 .post_request = tegra186_bpmp_post_message, 382 .ring_doorbell = tegra186_bpmp_ring_doorbell, 383 .resume = tegra186_bpmp_resume, 384 }; 385