soc/tegra: Changes for v5.16-rc1

This set consists of stub additions to enable compile testing for more
 drivers, exposes the PMC's USB regmap on all SoC generations, removes a
 state synchronization workaround that is no longer needed and adds an
 error reporting driver that can help troubleshoot crashes.
 
 To top it all off, an error handling path in the powergating code is
 fixed and the devm_platform_ioremap_resource() function is used to
 remove some boilerplate code.
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCAAxFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmFgoR8THHRyZWRpbmdA
 bnZpZGlhLmNvbQAKCRDdI6zXfz6zoaqZEACIQpriNo3b3/Fy9VD7BEjFcsRwFTfp
 sQTj9/R2BgotaLw9X8ToPtvP+QVgxvltL8YNCdYbujJRYwo+kzhXLZ7rqKSQ1f+0
 tElmtEpLBBrR2OkJOMZCx/3fLyMV5jMISdisuTtIqnCovk9r+/gLNnL0tUbnNa/+
 57HfJfHfrZIGiXb4gSTXZqUQJ82yo5rc7SFmDiuwgEDhYX5cgzBf5s7fsIaBFVr9
 xP9q+UQO2GAOqReW+SBbdR7wlwL8/d7G6O0P5quy1xxI8/EKEONYg4VI3ZRylpTx
 2qMfT5kMuznQiOe+gZ0kR5mNy1IOg7A5xJJkW4Bt9fAQmEvqya9+MKe0s5Wu8044
 xlpL+JrAHpVXt9fraYwoZhBOrLqJQeHcLcx8IVYoGobNhLI8hCbNGzsZVJ3iYsq3
 xaJsTOFM3nKReOFTKXdE35Asnv6VLUrd9OoufMyLOJD1Qf6eHZnPHQcc8S0W0ijk
 +lnrpOTGAoQZdJVmI4CxP5UUCLRGoOffXaDkfP2Oq2L2NAABMN4+xdjjIlSDfJ2X
 Qj0RfXX/fRFfuGYkpxIeGhHOL8Arm8gGzMOs9q7lz84rMtoeFVKwxNTCn3UO92nN
 0iWZZJPQ+vp+KKgLzwJYfZO/3OrV7+prORBdHHvQMmuP6eeUGKciqNQrfhO0sIQY
 tsc5aX3X67LZCQ==
 =79h+
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmFj/6YACgkQmmx57+YA
 GNk5ig/8CeSG5CnuPwRh1oB0euCsqApxmvofjDHJFPRYj9NMfbwdjrErSpSAqUtQ
 mn2a2p8/eKDCecWH/phFSuJXBxe/j8l7Rk8ul++TfHUwisYjrEZou8T9Fe934Iad
 3l7N20pnGA5JNK0MxWh0ETjfGCWOnB/GfYLCcxnv6kts5zqcRStzBr+L14Ort5mC
 XZz3GApVGOM9LN/UB+KUVzRDZxSKNIekT8QaxUIPNpvZmRyUxw/Z4zdU8tT33hZa
 e/yKi60LLpkGgcj5HYkyYIgjriqUpjEFgObCZ6MXA9HoxFajAq5jkeBm23/tirZR
 rQmH3xq7vLFUtmmv4bVeAxxomnVdIXv5TwzXew0KyeqW4DG4T8h9h7095vWpW2ys
 hR90JhoiG2Kksa0+KlX15ZEaEVmojNV2IAFsfq9n5mDNFFEgOt8vqxSfVjGHYXFn
 kyQb4b4MSt87qczRL/lhx6YKFK3R0u99NFnJkSlZ3Q4kNQn2WgvGaeYiPZdwcAWX
 52HQBnYLp3cyDgDnOSD/wKX+BSoTZrBNE5SKLhoaSLNowyGpAPOcrAs1ob+myF6g
 BebTd3+8Vf1m/h7iuIsCf4CMCRxp86Z2V+eMGwG+HZjAmpZAlXf4mQMsKp4aeZuZ
 yObANkb1CgeSvzDKK+/ej/JDMYwBdhfhES2JpfuSD01+zqJASHA=
 =DXSR
 -----END PGP SIGNATURE-----

Merge tag 'tegra-for-5.16-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into arm/drivers

soc/tegra: Changes for v5.16-rc1

This set consists of stub additions to enable compile testing for more
drivers, exposes the PMC's USB regmap on all SoC generations, removes a
state synchronization workaround that is no longer needed and adds an
error reporting driver that can help troubleshoot crashes.

To top it all off, an error handling path in the powergating code is
fixed and the devm_platform_ioremap_resource() function is used to
remove some boilerplate code.

* tag 'tegra-for-5.16-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  soc/tegra: pmc: Use devm_platform_ioremap_resource()
  soc/tegra: Add Tegra186 ARI driver
  soc/tegra: Fix an error handling path in tegra_powergate_power_up()
  soc/tegra: pmc: Expose USB regmap to all SoCs
  soc/tegra: pmc: Disable PMC state syncing
  soc/tegra: pm: Make stubs usable for compile testing
  soc/tegra: irq: Add stubs needed for compile testing
  soc/tegra: fuse: Add stubs needed for compile testing

Link: https://lore.kernel.org/r/20211008201132.1678814-4-thierry.reding@gmail.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2021-10-11 11:11:00 +02:00
commit 94b847c766
6 changed files with 138 additions and 13 deletions

View File

@ -7,3 +7,4 @@ obj-$(CONFIG_SOC_TEGRA_PMC) += pmc.o
obj-$(CONFIG_SOC_TEGRA_POWERGATE_BPMP) += powergate-bpmp.o
obj-$(CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER) += regulators-tegra20.o
obj-$(CONFIG_SOC_TEGRA30_VOLTAGE_COUPLER) += regulators-tegra30.o
obj-$(CONFIG_ARCH_TEGRA_186_SOC) += ari-tegra186.o

View File

@ -0,0 +1,80 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/arm-smccc.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/panic_notifier.h>
#define SMC_SIP_INVOKE_MCE 0xc2ffff00
#define MCE_SMC_READ_MCA 12
#define MCA_ARI_CMD_RD_SERR 1
#define MCA_ARI_RW_SUBIDX_STAT 1
#define SERR_STATUS_VAL BIT_ULL(63)
#define MCA_ARI_RW_SUBIDX_ADDR 2
#define MCA_ARI_RW_SUBIDX_MSC1 3
#define MCA_ARI_RW_SUBIDX_MSC2 4
static const char * const bank_names[] = {
"SYS:DPMU", "ROC:IOB", "ROC:MCB", "ROC:CCE", "ROC:CQX", "ROC:CTU",
};
static void read_uncore_mca(u8 cmd, u8 idx, u8 subidx, u8 inst, u64 *data)
{
struct arm_smccc_res res;
arm_smccc_smc(SMC_SIP_INVOKE_MCE | MCE_SMC_READ_MCA,
((u64)inst << 24) | ((u64)idx << 16) |
((u64)subidx << 8) | ((u64)cmd << 0),
0, 0, 0, 0, 0, 0, &res);
*data = res.a2;
}
static int tegra186_ari_panic_handler(struct notifier_block *nb,
unsigned long code, void *unused)
{
u64 status;
int i;
for (i = 0; i < ARRAY_SIZE(bank_names); i++) {
read_uncore_mca(MCA_ARI_CMD_RD_SERR, i, MCA_ARI_RW_SUBIDX_STAT,
0, &status);
if (status & SERR_STATUS_VAL) {
u64 addr, misc1, misc2;
read_uncore_mca(MCA_ARI_CMD_RD_SERR, i,
MCA_ARI_RW_SUBIDX_ADDR, 0, &addr);
read_uncore_mca(MCA_ARI_CMD_RD_SERR, i,
MCA_ARI_RW_SUBIDX_MSC1, 0, &misc1);
read_uncore_mca(MCA_ARI_CMD_RD_SERR, i,
MCA_ARI_RW_SUBIDX_MSC2, 0, &misc2);
pr_crit("Machine Check Error in %s\n"
" status=0x%llx addr=0x%llx\n"
" msc1=0x%llx msc2=0x%llx\n",
bank_names[i], status, addr, misc1, misc2);
}
}
return NOTIFY_DONE;
}
static struct notifier_block tegra186_ari_panic_nb = {
.notifier_call = tegra186_ari_panic_handler,
};
static int __init tegra186_ari_init(void)
{
if (of_machine_is_compatible("nvidia,tegra186"))
atomic_notifier_chain_register(&panic_notifier_list, &tegra186_ari_panic_nb);
return 0;
}
early_initcall(tegra186_ari_init);

View File

