greybus: firmware: Fetch es2 VID/PID to distinguish module vendors
The es2 chip doesn't have VID/PID programmed into the hardware and we need to hack that up to distinguish different modules and their firmware packages. This fetches VID/PID (over firmware protocol) for es2 chip only, when VID/PID already sent during hotplug are 0. Since only the bootrom contains a firmware protocol cport, this only affects bootrom's working and not nuttx. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Родитель
32945d6ecc
Коммит
f1e941a6e4
|
@ -11,9 +11,14 @@
|
|||
|
||||
#include "greybus.h"
|
||||
|
||||
#define ES2_UNIPRO_MFG_ID 0x00000126
|
||||
#define ES2_UNIPRO_PROD_ID 0x00001000
|
||||
|
||||
struct gb_firmware {
|
||||
struct gb_connection *connection;
|
||||
const struct firmware *fw;
|
||||
u32 vendor_id;
|
||||
u32 product_id;
|
||||
};
|
||||
|
||||
static void free_firmware(struct gb_firmware *firmware)
|
||||
|
@ -22,6 +27,45 @@ static void free_firmware(struct gb_firmware *firmware)
|
|||
firmware->fw = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The es2 chip doesn't have VID/PID programmed into the hardware and we need to
|
||||
* hack that up to distinguish different modules and their firmware blobs.
|
||||
*
|
||||
* This fetches VID/PID (over firmware protocol) for es2 chip only, when VID/PID
|
||||
* already sent during hotplug are 0.
|
||||
*
|
||||
* Otherwise, we keep firmware->vendor_id/product_id same as what's passed
|
||||
* during hotplug.
|
||||
*/
|
||||
static void firmware_es2_fixup_vid_pid(struct gb_firmware *firmware)
|
||||
{
|
||||
struct gb_firmware_get_vid_pid_response response;
|
||||
struct gb_connection *connection = firmware->connection;
|
||||
struct gb_interface *intf = connection->bundle->intf;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Use VID/PID specified at hotplug if:
|
||||
* - Bridge ASIC chip isn't ES2
|
||||
* - Received non-zero Vendor/Product ids
|
||||
*/
|
||||
if (intf->unipro_mfg_id != ES2_UNIPRO_MFG_ID ||
|
||||
intf->unipro_prod_id != ES2_UNIPRO_PROD_ID ||
|
||||
intf->vendor_id != 0 || intf->product_id != 0)
|
||||
return;
|
||||
|
||||
ret = gb_operation_sync(connection, GB_FIRMWARE_TYPE_GET_VID_PID,
|
||||
NULL, 0, &response, sizeof(response));
|
||||
if (ret) {
|
||||
dev_err(&connection->bundle->dev,
|
||||
"Firmware get vid/pid operation failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
firmware->vendor_id = le32_to_cpu(response.vendor_id);
|
||||
firmware->product_id = le32_to_cpu(response.product_id);
|
||||
}
|
||||
|
||||
/* This returns path of the firmware blob on the disk */
|
||||
static int download_firmware(struct gb_firmware *firmware, u8 stage)
|
||||
{
|
||||
|
@ -41,7 +85,7 @@ static int download_firmware(struct gb_firmware *firmware, u8 stage)
|
|||
snprintf(firmware_name, sizeof(firmware_name),
|
||||
"ara:%08x:%08x:%08x:%08x:%02x.tftf",
|
||||
intf->unipro_mfg_id, intf->unipro_prod_id,
|
||||
intf->vendor_id, intf->product_id, stage);
|
||||
firmware->vendor_id, firmware->product_id, stage);
|
||||
|
||||
return request_firmware(&firmware->fw, firmware_name,
|
||||
&connection->bundle->dev);
|
||||
|
@ -183,6 +227,11 @@ static int gb_firmware_connection_init(struct gb_connection *connection)
|
|||
firmware->connection = connection;
|
||||
connection->private = firmware;
|
||||
|
||||
firmware->vendor_id = connection->intf->vendor_id;
|
||||
firmware->product_id = connection->intf->product_id;
|
||||
|
||||
firmware_es2_fixup_vid_pid(firmware);
|
||||
|
||||
/*
|
||||
* Module's Bootrom needs a way to know (currently), when to start
|
||||
* sending requests to the AP. The version request is sent before this
|
||||
|
|
|
@ -158,6 +158,7 @@ struct gb_control_disconnected_request {
|
|||
#define GB_FIRMWARE_TYPE_GET_FIRMWARE 0x03
|
||||
#define GB_FIRMWARE_TYPE_READY_TO_BOOT 0x04
|
||||
#define GB_FIRMWARE_TYPE_AP_READY 0x05 /* Request with no-payload */
|
||||
#define GB_FIRMWARE_TYPE_GET_VID_PID 0x06 /* Request with no-payload */
|
||||
|
||||
/* Greybus firmware boot stages */
|
||||
#define GB_FIRMWARE_BOOT_STAGE_ONE 0x01 /* Reserved for the boot ROM */
|
||||
|
@ -197,6 +198,12 @@ struct gb_firmware_ready_to_boot_request {
|
|||
} __packed;
|
||||
/* Firmware protocol Ready to boot response has no payload */
|
||||
|
||||
/* Firmware protocol get VID/PID request has no payload */
|
||||
struct gb_firmware_get_vid_pid_response {
|
||||
__le32 vendor_id;
|
||||
__le32 product_id;
|
||||
} __packed;
|
||||
|
||||
|
||||
/* Power Supply */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче