aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clocksource/Kconfig3
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra.c1
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra30.c9
-rw-r--r--drivers/soc/tegra/pmc.c124
5 files changed, 128 insertions, 11 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fc01ec27d3c8..c062b6105d49 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -47,6 +47,9 @@ config SUN5I_HSTIMER
47 select CLKSRC_MMIO 47 select CLKSRC_MMIO
48 bool 48 bool
49 49
50config TEGRA_TIMER
51 bool
52
50config VT8500_TIMER 53config VT8500_TIMER
51 bool 54 bool
52 55
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 94d90b24b56b..ba9ebd868ec5 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_ARCH_U300) += timer-u300.o
27obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o 27obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o
28obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o 28obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o
29obj-$(CONFIG_MESON6_TIMER) += meson6_timer.o 29obj-$(CONFIG_MESON6_TIMER) += meson6_timer.o
30obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o 30obj-$(CONFIG_TEGRA_TIMER) += tegra20_timer.o
31obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o 31obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o
32obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o 32obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o
33obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o 33obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index 011a3363c265..c0d660f1aaac 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -81,6 +81,7 @@ static const struct of_device_id car_match[] __initconst = {
81 { .compatible = "nvidia,tegra30-car", }, 81 { .compatible = "nvidia,tegra30-car", },
82 { .compatible = "nvidia,tegra114-car", }, 82 { .compatible = "nvidia,tegra114-car", },
83 { .compatible = "nvidia,tegra124-car", }, 83 { .compatible = "nvidia,tegra124-car", },
84 { .compatible = "nvidia,tegra132-car", },
84 {}, 85 {},
85}; 86};
86 87
diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c
index 8646fa920d8d..4d2f71bf65c5 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra30.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra30.c
@@ -56,7 +56,7 @@ struct tegra_fuse_info {
56 56
57static void __iomem *fuse_base; 57static void __iomem *fuse_base;
58static struct clk *fuse_clk; 58static struct clk *fuse_clk;
59static struct tegra_fuse_info *fuse_info; 59static const struct tegra_fuse_info *fuse_info;
60 60
61u32 tegra30_fuse_readl(const unsigned int offset) 61u32 tegra30_fuse_readl(const unsigned int offset)
62{ 62{
@@ -78,18 +78,18 @@ u32 tegra30_fuse_readl(const unsigned int offset)
78 return val; 78 return val;
79} 79}
80 80
81static struct tegra_fuse_info tegra30_info = { 81static const struct tegra_fuse_info tegra30_info = {
82 .size = 0x2a4, 82 .size = 0x2a4,
83 .spare_bit = 0x144, 83 .spare_bit = 0x144,
84 .speedo_idx = SPEEDO_TEGRA30, 84 .speedo_idx = SPEEDO_TEGRA30,
85}; 85};
86 86
87static struct tegra_fuse_info tegra114_info = { 87static const struct tegra_fuse_info tegra114_info = {
88 .size = 0x2a0, 88 .size = 0x2a0,
89 .speedo_idx = SPEEDO_TEGRA114, 89 .speedo_idx = SPEEDO_TEGRA114,
90}; 90};
91 91
92static struct tegra_fuse_info tegra124_info = { 92static const struct tegra_fuse_info tegra124_info = {
93 .size = 0x300, 93 .size = 0x300,
94 .speedo_idx = SPEEDO_TEGRA124, 94 .speedo_idx = SPEEDO_TEGRA124,
95}; 95};
@@ -182,6 +182,7 @@ static void __init legacy_fuse_init(void)
182 fuse_info = &tegra114_info; 182 fuse_info = &tegra114_info;
183 break; 183 break;
184 case TEGRA124: 184 case TEGRA124:
185 case TEGRA132:
185 fuse_info = &tegra124_info; 186 fuse_info = &tegra124_info;
186 break; 187 break;
187 default: 188 default:
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index a2c0ceb95f8f..c956395cf46f 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -70,6 +70,10 @@
70 70
71#define PMC_SCRATCH41 0x140 71#define PMC_SCRATCH41 0x140
72 72
73#define PMC_SENSOR_CTRL 0x1b0
74#define PMC_SENSOR_CTRL_SCRATCH_WRITE (1 << 2)
75#define PMC_SENSOR_CTRL_ENABLE_RST (1 << 1)
76
73#define IO_DPD_REQ 0x1b8 77#define IO_DPD_REQ 0x1b8
74#define IO_DPD_REQ_CODE_IDLE (0 << 30) 78#define IO_DPD_REQ_CODE_IDLE (0 << 30)
75#define IO_DPD_REQ_CODE_OFF (1 << 30) 79#define IO_DPD_REQ_CODE_OFF (1 << 30)
@@ -81,6 +85,18 @@
81#define IO_DPD2_STATUS 0x1c4 85#define IO_DPD2_STATUS 0x1c4
82#define SEL_DPD_TIM 0x1c8 86#define SEL_DPD_TIM 0x1c8
83 87
88#define PMC_SCRATCH54 0x258
89#define PMC_SCRATCH54_DATA_SHIFT 8
90#define PMC_SCRATCH54_ADDR_SHIFT 0
91
92#define PMC_SCRATCH55 0x25c
93#define PMC_SCRATCH55_RESET_TEGRA (1 << 31)
94#define PMC_SCRATCH55_CNTRL_ID_SHIFT 27
95#define PMC_SCRATCH55_PINMUX_SHIFT 24
96#define PMC_SCRATCH55_16BITOP (1 << 15)
97#define PMC_SCRATCH55_CHECKSUM_SHIFT 16
98#define PMC_SCRATCH55_I2CSLV1_SHIFT 0
99
84#define GPU_RG_CNTRL 0x2d4 100#define GPU_RG_CNTRL 0x2d4
85 101
86struct tegra_pmc_soc { 102struct tegra_pmc_soc {
@@ -88,6 +104,9 @@ struct tegra_pmc_soc {
88 const char *const *powergates; 104 const char *const *powergates;
89 unsigned int num_cpu_powergates; 105 unsigned int num_cpu_powergates;
90 const u8 *cpu_powergates; 106 const u8 *cpu_powergates;
107
108 bool has_tsense_reset;
109 bool has_gpu_clamps;
91}; 110};
92 111
93/** 112/**
@@ -110,6 +129,7 @@ struct tegra_pmc_soc {
110 * @powergates_lock: mutex for power gate register access 129 * @powergates_lock: mutex for power gate register access
111 */ 130 */
112struct tegra_pmc { 131struct tegra_pmc {
132 struct device *dev;
113 void __iomem *base; 133 void __iomem *base;
114 struct clk *clk; 134 struct clk *clk;
115 135
@@ -225,11 +245,11 @@ int tegra_powergate_remove_clamping(int id)
225 return -EINVAL; 245 return -EINVAL;
226 246
227 /* 247 /*
228 * The Tegra124 GPU has a separate register (with different semantics) 248 * On Tegra124 and later, the clamps for the GPU are controlled by a
229 * to remove clamps. 249 * separate register (with different semantics).
230 */ 250 */
231 if (tegra_get_chip_id() == TEGRA124) { 251 if (id == TEGRA_POWERGATE_3D) {
232 if (id == TEGRA_POWERGATE_3D) { 252 if (pmc->soc->has_gpu_clamps) {
233 tegra_pmc_writel(0, GPU_RG_CNTRL); 253 tegra_pmc_writel(0, GPU_RG_CNTRL);
234 return 0; 254 return 0;
235 } 255 }
@@ -703,6 +723,83 @@ static void tegra_pmc_init(struct tegra_pmc *pmc)
703 tegra_pmc_writel(value, PMC_CNTRL); 723 tegra_pmc_writel(value, PMC_CNTRL);
704} 724}
705 725
726void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
727{
728 static const char disabled[] = "emergency thermal reset disabled";
729 u32 pmu_addr, ctrl_id, reg_addr, reg_data, pinmux;
730 struct device *dev = pmc->dev;
731 struct device_node *np;
732 u32 value, checksum;
733
734 if (!pmc->soc->has_tsense_reset)
735 goto out;
736
737 np = of_find_node_by_name(pmc->dev->of_node, "i2c-thermtrip");
738 if (!np) {
739 dev_warn(dev, "i2c-thermtrip node not found, %s.\n", disabled);
740 goto out;
741 }
742
743 if (of_property_read_u32(np, "nvidia,i2c-controller-id", &ctrl_id)) {
744 dev_err(dev, "I2C controller ID missing, %s.\n", disabled);
745 goto out;
746 }
747
748 if (of_property_read_u32(np, "nvidia,bus-addr", &pmu_addr)) {
749 dev_err(dev, "nvidia,bus-addr missing, %s.\n", disabled);
750 goto out;
751 }
752
753 if (of_property_read_u32(np, "nvidia,reg-addr", &reg_addr)) {
754 dev_err(dev, "nvidia,reg-addr missing, %s.\n", disabled);
755 goto out;
756 }
757
758 if (of_property_read_u32(np, "nvidia,reg-data", &reg_data)) {
759 dev_err(dev, "nvidia,reg-data missing, %s.\n", disabled);
760 goto out;
761 }
762
763 if (of_property_read_u32(np, "nvidia,pinmux-id", &pinmux))
764 pinmux = 0;
765
766 value = tegra_pmc_readl(PMC_SENSOR_CTRL);
767 value |= PMC_SENSOR_CTRL_SCRATCH_WRITE;
768 tegra_pmc_writel(value, PMC_SENSOR_CTRL);
769
770 value = (reg_data << PMC_SCRATCH54_DATA_SHIFT) |
771 (reg_addr << PMC_SCRATCH54_ADDR_SHIFT);
772 tegra_pmc_writel(value, PMC_SCRATCH54);
773
774 value = PMC_SCRATCH55_RESET_TEGRA;
775 value |= ctrl_id << PMC_SCRATCH55_CNTRL_ID_SHIFT;
776 value |= pinmux << PMC_SCRATCH55_PINMUX_SHIFT;
777 value |= pmu_addr << PMC_SCRATCH55_I2CSLV1_SHIFT;
778
779 /*
780 * Calculate checksum of SCRATCH54, SCRATCH55 fields. Bits 23:16 will
781 * contain the checksum and are currently zero, so they are not added.
782 */
783 checksum = reg_addr + reg_data + (value & 0xff) + ((value >> 8) & 0xff)
784 + ((value >> 24) & 0xff);
785 checksum &= 0xff;
786 checksum = 0x100 - checksum;
787
788 value |= checksum << PMC_SCRATCH55_CHECKSUM_SHIFT;
789
790 tegra_pmc_writel(value, PMC_SCRATCH55);
791
792 value = tegra_pmc_readl(PMC_SENSOR_CTRL);
793 value |= PMC_SENSOR_CTRL_ENABLE_RST;
794 tegra_pmc_writel(value, PMC_SENSOR_CTRL);
795
796 dev_info(pmc->dev, "emergency thermal reset enabled\n");
797
798out:
799 of_node_put(np);
800 return;
801}
802
706static int tegra_pmc_probe(struct platform_device *pdev) 803static int tegra_pmc_probe(struct platform_device *pdev)
707{ 804{
708 void __iomem *base = pmc->base; 805 void __iomem *base = pmc->base;
@@ -728,8 +825,12 @@ static int tegra_pmc_probe(struct platform_device *pdev)
728 return err; 825 return err;
729 } 826 }
730 827
828 pmc->dev = &pdev->dev;
829
731 tegra_pmc_init(pmc); 830 tegra_pmc_init(pmc);
732 831
832 tegra_pmc_init_tsense_reset(pmc);
833
733 if (IS_ENABLED(CONFIG_DEBUG_FS)) { 834 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
734 err = tegra_powergate_debugfs_init(); 835 err = tegra_powergate_debugfs_init();
735 if (err < 0) 836 if (err < 0)
@@ -739,7 +840,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
739 return 0; 840 return 0;
740} 841}
741 842
742#ifdef CONFIG_PM_SLEEP 843#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
743static int tegra_pmc_suspend(struct device *dev) 844static int tegra_pmc_suspend(struct device *dev)
744{ 845{
745 tegra_pmc_writel(virt_to_phys(tegra_resume), PMC_SCRATCH41); 846 tegra_pmc_writel(virt_to_phys(tegra_resume), PMC_SCRATCH41);
@@ -753,10 +854,11 @@ static int tegra_pmc_resume(struct device *dev)
753 854
754 return 0; 855 return 0;
755} 856}
756#endif
757 857
758static SIMPLE_DEV_PM_OPS(tegra_pmc_pm_ops, tegra_pmc_suspend, tegra_pmc_resume); 858static SIMPLE_DEV_PM_OPS(tegra_pmc_pm_ops, tegra_pmc_suspend, tegra_pmc_resume);
759 859
860#endif
861
760static const char * const tegra20_powergates[] = { 862static const char * const tegra20_powergates[] = {
761 [TEGRA_POWERGATE_CPU] = "cpu", 863 [TEGRA_POWERGATE_CPU] = "cpu",
762 [TEGRA_POWERGATE_3D] = "3d", 864 [TEGRA_POWERGATE_3D] = "3d",
@@ -772,6 +874,8 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
772 .powergates = tegra20_powergates, 874 .powergates = tegra20_powergates,
773 .num_cpu_powergates = 0, 875 .num_cpu_powergates = 0,
774 .cpu_powergates = NULL, 876 .cpu_powergates = NULL,
877 .has_tsense_reset = false,
878 .has_gpu_clamps = false,
775}; 879};
776 880
777static const char * const tegra30_powergates[] = { 881static const char * const tegra30_powergates[] = {
@@ -803,6 +907,8 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
803 .powergates = tegra30_powergates, 907 .powergates = tegra30_powergates,
804 .num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates), 908 .num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
805 .cpu_powergates = tegra30_cpu_powergates, 909 .cpu_powergates = tegra30_cpu_powergates,
910 .has_tsense_reset = true,
911 .has_gpu_clamps = false,
806}; 912};
807 913
808static const char * const tegra114_powergates[] = { 914static const char * const tegra114_powergates[] = {
@@ -838,6 +944,8 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
838 .powergates = tegra114_powergates, 944 .powergates = tegra114_powergates,
839 .num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates), 945 .num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates),
840 .cpu_powergates = tegra114_cpu_powergates, 946 .cpu_powergates = tegra114_cpu_powergates,
947 .has_tsense_reset = true,
948 .has_gpu_clamps = false,
841}; 949};
842 950
843static const char * const tegra124_powergates[] = { 951static const char * const tegra124_powergates[] = {
@@ -879,6 +987,8 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
879 .powergates = tegra124_powergates, 987 .powergates = tegra124_powergates,
880 .num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates), 988 .num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates),
881 .cpu_powergates = tegra124_cpu_powergates, 989 .cpu_powergates = tegra124_cpu_powergates,
990 .has_tsense_reset = true,
991 .has_gpu_clamps = true,
882}; 992};
883 993
884static const struct of_device_id tegra_pmc_match[] = { 994static const struct of_device_id tegra_pmc_match[] = {
@@ -894,7 +1004,9 @@ static struct platform_driver tegra_pmc_driver = {
894 .name = "tegra-pmc", 1004 .name = "tegra-pmc",
895 .suppress_bind_attrs = true, 1005 .suppress_bind_attrs = true,
896 .of_match_table = tegra_pmc_match, 1006 .of_match_table = tegra_pmc_match,
1007#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
897 .pm = &tegra_pmc_pm_ops, 1008 .pm = &tegra_pmc_pm_ops,
1009#endif
898 }, 1010 },
899 .probe = tegra_pmc_probe, 1011 .probe = tegra_pmc_probe,
900}; 1012};