summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/platform/tegra/tegra-camera-rtcpu.c139
-rw-r--r--include/linux/platform/tegra/emc_bwmgr.h1
2 files changed, 117 insertions, 23 deletions
diff --git a/drivers/platform/tegra/tegra-camera-rtcpu.c b/drivers/platform/tegra/tegra-camera-rtcpu.c
index 0e4fc172a..4b2900248 100644
--- a/drivers/platform/tegra/tegra-camera-rtcpu.c
+++ b/drivers/platform/tegra/tegra-camera-rtcpu.c
@@ -31,6 +31,7 @@
31#include <linux/of_irq.h> 31#include <linux/of_irq.h>
32#include <linux/of_platform.h> 32#include <linux/of_platform.h>
33#include <linux/platform_device.h> 33#include <linux/platform_device.h>
34#include <linux/platform/tegra/emc_bwmgr.h>
34#include <linux/pm_runtime.h> 35#include <linux/pm_runtime.h>
35#include <linux/sched.h> 36#include <linux/sched.h>
36#include <linux/seq_buf.h> 37#include <linux/seq_buf.h>
@@ -201,6 +202,10 @@ struct tegra_cam_rtcpu {
201 } cmd; 202 } cmd;
202 u32 fw_version; 203 u32 fw_version;
203 u8 fw_hash[RTCPU_FW_HASH_SIZE]; 204 u8 fw_hash[RTCPU_FW_HASH_SIZE];
205 struct {
206 u64 reset_complete;
207 u64 boot_handshake;
208 } stats;
204 union { 209 union {
205 void __iomem *regs[CAMRTC_NUM_REGS]; 210 void __iomem *regs[CAMRTC_NUM_REGS];
206 struct { 211 struct {
@@ -221,7 +226,10 @@ struct tegra_cam_rtcpu {
221 }; 226 };
222 const struct tegra_cam_rtcpu_pdata *pdata; 227 const struct tegra_cam_rtcpu_pdata *pdata;
223 struct camrtc_device_group *camera_devices; 228 struct camrtc_device_group *camera_devices;
229 struct tegra_bwmgr_client *bwmgr;
224 struct tegra_camrtc_mon *monitor; 230 struct tegra_camrtc_mon *monitor;
231 unsigned long full_bw;
232 u32 max_reboot_retry;
225 bool powered; 233 bool powered;
226 bool boot_sync_done; 234 bool boot_sync_done;
227 bool online; 235 bool online;
@@ -375,11 +383,64 @@ static void tegra_camrtc_assert_resets(struct device *dev)
375static int tegra_camrtc_deassert_resets(struct device *dev) 383static int tegra_camrtc_deassert_resets(struct device *dev)
376{ 384{
377 struct tegra_cam_rtcpu *rtcpu = dev_get_drvdata(dev); 385 struct tegra_cam_rtcpu *rtcpu = dev_get_drvdata(dev);
386 int ret = 0;
378 387
379 if (rtcpu->pdata->deassert_resets) 388 if (rtcpu->pdata->deassert_resets) {
380 return rtcpu->pdata->deassert_resets(dev); 389 ret = rtcpu->pdata->deassert_resets(dev);
390 rtcpu->stats.reset_complete = ktime_get_ns();
391 rtcpu->stats.boot_handshake = 0;
392 }
381 393
382 return 0; 394 return ret;
395}
396
397static void tegra_camrtc_init_bwmgr(struct device *dev)
398{
399 struct tegra_cam_rtcpu *rtcpu = dev_get_drvdata(dev);
400 u32 bw;
401
402 if (of_property_read_u32(dev->of_node, NV(memory-bw), &bw) != 0)
403 return;
404
405 if (bw == 0xFFFFFFFFU)
406 rtcpu->full_bw = tegra_bwmgr_get_max_emc_rate();
407 else
408 rtcpu->full_bw = tegra_bwmgr_round_rate(bw);
409
410 rtcpu->bwmgr = tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_CAMRTC);
411
412 if (IS_ERR_OR_NULL(rtcpu->bwmgr)) {
413 dev_warn(dev, "no memory bw manager\n");
414 rtcpu->bwmgr = NULL;
415 return;
416 }
417
418 dev_dbg(dev, "using emc rate %lu for power-on\n", rtcpu->full_bw);
419}
420
421static void tegra_camrtc_full_mem_bw(struct device *dev)
422{
423 struct tegra_cam_rtcpu *rtcpu = dev_get_drvdata(dev);
424
425 if (rtcpu->bwmgr != NULL) {
426 int ret = tegra_bwmgr_set_emc(rtcpu->bwmgr, rtcpu->full_bw,
427 TEGRA_BWMGR_SET_EMC_FLOOR);
428 if (ret < 0)
429 dev_info(dev, "emc request rate %lu failed, %d\n",
430 rtcpu->full_bw, ret);
431 else
432 dev_dbg(dev, "requested emc rate %lu\n",
433 rtcpu->full_bw);
434 }
435}
436
437static void tegra_camrtc_slow_mem_bw(struct device *dev)
438{
439 struct tegra_cam_rtcpu *rtcpu = dev_get_drvdata(dev);
440
441 if (rtcpu->bwmgr != NULL)
442 (void)tegra_bwmgr_set_emc(rtcpu->bwmgr, 0,
443 TEGRA_BWMGR_SET_EMC_FLOOR);
383} 444}
384 445
385/* 446/*
@@ -788,8 +849,10 @@ static int tegra_camrtc_poweron(struct device *dev, bool full_speed)
788 } 849 }
789 850
790 /* APE power domain may misbehave and try to resume while probing */ 851 /* APE power domain may misbehave and try to resume while probing */
791 if (rtcpu->sm_pair == NULL) 852 if (rtcpu->sm_pair == NULL) {
853 dev_info(dev, "poweron while probing");
792 return 0; 854 return 0;
855 }
793 856
794 /* Power on and let core run */ 857 /* Power on and let core run */
795 ret = tegra_camrtc_enable_clks(dev); 858 ret = tegra_camrtc_enable_clks(dev);
@@ -846,6 +909,18 @@ static int tegra_camrtc_boot_sync(struct device *dev)
846 return -EIO; 909 return -EIO;
847 } 910 }
848 911
912 if (rtcpu->stats.boot_handshake == 0) {
913 u64 bt;
914
915 rtcpu->stats.boot_handshake = ktime_get_ns();
916
917 bt = rtcpu->stats.boot_handshake -
918 rtcpu->stats.reset_complete + 500U;
919
920 dev_dbg(dev, "boot time %llu.%03u ms\n", bt / 1000000U,
921 (unsigned int)(bt % 10000000U) / 1000U);
922 }
923
849 command = RTCPU_COMMAND(FW_VERSION, RTCPU_DRIVER_SM5_VERSION); 924 command = RTCPU_COMMAND(FW_VERSION, RTCPU_DRIVER_SM5_VERSION);
850 ret = tegra_camrtc_command(dev, command, 0); 925 ret = tegra_camrtc_command(dev, command, 0);
851 if (ret < 0) 926 if (ret < 0)
@@ -866,7 +941,7 @@ static int tegra_camrtc_boot_sync(struct device *dev)
866 ret = tegra_rtcpu_trace_boot_sync(rtcpu->tracer); 941 ret = tegra_rtcpu_trace_boot_sync(rtcpu->tracer);
867 if (ret < 0) { 942 if (ret < 0) {
868 dev_err(dev, "trace boot sync failed: %d\n", ret); 943 dev_err(dev, "trace boot sync failed: %d\n", ret);
869 goto error; 944 return ret;
870 } 945 }
871 } 946 }
872 947
@@ -886,9 +961,6 @@ static int tegra_camrtc_boot_sync(struct device *dev)
886 } 961 }
887 962
888 return 0; 963 return 0;
889
890error:
891 return ret;
892} 964}
893 965
894/* 966/*
@@ -896,17 +968,35 @@ error:
896 */ 968 */
897static int tegra_camrtc_boot(struct device *dev) 969static int tegra_camrtc_boot(struct device *dev)
898{ 970{
971 struct tegra_cam_rtcpu *rtcpu = dev_get_drvdata(dev);
972 int retry = 0, max_retries = rtcpu->max_reboot_retry;
899 int ret; 973 int ret;
900 974
901 ret = tegra_camrtc_poweron(dev, true); 975 ret = tegra_camrtc_poweron(dev, true);
902 if (ret) 976 if (ret)
903 return ret; 977 return ret;
904 978
905 ret = tegra_camrtc_boot_sync(dev); 979 tegra_camrtc_full_mem_bw(dev);
980
981 for (;;) {
982 ret = tegra_camrtc_boot_sync(dev);
983 if (ret == 0)
984 break;
985 if (retry++ == max_retries)
986 break;
987 dev_warn(dev, "%s full reset, retry %u/%u\n",
988 rtcpu->name, retry, max_retries);