mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
muc_uart: add firmware upload
Add function to upload the firmware to the muc on a packetbus request to do so. Change-Id: I53d7444735ae95a945e6194b2e81eb3cd100f18e Signed-off-by: Ryan Lattrel <ryanl@motorola.com> Reviewed-on: https://gerrit.mot.com/1256019 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Ling Jin <lingjin@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
8ff2762f44
commit
86b35199c3
2 changed files with 126 additions and 1 deletions
|
|
@ -21,6 +21,17 @@ struct mmi_uart_hdr_t {
|
|||
} __packed;
|
||||
/* Followed by CRC16 (Poly8005) */
|
||||
|
||||
struct mmi_uart_fw_t {
|
||||
uint16_t port_id;
|
||||
uint16_t sn;
|
||||
uint8_t payload[];
|
||||
} __packed;
|
||||
|
||||
struct mmi_uart_pb_hdr_t {
|
||||
uint16_t port_id;
|
||||
uint16_t cmd;
|
||||
} __packed;
|
||||
|
||||
#define MSG_MAGIC 0xA1A1
|
||||
#define MSG_META_DATA_SIZE (sizeof(struct mmi_uart_hdr_t) + sizeof(uint16_t))
|
||||
|
||||
|
|
@ -42,6 +53,14 @@ struct mmi_uart_hdr_t {
|
|||
#define MOD_ATTACH_GPIO 36
|
||||
#define FORCE_USB_BOOT_GPIO 136
|
||||
|
||||
/* Packetbus update command */
|
||||
#define PACKETBUS_PORT_MUC_FW 0x0007
|
||||
#define BOLT_MSG_GET_MUC_FW 0x0000
|
||||
|
||||
/* TODO put in dev tree? */
|
||||
#define MUC_FIRMWARE_NAME "muc_firmware.zip"
|
||||
#define MUC_FW_PAYLOAD_SIZE 1022
|
||||
|
||||
enum { NORMAL = 0, BP_TOOLS, FACTORY, QCOM, };
|
||||
struct boot_mode_t {
|
||||
uint8_t boot_mode; /* androidboot.mode */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/ipc_logging.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <soc/qcom/mmi_boot_info.h>
|
||||
#include "muc_uart.h"
|
||||
#include "mmi_uart.h"
|
||||
|
|
@ -887,6 +888,108 @@ static int muc_uart_pb_put_q(struct mod_muc_data_t *mm_data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int muc_uart_send_firmware(struct mod_muc_data_t *mm_data)
|
||||
{
|
||||
struct mmi_uart_fw_t *fw_pkt;
|
||||
const struct firmware *fw = NULL;
|
||||
int fw_data_remaining;
|
||||
int fw_data_offset = 0;
|
||||
uint16_t fw_pkt_sn = 1;
|
||||
uint16_t fw_pkt_len;
|
||||
uint16_t fw_payload_len;
|
||||
|
||||
MUC_LOG("Updating muc firmware\n");
|
||||
|
||||
if (request_firmware(&fw, MUC_FIRMWARE_NAME, &mm_data->pdev->dev)) {
|
||||
MUC_ERR("Unable to locate firmware %s!\n", MUC_FIRMWARE_NAME);
|
||||
goto err;
|
||||
}
|
||||
|
||||
MUC_LOG("Firmware size is %zd bytes\n", fw->size);
|
||||
MUC_LOG("Queuing %zd messages for upload\n",
|
||||
(fw->size % MUC_FW_PAYLOAD_SIZE) > 0 ?
|
||||
(fw->size / MUC_FW_PAYLOAD_SIZE) + 2 :
|
||||
(fw->size / MUC_FW_PAYLOAD_SIZE) + 1);
|
||||
|
||||
fw_pkt = kmalloc(sizeof(struct mmi_uart_fw_t) +
|
||||
MUC_FW_PAYLOAD_SIZE, GFP_KERNEL);
|
||||
if (!fw_pkt) {
|
||||
MUC_ERR("Unable allocate firmware packet\n");
|
||||
goto err_mem;
|
||||
}
|
||||
|
||||
fw_pkt->port_id = PACKETBUS_PORT_MUC_FW;
|
||||
fw_data_remaining = fw->size;
|
||||
|
||||
while (fw_data_remaining > 0) {
|
||||
if (fw_data_remaining >= MUC_FW_PAYLOAD_SIZE)
|
||||
fw_payload_len = MUC_FW_PAYLOAD_SIZE;
|
||||
else
|
||||
fw_payload_len = fw_data_remaining;
|
||||
|
||||
memcpy(fw_pkt->payload,
|
||||
fw->data + fw_data_offset,
|
||||
fw_payload_len);
|
||||
|
||||
fw_pkt_len = sizeof(struct mmi_uart_fw_t) + fw_payload_len;
|
||||
fw_pkt->sn = fw_pkt_sn++;
|
||||
|
||||
if (muc_uart_queue_send(mm_data,
|
||||
PACKETBUS_PROT_MSG,
|
||||
(uint8_t *)fw_pkt,
|
||||
fw_pkt_len) != fw_pkt_len)
|
||||
goto err_pkt;
|
||||
|
||||
fw_data_offset += fw_payload_len;
|
||||
fw_data_remaining -= fw_payload_len;
|
||||
}
|
||||
|
||||
/* Last packet empty payload to indicate EOF */
|
||||
fw_pkt_len = sizeof(struct mmi_uart_fw_t);
|
||||
fw_pkt->sn = fw_pkt_sn;
|
||||
|
||||
if (muc_uart_queue_send(mm_data,
|
||||
PACKETBUS_PROT_MSG,
|
||||
(uint8_t *)fw_pkt,
|
||||
fw_pkt_len) != fw_pkt_len)
|
||||
goto err_pkt;
|
||||
|
||||
kfree(fw_pkt);
|
||||
release_firmware(fw);
|
||||
|
||||
return 0;
|
||||
err_pkt:
|
||||
kfree(fw_pkt);
|
||||
err_mem:
|
||||
release_firmware(fw);
|
||||
err:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int muc_uart_check_update(struct mod_muc_data_t *mm_data,
|
||||
size_t payload_len,
|
||||
uint8_t *payload)
|
||||
{
|
||||
struct mmi_uart_pb_hdr_t *pb_hdr;
|
||||
|
||||
/* Check if this message was for us instead of userspace */
|
||||
if (payload_len < sizeof(struct mmi_uart_pb_hdr_t))
|
||||
return 1;
|
||||
|
||||
pb_hdr = (struct mmi_uart_pb_hdr_t *)payload;
|
||||
|
||||
if (pb_hdr->port_id != PACKETBUS_PORT_MUC_FW)
|
||||
return 1;
|
||||
|
||||
if (pb_hdr->cmd != BOLT_MSG_GET_MUC_FW)
|
||||
return 1;
|
||||
|
||||
if (muc_uart_send_firmware(mm_data))
|
||||
MUC_ERR("Failed to send firmware to muc\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int muc_uart_pb_write(struct platform_device *pdev,
|
||||
const char __user *buf,
|
||||
size_t count)
|
||||
|
|
@ -951,7 +1054,10 @@ static void muc_uart_handle_message(struct mod_muc_data_t *mm_data,
|
|||
break;
|
||||
}
|
||||
case PACKETBUS_PROT_MSG: {
|
||||
if (!muc_uart_pb_put_q(mm_data,
|
||||
if (!muc_uart_check_update(mm_data,
|
||||
payload_len,
|
||||
payload) ||
|
||||
!muc_uart_pb_put_q(mm_data,
|
||||
payload_len,
|
||||
payload)) {
|
||||
muc_uart_send(mm_data,
|
||||
|
|
|
|||
Loading…
Reference in a new issue