speedo-tegra124.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
  4. */
  5. #include <linux/device.h>
  6. #include <linux/kernel.h>
  7. #include <linux/bug.h>
  8. #include <soc/tegra/fuse.h>
  9. #include "fuse.h"
  10. #define CPU_PROCESS_CORNERS 2
  11. #define GPU_PROCESS_CORNERS 2
  12. #define SOC_PROCESS_CORNERS 2
  13. #define FUSE_CPU_SPEEDO_0 0x14
  14. #define FUSE_CPU_SPEEDO_1 0x2c
  15. #define FUSE_CPU_SPEEDO_2 0x30
  16. #define FUSE_SOC_SPEEDO_0 0x34
  17. #define FUSE_SOC_SPEEDO_1 0x38
  18. #define FUSE_SOC_SPEEDO_2 0x3c
  19. #define FUSE_CPU_IDDQ 0x18
  20. #define FUSE_SOC_IDDQ 0x40
  21. #define FUSE_GPU_IDDQ 0x128
  22. #define FUSE_FT_REV 0x28
  23. enum {
  24. THRESHOLD_INDEX_0,
  25. THRESHOLD_INDEX_1,
  26. THRESHOLD_INDEX_COUNT,
  27. };
  28. static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
  29. {2190, UINT_MAX},
  30. {0, UINT_MAX},
  31. };
  32. static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = {
  33. {1965, UINT_MAX},
  34. {0, UINT_MAX},
  35. };
  36. static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
  37. {2101, UINT_MAX},
  38. {0, UINT_MAX},
  39. };
  40. static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
  41. int *threshold)
  42. {
  43. int sku = sku_info->sku_id;
  44. /* Assign to default */
  45. sku_info->cpu_speedo_id = 0;
  46. sku_info->soc_speedo_id = 0;
  47. sku_info->gpu_speedo_id = 0;
  48. *threshold = THRESHOLD_INDEX_0;
  49. switch (sku) {
  50. case 0x00: /* Eng sku */
  51. case 0x0F:
  52. case 0x23:
  53. /* Using the default */
  54. break;
  55. case 0x83:
  56. sku_info->cpu_speedo_id = 2;
  57. break;
  58. case 0x1F:
  59. case 0x87:
  60. case 0x27:
  61. sku_info->cpu_speedo_id = 2;
  62. sku_info->soc_speedo_id = 0;
  63. sku_info->gpu_speedo_id = 1;
  64. *threshold = THRESHOLD_INDEX_0;
  65. break;
  66. case 0x81:
  67. case 0x21:
  68. case 0x07:
  69. sku_info->cpu_speedo_id = 1;
  70. sku_info->soc_speedo_id = 1;
  71. sku_info->gpu_speedo_id = 1;
  72. *threshold = THRESHOLD_INDEX_1;
  73. break;
  74. case 0x49:
  75. case 0x4A:
  76. case 0x48:
  77. sku_info->cpu_speedo_id = 4;
  78. sku_info->soc_speedo_id = 2;
  79. sku_info->gpu_speedo_id = 3;
  80. *threshold = THRESHOLD_INDEX_1;
  81. break;
  82. default:
  83. pr_err("Tegra Unknown SKU %d\n", sku);
  84. /* Using the default for the error case */
  85. break;
  86. }
  87. }
  88. void __init tegra124_init_speedo_data(struct tegra_sku_info *sku_info)
  89. {
  90. int i, threshold, cpu_speedo_0_value, soc_speedo_0_value;
  91. int cpu_iddq_value, gpu_iddq_value, soc_iddq_value;
  92. BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
  93. THRESHOLD_INDEX_COUNT);
  94. BUILD_BUG_ON(ARRAY_SIZE(gpu_process_speedos) !=
  95. THRESHOLD_INDEX_COUNT);
  96. BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
  97. THRESHOLD_INDEX_COUNT);
  98. cpu_speedo_0_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_0);
  99. /* GPU Speedo is stored in CPU_SPEEDO_2 */
  100. sku_info->gpu_speedo_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_2);
  101. soc_speedo_0_value = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
  102. cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
  103. soc_iddq_value = tegra_fuse_read_early(FUSE_SOC_IDDQ);
  104. gpu_iddq_value = tegra_fuse_read_early(FUSE_GPU_IDDQ);
  105. sku_info->cpu_speedo_value = cpu_speedo_0_value;
  106. if (sku_info->cpu_speedo_value == 0) {
  107. pr_warn("Tegra Warning: Speedo value not fused.\n");
  108. WARN_ON(1);
  109. return;
  110. }
  111. rev_sku_to_speedo_ids(sku_info, &threshold);
  112. sku_info->cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
  113. for (i = 0; i < GPU_PROCESS_CORNERS; i++)
  114. if (sku_info->gpu_speedo_value <
  115. gpu_process_speedos[threshold][i])
  116. break;
  117. sku_info->gpu_process_id = i;
  118. for (i = 0; i < CPU_PROCESS_CORNERS; i++)
  119. if (sku_info->cpu_speedo_value <
  120. cpu_process_speedos[threshold][i])
  121. break;
  122. sku_info->cpu_process_id = i;
  123. for (i = 0; i < SOC_PROCESS_CORNERS; i++)
  124. if (soc_speedo_0_value <
  125. soc_process_speedos[threshold][i])
  126. break;
  127. sku_info->soc_process_id = i;
  128. pr_debug("Tegra GPU Speedo ID=%d, Speedo Value=%d\n",
  129. sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);
  130. }