vic.c (ca31fef11dc83e672415d5925a134749761329bd) | vic.c (9916612311a777cdf15a53491243589ea4fcc4e7) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2015, NVIDIA Corporation. 4 */ 5 6#include <linux/clk.h> 7#include <linux/delay.h> 8#include <linux/host1x.h> --- 15 unchanged lines hidden (view full) --- 24struct vic_config { 25 const char *firmware; 26 unsigned int version; 27 bool supports_sid; 28}; 29 30struct vic { 31 struct falcon falcon; | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2015, NVIDIA Corporation. 4 */ 5 6#include <linux/clk.h> 7#include <linux/delay.h> 8#include <linux/host1x.h> --- 15 unchanged lines hidden (view full) --- 24struct vic_config { 25 const char *firmware; 26 unsigned int version; 27 bool supports_sid; 28}; 29 30struct vic { 31 struct falcon falcon; |
32 bool booted; | |
33 34 void __iomem *regs; 35 struct tegra_drm_client client; 36 struct host1x_channel *channel; 37 struct device *dev; 38 struct clk *clk; 39 struct reset_control *rst; 40 --- 6 unchanged lines hidden (view full) --- 47 return container_of(client, struct vic, client); 48} 49 50static void vic_writel(struct vic *vic, u32 value, unsigned int offset) 51{ 52 writel(value, vic->regs + offset); 53} 54 | 32 33 void __iomem *regs; 34 struct tegra_drm_client client; 35 struct host1x_channel *channel; 36 struct device *dev; 37 struct clk *clk; 38 struct reset_control *rst; 39 --- 6 unchanged lines hidden (view full) --- 46 return container_of(client, struct vic, client); 47} 48 49static void vic_writel(struct vic *vic, u32 value, unsigned int offset) 50{ 51 writel(value, vic->regs + offset); 52} 53 |
55static int vic_runtime_resume(struct device *dev) 56{ 57 struct vic *vic = dev_get_drvdata(dev); 58 int err; 59 60 err = clk_prepare_enable(vic->clk); 61 if (err < 0) 62 return err; 63 64 usleep_range(10, 20); 65 66 err = reset_control_deassert(vic->rst); 67 if (err < 0) 68 goto disable; 69 70 usleep_range(10, 20); 71 72 return 0; 73 74disable: 75 clk_disable_unprepare(vic->clk); 76 return err; 77} 78 79static int vic_runtime_suspend(struct device *dev) 80{ 81 struct vic *vic = dev_get_drvdata(dev); 82 int err; 83 84 err = reset_control_assert(vic->rst); 85 if (err < 0) 86 return err; 87 88 usleep_range(2000, 4000); 89 90 clk_disable_unprepare(vic->clk); 91 92 vic->booted = false; 93 94 return 0; 95} 96 | |
97static int vic_boot(struct vic *vic) 98{ 99#ifdef CONFIG_IOMMU_API 100 struct iommu_fwspec *spec = dev_iommu_fwspec_get(vic->dev); 101#endif 102 u32 fce_ucode_size, fce_bin_data_offset; 103 void *hdr; 104 int err = 0; 105 | 54static int vic_boot(struct vic *vic) 55{ 56#ifdef CONFIG_IOMMU_API 57 struct iommu_fwspec *spec = dev_iommu_fwspec_get(vic->dev); 58#endif 59 u32 fce_ucode_size, fce_bin_data_offset; 60 void *hdr; 61 int err = 0; 62 |
106 if (vic->booted) 107 return 0; 108 | |
109#ifdef CONFIG_IOMMU_API 110 if (vic->config->supports_sid && spec) { 111 u32 value; 112 113 value = TRANSCFG_ATT(1, TRANSCFG_SID_FALCON) | 114 TRANSCFG_ATT(0, TRANSCFG_SID_HW); 115 vic_writel(vic, value, VIC_TFBIF_TRANSCFG); 116 --- 46 unchanged lines hidden (view full) --- 163 164 err = falcon_wait_idle(&vic->falcon); 165 if (err < 0) { 166 dev_err(vic->dev, 167 "failed to set application ID and FCE base\n"); 168 return err; 169 } 170 | 63#ifdef CONFIG_IOMMU_API 64 if (vic->config->supports_sid && spec) { 65 u32 value; 66 67 value = TRANSCFG_ATT(1, TRANSCFG_SID_FALCON) | 68 TRANSCFG_ATT(0, TRANSCFG_SID_HW); 69 vic_writel(vic, value, VIC_TFBIF_TRANSCFG); 70 --- 46 unchanged lines hidden (view full) --- 117 118 err = falcon_wait_idle(&vic->falcon); 119 if (err < 0) { 120 dev_err(vic->dev, 121 "failed to set application ID and FCE base\n"); 122 return err; 123 } 124 |
171 vic->booted = true; 172 | |
173 return 0; 174} 175 176static int vic_init(struct host1x_client *client) 177{ 178 struct tegra_drm_client *drm = host1x_to_drm_client(client); 179 struct drm_device *dev = dev_get_drvdata(client->host); 180 struct tegra_drm *tegra = dev->dev_private; --- 137 unchanged lines hidden (view full) --- 318 if (!client->group) 319 dma_free_coherent(vic->dev, size, virt, iova); 320 else 321 tegra_drm_free(tegra, size, virt, iova); 322 323 return err; 324} 325 | 125 return 0; 126} 127 128static int vic_init(struct host1x_client *client) 129{ 130 struct tegra_drm_client *drm = host1x_to_drm_client(client); 131 struct drm_device *dev = dev_get_drvdata(client->host); 132 struct tegra_drm *tegra = dev->dev_private; --- 137 unchanged lines hidden (view full) --- 270 if (!client->group) 271 dma_free_coherent(vic->dev, size, virt, iova); 272 else 273 tegra_drm_free(tegra, size, virt, iova); 274 275 return err; 276} 277 |
326static int vic_open_channel(struct tegra_drm_client *client, 327 struct tegra_drm_context *context) | 278 279static int vic_runtime_resume(struct device *dev) |
328{ | 280{ |
329 struct vic *vic = to_vic(client); | 281 struct vic *vic = dev_get_drvdata(dev); |
330 int err; 331 | 282 int err; 283 |
332 err = pm_runtime_resume_and_get(vic->dev); | 284 err = clk_prepare_enable(vic->clk); |
333 if (err < 0) 334 return err; 335 | 285 if (err < 0) 286 return err; 287 |
288 usleep_range(10, 20); 289 290 err = reset_control_deassert(vic->rst); 291 if (err < 0) 292 goto disable; 293 294 usleep_range(10, 20); 295 |
|
336 err = vic_load_firmware(vic); 337 if (err < 0) | 296 err = vic_load_firmware(vic); 297 if (err < 0) |
338 goto rpm_put; | 298 goto assert; |
339 340 err = vic_boot(vic); 341 if (err < 0) | 299 300 err = vic_boot(vic); 301 if (err < 0) |
342 goto rpm_put; | 302 goto assert; |
343 | 303 |
304 return 0; 305 306assert: 307 reset_control_assert(vic->rst); 308disable: 309 clk_disable_unprepare(vic->clk); 310 return err; 311} 312 313static int vic_runtime_suspend(struct device *dev) 314{ 315 struct vic *vic = dev_get_drvdata(dev); 316 int err; 317 318 err = reset_control_assert(vic->rst); 319 if (err < 0) 320 return err; 321 322 usleep_range(2000, 4000); 323 324 clk_disable_unprepare(vic->clk); 325 326 return 0; 327} 328 329static int vic_open_channel(struct tegra_drm_client *client, 330 struct tegra_drm_context *context) 331{ 332 struct vic *vic = to_vic(client); 333 int err; 334 335 err = pm_runtime_resume_and_get(vic->dev); 336 if (err < 0) 337 return err; 338 |
|
344 context->channel = host1x_channel_get(vic->channel); 345 if (!context->channel) { | 339 context->channel = host1x_channel_get(vic->channel); 340 if (!context->channel) { |
346 err = -ENOMEM; 347 goto rpm_put; | 341 pm_runtime_put(vic->dev); 342 return -ENOMEM; |
348 } 349 350 return 0; | 343 } 344 345 return 0; |
351 352rpm_put: 353 pm_runtime_put(vic->dev); 354 return err; | |
355} 356 357static void vic_close_channel(struct tegra_drm_context *context) 358{ 359 struct vic *vic = to_vic(context->client); 360 361 host1x_channel_put(context->channel); | 346} 347 348static void vic_close_channel(struct tegra_drm_context *context) 349{ 350 struct vic *vic = to_vic(context->client); 351 352 host1x_channel_put(context->channel); |
362 | |
363 pm_runtime_put(vic->dev); 364} 365 366static const struct tegra_drm_client_ops vic_ops = { 367 .open_channel = vic_open_channel, 368 .close_channel = vic_close_channel, 369 .submit = tegra_drm_submit, 370}; --- 183 unchanged lines hidden --- | 353 pm_runtime_put(vic->dev); 354} 355 356static const struct tegra_drm_client_ops vic_ops = { 357 .open_channel = vic_open_channel, 358 .close_channel = vic_close_channel, 359 .submit = tegra_drm_submit, 360}; --- 183 unchanged lines hidden --- |