firmware: gtm900b: fix flash-based hardware variant autodetection

The original code used simplified logic whereby it assumed that
Spansion flash means MG01GSMT and Samsung flash means MGCxGSMT.
However, there exist MGC2GSMT hw variants with Spansion S71PL032J
flash in them, thus it is necessary to check the complete device ID
rather than just the flash manufacturer ID to distinguish between
MG01GSMT with 8 MiB flash (S71PL064J) and MGCxGSMT with 4 MiB flash
(S71PL032J, K5A3281CTM or K5L3316CAM).

Distinguishing between 4 MiB and 8 MiB flash chip types is also
necessary in order to configure TIFFS reader for the correct FFS
location matching that used by the original firmware, which is
in turn necessary in order to read factory RF calibration values.

Closes: OS#4769
Change-Id: Iaa5bd295e9cbf6b525fa385f9d6cd7fcd7f8a4dd
This commit is contained in:
Mychaela Falconia 2020-09-28 19:42:41 +00:00 committed by Harald Welte
parent 7b2820526a
commit b40188ce31
2 changed files with 72 additions and 33 deletions

View File

@ -56,6 +56,8 @@
#define LPG_LCR_REG 0xfffe7800
#define LPG_PM_REG 0xfffe7801
int gtm900_hw_is_mg01gsmt;
static void board_io_init(void)
{
uint16_t reg;
@ -85,6 +87,68 @@ static void board_io_init(void)
writew(reg, ARM_CONF_REG);
}
/*
* There exist two firmware-incompatible versions of GTM900-B hardware:
* MG01GSMT and MGCxGSMT. They have different flash chip types (8 MiB
* vs. 4 MiB) with correspondingly different TIFFS configurations
* (and we need TIFFS in order to read factory RF calibration values),
* and they have different (incompatible) RFFE control signals.
*
* We are going to check the flash chip type and use it to decide which
* hw variant we are running on.
*/
static void board_flash_init(void)
{
uint16_t manufacturer_id, device_id[3];
/* Use an address above the Calypso boot ROM
* so we don't need to unmap it to access the flash. */
flash_get_id((void *)0x40000, &manufacturer_id, device_id);
switch (manufacturer_id) {
case CFI_MANUF_SPANSION:
/* is it S71PL064J? */
if (device_id[0] == 0x227E && device_id[1] == 0x2202 &&
device_id[2] == 0x2201) {
gtm900_hw_is_mg01gsmt = 1;
break;
}
/* is it S71PL032J? */
if (device_id[0] == 0x227E && device_id[1] == 0x220A &&
device_id[2] == 0x2201) {
gtm900_hw_is_mg01gsmt = 0;
break;
}
goto bad;
case CFI_MANUF_SAMSUNG:
/* is it K5A3281CTM? */
if (device_id[0] == 0x22A0) {
gtm900_hw_is_mg01gsmt = 0;
break;
}
/* is it K5L3316CAM? */
if (device_id[0] == 0x257E && device_id[1] == 0x2503 &&
device_id[2] == 0x2501) {
gtm900_hw_is_mg01gsmt = 0;
break;
}
/* FALL THRU */
default:
bad:
printf("Unknown module detected, "
"flash ID 0x%04x 0x%04x 0x%04x 0x%04x\n"
"Please contact mailing list!\n\n", manufacturer_id,
device_id[0], device_id[1], device_id[2]);
return;
}
/* Initialize TIFFS reader */
if (gtm900_hw_is_mg01gsmt)
tiffs_init(0x700000, 0x10000, 15);
else
tiffs_init(0x380000, 0x10000, 7);
}
void board_init(int with_irq)
{
/*
@ -151,4 +215,7 @@ https://www.freecalypso.org/hg/freecalypso-docs/file/tip/MEMIF-wait-states
/* Initialize ABB driver (uses SPI) */
twl3025_init();
/* Initialize board flash */
board_flash_init();
}

View File

@ -1,5 +1,5 @@
/* RF frontend driver for Huawei GTM900-B modems, supporting both
* MG01GSMT and MG01GSMT hardware variants */
* MG01GSMT and MGCxGSMT hardware variants */
/* (C) 2019 by Steve Markgraf <steve@steve-m.de>
*
@ -63,12 +63,7 @@
* Tx2: high band PA output
*/
typedef enum rffe_var {
RFFE_MGC2GSMT,
RFFE_MG01GSMT
} rffe_var_t;
static rffe_var_t rffe_variant = RFFE_MGC2GSMT;
extern int gtm900_hw_is_mg01gsmt; /* set in init.c */
static inline void rffe_mode_mgc2gsmt(enum gsm_band band, int tx)
{
@ -139,10 +134,10 @@ static inline void rffe_mode_mg01gsmt(enum gsm_band band, int tx)
/* switch RF Frontend Mode */
void rffe_mode(enum gsm_band band, int tx)
{
if (rffe_variant == RFFE_MGC2GSMT)
rffe_mode_mgc2gsmt(band, tx);
else
if (gtm900_hw_is_mg01gsmt)
rffe_mode_mg01gsmt(band, tx);
else
rffe_mode_mgc2gsmt(band, tx);
}
uint32_t rffe_get_rx_ports(void)
@ -166,7 +161,6 @@ int rffe_iq_swapped(uint16_t band_arfcn, int tx)
void rffe_init(void)
{
uint16_t reg;
uint16_t manufacturer_id = 0;
reg = readw(ARM_CONF_REG);
reg &= ~ (1 << 7); /* TSPACT4 I/O function, not nRDYMEM */
@ -176,28 +170,6 @@ void rffe_init(void)
tsp_setup(IOTA_STROBE, 1, 0, 0);
trf6151_init(RITA_STROBE, RITA_RESET);
/* Detect the used RFFE variant based on the used flash chip.
* The MGC2GSMT uses a Samsung flash, whereas the MG01GSMT uses
* a Spansion flash. We use an address above the Calpso bootrom
* so we do not need to unmap it to access the flash. */
flash_get_id((void *)0x40000, &manufacturer_id, NULL);
switch (manufacturer_id) {
case CFI_MANUF_SPANSION:
printf("Detected MG01GSMT module\n\n");
rffe_variant = RFFE_MG01GSMT;
break;
case CFI_MANUF_SAMSUNG:
printf("Detected MGC2GSMT module\n\n");
rffe_variant = RFFE_MGC2GSMT;
break;
default:
printf("Unknown module detected, flash ID 0x%4.4x\n"
"Please contact mailing list!\n\n", manufacturer_id);
rffe_variant = RFFE_MGC2GSMT;
break;
}
}
uint8_t rffe_get_gain(void)