@ -360,6 +360,7 @@ struct tegra_pmc_soc {
unsigned int num_pmc_clks;
bool has_blink_output;
bool has_usb_sleepwalk;
bool supports_core_domain;
};
/**
@ -782,7 +783,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
err = reset_control_deassert(pg->reset);
if (err)
goto powergate_off;
goto disable_clks;
usleep_range(10, 20);
@ -2815,8 +2816,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
return err;
/* take over the memory region from the early initialization */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
@ -3041,6 +3041,7 @@ static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
}
static const struct tegra_pmc_soc tegra20_pmc_soc = {
.supports_core_domain = false,
.num_powergates = ARRAY_SIZE(tegra20_powergates),
.powergates = tegra20_powergates,
.num_cpu_powergates = 0,
@ -3065,7 +3066,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
.pmc_clks_data = NULL,
.num_pmc_clks = 0,
.has_blink_output = true,
.has_usb_sleepwalk = false,
.has_usb_sleepwalk = true,
};
static const char * const tegra30_powergates[] = {
@ -3101,6 +3102,7 @@ static const char * const tegra30_reset_sources[] = {
};
static const struct tegra_pmc_soc tegra30_pmc_soc = {
.supports_core_domain = false,
.num_powergates = ARRAY_SIZE(tegra30_powergates),
.powergates = tegra30_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
@ -3125,7 +3127,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
.pmc_clks_data = tegra_pmc_clks_data,
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
.has_blink_output = true,
.has_usb_sleepwalk = false,
.has_usb_sleepwalk = true,
};
static const char * const tegra114_powergates[] = {
@ -3157,6 +3159,7 @@ static const u8 tegra114_cpu_powergates[] = {
};
static const struct tegra_pmc_soc tegra114_pmc_soc = {
.supports_core_domain = false,
.num_powergates = ARRAY_SIZE(tegra114_powergates),
.powergates = tegra114_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates),
@ -3181,7 +3184,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
.pmc_clks_data = tegra_pmc_clks_data,
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
.has_blink_output = true,
.has_usb_sleepwalk = false,
.has_usb_sleepwalk = true,
};
static const char * const tegra124_powergates[] = {
@ -3273,6 +3276,7 @@ static const struct pinctrl_pin_desc tegra124_pin_descs[] = {
};
static const struct tegra_pmc_soc tegra124_pmc_soc = {
.supports_core_domain = false,
.num_powergates = ARRAY_SIZE(tegra124_powergates),
.powergates = tegra124_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates),
@ -3398,6 +3402,7 @@ static const struct tegra_wake_event tegra210_wake_events[] = {
};
static const struct tegra_pmc_soc tegra210_pmc_soc = {
.supports_core_domain = false,
.num_powergates = ARRAY_SIZE(tegra210_powergates),
.powergates = tegra210_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra210_cpu_powergates),
@ -3555,6 +3560,7 @@ static const struct tegra_wake_event tegra186_wake_events[] = {
};
static const struct tegra_pmc_soc tegra186_pmc_soc = {
.supports_core_domain = false,
.num_powergates = 0,
.powergates = NULL,
.num_cpu_powergates = 0,
@ -3689,6 +3695,7 @@ static const struct tegra_wake_event tegra194_wake_events[] = {
};
static const struct tegra_pmc_soc tegra194_pmc_soc = {
.supports_core_domain = false,
.num_powergates = 0,
.powergates = NULL,
.num_cpu_powergates = 0,
@ -3757,6 +3764,7 @@ static const char * const tegra234_reset_sources[] = {
};
static const struct tegra_pmc_soc tegra234_pmc_soc = {
.supports_core_domain = false,
.num_powergates = 0,
.powergates = NULL,
.num_cpu_powergates = 0,
@ -3803,6 +3811,14 @@ static void tegra_pmc_sync_state(struct device *dev)
{
int err;
/*
* Newer device-trees have power domains, but we need to prepare all
* device drivers with runtime PM and OPP support first, otherwise
* state syncing is unsafe.
*/
if (!pmc->soc->supports_core_domain)
return;
/*
* Older device-trees don't have core PD, and thus, there are
* no dependencies that will block the state syncing. We shouldn't

View File

@ -6,6 +6,8 @@
#ifndef __SOC_TEGRA_FUSE_H__
#define __SOC_TEGRA_FUSE_H__
#include <linux/types.h>
#define TEGRA20 0x20
#define TEGRA30 0x30
#define TEGRA114 0x35
@ -22,11 +24,6 @@
#ifndef __ASSEMBLY__
u32 tegra_read_chipid(void);
u8 tegra_get_chip_id(void);
u8 tegra_get_platform(void);
bool tegra_is_silicon(void);
enum tegra_revision {
TEGRA_REVISION_UNKNOWN = 0,
TEGRA_REVISION_A01,
@ -57,6 +54,10 @@ extern struct tegra_sku_info tegra_sku_info;
u32 tegra_read_straps(void);
u32 tegra_read_ram_code(void);
int tegra_fuse_readl(unsigned long offset, u32 *value);
u32 tegra_read_chipid(void);
u8 tegra_get_chip_id(void);
u8 tegra_get_platform(void);
bool tegra_is_silicon(void);
#else
static struct tegra_sku_info tegra_sku_info __maybe_unused;
@ -74,6 +75,26 @@ static inline int tegra_fuse_readl(unsigned long offset, u32 *value)
{
return -ENODEV;
}
static inline u32 tegra_read_chipid(void)
{
return 0;
}
static inline u8 tegra_get_chip_id(void)
{
return 0;
}
static inline u8 tegra_get_platform(void)
{
return 0;
}
static inline bool tegra_is_silicon(void)
{
return false;
}
#endif
struct device *tegra_soc_device_register(void);

View File

@ -6,8 +6,15 @@
#ifndef __SOC_TEGRA_IRQ_H
#define __SOC_TEGRA_IRQ_H
#if defined(CONFIG_ARM)
#include <linux/types.h>
#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_TEGRA)
bool tegra_pending_sgi(void);
#else
static inline bool tegra_pending_sgi(void)
{
return false;
}
#endif
#endif /* __SOC_TEGRA_IRQ_H */

View File

@ -17,7 +17,7 @@ enum tegra_suspend_mode {
TEGRA_SUSPEND_NOT_READY,
};
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) && defined(CONFIG_ARCH_TEGRA)
enum tegra_suspend_mode
tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);