diff --git a/common/init.c b/common/init.c index 4ff7240..15d5744 100644 --- a/common/init.c +++ b/common/init.c @@ -28,7 +28,6 @@ #include #endif - static int tegra_hwpm_init_chip_ip_structures(struct tegra_soc_hwpm *hwpm, u32 chip_id, u32 chip_id_rev) { @@ -44,7 +43,7 @@ static int tegra_hwpm_init_chip_ip_structures(struct tegra_soc_hwpm *hwpm, break; default: #ifdef CONFIG_TEGRA_NEXT1_HWPM - err = tegra_hwpm_next1_init_chip_info(hwpm, + err = tegra_hwpm_next1_init_chip_ip_structures(hwpm, chip_id, chip_id_rev); #else tegra_hwpm_err(hwpm, "Chip 0x%x rev 0x%x not supported", @@ -55,7 +54,7 @@ static int tegra_hwpm_init_chip_ip_structures(struct tegra_soc_hwpm *hwpm, break; default: #ifdef CONFIG_TEGRA_NEXT2_HWPM - err = tegra_hwpm_next2_init_chip_info( + err = tegra_hwpm_next2_init_chip_ip_structures( hwpm, chip_id, chip_id_rev); #else tegra_hwpm_err(hwpm, "Chip 0x%x not supported", chip_id); diff --git a/include/tegra_hwpm_soc.h b/include/tegra_hwpm_soc.h index b8db8a5..055277f 100644 --- a/include/tegra_hwpm_soc.h +++ b/include/tegra_hwpm_soc.h @@ -18,13 +18,19 @@ #define CHIP_ID_UNKNOWN 0x0U #define CHIP_ID_REV_UNKNOWN 0x0U -#define PLAT_SI 0 -#define PLAT_PRE_SI_QT 1 -#define PLAT_PRE_SI_VDK 8 -#define PLAT_PRE_SI_VSP 9 -#define PLAT_INVALID 10 +#define PLAT_SI 0x0 +#define PLAT_PRE_SI_QT 0x1 +#define PLAT_PRE_SI_VDK 0x8 +#define PLAT_PRE_SI_VSP 0x9 +#define PLAT_INVALID 0xF #define TEGRA_FUSE_PRODUCTION_MODE 0x0 + +struct hwpm_soc_chip_info { + u32 chip_id; + u32 chip_id_rev; + u32 platform; +}; #endif #ifdef __KERNEL__ diff --git a/os/linux/driver.c b/os/linux/driver.c index f239c2c..b371de2 100644 --- a/os/linux/driver.c +++ b/os/linux/driver.c @@ -28,6 +28,9 @@ #include #include #include +#if defined(CONFIG_TEGRA_NEXT2_HWPM) +#include +#endif static const struct of_device_id tegra_soc_hwpm_of_match[] = { { @@ -57,22 +60,34 @@ static char *tegra_hwpm_get_devnode(struct device *dev, umode_t *mode) static bool tegra_hwpm_read_support_soc_tools_prop(struct platform_device *pdev) { +#if defined(CONFIG_ACPI) + /* This will be implemented in a follow-up patch */ + return true; +#else struct device_node *np = pdev->dev.of_node; bool allow_node = of_property_read_bool(np, "support-soc-tools"); - if (!tegra_hwpm_is_platform_silicon()) { - return true; - } - if (!allow_node) { tegra_hwpm_err(NULL, "support-soc-tools is absent"); } return allow_node; +#endif } -static int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux) +static int tegra_hwpm_get_chip_info(struct tegra_hwpm_os_linux *hwpm_linux) { +#if defined(CONFIG_TEGRA_HWPM_OOT) + int ret = 0; + + ret = tegra_hwpm_init_chip_info(hwpm_linux); + if (ret != 0) { + tegra_hwpm_err(&hwpm_linux->hwpm, + "Failed to initialize current chip info"); + return ret; + } +#endif + hwpm_linux->device_info.chip = tegra_hwpm_get_chip_id(); hwpm_linux->device_info.chip_revision = tegra_hwpm_get_major_rev(); hwpm_linux->device_info.revision = tegra_hwpm_chip_get_revision(); @@ -158,10 +173,10 @@ static int tegra_hwpm_probe(struct platform_device *pdev) tegra_hwpm_debugfs_init(hwpm_linux); - ret = tegra_hwpm_init_chip_info(hwpm_linux); + ret = tegra_hwpm_get_chip_info(hwpm_linux); if (ret != 0) { - tegra_hwpm_err(hwpm, "Failed to initialize current chip info"); - goto init_chip_info_fail; + tegra_hwpm_err(hwpm, "Failed to get current chip info"); + goto chip_info_fail; } ret = tegra_hwpm_init_sw_components(hwpm, hwpm_linux->device_info.chip, @@ -187,7 +202,7 @@ static int tegra_hwpm_probe(struct platform_device *pdev) tegra_hwpm_dbg(hwpm, hwpm_info, "Probe successful!"); goto success; -init_chip_info_fail: +chip_info_fail: init_sw_components_fail: tegra_hwpm_clk_rst_release(hwpm_linux); clock_reset_fail: @@ -251,6 +266,9 @@ static struct platform_driver tegra_soc_hwpm_pdrv = { .driver = { .name = TEGRA_SOC_HWPM_MODULE_NAME, .of_match_table = of_match_ptr(tegra_soc_hwpm_of_match), +#if defined(CONFIG_TEGRA_NEXT2_HWPM) && defined(CONFIG_ACPI) + .acpi_match_table = ACPI_PTR(tegra_hwpm_acpi_match), +#endif }, }; diff --git a/os/linux/soc_utils.c b/os/linux/soc_utils.c index bf7a4ed..5d67e5f 100644 --- a/os/linux/soc_utils.c +++ b/os/linux/soc_utils.c @@ -12,10 +12,14 @@ */ #include +#if CONFIG_ACPI +#include +#endif #include -#include +#include #include +#include #if defined(CONFIG_TEGRA_HWPM_OOT) #if defined(CONFIG_TEGRA_NEXT1_HWPM) @@ -24,134 +28,165 @@ #if defined(CONFIG_TEGRA_NEXT2_HWPM) #include #endif + +static struct hwpm_soc_chip_info chip_info = { + .chip_id = CHIP_ID_UNKNOWN, + .chip_id_rev = CHIP_ID_REV_UNKNOWN, + .platform = PLAT_INVALID, +}; +static bool chip_info_initialized; + +#if (!defined(CONFIG_ACPI)) +const struct hwpm_soc_chip_info t234_chip_info = { + .chip_id = 0x23, + .chip_id_rev = 0x4, + .platform = PLAT_SI, +}; #endif -u32 tegra_hwpm_get_chip_id_impl(void) +/* This function should be invoked only once before retrieving soc chip info */ +int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux) { -#if defined(CONFIG_TEGRA_HWPM_OOT) - u32 chip_id = CHIP_ID_UNKNOWN; + struct device *dev = hwpm_linux->dev; + struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm; +#if defined(CONFIG_ACPI) + const struct acpi_device_id *id; +#endif + if (chip_info_initialized) { + return 0; + } +#if defined(CONFIG_ACPI) + id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!id) { + tegra_hwpm_err(hwpm, "Couldn't find matching ACPI device"); + return -ENODEV; + } + + chip_info.chip_id = (id->driver_data >> 8) & 0xff; + chip_info.chip_id_rev = (id->driver_data >> 4) & 0xf; + chip_info.platform = (id->driver_data >> 20) & 0xf; + + goto complete; +#else /* !CONFIG_ACPI */ if (of_machine_is_compatible("nvidia,tegra234")) { - chip_id = 0x23U; - return chip_id; + chip_info.chip_id = t234_chip_info.chip_id; + chip_info.chip_id_rev = t234_chip_info.chip_id_rev; + chip_info.platform = t234_chip_info.platform; + + goto complete; } #if defined(CONFIG_TEGRA_NEXT1_HWPM) - chip_id = tegra_hwpm_next1_get_chip_id_impl(); - if (chip_id != CHIP_ID_UNKNOWN) { - return chip_id; + if (tegra_hwpm_next1_get_chip_compatible(&chip_info) == 0) { + goto complete; } #endif #if defined(CONFIG_TEGRA_NEXT2_HWPM) - chip_id = tegra_hwpm_next2_get_chip_id_impl(); - if (chip_id != CHIP_ID_UNKNOWN) { - return chip_id; + if (tegra_hwpm_next2_get_chip_compatible(&chip_info) == 0) { + goto complete; } #endif - return chip_id; -#else - return (u32)tegra_get_chip_id(); -#endif /* CONFIG_TEGRA_HWPM_OOT */ + +#endif /* CONFIG_ACPI */ + return -EINVAL; +complete: + chip_info_initialized = true; + return 0; +} + +u32 tegra_hwpm_get_chip_id_impl(void) +{ + if (chip_info_initialized) { + return chip_info.chip_id; + } + return CHIP_ID_UNKNOWN; } u32 tegra_hwpm_get_major_rev_impl(void) { -#if defined(CONFIG_TEGRA_HWPM_OOT) - u32 chip_id_rev = CHIP_ID_REV_UNKNOWN; - - if (of_machine_is_compatible("nvidia,tegra234")) { - chip_id_rev = 0x4U; - return chip_id_rev; + if (chip_info_initialized) { + return chip_info.chip_id_rev; } -#if defined(CONFIG_TEGRA_NEXT1_HWPM) - chip_id_rev = tegra_hwpm_next1_get_major_rev_impl(); - if (chip_id_rev != CHIP_ID_REV_UNKNOWN) { - return chip_id_rev; - } -#endif -#if defined(CONFIG_TEGRA_NEXT2_HWPM) - chip_id_rev = tegra_hwpm_next2_get_major_rev_impl(); - if (chip_id_rev != CHIP_ID_REV_UNKNOWN) { - return chip_id_rev; - } -#endif - return chip_id_rev; -#else - return (u32)tegra_get_major_rev(); -#endif -} - -u32 tegra_hwpm_chip_get_revision_impl(void) -{ -#if defined(CONFIG_TEGRA_HWPM_OOT) - return 0x0U; -#else - return (u32)tegra_chip_get_revision(); -#endif + return CHIP_ID_REV_UNKNOWN; } u32 tegra_hwpm_get_platform_impl(void) { -#if defined(CONFIG_TEGRA_HWPM_OOT) - u32 plat = PLAT_INVALID; + if (chip_info_initialized) { + return chip_info.platform; + } + return PLAT_INVALID; +} - if (of_machine_is_compatible("nvidia,tegra234")) { - plat = PLAT_SI; - return plat; - } -#if defined(CONFIG_TEGRA_NEXT1_HWPM) - plat = tegra_hwpm_next1_get_major_rev_impl(); - if (plat != PLAT_INVALID) { - return plat; - } -#endif -#if defined(CONFIG_TEGRA_NEXT2_HWPM) - plat = tegra_hwpm_next2_get_major_rev_impl(); - if (plat != PLAT_INVALID) { - return plat; - } -#endif - return plat; -#else - return (u32)tegra_get_platform(); -#endif +u32 tegra_hwpm_chip_get_revision_impl(void) +{ + return 0x0U; } bool tegra_hwpm_is_platform_silicon_impl(void) { -#if defined(CONFIG_TEGRA_HWPM_OOT) return tegra_hwpm_get_platform() == PLAT_SI; -#else - return tegra_platform_is_silicon(); -#endif } bool tegra_hwpm_is_platform_simulation_impl(void) { -#if defined(CONFIG_TEGRA_HWPM_OOT) return tegra_hwpm_get_platform() == PLAT_PRE_SI_VDK; -#else - return tegra_platform_is_vdk(); -#endif } bool tegra_hwpm_is_platform_vsp_impl(void) { -#if defined(CONFIG_TEGRA_HWPM_OOT) return tegra_hwpm_get_platform() == PLAT_PRE_SI_VSP; -#else - return tegra_platform_is_vsp(); -#endif } bool tegra_hwpm_is_hypervisor_mode_impl(void) { -#if defined(CONFIG_TEGRA_HWPM_OOT) return false; -#else - return is_tegra_hypervisor_mode(); -#endif } +#else /* !CONFIG_TEGRA_HWPM_OOT */ + +u32 tegra_hwpm_get_chip_id_impl(void) +{ + return (u32)tegra_get_chip_id(); +} + +u32 tegra_hwpm_get_major_rev_impl(void) +{ + return (u32)tegra_get_major_rev(); +} + +u32 tegra_hwpm_chip_get_revision_impl(void) +{ + return (u32)tegra_chip_get_revision(); +} + +u32 tegra_hwpm_get_platform_impl(void) +{ + return (u32)tegra_get_platform(); +} + +bool tegra_hwpm_is_platform_silicon_impl(void) +{ + return tegra_platform_is_silicon(); +} + +bool tegra_hwpm_is_platform_simulation_impl(void) +{ + return tegra_platform_is_vdk(); +} + +bool tegra_hwpm_is_platform_vsp_impl(void) +{ + return tegra_platform_is_vsp(); +} + +bool tegra_hwpm_is_hypervisor_mode_impl(void) +{ + return is_tegra_hypervisor_mode(); +} + +#endif /* CONFIG_TEGRA_HWPM_OOT */ + int tegra_hwpm_fuse_readl_impl(struct tegra_soc_hwpm *hwpm, u64 reg_offset, u32 *val) { diff --git a/os/linux/soc_utils.h b/os/linux/soc_utils.h index 620f1af..56b343a 100644 --- a/os/linux/soc_utils.h +++ b/os/linux/soc_utils.h @@ -14,8 +14,10 @@ #ifndef TEGRA_HWPM_OS_LINUX_SOC_UTILS_H #define TEGRA_HWPM_OS_LINUX_SOC_UTILS_H +struct tegra_hwpm_os_linux; struct tegra_soc_hwpm; +int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux); u32 tegra_hwpm_get_chip_id_impl(void); u32 tegra_hwpm_get_major_rev_impl(void); u32 tegra_hwpm_chip_get_revision_impl(void);