summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Pessi <ppessi@nvidia.com>2018-08-20 13:25:22 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-09-12 20:47:24 -0400
commita16f79eeff8f61dccc679dd84a0ecb1f138c506e (patch)
treeabca699a8e25f576a258c51c17b43cb11eb17399
parentc100fa4ba34599cde78e770785a6c8949a14b34b (diff)
tegra: camera: rtcpu: fix boot timeouts
The t186-sce boot time sometimes exceeds 2000 milliseconds. The undue boot time is because the memory bandwidth problems. During the boot the DRAM image is read twice (once when copying, once when calculating SHA1). Calculate time from deasserting resets to the first mailbox handshake with camrtc. Add a dedicated bandwidth manager client for camrtc. Request for extra memory bandwidth during boot time. Retry camrtc boot if it fails. Report failed boot handshake correctly to the platform, avoid corruption. Bug 2305627 Change-Id: Ia96e369ee1b09d6298268f7bd309db1c8f326564 Signed-off-by: Pekka Pessi <ppessi@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1803895 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Semi Malinen <smalinen@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-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 (;;) {