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 (;;) {
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);
989 tegra_camrtc_assert_resets(dev);
990 usleep_range(10, 30);
991 tegra_camrtc_deassert_resets(dev);
992 }
993
906 if (ret == 0) { 994 if (ret == 0) {
907 tegra_camrtc_set_online(dev, true); 995 tegra_camrtc_set_online(dev, true);
908 } 996 }
909 997
998 tegra_camrtc_slow_mem_bw(dev);
999
910 return 0; 1000 return 0;
911} 1001}
912 1002
@@ -1012,19 +1102,11 @@ static int tegra_cam_rtcpu_runtime_resume(struct device *dev)
1012 if (ret < 0) 1102 if (ret < 0)
1013 return ret; 1103 return ret;
1014 1104
1015 ret = tegra_camrtc_poweron(dev, true); 1105 ret = tegra_camrtc_boot(dev);
1016 if (ret)
1017 goto error;
1018
1019 ret = tegra_camrtc_boot_sync(dev);
1020 if (ret)
1021 goto error;
1022 1106
1023 tegra_camrtc_set_online(dev, true); 1107 if (ret < 0)
1108 camrtc_device_group_idle(rtcpu->camera_devices);
1024 1109
1025 return 0;
1026error:
1027 camrtc_device_group_idle(rtcpu->camera_devices);
1028 return ret; 1110 return ret;
1029} 1111}
1030 1112
@@ -1120,10 +1202,14 @@ static int tegra_cam_rtcpu_remove(struct platform_device *pdev)
1120 } 1202 }
1121 1203
1122 tegra_rtcpu_trace_destroy(rtcpu->tracer); 1204 tegra_rtcpu_trace_destroy(rtcpu->tracer);
1123 if (rtcpu->coverage != NULL) 1205 rtcpu->tracer = NULL;
1124 tegra_rtcpu_coverage_destroy(rtcpu->coverage); 1206 tegra_rtcpu_coverage_destroy(rtcpu->coverage);
1207 rtcpu->coverage = NULL;
1125 1208
1126 tegra_camrtc_poweroff(&pdev->dev); 1209 tegra_camrtc_poweroff(&pdev->dev);
1210 if (rtcpu->bwmgr != NULL)
1211 tegra_bwmgr_unregister(rtcpu->bwmgr);
1212 rtcpu->bwmgr = NULL;
1127 tegra_pd_remove_device(&pdev->dev); 1213 tegra_pd_remove_device(&pdev->dev);
1128 tegra_cam_rtcpu_mon_destroy(rtcpu->monitor); 1214 tegra_cam_rtcpu_mon_destroy(rtcpu->monitor);
1129 tegra_ivc_bus_destroy(rtcpu->ivc); 1215 tegra_ivc_bus_destroy(rtcpu->ivc);
@@ -1170,6 +1256,10 @@ static int tegra_cam_rtcpu_probe(struct platform_device *pdev)
1170 if (ret) 1256 if (ret)
1171 goto fail; 1257 goto fail;
1172 1258
1259 rtcpu->max_reboot_retry = 2;
1260 (void)of_property_read_u32(dev->of_node, NV(max-reboot),
1261 &rtcpu->max_reboot_retry);
1262
1173 timeout = 2000; 1263 timeout = 2000;
1174 (void)of_property_read_u32(dev->of_node, NV(cmd-timeout), &timeout); 1264 (void)of_property_read_u32(dev->of_node, NV(cmd-timeout), &timeout);
1175 rtcpu->cmd.timeout = msecs_to_jiffies(timeout); 1265 rtcpu->cmd.timeout = msecs_to_jiffies(timeout);
@@ -1181,6 +1271,8 @@ static int tegra_cam_rtcpu_probe(struct platform_device *pdev)
1181 pm_runtime_set_autosuspend_delay(&pdev->dev, timeout); 1271 pm_runtime_set_autosuspend_delay(&pdev->dev, timeout);
1182 } 1272 }
1183 1273
1274 tegra_camrtc_init_bwmgr(dev);
1275
1184 dev->dma_parms = &rtcpu->dma_parms; 1276 dev->dma_parms = &rtcpu->dma_parms;
1185 dma_set_max_seg_size(dev, UINT_MAX); 1277 dma_set_max_seg_size(dev, UINT_MAX);
1186 1278
@@ -1193,7 +1285,8 @@ static int tegra_cam_rtcpu_probe(struct platform_device *pdev)
1193 goto fail; 1285 goto fail;
1194 1286
1195 /* Power on device */ 1287 /* Power on device */
1196 if (pm_runtime_get_sync(dev) < 0) 1288 ret = pm_runtime_get_sync(dev);
1289 if (ret < 0)
1197 goto fail; 1290 goto fail;
1198 1291
1199 /* Clocks are on, resets are deasserted, we can touch the hardware */ 1292 /* Clocks are on, resets are deasserted, we can touch the hardware */
diff --git a/include/linux/platform/tegra/emc_bwmgr.h b/include/linux/platform/tegra/emc_bwmgr.h
index 64d6f6f89..cbc79b03b 100644
--- a/include/linux/platform/tegra/emc_bwmgr.h
+++ b/include/linux/platform/tegra/emc_bwmgr.h
@@ -50,6 +50,7 @@ enum tegra_bwmgr_client_id {
50 TEGRA_BWMGR_CLIENT_ISPB, 50 TEGRA_BWMGR_CLIENT_ISPB,
51 TEGRA_BWMGR_CLIENT_CAMERA, 51 TEGRA_BWMGR_CLIENT_CAMERA,
52 TEGRA_BWMGR_CLIENT_CAMERA_NON_ISO, 52 TEGRA_BWMGR_CLIENT_CAMERA_NON_ISO,
53 TEGRA_BWMGR_CLIENT_CAMRTC,
53 TEGRA_BWMGR_CLIENT_ISOMGR, 54 TEGRA_BWMGR_CLIENT_ISOMGR,
54 TEGRA_BWMGR_CLIENT_THERMAL_CAP, 55 TEGRA_BWMGR_CLIENT_THERMAL_CAP,
55 TEGRA_BWMGR_CLIENT_VIC, 56 TEGRA_BWMGR_CLIENT_VIC,