// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2024 PHYTEC Messtechnik GmbH * Author: Daniel Schultz */ #include #include "am6_som_detection.h" extern struct phytec_eeprom_data eeprom_data; #if IS_ENABLED(CONFIG_PHYTEC_AM62_SOM_DETECTION) || \ IS_ENABLED(CONFIG_PHYTEC_AM64_SOM_DETECTION) /* Check if the SoM is actually one of the following products: * - phyCORE-AM62x * - phyCORE-AM64x * * Returns 0 in case it's a known SoM. Otherwise, returns -1. */ int phytec_am6_detect(struct phytec_eeprom_data *data) { char *opt; u8 som; if (!data) data = &eeprom_data; /* We cannot do the check for early API revisions */ if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) return -1; som = data->payload.data.data_api2.som_no; debug("%s: som id: %u\n", __func__, som); opt = phytec_get_opt(data); if (!opt) return -1; if (som == PHYTEC_AM62X_SOM && soc_is_am62x()) return 0; if (som == PHYTEC_AM64X_SOM && soc_is_am64x()) return 0; return -1; } static u8 phytec_check_opt(struct phytec_eeprom_data *data, u8 option) { char *opt; if (!data) data = &eeprom_data; if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) return PHYTEC_EEPROM_INVAL; if (option > 8) return PHYTEC_EEPROM_INVAL; opt = phytec_get_opt(data); if (opt) return PHYTEC_GET_OPTION(opt[option]); return PHYTEC_EEPROM_INVAL; } /* * Reads LPDDR4 ram size from EEPROM. * * returns: * - The size * - PHYTEC_EEPROM_INVAL when the data is invalid. */ u8 __maybe_unused phytec_get_am62_ddr_size(struct phytec_eeprom_data *data) { u8 ddr_id = phytec_check_opt(data, 3); pr_debug("%s: ddr id: %u\n", __func__, ddr_id); return ddr_id; } /* * Reads SPI-NOR flash size and type from EEPROM. * * returns: * - PHYTEC_EEPROM_VALUE_X if no SPI is poulated. * - Otherwise a board depended code for the size. * - PHYTEC_EEPROM_INVAL when the data is invalid. */ u8 __maybe_unused phytec_get_am62_spi(struct phytec_eeprom_data *data) { u8 spi = phytec_check_opt(data, 5); pr_debug("%s: spi: %u\n", __func__, spi); return spi; } /* * Reads Ethernet phy information from EEPROM. * * returns: * - 0x0 no ethernet phy is populated. * - 0x1 if 10/100/1000 MBit Phy is populated. * - PHYTEC_EEPROM_INVAL when the data is invalid. */ u8 __maybe_unused phytec_get_am62_eth(struct phytec_eeprom_data *data) { u8 eth = phytec_check_opt(data, 6); pr_debug("%s: eth: %u\n", __func__, eth); return eth; } /* * Reads RTC information from EEPROM. * * returns: * - 0 if no RTC is poulated. * - 1 if it is populated. * - PHYTEC_EEPROM_INVAL when the data is invalid. */ u8 __maybe_unused phytec_get_am62_rtc(struct phytec_eeprom_data *data) { u8 rtc = phytec_check_opt(data, 7); pr_debug("%s: rtc: %u\n", __func__, rtc); return rtc; } #else inline int __maybe_unused phytec_am62_detect(struct phytec_eeprom_data *data) { return -1; } inline u8 __maybe_unused phytec_get_am62_ddr_size(struct phytec_eeprom_data *data) { return PHYTEC_EEPROM_INVAL; } inline u8 __maybe_unused phytec_get_am62_spi(struct phytec_eeprom_data *data) { return PHYTEC_EEPROM_INVAL; } inline u8 __maybe_unused phytec_get_am62_eth(struct phytec_eeprom_data *data) { return PHYTEC_EEPROM_INVAL; } inline u8 __maybe_unused phytec_get_am62_rtc(struct phytec_eeprom_data *data) { return PHYTEC_EEPROM_INVAL; } #endif