1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2024 PHYTEC Messtechnik GmbH 4 * Author: Daniel Schultz <d.schultz@phytec.de> 5 */ 6 7#include <asm/arch/hardware.h> 8 9#include "am6_som_detection.h" 10 11extern struct phytec_eeprom_data eeprom_data; 12 13#if IS_ENABLED(CONFIG_PHYTEC_AM62_SOM_DETECTION) || \ 14 IS_ENABLED(CONFIG_PHYTEC_AM64_SOM_DETECTION) 15 16/* Check if the SoM is actually one of the following products: 17 * - phyCORE-AM62x 18 * - phyCORE-AM64x 19 * 20 * Returns 0 in case it's a known SoM. Otherwise, returns -1. 21 */ 22int phytec_am6_detect(struct phytec_eeprom_data *data) 23{ 24 char *opt; 25 u8 som; 26 27 if (!data) 28 data = &eeprom_data; 29 30 /* We cannot do the check for early API revisions */ 31 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) 32 return -1; 33 34 som = data->payload.data.data_api2.som_no; 35 debug("%s: som id: %u\n", __func__, som); 36 37 opt = phytec_get_opt(data); 38 if (!opt) 39 return -1; 40 41 if (som == PHYTEC_AM62X_SOM && soc_is_am62x()) 42 return 0; 43 44 if (som == PHYTEC_AM64X_SOM && soc_is_am64x()) 45 return 0; 46 47 return -1; 48} 49 50static u8 phytec_check_opt(struct phytec_eeprom_data *data, u8 option) 51{ 52 char *opt; 53 54 if (!data) 55 data = &eeprom_data; 56 57 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) 58 return PHYTEC_EEPROM_INVAL; 59 60 if (option > 8) 61 return PHYTEC_EEPROM_INVAL; 62 63 opt = phytec_get_opt(data); 64 if (opt) 65 return PHYTEC_GET_OPTION(opt[option]); 66 return PHYTEC_EEPROM_INVAL; 67} 68 69/* 70 * Reads LPDDR4 ram size from EEPROM. 71 * 72 * returns: 73 * - The size 74 * - PHYTEC_EEPROM_INVAL when the data is invalid. 75 */ 76u8 __maybe_unused phytec_get_am62_ddr_size(struct phytec_eeprom_data *data) 77{ 78 u8 ddr_id = phytec_check_opt(data, 3); 79 80 pr_debug("%s: ddr id: %u\n", __func__, ddr_id); 81 return ddr_id; 82} 83 84/* 85 * Reads SPI-NOR flash size and type from EEPROM. 86 * 87 * returns: 88 * - PHYTEC_EEPROM_VALUE_X if no SPI is poulated. 89 * - Otherwise a board depended code for the size. 90 * - PHYTEC_EEPROM_INVAL when the data is invalid. 91 */ 92u8 __maybe_unused phytec_get_am62_spi(struct phytec_eeprom_data *data) 93{ 94 u8 spi = phytec_check_opt(data, 5); 95 96 pr_debug("%s: spi: %u\n", __func__, spi); 97 return spi; 98} 99 100/* 101 * Reads Ethernet phy information from EEPROM. 102 * 103 * returns: 104 * - 0x0 no ethernet phy is populated. 105 * - 0x1 if 10/100/1000 MBit Phy is populated. 106 * - PHYTEC_EEPROM_INVAL when the data is invalid. 107 */ 108u8 __maybe_unused phytec_get_am62_eth(struct phytec_eeprom_data *data) 109{ 110 u8 eth = phytec_check_opt(data, 6); 111 112 pr_debug("%s: eth: %u\n", __func__, eth); 113 return eth; 114} 115 116/* 117 * Reads RTC information from EEPROM. 118 * 119 * returns: 120 * - 0 if no RTC is poulated. 121 * - 1 if it is populated. 122 * - PHYTEC_EEPROM_INVAL when the data is invalid. 123 */ 124u8 __maybe_unused phytec_get_am62_rtc(struct phytec_eeprom_data *data) 125{ 126 u8 rtc = phytec_check_opt(data, 7); 127 128 pr_debug("%s: rtc: %u\n", __func__, rtc); 129 return rtc; 130} 131 132#else 133 134inline int __maybe_unused phytec_am62_detect(struct phytec_eeprom_data *data) 135{ 136 return -1; 137} 138 139inline u8 __maybe_unused 140phytec_get_am62_ddr_size(struct phytec_eeprom_data *data) 141{ 142 return PHYTEC_EEPROM_INVAL; 143} 144 145inline u8 __maybe_unused phytec_get_am62_spi(struct phytec_eeprom_data *data) 146{ 147 return PHYTEC_EEPROM_INVAL; 148} 149 150inline u8 __maybe_unused phytec_get_am62_eth(struct phytec_eeprom_data *data) 151{ 152 return PHYTEC_EEPROM_INVAL; 153} 154 155inline u8 __maybe_unused phytec_get_am62_rtc(struct phytec_eeprom_data *data) 156{ 157 return PHYTEC_EEPROM_INVAL; 158} 159#endif 160