GPIO0LV5 J15 FAB_ID1 0 0 0 1 0 1 0
*/
enum {
- MFLD_BID_UNKNOWN = 0,
+ MFLD_BID_UNKNOWN = 0,
MFLD_BID_CDK = 0x12,
MFLD_BID_AAVA = 0x06,
MFLD_BID_PR2_PROTO = 0x15,
MFLD_BID_PR2_VOLUME = 0x25,
MFLD_BID_PR3 = 0x35,
MFLD_BID_PR3_PNP = 0x18,
- MFLD_BID_LEX = 0xe0000025
+ MFLD_BID_RR_DV10 = 0x25,
+ MFLD_BID_RR_DV20 = 0x15,
+ MFLD_BID_LEX = 0xe0000025,
+ CLVT_BID_VV = 0x08,
+ CLVT_BID_PR0 = 0x04
};
extern u32 mfld_board_id(void);
};
extern u32 ctp_board_id(void);
+#define spid_attr(_name) \
+static struct kobj_attribute _name##_attr = { \
+ .attr = { \
+ .name = __stringify(_name), \
+ .mode = 0444, \
+ }, \
+ .show = _name##_show, \
+}
+
+/* Customer_ID table */
+enum {
+ CUSTOMER_INTEL,
+ CUSTOMER_AT,
+ CUSTOMER_OR,
+ CUSTOMER_UNKNOWN
+};
+
+/* Vendor_ID table */
+enum {
+ VENDOR_INTEL,
+ VENDOR_LN,
+ VENDOR_MO,
+ VENDOR_UNKNOWN
+};
+
+/* Manufacturer_ID table for Vendor_ID == VENDOR_INTEL */
+enum {
+ MANUFACTURER_FC_FAB1,
+ MANUFACTURER_FC_FAB2,
+ MANUFACTURER_INTEL_FAB1,
+ MANUFACTURER_UNKNOWN
+};
+
+/* Platform_Family_ID table for Vendor_ID == VENDOR_INTEL */
+enum {
+ INTEL_MFLD_PHONE,
+ INTEL_MFLD_TABLET,
+ INTEL_CLVTP_PHONE,
+ INTEL_CLVT_TABLET,
+ INTEL_MRFL_PHONE,
+ INTEL_MRFL_TABLET,
+ INTEL_PLATFORM_UNKNOWN
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_MFLD_PHONE */
+enum {
+ INTEL_MFLDP_BB15_PRO = 0x0000,
+ INTEL_MFLDP_BB15_ENG = 0x8000,
+ INTEL_MFLDP_BB20_PRO = 0x0001,
+ INTEL_MFLDP_BB20_ENG = 0x8001,
+ INTEL_MFLDP_OR_PRO = 0x0002,
+ INTEL_MFLDP_OR_ENG = 0x8002,
+ INTEL_MFLDP_AT_PRO = 0x0003,
+ INTEL_MFLDP_AT_ENG = 0x8003,
+ INTEL_MFLDP_LEX_PRO = 0x0004,
+ INTEL_MFLDP_LEX_ENG = 0x8004,
+ INTEL_MFLDP_UNKNOWN = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_MFLD_TABLET */
+enum {
+ INTEL_MFLDT_RR_PRO = 0x0000,
+ INTEL_MFLDT_RR_ENG = 0x8000,
+ INTEL_MFLDT_UNKNOWN = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_CLVTP_PHONE */
+enum {
+ INTEL_CLVTPP_RHB_PRO = 0x0000,
+ INTEL_CLVTPP_RHB_ENG = 0x8000,
+ INTEL_CLVTPP_UNKNOWN = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_CLVT_TABLET */
+enum {
+ INTEL_CLVTT_TBD_PRO = 0x0000,
+ INTEL_CLVTT_TBD_ENG = 0x8000,
+ INTEL_CLVTT_UNKNOWN = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_MRFL_PHONE */
+enum {
+ INTEL_MRFLP_TBD_PRO = 0x0000,
+ INTEL_MRFLP_TBD_ENG = 0x8000,
+ INTEL_MRFLP_UNKNOWN = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_MRFL_TABLET */
+enum {
+ INTEL_MRFLT_TBD_PRO = 0x0000,
+ INTEL_MRFLT_TBD_ENG = 0x8000,
+ INTEL_MRFLT_UNKNOWN = 0xFFFF
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_BB15_PRO */
+enum {
+ MFLDP_BB15_PRO_PR33, /* CRAK D1 - 1.6GHz */
+ MFLDP_BB15_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_BB15_ENG */
+enum {
+ MFLDP_BB15_ENG_PR20, /* CRAK C0 */
+ MFLDP_BB15_ENG_PR31, /* CRAK D0 */
+ MFLDP_BB15_ENG_PR32, /* CRAK D0 */
+ MFLDP_BB15_ENG_PR33, /* CRAK D1 - 1.6GHz */
+ MFLDP_BB15_ENG_PR34, /* CRAK D1 - 1.6GHz, alt eMMC, DDR2 */
+ MFLDP_BB15_ENG_PR35, /* CRAK D1 - 1.6GHz, alt eMMC, DDR2 */
+ MFLDP_BB15_ENG_PR36, /* CRAK D1 - 1.6GHz, alt eMMC, DDR2, MSIC C2 */
+ MFLDP_BB15_ENG_PR40, /* CRAK D1 - 2.0GHz */
+ MFLDP_BB15_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_BB20_PRO */
+enum {
+ MFLDP_BB20_PRO_TBD,
+ MFLDP_BB20_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_BB20_ENG */
+enum {
+ MFLDP_BB20_ENG_TBD,
+ MFLDP_BB20_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_OR_PRO */
+enum {
+ MFLDP_OR_PRO_NHDV30, /* CRAK D1 */
+ MFLDP_OR_PRO_NHDV31, /* CRAK D1 */
+ MFLDP_OR_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_OR_ENG */
+enum {
+ MFLDP_OR_ENG_NHDV1, /* CRAK D0 */
+ MFLDP_OR_ENG_NHDV2, /* CRAK D1 */
+ MFLDP_OR_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_AT_PRO */
+enum {
+ MFLDP_AT_PRO_LA, /* CAAK D1 */
+ MFLDP_AT_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_AT_ENG */
+enum {
+ MFLDP_AT_ENG_LA, /* CAAK D1 */
+ MFLDP_AT_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_LEX_PRO */
+enum {
+ MFLDP_LEX_PRO_TBD,
+ MFLDP_LEX_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_LEX_ENG */
+enum {
+ MFLDP_LEX_ENG_PR11, /* RYS/PNW 1GHz CREK D1 */
+ MFLDP_LEX_ENG_PR1M, /* RYS/PNW 1GHz CREK D1 */
+ MFLDP_LEX_ENG_PR21, /* RYS/PNW 1GHz CSEK D1 */
+ MFLDP_LEX_ENG_PR2M, /* RYS/PNW 1GHz CSEK D1 */
+ MFLDP_LEX_ENG_PR30, /* RYS/PNW 1GHz CSEK D1 */
+ MFLDP_LEX_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDT_RR_PRO */
+enum {
+ MFLDT_RR_PRO_DV21, /* CRAK D1 */
+ MFLDT_RR_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDT_RR_ENG */
+enum {
+ MFLDT_RR_ENG_DV10, /* CRAK D0 */
+ MFLDT_RR_ENG_DV15, /* CRAK D0/D1 */
+ MFLDT_RR_ENG_DV20, /* CRAK D1 */
+ MFLDT_RR_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_CLVTPP_RHB_PRO */
+enum {
+ CLVTPP_RHB_PRO_DV1,
+ CLVTPP_RHB_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_CLVTPP_RHB_ENG */
+enum {
+ CLVTPP_RHB_ENG_CCVVA, /* Clover City VV FAB A */
+ CLVTPP_RHB_ENG_CCVVB, /* Clover City VV FAB B */
+ CLVTPP_RHB_ENG_CCVVC, /* Clover City VV FAB C */
+ CLVTPP_RHB_ENG_CLEV, /* Clover Lake CRB EV */
+ CLVTPP_RHB_ENG_PR01, /* CLV A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_PR02, /* CLV A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_PMPR10, /* CLV A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_PVV1, /* CLV A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_PPR10, /* CLV A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_MPR10, /* CLV+ A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_VVPR10, /* CLV+ A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_PR10, /* CLV+ A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_MPR15, /* CLV+ A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_VVPR15, /* CLV+ A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_PR15, /* CLV+ A0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_MPR20, /* CLV+ B0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_VVPR20, /* CLV+ B0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_PR20, /* CLV+ B0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_MPR30, /* CLV+ B0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_VVPR30, /* CLV+ B0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_PR30, /* CLV+ B0 ?FUSE CLASS? */
+ CLVTPP_RHB_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_CLVTT_TBD_PRO */
+enum {
+ CLVTT_TBD_PRO_TBD,
+ CLVTT_TBD_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_CLVTT_TBD_ENG */
+enum {
+ CLVTT_TBD_ENG_CLEVA, /* Clover Lake EV - CRB - FAB A */
+ CLVTT_TBD_ENG_CLEVB, /* Clover Lake EV - CRB - FAB B */
+ CLVTT_TBD_ENG_CLEVC, /* Clover Lake EV - CRB - FAB C */
+ CLVTT_TBD_ENG_CLEVD, /* Clover Lake EV - CRB - FAB D */
+ CLVTT_TBD_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MRFLP_TBD_PRO */
+enum {
+ MRFLP_TBD_PRO_TBD,
+ MRFLP_TBD_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MRFLP_TBD_ENG */
+enum {
+ MRFLP_TBD_ENG_SRVVA, /* SilverRidge VV FAB A */
+ MRFLP_TBD_ENG_SRVVB, /* SilverRidge VV FAB B */
+ MRFLP_TBD_ENG_SRVVC, /* SilverRidge VV FAB C */
+ MRFLP_TBD_ENG_SRVVD, /* SilverRidge VV FAB D */
+ MRFLP_TBD_ENG_SRSVA, /* SilverRidge VV FAB A */
+ MRFLP_TBD_ENG_SRSVB, /* SilverRidge VV FAB B */
+ MRFLP_TBD_ENG_SRSVC, /* SilverRidge VV FAB C */
+ MRFLP_TBD_ENG_SRSVD, /* SilverRidge VV FAB D */
+ MRFLP_TBD_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MRFLT_TBD_PRO */
+enum {
+ MRFLT_TBD_PRO_TBD,
+ MRFLT_TBD_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MRFLT_TBD_ENG */
+enum {
+ MRFLT_TBD_ENG_TBD,
+ MRFLT_TBD_ENG_UNKNOWN
+};
+
/*
* Penwell uses spread spectrum clock, so the freq number is not exactly
* the same as reported by MSR based on SDM.
__cpuinitdata enum intel_mid_timer_options intel_mid_timer_options;
+struct kobject *spid_kobj;
+struct sfi_soft_platform_id spid;
u32 board_id;
static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
board_id = oemb->board_id | (oemb->board_fab << 4);
+ /* SPID support starts from version 4, D0 Penwell based products
+ * will stay with old firmware, so we still have to use the
+ * deprecating board_id to identify these hardware */
+ if (oemb->header.rev < 4) {
+ memset(spid.fru, 0, SPID_FRU_SIZE);
+ spid.customer_id = CUSTOMER_INTEL;
+ spid.vendor_id = VENDOR_INTEL;
+ spid.manufacturer_id = MANUFACTURER_INTEL_FAB1;
+ switch (board_id) {
+ case MFLD_BID_PR3:
+ spid.platform_family_id = INTEL_MFLD_PHONE;
+ spid.product_line_id = INTEL_MFLDP_BB15_ENG;
+ spid.hardware_id = MFLDP_BB15_ENG_PR31;
+ break;
+ case MFLD_BID_RR_DV10:
+ spid.platform_family_id = INTEL_MFLD_TABLET;
+ spid.product_line_id = INTEL_MFLDT_RR_ENG;
+ spid.hardware_id = MFLDT_RR_ENG_DV10;
+ break;
+ case MFLD_BID_RR_DV20:
+ spid.platform_family_id = INTEL_MFLD_TABLET;
+ spid.product_line_id = INTEL_MFLDT_RR_ENG;
+ spid.hardware_id = MFLDT_RR_ENG_DV20;
+ break;
+ case MFLD_BID_LEX:
+ spid.platform_family_id = INTEL_MFLD_PHONE;
+ spid.product_line_id = INTEL_MFLDP_LEX_ENG;
+ spid.hardware_id = MFLDP_LEX_ENG_PR11;
+ break;
+ case CLVT_BID_VV:
+ spid.platform_family_id = INTEL_CLVTP_PHONE;
+ spid.product_line_id = INTEL_CLVTPP_RHB_ENG;
+ spid.hardware_id = CLVTPP_RHB_ENG_CCVVA;
+ break;
+ case CLVT_BID_PR0:
+ spid.platform_family_id = INTEL_CLVTP_PHONE;
+ spid.product_line_id = INTEL_CLVTPP_RHB_ENG;
+ spid.hardware_id = CLVTPP_RHB_ENG_PR01;
+ break;
+ default:
+ memset(&spid, 0xff, sizeof(struct sfi_soft_platform_id));
+ break;
+ }
+ } else
+ memcpy(&spid, &oemb->spid, sizeof(struct sfi_soft_platform_id));
+
snprintf(sig, (SFI_SIGNATURE_SIZE + 1), "%s",
oemb->header.sig);
snprintf(oem_id, (SFI_OEM_ID_SIZE + 1), "%s",
snprintf(oem_table_id, (SFI_OEM_TABLE_ID_SIZE + 1), "%s",
oemb->header.oem_table_id);
pr_info("MFLD Validation SFI OEMB Layout\n");
- pr_info("\tOEMB signature : %s\n"
- "\tOEMB length : %d\n"
- "\tOEMB revision : %d\n"
- "\tOEMB checksum : 0x%X\n"
- "\tOEMB oem_id : %s\n"
- "\tOEMB oem_table_id : %s\n"
- "\tOEMB board_id : 0x%02X\n"
- "\tOEMB iafw version : %03d.%03d\n"
- "\tOEMB val_hooks version : %03d.%03d\n"
- "\tOEMB ia suppfw version : %03d.%03d\n"
- "\tOEMB scu runtime version : %03d.%03d\n"
- "\tOEMB ifwi version : %03d.%03d\n",
+ pr_info("\tOEMB signature : %s\n"
+ "\tOEMB length : %d\n"
+ "\tOEMB revision : %d\n"
+ "\tOEMB checksum : 0x%X\n"
+ "\tOEMB oem_id : %s\n"
+ "\tOEMB oem_table_id : %s\n"
+ "\tOEMB board_id : 0x%02X\n"
+ "\tOEMB iafw version : %03d.%03d\n"
+ "\tOEMB val_hooks version : %03d.%03d\n"
+ "\tOEMB ia suppfw version : %03d.%03d\n"
+ "\tOEMB scu runtime version : %03d.%03d\n"
+ "\tOEMB ifwi version : %03d.%03d\n"
+ "\tOEMB spid customer id : %04x\n"
+ "\tOEMB spid vendor id : %04x\n"
+ "\tOEMB spid manufacturer id : %04x\n"
+ "\tOEMB spid platform family id : %04x\n"
+ "\tOEMB spid product line id : %04x\n"
+ "\tOEMB spid hardware id : %04x\n"
+ "\tOEMB spid fru[4..0] : %02x %02x %02x %02x %02x\n"
+ "\tOEMB spid fru[9..5] : %02x %02x %02x %02x %02x\n",
sig,
oemb->header.len,
oemb->header.rev,
oemb->scu_runtime_major_version,
oemb->scu_runtime_minor_version,
oemb->ifwi_major_version,
- oemb->ifwi_minor_version);
+ oemb->ifwi_minor_version,
+ spid.customer_id,
+ spid.vendor_id,
+ spid.manufacturer_id,
+ spid.platform_family_id,
+ spid.product_line_id,
+ spid.hardware_id,
+ spid.fru[4], spid.fru[3], spid.fru[2], spid.fru[1],
+ spid.fru[0], spid.fru[9], spid.fru[8], spid.fru[7],
+ spid.fru[6], spid.fru[5]);
return 0;
}
+static ssize_t customer_id_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%04x\n", spid.customer_id);
+}
+spid_attr(customer_id);
+
+static ssize_t vendor_id_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%04x\n", spid.vendor_id);
+}
+spid_attr(vendor_id);
+
+static ssize_t manufacturer_id_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%04x\n", spid.manufacturer_id);
+}
+spid_attr(manufacturer_id);
+
+static ssize_t platform_family_id_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%04x\n", spid.platform_family_id);
+}
+spid_attr(platform_family_id);
+
+static ssize_t product_line_id_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%04x\n", spid.product_line_id);
+}
+spid_attr(product_line_id);
+
+static ssize_t hardware_id_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%04x\n", spid.hardware_id);
+}
+spid_attr(hardware_id);
+
+static ssize_t fru_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%02x\n%02x\n%02x\n%02x\n%02x\n"
+ "%02x\n%02x\n%02x\n%02x\n%02x\n",
+ spid.fru[0], spid.fru[1], spid.fru[2], spid.fru[3],
+ spid.fru[4], spid.fru[5], spid.fru[6], spid.fru[7],
+ spid.fru[8], spid.fru[9]);
+}
+spid_attr(fru);
+
+static struct attribute *spid_attrs[] = {
+ &customer_id_attr.attr,
+ &vendor_id_attr.attr,
+ &manufacturer_id_attr.attr,
+ &platform_family_id_attr.attr,
+ &product_line_id_attr.attr,
+ &hardware_id_attr.attr,
+ &fru_attr.attr,
+ NULL,
+};
+
+static struct attribute_group spid_attr_group = {
+ .attrs = spid_attrs,
+};
+
static struct kobject *board_properties;
static int __init intel_mid_board_properties(void)
{
intel_mid_board_properties();
+ /* create sysfs entries for soft platform id */
+ spid_kobj = kobject_create_and_add("spid", NULL);
+ if (!spid_kobj)
+ pr_err("SPID: ENOMEM for spid_kobj\n");
+ if (sysfs_create_group(spid_kobj, &spid_attr_group))
+ pr_err("SPID: failed to create /sys/spid\n");
+
/* Get MFD Validation SFI OEMB Layout */
sfi_table_parse(SFI_SIG_OEMB, NULL, NULL, sfi_parse_oemb);
sfi_table_parse(SFI_SIG_OEM0, NULL, NULL, sfi_parse_oem0);
#define SFI_GET_NUM_ENTRIES(ptable, entry_type) \
((ptable->header.len - sizeof(struct sfi_table_header)) / \
(sizeof(entry_type)))
+
+#define SPID_FRU_SIZE 10
/*
* Table structures must be byte-packed to match the SFI specification,
* as they are provided by the BIOS.
u64 pentry[1];
} __packed;
+struct sfi_soft_platform_id {
+ u16 customer_id; /*Defines the final customer for the product */
+ u16 vendor_id; /* Defines who owns the final product delivery */
+ u16 manufacturer_id; /* Defines who build the hardware. This can be
+ * different for the same product */
+ u16 platform_family_id; /* Defined by vendor and defines the family of
+ * the product with the same root components */
+ u16 product_line_id; /* Defined by vendor and defines the name of the
+ * product. This can be used to differentiate the
+ * feature set for the same product family (low
+ * cost vs full feature). */
+ u16 hardware_id; /* Defined by vendor and defines the physical hardware
+ * component set present on the PCB/FAB */
+ u8 fru[SPID_FRU_SIZE]; /* Field Replaceabl Unit */
+} __packed;
+
/* OEMB table */
struct sfi_table_oemb {
struct sfi_table_header header;
u8 scu_runtime_minor_version;
u8 ifwi_major_version;
u8 ifwi_minor_version;
+ struct sfi_soft_platform_id spid;
} __packed;
/* Comply with UEFI spec 2.1 */