mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-03 09:41:54 +09:00
greybus: firmware and svc: detect the difference between ES2 and ES3 chips
The Greybus SVC code needs to read and clear the module boot status upon hotplug; this requires reading two different attributes depending on whether we're running on ES2 or ES3. On Marti Bolivar's (mbolivar@leaflabs.com) advice, we detect ES2 using the unique ES2_DDBL1_MFR_ID and ES2_DDBL1_PROD_ID for ES2 hardware, and treat all other chips as ES3 appropriately. This patch detects the difference and adds the appropriate definitions for ES3 hardware. Signed-off-by: Eli Sennesh <esennesh@leaflabs.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
0e9403a0fb
commit
3563ff88e6
@@ -11,9 +11,6 @@
|
||||
|
||||
#include "greybus.h"
|
||||
|
||||
#define ES2_DDBL1_MFR_ID 0x00000126
|
||||
#define ES2_DDBL1_PROD_ID 0x00001000
|
||||
|
||||
struct gb_firmware {
|
||||
struct gb_connection *connection;
|
||||
const struct firmware *fw;
|
||||
|
||||
@@ -160,6 +160,10 @@ struct gb_control_disconnected_request {
|
||||
#define GB_FIRMWARE_TYPE_AP_READY 0x05 /* Request with no-payload */
|
||||
#define GB_FIRMWARE_TYPE_GET_VID_PID 0x06 /* Request with no-payload */
|
||||
|
||||
/* FIXME: remove all ES2-specific identifiers from the kernel */
|
||||
#define ES2_DDBL1_MFR_ID 0x00000126
|
||||
#define ES2_DDBL1_PROD_ID 0x00001000
|
||||
|
||||
/* Greybus firmware boot stages */
|
||||
#define GB_FIRMWARE_BOOT_STAGE_ONE 0x01 /* Reserved for the boot ROM */
|
||||
#define GB_FIRMWARE_BOOT_STAGE_TWO 0x02 /* Firmware package to be loaded by the boot ROM */
|
||||
@@ -823,14 +827,16 @@ struct gb_svc_link_config_request {
|
||||
|
||||
/* Attributes for peer get/set operations */
|
||||
#define DME_ATTR_SELECTOR_INDEX 0
|
||||
/* FIXME: remove ES2 support and DME_ATTR_T_TST_SRC_INCREMENT */
|
||||
#define DME_ATTR_T_TST_SRC_INCREMENT 0x4083
|
||||
#define DME_ATTR_ES3_INIT_STATUS 0x6101
|
||||
|
||||
/* Return value from TST_SRC_INCREMENT */
|
||||
#define DME_TSI_SPI_BOOT_STARTED 0x02
|
||||
#define DME_TSI_TRUSTED_SPI_BOOT_FINISHED 0x03
|
||||
#define DME_TSI_UNTRUSTED_SPI_BOOT_FINISHED 0x04
|
||||
#define DME_TSI_UNIPRO_BOOT_STARTED 0x06
|
||||
#define DME_TSI_FALLBACK_UNIPRO_BOOT_STARTED 0x09
|
||||
/* Return value from init-status attributes listed above */
|
||||
#define DME_DIS_SPI_BOOT_STARTED 0x02
|
||||
#define DME_DIS_TRUSTED_SPI_BOOT_FINISHED 0x03
|
||||
#define DME_DIS_UNTRUSTED_SPI_BOOT_FINISHED 0x04
|
||||
#define DME_DIS_UNIPRO_BOOT_STARTED 0x06
|
||||
#define DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED 0x09
|
||||
|
||||
struct gb_svc_route_create_request {
|
||||
__u8 intf1_id;
|
||||
|
||||
@@ -139,8 +139,8 @@ EXPORT_SYMBOL_GPL(gb_svc_dme_peer_set);
|
||||
|
||||
/*
|
||||
* T_TstSrcIncrement is written by the module on ES2 as a stand-in for boot
|
||||
* status attribute. AP needs to read and clear it, after reading a non-zero
|
||||
* value from it.
|
||||
* status attribute ES3_INIT_STATUS. AP needs to read and clear it, after
|
||||
* reading a non-zero value from it.
|
||||
*
|
||||
* FIXME: This is module-hardware dependent and needs to be extended for every
|
||||
* type of module we want to support.
|
||||
@@ -150,10 +150,22 @@ static int gb_svc_read_and_clear_module_boot_status(struct gb_interface *intf)
|
||||
struct gb_host_device *hd = intf->hd;
|
||||
int ret;
|
||||
u32 value;
|
||||
u16 attr;
|
||||
u8 init_status;
|
||||
|
||||
/* Read and clear boot status in T_TstSrcIncrement */
|
||||
ret = gb_svc_dme_peer_get(hd->svc, intf->interface_id,
|
||||
DME_ATTR_T_TST_SRC_INCREMENT,
|
||||
/*
|
||||
* Check if the module is ES2 or ES3, and choose attr number
|
||||
* appropriately.
|
||||
* FIXME: Remove ES2 support from the kernel entirely.
|
||||
*/
|
||||
if (intf->ddbl1_manufacturer_id == ES2_DDBL1_MFR_ID &&
|
||||
intf->ddbl1_product_id == ES2_DDBL1_PROD_ID)
|
||||
attr = DME_ATTR_T_TST_SRC_INCREMENT;
|
||||
else
|
||||
attr = DME_ATTR_ES3_INIT_STATUS;
|
||||
|
||||
/* Read and clear boot status in ES3_INIT_STATUS */
|
||||
ret = gb_svc_dme_peer_get(hd->svc, intf->interface_id, attr,
|
||||
DME_ATTR_SELECTOR_INDEX, &value);
|
||||
|
||||
if (ret)
|
||||
@@ -169,19 +181,22 @@ static int gb_svc_read_and_clear_module_boot_status(struct gb_interface *intf)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the module needs to boot from unipro.
|
||||
* Check if the module needs to boot from UniPro.
|
||||
* For ES2: We need to check lowest 8 bits of 'value'.
|
||||
* For ES3: We need to check highest 8 bits out of 32 of 'value'.
|
||||
*
|
||||
* FIXME: Add code to find if we are on ES2 or ES3 to have separate
|
||||
* checks.
|
||||
* FIXME: Remove ES2 support from the kernel entirely.
|
||||
*/
|
||||
if (value == DME_TSI_UNIPRO_BOOT_STARTED ||
|
||||
value == DME_TSI_FALLBACK_UNIPRO_BOOT_STARTED)
|
||||
if (intf->ddbl1_manufacturer_id == ES2_DDBL1_MFR_ID &&
|
||||
intf->ddbl1_product_id == ES2_DDBL1_PROD_ID)
|
||||
init_status = value;
|
||||
else
|
||||
init_status = value >> 24;
|
||||
|
||||
if (init_status == DME_DIS_UNIPRO_BOOT_STARTED ||
|
||||
init_status == DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED)
|
||||
intf->boot_over_unipro = true;
|
||||
|
||||
return gb_svc_dme_peer_set(hd->svc, intf->interface_id,
|
||||
DME_ATTR_T_TST_SRC_INCREMENT,
|
||||
return gb_svc_dme_peer_set(hd->svc, intf->interface_id, attr,
|
||||
DME_ATTR_SELECTOR_INDEX, 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user