mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-usb
- Mostly DFU fixes and r8152 fixes
This commit is contained in:
commit
9bfb567e5f
39 changed files with 1867 additions and 101 deletions
|
@ -187,6 +187,12 @@ int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SDPV_BCD_DEVICE 0x500
|
||||
int g_dnl_get_board_bcd_device_number(int gcnum)
|
||||
{
|
||||
return SDPV_BCD_DEVICE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPL_MMC_SUPPORT)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <fastboot.h>
|
||||
#include <init.h>
|
||||
#include <net.h>
|
||||
#include <asm/arch/boot.h>
|
||||
|
@ -153,8 +154,11 @@ int board_late_init(void)
|
|||
#if CONFIG_IS_ENABLED(FASTBOOT)
|
||||
static unsigned int reboot_reason = REBOOT_REASON_NORMAL;
|
||||
|
||||
int fastboot_set_reboot_flag()
|
||||
int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
|
||||
{
|
||||
if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER)
|
||||
return -ENOTSUPP;
|
||||
|
||||
reboot_reason = REBOOT_REASON_BOOTLOADER;
|
||||
|
||||
printf("Using reboot reason: 0x%x\n", reboot_reason);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <clk.h>
|
||||
#include <cpu_func.h>
|
||||
#include <dm.h>
|
||||
#include <fastboot.h>
|
||||
#include <init.h>
|
||||
#include <log.h>
|
||||
#include <ram.h>
|
||||
|
@ -152,8 +153,11 @@ int board_usb_init(int index, enum usb_init_type init)
|
|||
#endif /* CONFIG_USB_GADGET */
|
||||
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT)
|
||||
int fastboot_set_reboot_flag(void)
|
||||
int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
|
||||
{
|
||||
if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER)
|
||||
return -ENOTSUPP;
|
||||
|
||||
printf("Setting reboot to fastboot flag ...\n");
|
||||
/* Set boot mode to fastboot */
|
||||
writel(BOOT_FASTBOOT, CONFIG_ROCKCHIP_BOOT_MODE_REG);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <env.h>
|
||||
#include <fastboot.h>
|
||||
#include <init.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/usb/musb.h>
|
||||
|
@ -163,8 +164,11 @@ void get_board_serial(struct tag_serialnr *serialnr)
|
|||
omap_die_id_get_board_serial(serialnr);
|
||||
}
|
||||
|
||||
int fastboot_set_reboot_flag(void)
|
||||
int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
|
||||
{
|
||||
if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER)
|
||||
return -ENOTSUPP;
|
||||
|
||||
return omap_reboot_mode_store("b");
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <env.h>
|
||||
#include <fastboot.h>
|
||||
#include <init.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/usb/musb.h>
|
||||
|
@ -175,8 +176,11 @@ void reset_misc(void)
|
|||
omap_reboot_mode_store(reboot_mode);
|
||||
}
|
||||
|
||||
int fastboot_set_reboot_flag(void)
|
||||
int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
|
||||
{
|
||||
if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER)
|
||||
return -ENOTSUPP;
|
||||
|
||||
return omap_reboot_mode_store("b");
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <env.h>
|
||||
#include <fastboot.h>
|
||||
#include <fdt_support.h>
|
||||
#include <image.h>
|
||||
#include <init.h>
|
||||
|
@ -1172,8 +1173,11 @@ int board_fit_config_name_match(const char *name)
|
|||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT) && !CONFIG_IS_ENABLED(ENV_IS_NOWHERE)
|
||||
int fastboot_set_reboot_flag(void)
|
||||
int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
|
||||
{
|
||||
if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER)
|
||||
return -ENOTSUPP;
|
||||
|
||||
printf("Setting reboot to fastboot flag ...\n");
|
||||
env_set("dofastboot", "1");
|
||||
env_save();
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <common.h>
|
||||
#include <env.h>
|
||||
#include <fdt_support.h>
|
||||
#include <fastboot.h>
|
||||
#include <image.h>
|
||||
#include <init.h>
|
||||
#include <spl.h>
|
||||
|
@ -1050,8 +1051,11 @@ int board_fit_config_name_match(const char *name)
|
|||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT) && !CONFIG_IS_ENABLED(ENV_IS_NOWHERE)
|
||||
int fastboot_set_reboot_flag(void)
|
||||
int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
|
||||
{
|
||||
if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER)
|
||||
return -ENOTSUPP;
|
||||
|
||||
printf("Setting reboot to fastboot flag ...\n");
|
||||
env_set("dofastboot", "1");
|
||||
env_save();
|
||||
|
|
|
@ -170,7 +170,7 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag,
|
|||
goto cleanup_ums_init;
|
||||
}
|
||||
|
||||
rc = fsg_init(ums, ums_count);
|
||||
rc = fsg_init(ums, ums_count, controller_index);
|
||||
if (rc) {
|
||||
pr_err("fsg_init failed\n");
|
||||
rc = CMD_RET_FAILURE;
|
||||
|
|
|
@ -19,6 +19,8 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image,
|
|||
|
||||
usb_gadget_initialize(controller_index);
|
||||
|
||||
board_usb_init(0, USB_INIT_DEVICE);
|
||||
|
||||
g_dnl_clear_detach();
|
||||
ret = g_dnl_register("usb_dnl_sdp");
|
||||
if (ret) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <net.h>
|
||||
#include <net/tftp.h>
|
||||
#include <malloc.h>
|
||||
#include <mapmem.h>
|
||||
#include <dfu.h>
|
||||
#include <errno.h>
|
||||
#include <mtd/cfi_flash.h>
|
||||
|
@ -280,7 +281,7 @@ int update_tftp(ulong addr, char *interface, char *devstring)
|
|||
}
|
||||
|
||||
got_update_file:
|
||||
fit = (void *)addr;
|
||||
fit = map_sysmem(addr, 0);
|
||||
|
||||
if (!fit_check_format((void *)fit)) {
|
||||
printf("Bad FIT format of the update file, aborting "
|
||||
|
@ -309,8 +310,7 @@ got_update_file:
|
|||
printf("\n");
|
||||
if (update_fit_getparams(fit, noffset, &update_addr,
|
||||
&update_fladdr, &update_size)) {
|
||||
printf("Error: can't get update parameteres, "
|
||||
"aborting\n");
|
||||
printf("Error: can't get update parameters, aborting\n");
|
||||
ret = 1;
|
||||
goto next_node;
|
||||
}
|
||||
|
|
|
@ -10,25 +10,34 @@ CONFIG_FIT_SIGNATURE=y
|
|||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_FIT_BEST_MATCH=y
|
||||
CONFIG_LEGACY_IMAGE_FORMAT=y
|
||||
CONFIG_USE_PREBOOT=y
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_PCI_INIT_R=y
|
||||
CONFIG_CMD_BOOTEFI_SELFTEST=y
|
||||
CONFIG_CMD_NVEDIT_EFI=y
|
||||
CONFIG_CMD_DFU=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_PCI=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_OF_BOARD=y
|
||||
CONFIG_ENV_IS_IN_FLASH=y
|
||||
CONFIG_ENV_ADDR=0x4000000
|
||||
CONFIG_SCSI_AHCI=y
|
||||
CONFIG_AHCI_PCI=y
|
||||
CONFIG_BLK=y
|
||||
CONFIG_DFU_TFTP=y
|
||||
CONFIG_DFU_RAM=y
|
||||
CONFIG_DFU_MTD=y
|
||||
# CONFIG_MMC is not set
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_NOR_FLASH=y
|
||||
CONFIG_FLASH_CFI_DRIVER=y
|
||||
CONFIG_CFI_FLASH=y
|
||||
CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
|
||||
CONFIG_FLASH_CFI_MTD=y
|
||||
CONFIG_SYS_FLASH_CFI=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_E1000=y
|
||||
|
|
|
@ -13,25 +13,34 @@ CONFIG_FIT_SIGNATURE=y
|
|||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_FIT_BEST_MATCH=y
|
||||
CONFIG_LEGACY_IMAGE_FORMAT=y
|
||||
CONFIG_USE_PREBOOT=y
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_PCI_INIT_R=y
|
||||
CONFIG_CMD_BOOTEFI_SELFTEST=y
|
||||
CONFIG_CMD_NVEDIT_EFI=y
|
||||
CONFIG_CMD_DFU=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_PCI=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_OF_BOARD=y
|
||||
CONFIG_ENV_IS_IN_FLASH=y
|
||||
CONFIG_ENV_ADDR=0x4000000
|
||||
CONFIG_SCSI_AHCI=y
|
||||
CONFIG_AHCI_PCI=y
|
||||
CONFIG_BLK=y
|
||||
CONFIG_DFU_TFTP=y
|
||||
CONFIG_DFU_RAM=y
|
||||
CONFIG_DFU_MTD=y
|
||||
# CONFIG_MMC is not set
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_NOR_FLASH=y
|
||||
CONFIG_FLASH_CFI_DRIVER=y
|
||||
CONFIG_CFI_FLASH=y
|
||||
CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
|
||||
CONFIG_FLASH_CFI_MTD=y
|
||||
CONFIG_SYS_FLASH_CFI=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_E1000=y
|
||||
|
|
|
@ -85,6 +85,25 @@ for example::
|
|||
|
||||
fastboot_partition_alias_boot=LNX
|
||||
|
||||
Raw partition descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In cases where no partition table is present, a raw partition descriptor can be
|
||||
defined, specifying the offset, size, and optionally the MMC hardware partition
|
||||
number for a given partition name.
|
||||
|
||||
This is useful when using fastboot to flash files (e.g. SPL or U-Boot) to a
|
||||
specific offset in the eMMC boot partition, without having to update the entire
|
||||
boot partition.
|
||||
|
||||
To define a raw partition descriptor, add an environment variable similar to::
|
||||
|
||||
fastboot_raw_partition_<raw partition name>=<offset> <size> [mmcpart <num>]
|
||||
|
||||
for example::
|
||||
|
||||
fastboot_raw_partition_boot=0x100 0x1f00 mmcpart 1
|
||||
|
||||
Variable overrides
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ config DFU_SF_PART
|
|||
config DFU_MTD
|
||||
bool "MTD back end for DFU"
|
||||
depends on DM_MTD
|
||||
depends on CMD_MTDPARTS
|
||||
help
|
||||
This option enables using DFU to read and write to on any MTD device.
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <mapmem.h>
|
||||
#include <errno.h>
|
||||
#include <dfu.h>
|
||||
|
||||
|
@ -27,9 +28,9 @@ static int dfu_transfer_medium_ram(enum dfu_op op, struct dfu_entity *dfu,
|
|||
}
|
||||
|
||||
if (op == DFU_OP_WRITE)
|
||||
memcpy(dfu->data.ram.start + offset, buf, *len);
|
||||
memcpy(map_sysmem(dfu->data.ram.start + offset, 0), buf, *len);
|
||||
else
|
||||
memcpy(buf, dfu->data.ram.start + offset, *len);
|
||||
memcpy(buf, map_sysmem(dfu->data.ram.start + offset, 0), *len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -73,7 +74,7 @@ int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr, char *s)
|
|||
}
|
||||
|
||||
dfu->layout = DFU_RAM_ADDR;
|
||||
dfu->data.ram.start = (void *)simple_strtoul(argv[1], NULL, 16);
|
||||
dfu->data.ram.start = simple_strtoul(argv[1], NULL, 16);
|
||||
dfu->data.ram.size = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
dfu->write_medium = dfu_write_medium_ram;
|
||||
|
|
|
@ -165,6 +165,18 @@ config FASTBOOT_CMD_OEM_FORMAT
|
|||
relies on the env variable partitions to contain the list of
|
||||
partitions as required by the gpt command.
|
||||
|
||||
config FASTBOOT_USE_BCB_SET_REBOOT_FLAG
|
||||
bool "Use BCB by fastboot to set boot reason"
|
||||
depends on CMD_BCB && !ARCH_MESON && !ARCH_ROCKCHIP && !TARGET_KC1 && \
|
||||
!TARGET_SNIPER && !TARGET_AM57XX_EVM && !TARGET_DRA7XX_EVM
|
||||
default y
|
||||
help
|
||||
Fastboot could implement setting of reboot reason in a generic fashion
|
||||
via BCB commands. BCB commands are able to write reboot reason into
|
||||
command field of boot control block. In general case it is sufficient
|
||||
implementation if your platform supports BCB commands and doesn't
|
||||
require any specific reboot reason handling.
|
||||
|
||||
endif # FASTBOOT
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -5,3 +5,4 @@ obj-y += fb_getvar.o
|
|||
obj-y += fb_command.o
|
||||
obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_mmc.o
|
||||
obj-$(CONFIG_FASTBOOT_FLASH_NAND) += fb_nand.o
|
||||
obj-$(CONFIG_FASTBOOT_USE_BCB_SET_REBOOT_FLAG) += fb_bcb_impl.o
|
||||
|
|
43
drivers/fastboot/fb_bcb_impl.c
Normal file
43
drivers/fastboot/fb_bcb_impl.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2020 GlobalLogic.
|
||||
* Roman Kovalivskyi <roman.kovalivskyi@globallogic.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fastboot.h>
|
||||
|
||||
/**
|
||||
* fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader
|
||||
*
|
||||
* Set flag which indicates that we should reboot into the bootloader
|
||||
* following the reboot that fastboot executes after this function.
|
||||
*
|
||||
* This function should be overridden in your board file with one
|
||||
* which sets whatever flag your board specific Android bootloader flow
|
||||
* requires in order to re-enter the bootloader.
|
||||
*/
|
||||
int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
|
||||
{
|
||||
char cmd[64];
|
||||
|
||||
if (reason >= FASTBOOT_REBOOT_REASONS_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "bcb load %d misc",
|
||||
CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
|
||||
if (run_command(cmd, 0))
|
||||
return -ENODEV;
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "bcb set command %s",
|
||||
fastboot_boot_cmds[reason]);
|
||||
|
||||
if (run_command(cmd, 0))
|
||||
return -ENOEXEC;
|
||||
|
||||
if (run_command("bcb store", 0))
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -37,6 +37,8 @@ static void flash(char *, char *);
|
|||
static void erase(char *, char *);
|
||||
#endif
|
||||
static void reboot_bootloader(char *, char *);
|
||||
static void reboot_fastbootd(char *, char *);
|
||||
static void reboot_recovery(char *, char *);
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
|
||||
static void oem_format(char *, char *);
|
||||
#endif
|
||||
|
@ -79,6 +81,14 @@ static const struct {
|
|||
.command = "reboot-bootloader",
|
||||
.dispatch = reboot_bootloader
|
||||
},
|
||||
[FASTBOOT_COMMAND_REBOOT_FASTBOOTD] = {
|
||||
.command = "reboot-fastboot",
|
||||
.dispatch = reboot_fastbootd
|
||||
},
|
||||
[FASTBOOT_COMMAND_REBOOT_RECOVERY] = {
|
||||
.command = "reboot-recovery",
|
||||
.dispatch = reboot_recovery
|
||||
},
|
||||
[FASTBOOT_COMMAND_SET_ACTIVE] = {
|
||||
.command = "set_active",
|
||||
.dispatch = okay
|
||||
|
@ -307,12 +317,40 @@ static void erase(char *cmd_parameter, char *response)
|
|||
*/
|
||||
static void reboot_bootloader(char *cmd_parameter, char *response)
|
||||
{
|
||||
if (fastboot_set_reboot_flag())
|
||||
if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_BOOTLOADER))
|
||||
fastboot_fail("Cannot set reboot flag", response);
|
||||
else
|
||||
fastboot_okay(NULL, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* reboot_fastbootd() - Sets reboot fastboot flag.
|
||||
*
|
||||
* @cmd_parameter: Pointer to command parameter
|
||||
* @response: Pointer to fastboot response buffer
|
||||
*/
|
||||
static void reboot_fastbootd(char *cmd_parameter, char *response)
|
||||
{
|
||||
if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_FASTBOOTD))
|
||||
fastboot_fail("Cannot set fastboot flag", response);
|
||||
else
|
||||
fastboot_okay(NULL, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* reboot_recovery() - Sets reboot recovery flag.
|
||||
*
|
||||
* @cmd_parameter: Pointer to command parameter
|
||||
* @response: Pointer to fastboot response buffer
|
||||
*/
|
||||
static void reboot_recovery(char *cmd_parameter, char *response)
|
||||
{
|
||||
if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_RECOVERY))
|
||||
fastboot_fail("Cannot set recovery flag", response);
|
||||
else
|
||||
fastboot_okay(NULL, response);
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
|
||||
/**
|
||||
* oem_format() - Execute the OEM format command
|
||||
|
|
|
@ -88,7 +88,7 @@ void fastboot_okay(const char *reason, char *response)
|
|||
* which sets whatever flag your board specific Android bootloader flow
|
||||
* requires in order to re-enter the bootloader.
|
||||
*/
|
||||
int __weak fastboot_set_reboot_flag(void)
|
||||
int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ static const struct {
|
|||
*
|
||||
* @param[in] part_name Info for which partition name to look for
|
||||
* @param[in,out] response Pointer to fastboot response buffer
|
||||
* @param[out] size If not NULL, will contain partition size (in blocks)
|
||||
* @param[out] size If not NULL, will contain partition size
|
||||
* @return Partition number or negative value on error
|
||||
*/
|
||||
static int getvar_get_part_info(const char *part_name, char *response,
|
||||
|
@ -109,7 +109,7 @@ static int getvar_get_part_info(const char *part_name, char *response,
|
|||
r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
|
||||
response);
|
||||
if (r >= 0 && size)
|
||||
*size = part_info.size;
|
||||
*size = part_info.size * part_info.blksz;
|
||||
# elif CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
|
||||
struct part_info *part_info;
|
||||
|
||||
|
|
|
@ -50,6 +50,48 @@ static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int raw_part_get_info_by_name(struct blk_desc *dev_desc,
|
||||
const char *name, struct disk_partition *info, int *mmcpart)
|
||||
{
|
||||
/* strlen("fastboot_raw_partition_") + PART_NAME_LEN + 1 */
|
||||
char env_desc_name[23 + PART_NAME_LEN + 1];
|
||||
char *raw_part_desc;
|
||||
const char *argv[2];
|
||||
const char **parg = argv;
|
||||
|
||||
/* check for raw partition descriptor */
|
||||
strcpy(env_desc_name, "fastboot_raw_partition_");
|
||||
strncat(env_desc_name, name, PART_NAME_LEN);
|
||||
raw_part_desc = strdup(env_get(env_desc_name));
|
||||
if (raw_part_desc == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* parse partition descriptor
|
||||
*
|
||||
* <lba_start> <lba_size> [mmcpart <num>]
|
||||
*/
|
||||
for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) {
|
||||
*parg = strsep(&raw_part_desc, " ");
|
||||
if (*parg == NULL) {
|
||||
pr_err("Invalid number of arguments.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
info->start = simple_strtoul(argv[0], NULL, 0);
|
||||
info->size = simple_strtoul(argv[1], NULL, 0);
|
||||
info->blksz = dev_desc->blksz;
|
||||
strncpy((char *)info->name, name, PART_NAME_LEN);
|
||||
|
||||
if (raw_part_desc) {
|
||||
if (strcmp(strsep(&raw_part_desc, " "), "mmcpart") == 0)
|
||||
*mmcpart = simple_strtoul(raw_part_desc, NULL, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fb_mmc_blk_write() - Write/erase MMC in chunks of FASTBOOT_MAX_BLK_WRITE
|
||||
*
|
||||
|
@ -376,7 +418,8 @@ int fastboot_mmc_get_part_info(const char *part_name,
|
|||
struct blk_desc **dev_desc,
|
||||
struct disk_partition *part_info, char *response)
|
||||
{
|
||||
int r;
|
||||
int r = 0;
|
||||
int mmcpart;
|
||||
|
||||
*dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
if (!*dev_desc) {
|
||||
|
@ -388,10 +431,12 @@ int fastboot_mmc_get_part_info(const char *part_name,
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
r = part_get_info_by_name_or_alias(*dev_desc, part_name, part_info);
|
||||
if (r < 0) {
|
||||
fastboot_fail("partition not found", response);
|
||||
return r;
|
||||
if (raw_part_get_info_by_name(*dev_desc, part_name, part_info, &mmcpart) < 0) {
|
||||
r = part_get_info_by_name_or_alias(*dev_desc, part_name, part_info);
|
||||
if (r < 0) {
|
||||
fastboot_fail("partition not found", response);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -410,6 +455,7 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
|
|||
{
|
||||
struct blk_desc *dev_desc;
|
||||
struct disk_partition info;
|
||||
int mmcpart = 0;
|
||||
|
||||
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
|
||||
|
@ -482,7 +528,13 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
|
||||
if (raw_part_get_info_by_name(dev_desc, cmd, &info, &mmcpart) == 0) {
|
||||
if (blk_dselect_hwpart(dev_desc, mmcpart)) {
|
||||
pr_err("Failed to select hwpart\n");
|
||||
fastboot_fail("Failed to select hwpart", response);
|
||||
return;
|
||||
}
|
||||
} else if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
|
||||
pr_err("cannot find partition: '%s'\n", cmd);
|
||||
fastboot_fail("cannot find partition", response);
|
||||
return;
|
||||
|
@ -524,11 +576,11 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
|
|||
*/
|
||||
void fastboot_mmc_erase(const char *cmd, char *response)
|
||||
{
|
||||
int ret;
|
||||
struct blk_desc *dev_desc;
|
||||
struct disk_partition info;
|
||||
lbaint_t blks, blks_start, blks_size, grp_size;
|
||||
struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
int mmcpart = 0;
|
||||
|
||||
if (mmc == NULL) {
|
||||
pr_err("invalid mmc device\n");
|
||||
|
@ -562,8 +614,13 @@ void fastboot_mmc_erase(const char *cmd, char *response)
|
|||
}
|
||||
#endif
|
||||
|
||||
ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info);
|
||||
if (ret < 0) {
|
||||
if (raw_part_get_info_by_name(dev_desc, cmd, &info, &mmcpart) == 0) {
|
||||
if (blk_dselect_hwpart(dev_desc, mmcpart)) {
|
||||
pr_err("Failed to select hwpart\n");
|
||||
fastboot_fail("Failed to select hwpart", response);
|
||||
return;
|
||||
}
|
||||
} else if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
|
||||
pr_err("cannot find partition: '%s'\n", cmd);
|
||||
fastboot_fail("cannot find partition", response);
|
||||
return;
|
||||
|
|
|
@ -68,6 +68,8 @@ static const struct r8152_version r8152_versions[] = {
|
|||
{ 0x5c20, RTL_VER_05, 1 },
|
||||
{ 0x5c30, RTL_VER_06, 1 },
|
||||
{ 0x4800, RTL_VER_07, 0 },
|
||||
{ 0x6000, RTL_VER_08, 1 },
|
||||
{ 0x6010, RTL_VER_09, 1 },
|
||||
};
|
||||
|
||||
static
|
||||
|
@ -331,6 +333,12 @@ void sram_write(struct r8152 *tp, u16 addr, u16 data)
|
|||
ocp_reg_write(tp, OCP_SRAM_DATA, data);
|
||||
}
|
||||
|
||||
static u16 sram_read(struct r8152 *tp, u16 addr)
|
||||
{
|
||||
ocp_reg_write(tp, OCP_SRAM_ADDR, addr);
|
||||
return ocp_reg_read(tp, OCP_SRAM_DATA);
|
||||
}
|
||||
|
||||
int r8152_wait_for_bit(struct r8152 *tp, bool ocp_reg, u16 type, u16 index,
|
||||
const u32 mask, bool set, unsigned int timeout)
|
||||
{
|
||||
|
@ -467,12 +475,56 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp)
|
|||
{
|
||||
u32 ocp_data = tp->coalesce / 8;
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT, ocp_data);
|
||||
switch (tp->version) {
|
||||
case RTL_VER_03:
|
||||
case RTL_VER_04:
|
||||
case RTL_VER_05:
|
||||
case RTL_VER_06:
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT,
|
||||
ocp_data);
|
||||
break;
|
||||
|
||||
case RTL_VER_08:
|
||||
case RTL_VER_09:
|
||||
/* The RTL8153B uses USB_RX_EXTRA_AGGR_TMR for rx timeout
|
||||
* primarily. For USB_RX_EARLY_TIMEOUT, we fix it to 1264ns.
|
||||
*/
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT,
|
||||
RX_AUXILIARY_TIMER / 8);
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EXTRA_AGGR_TMR,
|
||||
ocp_data);
|
||||
break;
|
||||
|
||||
default:
|
||||
debug("** %s Invalid Device\n", __func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void r8153_set_rx_early_size(struct r8152 *tp)
|
||||
{
|
||||
u32 ocp_data = (RTL8152_AGG_BUF_SZ - RTL8153_RMS) / 4;
|
||||
u32 ocp_data = (RTL8152_AGG_BUF_SZ - RTL8153_RMS -
|
||||
sizeof(struct rx_desc));
|
||||
|
||||
switch (tp->version) {
|
||||
case RTL_VER_03:
|
||||
case RTL_VER_04:
|
||||
case RTL_VER_05:
|
||||
case RTL_VER_06:
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE,
|
||||
ocp_data / 4);
|
||||
break;
|
||||
|
||||
case RTL_VER_08:
|
||||
case RTL_VER_09:
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE,
|
||||
ocp_data / 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
debug("** %s Invalid Device\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data);
|
||||
}
|
||||
|
@ -540,6 +592,19 @@ static void r8153_u1u2en(struct r8152 *tp, bool enable)
|
|||
usb_ocp_write(tp, USB_TOLERANCE, BYTE_EN_SIX_BYTES, sizeof(u1u2), u1u2);
|
||||
}
|
||||
|
||||
static void r8153b_u1u2en(struct r8152 *tp, bool enable)
|
||||
{
|
||||
u16 ocp_data;
|
||||
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_LPM_CONFIG);
|
||||
if (enable)
|
||||
ocp_data |= LPM_U1U2_EN;
|
||||
else
|
||||
ocp_data &= ~LPM_U1U2_EN;
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_LPM_CONFIG, ocp_data);
|
||||
}
|
||||
|
||||
static void r8153_u2p3en(struct r8152 *tp, bool enable)
|
||||
{
|
||||
u32 ocp_data;
|
||||
|
@ -568,6 +633,17 @@ static void r8153_power_cut_en(struct r8152 *tp, bool enable)
|
|||
ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data);
|
||||
}
|
||||
|
||||
static void rtl_reset_bmu(struct r8152 *tp)
|
||||
{
|
||||
u8 ocp_data;
|
||||
|
||||
ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_BMU_RESET);
|
||||
ocp_data &= ~(BMU_RESET_EP_IN | BMU_RESET_EP_OUT);
|
||||
ocp_write_byte(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data);
|
||||
ocp_data |= BMU_RESET_EP_IN | BMU_RESET_EP_OUT;
|
||||
ocp_write_byte(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data);
|
||||
}
|
||||
|
||||
static int r8152_read_mac(struct r8152 *tp, unsigned char *macaddr)
|
||||
{
|
||||
int ret;
|
||||
|
@ -773,6 +849,71 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
|
|||
sram_write(tp, SRAM_10M_AMP2, 0x0208);
|
||||
}
|
||||
|
||||
static u32 r8152_efuse_read(struct r8152 *tp, u8 addr)
|
||||
{
|
||||
u32 ocp_data;
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_EFUSE_CMD, EFUSE_READ_CMD | addr);
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EFUSE_CMD);
|
||||
ocp_data = (ocp_data & EFUSE_DATA_BIT16) << 9; /* data of bit16 */
|
||||
ocp_data |= ocp_read_word(tp, MCU_TYPE_PLA, PLA_EFUSE_DATA);
|
||||
|
||||
return ocp_data;
|
||||
}
|
||||
|
||||
static void r8153b_hw_phy_cfg(struct r8152 *tp)
|
||||
{
|
||||
u32 ocp_data;
|
||||
u16 data;
|
||||
|
||||
data = r8152_mdio_read(tp, MII_BMCR);
|
||||
if (data & BMCR_PDOWN) {
|
||||
data &= ~BMCR_PDOWN;
|
||||
r8152_mdio_write(tp, MII_BMCR, data);
|
||||
}
|
||||
|
||||
/* U1/U2/L1 idle timer. 500 us */
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500);
|
||||
|
||||
r8153b_firmware(tp);
|
||||
|
||||
data = sram_read(tp, SRAM_GREEN_CFG);
|
||||
data |= R_TUNE_EN;
|
||||
sram_write(tp, SRAM_GREEN_CFG, data);
|
||||
data = ocp_reg_read(tp, OCP_NCTL_CFG);
|
||||
data |= PGA_RETURN_EN;
|
||||
ocp_reg_write(tp, OCP_NCTL_CFG, data);
|
||||
|
||||
/* ADC Bias Calibration:
|
||||
* read efuse offset 0x7d to get a 17-bit data. Remove the dummy/fake
|
||||
* bit (bit3) to rebuild the real 16-bit data. Write the data to the
|
||||
* ADC ioffset.
|
||||
*/
|
||||
ocp_data = r8152_efuse_read(tp, 0x7d);
|
||||
ocp_data = ((ocp_data & 0x1fff0) >> 1) | (ocp_data & 0x7);
|
||||
if (ocp_data != 0xffff)
|
||||
ocp_reg_write(tp, OCP_ADC_IOFFSET, ocp_data);
|
||||
|
||||
/* ups mode tx-link-pulse timing adjustment:
|
||||
* rg_saw_cnt = OCP reg 0xC426 Bit[13:0]
|
||||
* swr_cnt_1ms_ini = 16000000 / rg_saw_cnt
|
||||
*/
|
||||
ocp_data = ocp_reg_read(tp, 0xc426);
|
||||
ocp_data &= 0x3fff;
|
||||
if (ocp_data) {
|
||||
u32 swr_cnt_1ms_ini;
|
||||
|
||||
swr_cnt_1ms_ini = (16000000 / ocp_data) & SAW_CNT_1MS_MASK;
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CFG);
|
||||
ocp_data = (ocp_data & ~SAW_CNT_1MS_MASK) | swr_cnt_1ms_ini;
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CFG, ocp_data);
|
||||
}
|
||||
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR);
|
||||
ocp_data |= PFM_PWM_SWITCH;
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data);
|
||||
}
|
||||
|
||||
static void r8153_first_init(struct r8152 *tp)
|
||||
{
|
||||
u32 ocp_data;
|
||||
|
@ -786,6 +927,7 @@ static void r8153_first_init(struct r8152 *tp)
|
|||
r8153_hw_phy_cfg(tp);
|
||||
|
||||
rtl8152_nic_reset(tp);
|
||||
rtl_reset_bmu(tp);
|
||||
|
||||
ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
|
||||
ocp_data &= ~NOW_IS_OOB;
|
||||
|
@ -832,6 +974,7 @@ static void r8153_enter_oob(struct r8152 *tp)
|
|||
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
|
||||
|
||||
rtl_disable(tp);
|
||||
rtl_reset_bmu(tp);
|
||||
|
||||
rtl8152_reinit_ll(tp);
|
||||
|
||||
|
@ -873,6 +1016,7 @@ static void rtl8153_disable(struct r8152 *tp)
|
|||
{
|
||||
r8153_disable_aldps(tp);
|
||||
rtl_disable(tp);
|
||||
rtl_reset_bmu(tp);
|
||||
}
|
||||
|
||||
static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex)
|
||||
|
@ -933,7 +1077,7 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
|
||||
bmcr = BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET;
|
||||
}
|
||||
|
||||
if (tp->supports_gmii)
|
||||
|
@ -977,6 +1121,16 @@ static void rtl8153_down(struct r8152 *tp)
|
|||
r8153_enter_oob(tp);
|
||||
}
|
||||
|
||||
static void rtl8153b_up(struct r8152 *tp)
|
||||
{
|
||||
r8153_first_init(tp);
|
||||
}
|
||||
|
||||
static void rtl8153b_down(struct r8152 *tp)
|
||||
{
|
||||
r8153_enter_oob(tp);
|
||||
}
|
||||
|
||||
static void r8152b_get_version(struct r8152 *tp)
|
||||
{
|
||||
u32 ocp_data;
|
||||
|
@ -1140,6 +1294,60 @@ static void r8153_init(struct r8152 *tp)
|
|||
rtl_tally_reset(tp);
|
||||
}
|
||||
|
||||
static void r8153b_init(struct r8152 *tp)
|
||||
{
|
||||
u32 ocp_data;
|
||||
int i;
|
||||
|
||||
r8153_disable_aldps(tp);
|
||||
r8153b_u1u2en(tp, false);
|
||||
|
||||
r8152_wait_for_bit(tp, 0, MCU_TYPE_PLA, PLA_BOOT_CTRL,
|
||||
AUTOLOAD_DONE, 1, R8152_WAIT_TIMEOUT);
|
||||
|
||||
for (i = 0; i < R8152_WAIT_TIMEOUT; i++) {
|
||||
ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK;
|
||||
if (ocp_data == PHY_STAT_LAN_ON || ocp_data == PHY_STAT_PWRDN)
|
||||
break;
|
||||
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
r8153_u2p3en(tp, false);
|
||||
|
||||
/* MSC timer = 0xfff * 8ms = 32760 ms */
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff);
|
||||
|
||||
r8153_power_cut_en(tp, false);
|
||||
|
||||
/* MAC clock speed down */
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2);
|
||||
ocp_data |= MAC_CLK_SPDWN_EN;
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data);
|
||||
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3);
|
||||
ocp_data &= ~PLA_MCU_SPDWN_EN;
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data);
|
||||
|
||||
if (tp->version == RTL_VER_09) {
|
||||
/* Disable Test IO for 32QFN */
|
||||
if (ocp_read_byte(tp, MCU_TYPE_PLA, 0xdc00) & BIT(5)) {
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR);
|
||||
ocp_data |= TEST_IO_OFF;
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data);
|
||||
}
|
||||
}
|
||||
|
||||
/* rx aggregation */
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
|
||||
ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN);
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
|
||||
|
||||
rtl_tally_reset(tp);
|
||||
r8153b_hw_phy_cfg(tp);
|
||||
r8152b_enable_fc(tp);
|
||||
}
|
||||
|
||||
static void rtl8152_unload(struct r8152 *tp)
|
||||
{
|
||||
if (tp->version != RTL_VER_01)
|
||||
|
@ -1180,6 +1388,15 @@ static int rtl_ops_init(struct r8152 *tp)
|
|||
ops->unload = rtl8153_unload;
|
||||
break;
|
||||
|
||||
case RTL_VER_08:
|
||||
case RTL_VER_09:
|
||||
ops->init = r8153b_init;
|
||||
ops->enable = rtl8153_enable;
|
||||
ops->disable = rtl8153_disable;
|
||||
ops->up = rtl8153b_up;
|
||||
ops->down = rtl8153b_down;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENODEV;
|
||||
printf("r8152 Unknown Device\n");
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#define PLA_TEREDO_TIMER 0xd2cc
|
||||
#define PLA_REALWOW_TIMER 0xd2e8
|
||||
#define PLA_EXTRA_STATUS 0xd398
|
||||
#define PLA_EFUSE_DATA 0xdd00
|
||||
#define PLA_EFUSE_CMD 0xdd02
|
||||
#define PLA_LEDSEL 0xdd90
|
||||
#define PLA_LED_FEATURE 0xdd92
|
||||
#define PLA_PHYAR 0xde00
|
||||
|
@ -76,8 +78,10 @@
|
|||
#define USB_CSR_DUMMY2 0xb466
|
||||
#define USB_DEV_STAT 0xb808
|
||||
#define USB_CONNECT_TIMER 0xcbf8
|
||||
#define USB_MSC_TIMER 0xcbfc
|
||||
#define USB_BURST_SIZE 0xcfc0
|
||||
#define USB_FW_FIX_EN1 0xcfcc
|
||||
#define USB_LPM_CONFIG 0xcfd8
|
||||
#define USB_USB_CTRL 0xd406
|
||||
#define USB_PHY_CTRL 0xd408
|
||||
#define USB_TX_AGG 0xd40a
|
||||
|
@ -85,25 +89,23 @@
|
|||
#define USB_USB_TIMER 0xd428
|
||||
#define USB_RX_EARLY_TIMEOUT 0xd42c
|
||||
#define USB_RX_EARLY_SIZE 0xd42e
|
||||
#define USB_PM_CTRL_STATUS 0xd432
|
||||
#define USB_PM_CTRL_STATUS 0xd432 /* RTL8153A */
|
||||
#define USB_RX_EXTRA_AGGR_TMR 0xd432 /* RTL8153B */
|
||||
#define USB_TX_DMA 0xd434
|
||||
#define USB_TOLERANCE 0xd490
|
||||
#define USB_LPM_CTRL 0xd41a
|
||||
#define USB_BMU_RESET 0xd4b0
|
||||
#define USB_U1U2_TIMER 0xd4da
|
||||
#define USB_UPS_CTRL 0xd800
|
||||
#define USB_MISC_0 0xd81a
|
||||
#define USB_POWER_CUT 0xd80a
|
||||
#define USB_MISC_0 0xd81a
|
||||
#define USB_AFE_CTRL2 0xd824
|
||||
#define USB_UPS_CFG 0xd842
|
||||
#define USB_WDT11_CTRL 0xe43c
|
||||
#define USB_BP_BA 0xfc26
|
||||
#define USB_BP_0 0xfc28
|
||||
#define USB_BP_1 0xfc2a
|
||||
#define USB_BP_2 0xfc2c
|
||||
#define USB_BP_3 0xfc2e
|
||||
#define USB_BP_4 0xfc30
|
||||
#define USB_BP_5 0xfc32
|
||||
#define USB_BP_6 0xfc34
|
||||
#define USB_BP_7 0xfc36
|
||||
#define USB_BP_EN 0xfc38
|
||||
#define USB_BP_BA PLA_BP_BA
|
||||
#define USB_BP(n) (0xfc28 + 2 * (n))
|
||||
#define USB_BP_EN PLA_BP_EN /* RTL8153A */
|
||||
#define USB_BP2_EN 0xfc48
|
||||
|
||||
/* OCP Registers */
|
||||
#define OCP_ALDPS_CONFIG 0x2010
|
||||
|
@ -114,6 +116,7 @@
|
|||
#define OCP_EEE_AR 0xa41a
|
||||
#define OCP_EEE_DATA 0xa41c
|
||||
#define OCP_PHY_STATUS 0xa420
|
||||
#define OCP_NCTL_CFG 0xa42c
|
||||
#define OCP_POWER_CFG 0xa430
|
||||
#define OCP_EEE_CFG 0xa432
|
||||
#define OCP_SRAM_ADDR 0xa436
|
||||
|
@ -123,9 +126,11 @@
|
|||
#define OCP_EEE_ADV 0xa5d0
|
||||
#define OCP_EEE_LPABLE 0xa5d2
|
||||
#define OCP_PHY_STATE 0xa708 /* nway state for 8153 */
|
||||
#define OCP_ADC_IOFFSET 0xbcfc
|
||||
#define OCP_ADC_CFG 0xbc06
|
||||
|
||||
/* SRAM Register */
|
||||
#define SRAM_GREEN_CFG 0x8011
|
||||
#define SRAM_LPF_CFG 0x8012
|
||||
#define SRAM_10M_AMP1 0x8080
|
||||
#define SRAM_10M_AMP2 0x8082
|
||||
|
@ -207,6 +212,7 @@
|
|||
/* PLA_PHY_PWR */
|
||||
#define PLA_PHY_PWR_LLR (LINK_LIST_READY << 24)
|
||||
#define PLA_PHY_PWR_TXEMP (TXFIFO_EMPTY << 24)
|
||||
#define TEST_IO_OFF BIT(4)
|
||||
|
||||
/* PLA_MISC_1 */
|
||||
#define RXDY_GATED_EN 0x0008
|
||||
|
@ -230,6 +236,10 @@
|
|||
/* PLA_BDC_CR */
|
||||
#define ALDPS_PROXY_MODE 0x0001
|
||||
|
||||
/* PLA_EFUSE_CMD */
|
||||
#define EFUSE_READ_CMD BIT(15)
|
||||
#define EFUSE_DATA_BIT16 BIT(7)
|
||||
|
||||
/* PLA_CONFIG34 */
|
||||
#define LINK_ON_WAKE_EN 0x0010
|
||||
#define LINK_OFF_WAKE_EN 0x0008
|
||||
|
@ -255,8 +265,10 @@
|
|||
|
||||
/* PLA_MAC_PWR_CTRL2 */
|
||||
#define EEE_SPDWN_RATIO 0x8007
|
||||
#define MAC_CLK_SPDWN_EN BIT(15)
|
||||
|
||||
/* PLA_MAC_PWR_CTRL3 */
|
||||
#define PLA_MCU_SPDWN_EN BIT(14)
|
||||
#define PKT_AVAIL_SPDWN_EN 0x0100
|
||||
#define SUSPEND_SPDWN_EN 0x0004
|
||||
#define U1U2_SPDWN_EN 0x0002
|
||||
|
@ -312,6 +324,9 @@
|
|||
/* USB_FW_FIX_EN1 */
|
||||
#define FW_IP_RESET_EN BIT(9)
|
||||
|
||||
/* USB_LPM_CONFIG */
|
||||
#define LPM_U1U2_EN BIT(0)
|
||||
|
||||
/* USB_TX_AGG */
|
||||
#define TX_AGG_MAX_THRESHOLD 0x03
|
||||
|
||||
|
@ -320,10 +335,17 @@
|
|||
#define RX_THR_HIGH 0x7a120180
|
||||
#define RX_THR_SLOW 0xffff0180
|
||||
|
||||
/* USB_RX_EARLY_TIMEOUT */
|
||||
#define RX_AUXILIARY_TIMER 1264
|
||||
|
||||
/* USB_TX_DMA */
|
||||
#define TEST_MODE_DISABLE 0x00000001
|
||||
#define TX_SIZE_ADJUST1 0x00000100
|
||||
|
||||
/* USB_BMU_RESET */
|
||||
#define BMU_RESET_EP_IN 0x01
|
||||
#define BMU_RESET_EP_OUT 0x02
|
||||
|
||||
/* USB_UPS_CTRL */
|
||||
#define POWER_CUT 0x0100
|
||||
|
||||
|
@ -366,6 +388,9 @@
|
|||
#define SEN_VAL_NORMAL 0xa000
|
||||
#define SEL_RXIDLE 0x0100
|
||||
|
||||
/* USB_UPS_CFG */
|
||||
#define SAW_CNT_1MS_MASK 0x0fff
|
||||
|
||||
/* OCP_ALDPS_CONFIG */
|
||||
#define ENPWRSAVE 0x8000
|
||||
#define ENPDNPS 0x0200
|
||||
|
@ -377,6 +402,9 @@
|
|||
#define PHY_STAT_LAN_ON 3
|
||||
#define PHY_STAT_PWRDN 5
|
||||
|
||||
/* OCP_NCTL_CFG */
|
||||
#define PGA_RETURN_EN BIT(1)
|
||||
|
||||
/* OCP_POWER_CFG */
|
||||
#define EEE_CLKDIV_EN 0x8000
|
||||
#define EN_ALDPS 0x0004
|
||||
|
@ -429,6 +457,10 @@
|
|||
#define ADC_EN 0x0080
|
||||
#define EN_EMI_L 0x0040
|
||||
|
||||
/* SRAM_GREEN_CFG */
|
||||
#define GREEN_ETH_EN BIT(15)
|
||||
#define R_TUNE_EN BIT(11)
|
||||
|
||||
/* SRAM_LPF_CFG */
|
||||
#define LPF_AUTO_TUNE 0x8000
|
||||
|
||||
|
@ -573,6 +605,8 @@ enum rtl_version {
|
|||
RTL_VER_05,
|
||||
RTL_VER_06,
|
||||
RTL_VER_07,
|
||||
RTL_VER_08,
|
||||
RTL_VER_09,
|
||||
RTL_VER_MAX
|
||||
};
|
||||
|
||||
|
@ -640,4 +674,5 @@ int r8152_wait_for_bit(struct r8152 *tp, bool ocp_reg, u16 type, u16 index,
|
|||
|
||||
void r8152b_firmware(struct r8152 *tp);
|
||||
void r8153_firmware(struct r8152 *tp);
|
||||
void r8153b_firmware(struct r8152 *tp);
|
||||
#endif
|
||||
|
|
|
@ -729,28 +729,161 @@ static u16 r8153_pla_patch_d_bp[] = {
|
|||
0xfc2e, 0x0000, 0xfc30, 0x0000, 0xfc32, 0x0000, 0xfc34, 0x0000,
|
||||
0xfc36, 0x0000, 0xfc38, 0x0007 };
|
||||
|
||||
static void rtl_clear_bp(struct r8152 *tp)
|
||||
static u8 usb_patch2_b[] = {
|
||||
0x10, 0xe0, 0x26, 0xe0, 0x3a, 0xe0, 0x58, 0xe0,
|
||||
0x6c, 0xe0, 0x85, 0xe0, 0xa5, 0xe0, 0xbe, 0xe0,
|
||||
0xd8, 0xe0, 0xdb, 0xe0, 0xf3, 0xe0, 0xf5, 0xe0,
|
||||
0xf7, 0xe0, 0xf9, 0xe0, 0xfb, 0xe0, 0xfd, 0xe0,
|
||||
0x16, 0xc0, 0x00, 0x75, 0xd1, 0x49, 0x0d, 0xf0,
|
||||
0x0f, 0xc0, 0x0f, 0xc5, 0x00, 0x1e, 0x08, 0x9e,
|
||||
0x0c, 0x9d, 0x0c, 0xc6, 0x0a, 0x9e, 0x8f, 0x1c,
|
||||
0x0e, 0x8c, 0x0e, 0x74, 0xcf, 0x49, 0xfe, 0xf1,
|
||||
0x02, 0xc0, 0x00, 0xb8, 0x96, 0x31, 0x00, 0xdc,
|
||||
0x24, 0xe4, 0x80, 0x02, 0x34, 0xd3, 0xff, 0xc3,
|
||||
0x60, 0x72, 0xa1, 0x49, 0x0d, 0xf0, 0xf8, 0xc3,
|
||||
0xf8, 0xc2, 0x00, 0x1c, 0x68, 0x9c, 0xf6, 0xc4,
|
||||
0x6a, 0x9c, 0x6c, 0x9a, 0x8f, 0x1c, 0x6e, 0x8c,
|
||||
0x6e, 0x74, 0xcf, 0x49, 0xfe, 0xf1, 0x04, 0xc0,
|
||||
0x02, 0xc2, 0x00, 0xba, 0xa8, 0x28, 0xf8, 0xc7,
|
||||
0xea, 0xc0, 0x00, 0x75, 0xd1, 0x49, 0x15, 0xf0,
|
||||
0x19, 0xc7, 0x17, 0xc2, 0xec, 0x9a, 0x00, 0x19,
|
||||
0xee, 0x89, 0xee, 0x71, 0x9f, 0x49, 0xfe, 0xf1,
|
||||
0xea, 0x71, 0x9f, 0x49, 0x0a, 0xf0, 0xd9, 0xc2,
|
||||
0xec, 0x9a, 0x00, 0x19, 0xe8, 0x99, 0x81, 0x19,
|
||||
0xee, 0x89, 0xee, 0x71, 0x9f, 0x49, 0xfe, 0xf1,
|
||||
0x06, 0xc3, 0x02, 0xc2, 0x00, 0xba, 0xf0, 0x1d,
|
||||
0x4c, 0xe8, 0x00, 0xdc, 0x00, 0xd4, 0xcb, 0xc0,
|
||||
0x00, 0x75, 0xd1, 0x49, 0x0d, 0xf0, 0xc4, 0xc0,
|
||||
0xc4, 0xc5, 0x00, 0x1e, 0x08, 0x9e, 0xc2, 0xc6,
|
||||
0x0a, 0x9e, 0x0c, 0x9d, 0x8f, 0x1c, 0x0e, 0x8c,
|
||||
0x0e, 0x74, 0xcf, 0x49, 0xfe, 0xf1, 0x04, 0xc0,
|
||||
0x02, 0xc1, 0x00, 0xb9, 0xc4, 0x16, 0x20, 0xd4,
|
||||
0xb6, 0xc0, 0x00, 0x75, 0xd1, 0x48, 0x00, 0x9d,
|
||||
0xe5, 0xc7, 0xaf, 0xc2, 0xec, 0x9a, 0x00, 0x19,
|
||||
0xe8, 0x9a, 0x81, 0x19, 0xee, 0x89, 0xee, 0x71,
|
||||
0x9f, 0x49, 0xfe, 0xf1, 0x2c, 0xc1, 0xec, 0x99,
|
||||
0x81, 0x19, 0xee, 0x89, 0xee, 0x71, 0x9f, 0x49,
|
||||
0xfe, 0xf1, 0x04, 0xc3, 0x02, 0xc2, 0x00, 0xba,
|
||||
0x96, 0x1c, 0xc0, 0xd4, 0xc0, 0x88, 0x1e, 0xc6,
|
||||
0xc0, 0x70, 0x8f, 0x49, 0x0e, 0xf0, 0x8f, 0x48,
|
||||
0x93, 0xc6, 0xca, 0x98, 0x11, 0x18, 0xc8, 0x98,
|
||||
0x16, 0xc0, 0xcc, 0x98, 0x8f, 0x18, 0xce, 0x88,
|
||||
0xce, 0x70, 0x8f, 0x49, 0xfe, 0xf1, 0x0b, 0xe0,
|
||||
0x43, 0xc6, 0x00, 0x18, 0xc8, 0x98, 0x0b, 0xc0,
|
||||
0xcc, 0x98, 0x81, 0x18, 0xce, 0x88, 0xce, 0x70,
|
||||
0x8f, 0x49, 0xfe, 0xf1, 0x02, 0xc0, 0x00, 0xb8,
|
||||
0xf2, 0x19, 0x40, 0xd3, 0x20, 0xe4, 0x33, 0xc2,
|
||||
0x40, 0x71, 0x91, 0x48, 0x40, 0x99, 0x30, 0xc2,
|
||||
0x00, 0x19, 0x48, 0x99, 0xf8, 0xc1, 0x4c, 0x99,
|
||||
0x81, 0x19, 0x4e, 0x89, 0x4e, 0x71, 0x9f, 0x49,
|
||||
0xfe, 0xf1, 0x0b, 0xc1, 0x4c, 0x99, 0x81, 0x19,
|
||||
0x4e, 0x89, 0x4e, 0x71, 0x9f, 0x49, 0xfe, 0xf1,
|
||||
0x02, 0x71, 0x02, 0xc2, 0x00, 0xba, 0x0e, 0x34,
|
||||
0x24, 0xe4, 0x19, 0xc2, 0x40, 0x71, 0x91, 0x48,
|
||||
0x40, 0x99, 0x16, 0xc2, 0x00, 0x19, 0x48, 0x99,
|
||||
0xde, 0xc1, 0x4c, 0x99, 0x81, 0x19, 0x4e, 0x89,
|
||||
0x4e, 0x71, 0x9f, 0x49, 0xfe, 0xf1, 0xf1, 0xc1,
|
||||
0x4c, 0x99, 0x81, 0x19, 0x4e, 0x89, 0x4e, 0x71,
|
||||
0x9f, 0x49, 0xfe, 0xf1, 0x02, 0x71, 0x02, 0xc2,
|
||||
0x00, 0xba, 0x60, 0x33, 0x34, 0xd3, 0x00, 0xdc,
|
||||
0x1e, 0x89, 0x02, 0xc0, 0x00, 0xb8, 0xfa, 0x12,
|
||||
0x18, 0xc0, 0x00, 0x65, 0xd1, 0x49, 0x0e, 0xf0,
|
||||
0x11, 0xc0, 0x11, 0xc5, 0x00, 0x1e, 0x08, 0x9e,
|
||||
0x0c, 0x9d, 0x0e, 0xc6, 0x0a, 0x9e, 0x8f, 0x1c,
|
||||
0x0e, 0x8c, 0x0e, 0x74, 0xcf, 0x49, 0xfe, 0xf1,
|
||||
0x04, 0xc0, 0x02, 0xc2, 0x00, 0xba, 0xa0, 0x41,
|
||||
0x06, 0xd4, 0x00, 0xdc, 0x24, 0xe4, 0x80, 0x02,
|
||||
0x34, 0xd3, 0x02, 0xc0, 0x00, 0xb8, 0x00, 0x00,
|
||||
0x02, 0xc0, 0x00, 0xb8, 0x00, 0x00, 0x02, 0xc0,
|
||||
0x00, 0xb8, 0x00, 0x00, 0x02, 0xc0, 0x00, 0xb8,
|
||||
0x00, 0x00, 0x02, 0xc0, 0x00, 0xb8, 0x00, 0x00,
|
||||
0x02, 0xc0, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
static u16 r8153b_usb_patch_b_bp[] = {
|
||||
0xfc26, 0xa000, 0xfc28, 0x2a20, 0xfc2a, 0x28a6, 0xfc2c, 0x1dee,
|
||||
0xfc2e, 0x16c2, 0xfc30, 0x1c94, 0xfc32, 0x19f0, 0xfc34, 0x340c,
|
||||
0xfc36, 0x335e, 0xfc38, 0x12f8, 0xfc3a, 0x419e, 0xfc3c, 0x0000,
|
||||
0xfc3e, 0x0000, 0xfc40, 0x0000, 0xfc42, 0x0000, 0xfc44, 0x0000,
|
||||
0xfc46, 0x0000, 0xfc48, 0x03ff };
|
||||
|
||||
static u8 pla_patch2_b[] = {
|
||||
0x05, 0xe0, 0x1b, 0xe0, 0x2c, 0xe0, 0x60, 0xe0,
|
||||
0x73, 0xe0, 0x15, 0xc6, 0xc2, 0x64, 0xd2, 0x49,
|
||||
0x06, 0xf1, 0xc4, 0x48, 0xc5, 0x48, 0xc6, 0x48,
|
||||
0xc7, 0x48, 0x05, 0xe0, 0x44, 0x48, 0x45, 0x48,
|
||||
0x46, 0x48, 0x47, 0x48, 0xc2, 0x8c, 0xc0, 0x64,
|
||||
0x46, 0x48, 0xc0, 0x8c, 0x05, 0xc5, 0x02, 0xc4,
|
||||
0x00, 0xbc, 0x18, 0x02, 0x06, 0xdc, 0xb0, 0xc0,
|
||||
0x10, 0xc5, 0xa0, 0x77, 0xa0, 0x74, 0x46, 0x48,
|
||||
0x47, 0x48, 0xa0, 0x9c, 0x0b, 0xc5, 0xa0, 0x74,
|
||||
0x44, 0x48, 0x43, 0x48, 0xa0, 0x9c, 0x05, 0xc5,
|
||||
0xa0, 0x9f, 0x02, 0xc5, 0x00, 0xbd, 0x3c, 0x03,
|
||||
0x1c, 0xe8, 0x20, 0xe8, 0xd4, 0x49, 0x04, 0xf1,
|
||||
0xd5, 0x49, 0x20, 0xf1, 0x28, 0xe0, 0x2a, 0xc7,
|
||||
0xe0, 0x75, 0xda, 0x49, 0x14, 0xf0, 0x27, 0xc7,
|
||||
0xe0, 0x75, 0xdc, 0x49, 0x10, 0xf1, 0x24, 0xc7,
|
||||
0xe0, 0x75, 0x25, 0xc7, 0xe0, 0x74, 0x2c, 0x40,
|
||||
0x0a, 0xfa, 0x1f, 0xc7, 0xe4, 0x75, 0xd0, 0x49,
|
||||
0x09, 0xf1, 0x1c, 0xc5, 0xe6, 0x9d, 0x11, 0x1d,
|
||||
0xe4, 0x8d, 0x04, 0xe0, 0x16, 0xc7, 0x00, 0x1d,
|
||||
0xe4, 0x8d, 0xe0, 0x8e, 0x11, 0x1d, 0xe0, 0x8d,
|
||||
0x07, 0xe0, 0x0c, 0xc7, 0xe0, 0x75, 0xda, 0x48,
|
||||
0xe0, 0x9d, 0x0b, 0xc7, 0xe4, 0x8e, 0x02, 0xc4,
|
||||
0x00, 0xbc, 0x28, 0x03, 0x02, 0xc4, 0x00, 0xbc,
|
||||
0x14, 0x03, 0x12, 0xe8, 0x4e, 0xe8, 0x1c, 0xe6,
|
||||
0x20, 0xe4, 0x80, 0x02, 0xa4, 0xc0, 0x12, 0xc2,
|
||||
0x40, 0x73, 0xb0, 0x49, 0x08, 0xf0, 0xb8, 0x49,
|
||||
0x06, 0xf0, 0xb8, 0x48, 0x40, 0x9b, 0x0b, 0xc2,
|
||||
0x40, 0x76, 0x05, 0xe0, 0x02, 0x61, 0x02, 0xc3,
|
||||
0x00, 0xbb, 0x0a, 0x0a, 0x02, 0xc3, 0x00, 0xbb,
|
||||
0x1a, 0x0a, 0x98, 0xd3, 0x1e, 0xfc, 0xfe, 0xc0,
|
||||
0x02, 0x62, 0xa0, 0x48, 0x02, 0x8a, 0x00, 0x72,
|
||||
0xa0, 0x49, 0x11, 0xf0, 0x13, 0xc1, 0x20, 0x62,
|
||||
0x2e, 0x21, 0x2f, 0x25, 0x00, 0x71, 0x9f, 0x24,
|
||||
0x0a, 0x40, 0x09, 0xf0, 0x00, 0x71, 0x18, 0x48,
|
||||
0xa0, 0x49, 0x03, 0xf1, 0x9f, 0x48, 0x02, 0xe0,
|
||||
0x1f, 0x48, 0x00, 0x99, 0x02, 0xc2, 0x00, 0xba,
|
||||
0xda, 0x0e, 0x08, 0xe9 };
|
||||
|
||||
static u16 r8153b_pla_patch_b_bp[] = {
|
||||
0xfc26, 0x8000, 0xfc28, 0x0216, 0xfc2a, 0x0332, 0xfc2c, 0x030c,
|
||||
0xfc2e, 0x0a08, 0xfc30, 0x0ec0, 0xfc32, 0x0000, 0xfc34, 0x0000,
|
||||
0xfc36, 0x0000, 0xfc38, 0x001e };
|
||||
|
||||
static void rtl_clear_bp(struct r8152 *tp, u16 type)
|
||||
{
|
||||
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
|
||||
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_2, 0);
|
||||
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_4, 0);
|
||||
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_6, 0);
|
||||
ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_0, 0);
|
||||
ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_2, 0);
|
||||
ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_4, 0);
|
||||
ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_6, 0);
|
||||
u8 zeros[16] = {0};
|
||||
|
||||
switch (tp->version) {
|
||||
case RTL_VER_01:
|
||||
case RTL_VER_02:
|
||||
case RTL_VER_07:
|
||||
break;
|
||||
case RTL_VER_03:
|
||||
case RTL_VER_04:
|
||||
case RTL_VER_05:
|
||||
case RTL_VER_06:
|
||||
ocp_write_byte(tp, type, PLA_BP_EN, 0);
|
||||
break;
|
||||
case RTL_VER_08:
|
||||
case RTL_VER_09:
|
||||
default:
|
||||
if (type == MCU_TYPE_USB) {
|
||||
ocp_write_byte(tp, MCU_TYPE_USB, USB_BP2_EN, 0);
|
||||
|
||||
generic_ocp_write(tp, USB_BP(8), 0xff, sizeof(zeros),
|
||||
zeros, type);
|
||||
} else {
|
||||
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
generic_ocp_write(tp, USB_BP(0), 0xff, sizeof(zeros), zeros, type);
|
||||
|
||||
mdelay(6);
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0);
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0);
|
||||
}
|
||||
|
||||
static void r8153_clear_bp(struct r8152 *tp)
|
||||
{
|
||||
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0);
|
||||
ocp_write_byte(tp, MCU_TYPE_USB, USB_BP_EN, 0);
|
||||
rtl_clear_bp(tp);
|
||||
ocp_write_word(tp, type, PLA_BP_BA, 0);
|
||||
}
|
||||
|
||||
static void r8152b_set_dq_desc(struct r8152 *tp)
|
||||
|
@ -826,7 +959,7 @@ void r8152b_firmware(struct r8152 *tp)
|
|||
int i;
|
||||
|
||||
r8152b_set_dq_desc(tp);
|
||||
rtl_clear_bp(tp);
|
||||
rtl_clear_bp(tp, MCU_TYPE_PLA);
|
||||
|
||||
generic_ocp_write(tp, 0xf800, 0x3f,
|
||||
sizeof(r8152b_pla_patch_a),
|
||||
|
@ -847,7 +980,7 @@ void r8152b_firmware(struct r8152 *tp)
|
|||
ocp_write_word(tp, MCU_TYPE_PLA, 0xb098, 0x0200);
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, 0xb092, 0x7030);
|
||||
} else if (tp->version == RTL_VER_02) {
|
||||
rtl_clear_bp(tp);
|
||||
rtl_clear_bp(tp, MCU_TYPE_PLA);
|
||||
|
||||
generic_ocp_write(tp, 0xf800, 0xff,
|
||||
sizeof(r8152b_pla_patch_a2),
|
||||
|
@ -866,8 +999,6 @@ void r8153_firmware(struct r8152 *tp)
|
|||
int i;
|
||||
|
||||
if (tp->version == RTL_VER_03) {
|
||||
r8153_clear_bp(tp);
|
||||
|
||||
r8153_pre_ram_code(tp, 0x7000);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(r8153_ram_code_a); i += 2)
|
||||
|
@ -887,7 +1018,8 @@ void r8153_firmware(struct r8152 *tp)
|
|||
r8153_post_ram_code(tp);
|
||||
|
||||
r8153_wdt1_end(tp);
|
||||
r8153_clear_bp(tp);
|
||||
|
||||
rtl_clear_bp(tp, MCU_TYPE_USB);
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x0000);
|
||||
generic_ocp_write(tp, 0xf800, 0xff,
|
||||
|
@ -904,6 +1036,8 @@ void r8153_firmware(struct r8152 *tp)
|
|||
ocp_write_word(tp, MCU_TYPE_PLA, 0xd38e, 0x0082);
|
||||
}
|
||||
|
||||
rtl_clear_bp(tp, MCU_TYPE_PLA);
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000);
|
||||
generic_ocp_write(tp, 0xf800, 0xff,
|
||||
sizeof(r8153_pla_patch_b),
|
||||
|
@ -932,7 +1066,8 @@ void r8153_firmware(struct r8152 *tp)
|
|||
r8153_post_ram_code(tp);
|
||||
|
||||
r8153_wdt1_end(tp);
|
||||
r8153_clear_bp(tp);
|
||||
|
||||
rtl_clear_bp(tp, MCU_TYPE_USB);
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x0000);
|
||||
generic_ocp_write(tp, 0xf800, 0xff,
|
||||
|
@ -951,6 +1086,8 @@ void r8153_firmware(struct r8152 *tp)
|
|||
ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x00ef);
|
||||
}
|
||||
|
||||
rtl_clear_bp(tp, MCU_TYPE_PLA);
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000);
|
||||
generic_ocp_write(tp, 0xf800, 0xff,
|
||||
sizeof(r8153_pla_patch_c),
|
||||
|
@ -985,7 +1122,7 @@ void r8153_firmware(struct r8152 *tp)
|
|||
|
||||
r8153_post_ram_code(tp);
|
||||
|
||||
r8153_clear_bp(tp);
|
||||
rtl_clear_bp(tp, MCU_TYPE_USB);
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x0000);
|
||||
generic_ocp_write(tp, 0xf800, 0xff, sizeof(usb_patch_d),
|
||||
|
@ -996,6 +1133,8 @@ void r8153_firmware(struct r8152 *tp)
|
|||
r8153_usb_patch_d_bp[i],
|
||||
r8153_usb_patch_d_bp[i+1]);
|
||||
|
||||
rtl_clear_bp(tp, MCU_TYPE_PLA);
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000);
|
||||
generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_d),
|
||||
pla_patch_d, MCU_TYPE_PLA);
|
||||
|
@ -1014,3 +1153,42 @@ void r8153_firmware(struct r8152 *tp)
|
|||
ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data);
|
||||
}
|
||||
}
|
||||
|
||||
void r8153b_firmware(struct r8152 *tp)
|
||||
{
|
||||
u32 ocp_data;
|
||||
int i;
|
||||
|
||||
if (tp->version != RTL_VER_09)
|
||||
return;
|
||||
|
||||
rtl_clear_bp(tp, MCU_TYPE_USB);
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x0000);
|
||||
generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb_patch2_b),
|
||||
usb_patch2_b, MCU_TYPE_USB);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(r8153b_usb_patch_b_bp); i += 2)
|
||||
ocp_write_word(tp, MCU_TYPE_USB,
|
||||
r8153b_usb_patch_b_bp[i],
|
||||
r8153b_usb_patch_b_bp[i + 1]);
|
||||
|
||||
rtl_clear_bp(tp, MCU_TYPE_PLA);
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000);
|
||||
generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch2_b),
|
||||
pla_patch2_b, MCU_TYPE_PLA);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(r8153b_pla_patch_b_bp); i += 2)
|
||||
ocp_write_word(tp, MCU_TYPE_PLA,
|
||||
r8153b_pla_patch_b_bp[i],
|
||||
r8153b_pla_patch_b_bp[i + 1]);
|
||||
|
||||
ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY);
|
||||
ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND;
|
||||
ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data);
|
||||
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1);
|
||||
ocp_data |= FW_IP_RESET_EN;
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data);
|
||||
}
|
||||
|
|
|
@ -105,6 +105,12 @@ config CI_UDC
|
|||
Say Y here to enable device controller functionality of the
|
||||
ChipIdea driver.
|
||||
|
||||
config USB_GADGET_MAX3420
|
||||
bool "MAX3420 USB Over SPI"
|
||||
depends on DM_SPI
|
||||
help
|
||||
MAX3420, from MAXIM, implements USB-over-SPI Full-Speed device controller.
|
||||
|
||||
config USB_GADGET_VBUS_DRAW
|
||||
int "Maximum VBUS Power usage (2-500 mA)"
|
||||
range 2 500
|
||||
|
|
|
@ -20,6 +20,7 @@ obj-$(CONFIG_USB_GADGET_BCM_UDC_OTG_PHY) += bcm_udc_otg_phy.o
|
|||
obj-$(CONFIG_USB_GADGET_DWC2_OTG) += dwc2_udc_otg.o
|
||||
obj-$(CONFIG_USB_GADGET_DWC2_OTG_PHY) += dwc2_udc_otg_phy.o
|
||||
obj-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
|
||||
obj-$(CONFIG_USB_GADGET_MAX3420) += max3420_udc.o
|
||||
obj-$(CONFIG_CI_UDC) += ci_udc.o
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o
|
||||
|
|
|
@ -1053,6 +1053,13 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
|
|||
free(controller.items_mem);
|
||||
free(controller.epts);
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_USB)
|
||||
usb_remove_ehci_gadget(&controller.ctrl);
|
||||
#else
|
||||
usb_lowlevel_stop(0);
|
||||
controller.ctrl = NULL;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -441,8 +441,6 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
|
|||
req->length = rx_bytes_expected(ep);
|
||||
}
|
||||
|
||||
fastboot_tx_write_str(response);
|
||||
|
||||
if (!strncmp("OKAY", response, 4)) {
|
||||
switch (cmd) {
|
||||
case FASTBOOT_COMMAND_BOOT:
|
||||
|
@ -455,11 +453,15 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
|
|||
|
||||
case FASTBOOT_COMMAND_REBOOT:
|
||||
case FASTBOOT_COMMAND_REBOOT_BOOTLOADER:
|
||||
case FASTBOOT_COMMAND_REBOOT_FASTBOOTD:
|
||||
case FASTBOOT_COMMAND_REBOOT_RECOVERY:
|
||||
fastboot_func->in_req->complete = compl_do_reset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fastboot_tx_write_str(response);
|
||||
|
||||
*cmdbuf = '\0';
|
||||
req->actual = 0;
|
||||
usb_ep_queue(ep, req, 0);
|
||||
|
|
|
@ -435,6 +435,7 @@ static void set_bulk_out_req_length(struct fsg_common *common,
|
|||
static struct ums *ums;
|
||||
static int ums_count;
|
||||
static struct fsg_common *the_fsg_common;
|
||||
static unsigned int controller_index;
|
||||
|
||||
static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
|
||||
{
|
||||
|
@ -679,7 +680,7 @@ static int sleep_thread(struct fsg_common *common)
|
|||
k = 0;
|
||||
}
|
||||
|
||||
usb_gadget_handle_interrupts(0);
|
||||
usb_gadget_handle_interrupts(controller_index);
|
||||
}
|
||||
common->thread_wakeup_needed = 0;
|
||||
return rc;
|
||||
|
@ -2764,10 +2765,11 @@ int fsg_add(struct usb_configuration *c)
|
|||
return fsg_bind_config(c->cdev, c, fsg_common);
|
||||
}
|
||||
|
||||
int fsg_init(struct ums *ums_devs, int count)
|
||||
int fsg_init(struct ums *ums_devs, int count, unsigned int controller_idx)
|
||||
{
|
||||
ums = ums_devs;
|
||||
ums_count = count;
|
||||
controller_index = controller_idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,10 @@ struct hid_report {
|
|||
|
||||
#define SDP_COMMAND_LEN 16
|
||||
|
||||
#define SDP_HID_PACKET_SIZE_EP1 1024
|
||||
|
||||
#define SDP_EXIT 1
|
||||
|
||||
struct sdp_command {
|
||||
u16 cmd;
|
||||
u32 addr;
|
||||
|
@ -82,8 +86,10 @@ struct sdp_command {
|
|||
|
||||
enum sdp_state {
|
||||
SDP_STATE_IDLE,
|
||||
SDP_STATE_RX_CMD,
|
||||
SDP_STATE_RX_DCD_DATA,
|
||||
SDP_STATE_RX_FILE_DATA,
|
||||
SDP_STATE_RX_FILE_DATA_BUSY,
|
||||
SDP_STATE_TX_SEC_CONF,
|
||||
SDP_STATE_TX_SEC_CONF_BUSY,
|
||||
SDP_STATE_TX_REGISTER,
|
||||
|
@ -114,8 +120,12 @@ struct f_sdp {
|
|||
/* EP1 IN */
|
||||
struct usb_ep *in_ep;
|
||||
struct usb_request *in_req;
|
||||
/* EP1 OUT */
|
||||
struct usb_ep *out_ep;
|
||||
struct usb_request *out_req;
|
||||
|
||||
bool configuration_done;
|
||||
bool ep_int_enable;
|
||||
};
|
||||
|
||||
static struct f_sdp *sdp_func;
|
||||
|
@ -129,7 +139,7 @@ static struct usb_interface_descriptor sdp_intf_runtime = {
|
|||
.bLength = sizeof(sdp_intf_runtime),
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 1,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_HID,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
|
@ -159,10 +169,49 @@ static struct usb_endpoint_descriptor in_desc = {
|
|||
.bInterval = 1,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT, /*USB_DT_CS_ENDPOINT*/
|
||||
|
||||
.bEndpointAddress = 1 | USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor in_hs_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT, /*USB_DT_CS_ENDPOINT*/
|
||||
|
||||
.bEndpointAddress = 1 | USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = 512,
|
||||
.bInterval = 3,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor out_hs_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT, /*USB_DT_CS_ENDPOINT*/
|
||||
|
||||
.bEndpointAddress = 1 | USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = SDP_HID_PACKET_SIZE_EP1,
|
||||
.bInterval = 3,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *sdp_runtime_descs[] = {
|
||||
(struct usb_descriptor_header *)&sdp_intf_runtime,
|
||||
(struct usb_descriptor_header *)&sdp_hid_desc,
|
||||
(struct usb_descriptor_header *)&in_desc,
|
||||
(struct usb_descriptor_header *)&out_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *sdp_runtime_hs_descs[] = {
|
||||
(struct usb_descriptor_header *)&sdp_intf_runtime,
|
||||
(struct usb_descriptor_header *)&sdp_hid_desc,
|
||||
(struct usb_descriptor_header *)&in_hs_desc,
|
||||
(struct usb_descriptor_header *)&out_hs_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -328,7 +377,7 @@ static void sdp_rx_data_complete(struct usb_ep *ep, struct usb_request *req)
|
|||
int status = req->status;
|
||||
u8 *data = req->buf;
|
||||
u8 report = data[0];
|
||||
int datalen = req->length - 1;
|
||||
int datalen = req->actual - 1;
|
||||
|
||||
if (status != 0) {
|
||||
pr_err("Status: %d\n", status);
|
||||
|
@ -351,13 +400,15 @@ static void sdp_rx_data_complete(struct usb_ep *ep, struct usb_request *req)
|
|||
sdp->dnl_bytes_remaining -= datalen;
|
||||
}
|
||||
|
||||
if (sdp->state == SDP_STATE_RX_FILE_DATA) {
|
||||
if (sdp->state == SDP_STATE_RX_FILE_DATA_BUSY) {
|
||||
memcpy(sdp_ptr(sdp->dnl_address), req->buf + 1, datalen);
|
||||
sdp->dnl_address += datalen;
|
||||
}
|
||||
|
||||
if (sdp->dnl_bytes_remaining)
|
||||
if (sdp->dnl_bytes_remaining) {
|
||||
sdp->state = SDP_STATE_RX_FILE_DATA;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
env_set_hex("filesize", sdp->dnl_bytes);
|
||||
|
@ -365,7 +416,7 @@ static void sdp_rx_data_complete(struct usb_ep *ep, struct usb_request *req)
|
|||
printf("done\n");
|
||||
|
||||
switch (sdp->state) {
|
||||
case SDP_STATE_RX_FILE_DATA:
|
||||
case SDP_STATE_RX_FILE_DATA_BUSY:
|
||||
sdp->state = SDP_STATE_TX_SEC_CONF;
|
||||
break;
|
||||
case SDP_STATE_RX_DCD_DATA:
|
||||
|
@ -446,10 +497,12 @@ static int sdp_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
|
|||
case 1:
|
||||
value = SDP_COMMAND_LEN + 1;
|
||||
req->complete = sdp_rx_command_complete;
|
||||
sdp_func->ep_int_enable = false;
|
||||
break;
|
||||
case 2:
|
||||
value = len;
|
||||
req->complete = sdp_rx_data_complete;
|
||||
sdp_func->state = SDP_STATE_RX_FILE_DATA_BUSY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -480,16 +533,29 @@ static int sdp_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
return id;
|
||||
sdp_intf_runtime.bInterfaceNumber = id;
|
||||
|
||||
struct usb_ep *ep;
|
||||
struct usb_ep *ep_in, *ep_out;
|
||||
|
||||
/* allocate instance-specific endpoints */
|
||||
ep = usb_ep_autoconfig(gadget, &in_desc);
|
||||
if (!ep) {
|
||||
ep_in = usb_ep_autoconfig(gadget, &in_desc);
|
||||
if (!ep_in) {
|
||||
rv = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
sdp->in_ep = ep; /* Store IN EP for enabling @ setup */
|
||||
ep_out = usb_ep_autoconfig(gadget, &out_desc);
|
||||
if (!ep_out) {
|
||||
rv = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (gadget_is_dualspeed(gadget)) {
|
||||
/* Assume endpoint addresses are the same for both speeds */
|
||||
in_hs_desc.bEndpointAddress = in_desc.bEndpointAddress;
|
||||
out_hs_desc.bEndpointAddress = out_desc.bEndpointAddress;
|
||||
}
|
||||
|
||||
sdp->in_ep = ep_in; /* Store IN EP for enabling @ setup */
|
||||
sdp->out_ep = ep_out;
|
||||
|
||||
cdev->req->context = sdp;
|
||||
|
||||
|
@ -522,18 +588,29 @@ static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
|
|||
}
|
||||
|
||||
|
||||
static struct usb_request *sdp_start_ep(struct usb_ep *ep)
|
||||
static struct usb_request *sdp_start_ep(struct usb_ep *ep, bool in)
|
||||
{
|
||||
struct usb_request *req;
|
||||
|
||||
req = alloc_ep_req(ep, 64);
|
||||
if (in)
|
||||
req = alloc_ep_req(ep, 65);
|
||||
else
|
||||
req = alloc_ep_req(ep, 2048);
|
||||
/*
|
||||
* OUT endpoint request length should be an integral multiple of
|
||||
* maxpacket size 1024, else we break on certain controllers like
|
||||
* DWC3 that expect bulk OUT requests to be divisible by maxpacket size.
|
||||
*/
|
||||
debug("%s: ep:%p req:%p\n", __func__, ep, req);
|
||||
|
||||
if (!req)
|
||||
return NULL;
|
||||
|
||||
memset(req->buf, 0, req->length);
|
||||
req->complete = sdp_tx_complete;
|
||||
if (in)
|
||||
req->complete = sdp_tx_complete;
|
||||
else
|
||||
req->complete = sdp_rx_command_complete;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
@ -541,20 +618,32 @@ static int sdp_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
|||
{
|
||||
struct f_sdp *sdp = func_to_sdp(f);
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
struct usb_gadget *gadget = cdev->gadget;
|
||||
int result;
|
||||
|
||||
debug("%s: intf: %d alt: %d\n", __func__, intf, alt);
|
||||
|
||||
result = usb_ep_enable(sdp->in_ep, &in_desc);
|
||||
if (gadget_is_dualspeed(gadget) && gadget->speed == USB_SPEED_HIGH) {
|
||||
result = usb_ep_enable(sdp->in_ep, &in_hs_desc);
|
||||
result |= usb_ep_enable(sdp->out_ep, &out_hs_desc);
|
||||
} else {
|
||||
result = usb_ep_enable(sdp->in_ep, &in_desc);
|
||||
result |= usb_ep_enable(sdp->out_ep, &out_desc);
|
||||
}
|
||||
if (result)
|
||||
return result;
|
||||
sdp->in_req = sdp_start_ep(sdp->in_ep);
|
||||
|
||||
sdp->in_req = sdp_start_ep(sdp->in_ep, true);
|
||||
sdp->in_req->context = sdp;
|
||||
sdp->out_req = sdp_start_ep(sdp->out_ep, false);
|
||||
sdp->out_req->context = sdp;
|
||||
|
||||
sdp->in_ep->driver_data = cdev; /* claim */
|
||||
sdp->out_ep->driver_data = cdev; /* claim */
|
||||
|
||||
sdp->altsetting = alt;
|
||||
sdp->state = SDP_STATE_IDLE;
|
||||
sdp->ep_int_enable = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -571,11 +660,18 @@ static void sdp_disable(struct usb_function *f)
|
|||
struct f_sdp *sdp = func_to_sdp(f);
|
||||
|
||||
usb_ep_disable(sdp->in_ep);
|
||||
usb_ep_disable(sdp->out_ep);
|
||||
|
||||
if (sdp->in_req) {
|
||||
free(sdp->in_req);
|
||||
free(sdp->in_req->buf);
|
||||
usb_ep_free_request(sdp->in_ep, sdp->in_req);
|
||||
sdp->in_req = NULL;
|
||||
}
|
||||
if (sdp->out_req) {
|
||||
free(sdp->out_req->buf);
|
||||
usb_ep_free_request(sdp->out_ep, sdp->out_req);
|
||||
sdp->out_req = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int sdp_bind_config(struct usb_configuration *c)
|
||||
|
@ -591,7 +687,7 @@ static int sdp_bind_config(struct usb_configuration *c)
|
|||
memset(sdp_func, 0, sizeof(*sdp_func));
|
||||
|
||||
sdp_func->usb_function.name = "sdp";
|
||||
sdp_func->usb_function.hs_descriptors = sdp_runtime_descs;
|
||||
sdp_func->usb_function.hs_descriptors = sdp_runtime_hs_descs;
|
||||
sdp_func->usb_function.descriptors = sdp_runtime_descs;
|
||||
sdp_func->usb_function.bind = sdp_bind;
|
||||
sdp_func->usb_function.unbind = sdp_unbind;
|
||||
|
@ -641,19 +737,43 @@ static u32 sdp_jump_imxheader(void *address)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
static ulong sdp_fit_read(struct spl_load_info *load, ulong sector,
|
||||
ulong count, void *buf)
|
||||
static ulong sdp_load_read(struct spl_load_info *load, ulong sector,
|
||||
ulong count, void *buf)
|
||||
{
|
||||
debug("%s: sector %lx, count %lx, buf %lx\n",
|
||||
__func__, sector, count, (ulong)buf);
|
||||
memcpy(buf, (void *)(load->dev + sector), count);
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
static ulong search_fit_header(ulong p, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i += 4) {
|
||||
if (genimg_get_format((const void *)(p + i)) == IMAGE_FORMAT_FIT)
|
||||
return p + i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong search_container_header(ulong p, int size)
|
||||
{
|
||||
int i;
|
||||
u8 *hdr;
|
||||
|
||||
for (i = 0; i < size; i += 4) {
|
||||
hdr = (u8 *)(p + i);
|
||||
if (*(hdr + 3) == 0x87 && *hdr == 0)
|
||||
if (*(hdr + 1) != 0 || *(hdr + 2) != 0)
|
||||
return p + i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void sdp_handle_in_ep(struct spl_image_info *spl_image)
|
||||
static int sdp_handle_in_ep(struct spl_image_info *spl_image)
|
||||
{
|
||||
u8 *data = sdp_func->in_req->buf;
|
||||
u32 status;
|
||||
|
@ -705,6 +825,15 @@ static void sdp_handle_in_ep(struct spl_image_info *spl_image)
|
|||
/* If imx header fails, try some U-Boot specific headers */
|
||||
if (status) {
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER))
|
||||
sdp_func->jmp_address = (u32)search_container_header((ulong)sdp_func->jmp_address, sdp_func->dnl_bytes);
|
||||
else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT))
|
||||
sdp_func->jmp_address = (u32)search_fit_header((ulong)sdp_func->jmp_address, sdp_func->dnl_bytes);
|
||||
if (sdp_func->jmp_address == 0)
|
||||
panic("Error in search header, failed to jump\n");
|
||||
|
||||
printf("Found header at 0x%08x\n", sdp_func->jmp_address);
|
||||
|
||||
image_header_t *header =
|
||||
sdp_ptr(sdp_func->jmp_address);
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
|
@ -714,13 +843,23 @@ static void sdp_handle_in_ep(struct spl_image_info *spl_image)
|
|||
debug("Found FIT\n");
|
||||
load.dev = header;
|
||||
load.bl_len = 1;
|
||||
load.read = sdp_fit_read;
|
||||
load.read = sdp_load_read;
|
||||
spl_load_simple_fit(spl_image, &load, 0,
|
||||
header);
|
||||
|
||||
return;
|
||||
return SDP_EXIT;
|
||||
}
|
||||
#endif
|
||||
if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
|
||||
struct spl_load_info load;
|
||||
|
||||
load.dev = header;
|
||||
load.bl_len = 1;
|
||||
load.read = sdp_load_read;
|
||||
spl_load_imx_container(spl_image, &load, 0);
|
||||
return SDP_EXIT;
|
||||
}
|
||||
|
||||
/* In SPL, allow jumps to U-Boot images */
|
||||
struct spl_image_info spl_image = {};
|
||||
spl_parse_image_header(&spl_image, header);
|
||||
|
@ -743,6 +882,29 @@ static void sdp_handle_in_ep(struct spl_image_info *spl_image)
|
|||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdp_handle_out_ep(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (sdp_func->state == SDP_STATE_IDLE) {
|
||||
sdp_func->out_req->complete = sdp_rx_command_complete;
|
||||
rc = usb_ep_queue(sdp_func->out_ep, sdp_func->out_req, 0);
|
||||
if (rc)
|
||||
printf("error in submission: %s\n",
|
||||
sdp_func->out_ep->name);
|
||||
sdp_func->state = SDP_STATE_RX_CMD;
|
||||
} else if (sdp_func->state == SDP_STATE_RX_FILE_DATA) {
|
||||
sdp_func->out_req->complete = sdp_rx_data_complete;
|
||||
rc = usb_ep_queue(sdp_func->out_ep, sdp_func->out_req, 0);
|
||||
if (rc)
|
||||
printf("error in submission: %s\n",
|
||||
sdp_func->out_ep->name);
|
||||
sdp_func->state = SDP_STATE_RX_FILE_DATA_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
|
@ -751,6 +913,7 @@ int sdp_handle(int controller_index)
|
|||
int spl_sdp_handle(int controller_index, struct spl_image_info *spl_image)
|
||||
#endif
|
||||
{
|
||||
int flag = 0;
|
||||
printf("SDP: handle requests...\n");
|
||||
while (1) {
|
||||
if (ctrlc()) {
|
||||
|
@ -758,19 +921,19 @@ int spl_sdp_handle(int controller_index, struct spl_image_info *spl_image)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
if (spl_image->flags & SPL_FIT_FOUND)
|
||||
if (flag == SDP_EXIT)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
WATCHDOG_RESET();
|
||||
usb_gadget_handle_interrupts(controller_index);
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
sdp_handle_in_ep(spl_image);
|
||||
flag = sdp_handle_in_ep(spl_image);
|
||||
#else
|
||||
sdp_handle_in_ep(NULL);
|
||||
flag = sdp_handle_in_ep(NULL);
|
||||
#endif
|
||||
if (sdp_func->ep_int_enable)
|
||||
sdp_handle_out_ep();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,6 +155,12 @@
|
|||
#define gadget_is_cdns3(g) 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_GADGET_MAX3420
|
||||
#define gadget_is_max3420(g) (!strcmp("max3420-udc", (g)->name))
|
||||
#else
|
||||
#define gadget_is_max3420(g) 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* usb_gadget_controller_number - support bcdDevice id convention
|
||||
* @gadget: the controller being driven
|
||||
|
@ -216,5 +222,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
|
|||
return 0x23;
|
||||
else if (gadget_is_cdns3(gadget))
|
||||
return 0x24;
|
||||
else if (gadget_is_max3420(gadget))
|
||||
return 0x25;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
|
875
drivers/usb/gadget/max3420_udc.c
Normal file
875
drivers/usb/gadget/max3420_udc.c
Normal file
|
@ -0,0 +1,875 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <malloc.h>
|
||||
#include <spi.h>
|
||||
#include <dm.h>
|
||||
#include <g_dnl.h>
|
||||
|
||||
#define MAX3420_MAX_EPS 4
|
||||
#define EP_MAX_PACKET 64 /* Same for all Endpoints */
|
||||
#define EPNAME_SIZE 16 /* Buffer size for endpoint name */
|
||||
|
||||
#define MAX3420_SPI_DIR_RD 0 /* read register from MAX3420 */
|
||||
#define MAX3420_SPI_DIR_WR 1 /* write register to MAX3420 */
|
||||
|
||||
/* SPI commands: */
|
||||
#define MAX3420_SPI_ACK_MASK BIT(0)
|
||||
#define MAX3420_SPI_DIR_MASK BIT(1)
|
||||
#define MAX3420_SPI_REG_MASK GENMASK(7, 3)
|
||||
|
||||
#define MAX3420_REG_EP0FIFO 0
|
||||
#define MAX3420_REG_EP1FIFO 1
|
||||
#define MAX3420_REG_EP2FIFO 2
|
||||
#define MAX3420_REG_EP3FIFO 3
|
||||
#define MAX3420_REG_SUDFIFO 4
|
||||
#define MAX3420_REG_EP0BC 5
|
||||
#define MAX3420_REG_EP1BC 6
|
||||
#define MAX3420_REG_EP2BC 7
|
||||
#define MAX3420_REG_EP3BC 8
|
||||
|
||||
#define MAX3420_REG_EPSTALLS 9
|
||||
#define bACKSTAT BIT(6)
|
||||
#define bSTLSTAT BIT(5)
|
||||
#define bSTLEP3IN BIT(4)
|
||||
#define bSTLEP2IN BIT(3)
|
||||
#define bSTLEP1OUT BIT(2)
|
||||
#define bSTLEP0OUT BIT(1)
|
||||
#define bSTLEP0IN BIT(0)
|
||||
|
||||
#define MAX3420_REG_CLRTOGS 10
|
||||
#define bEP3DISAB BIT(7)
|
||||
#define bEP2DISAB BIT(6)
|
||||
#define bEP1DISAB BIT(5)
|
||||
#define bCTGEP3IN BIT(4)
|
||||
#define bCTGEP2IN BIT(3)
|
||||
#define bCTGEP1OUT BIT(2)
|
||||
|
||||
#define MAX3420_REG_EPIRQ 11
|
||||
#define MAX3420_REG_EPIEN 12
|
||||
#define bSUDAVIRQ BIT(5)
|
||||
#define bIN3BAVIRQ BIT(4)
|
||||
#define bIN2BAVIRQ BIT(3)
|
||||
#define bOUT1DAVIRQ BIT(2)
|
||||
#define bOUT0DAVIRQ BIT(1)
|
||||
#define bIN0BAVIRQ BIT(0)
|
||||
|
||||
#define MAX3420_REG_USBIRQ 13
|
||||
#define MAX3420_REG_USBIEN 14
|
||||
#define bOSCOKIRQ BIT(0)
|
||||
#define bRWUDNIRQ BIT(1)
|
||||
#define bBUSACTIRQ BIT(2)
|
||||
#define bURESIRQ BIT(3)
|
||||
#define bSUSPIRQ BIT(4)
|
||||
#define bNOVBUSIRQ BIT(5)
|
||||
#define bVBUSIRQ BIT(6)
|
||||
#define bURESDNIRQ BIT(7)
|
||||
|
||||
#define MAX3420_REG_USBCTL 15
|
||||
#define bHOSCSTEN BIT(7)
|
||||
#define bVBGATE BIT(6)
|
||||
#define bCHIPRES BIT(5)
|
||||
#define bPWRDOWN BIT(4)
|
||||
#define bCONNECT BIT(3)
|
||||
#define bSIGRWU BIT(2)
|
||||
|
||||
#define MAX3420_REG_CPUCTL 16
|
||||
#define bIE BIT(0)
|
||||
|
||||
#define MAX3420_REG_PINCTL 17
|
||||
#define bEP3INAK BIT(7)
|
||||
#define bEP2INAK BIT(6)
|
||||
#define bEP0INAK BIT(5)
|
||||
#define bFDUPSPI BIT(4)
|
||||
#define bINTLEVEL BIT(3)
|
||||
#define bPOSINT BIT(2)
|
||||
#define bGPXB BIT(1)
|
||||
#define bGPXA BIT(0)
|
||||
|
||||
#define MAX3420_REG_REVISION 18
|
||||
|
||||
#define MAX3420_REG_FNADDR 19
|
||||
#define FNADDR_MASK 0x7f
|
||||
|
||||
#define MAX3420_REG_IOPINS 20
|
||||
#define MAX3420_REG_IOPINS2 21
|
||||
#define MAX3420_REG_GPINIRQ 22
|
||||
#define MAX3420_REG_GPINIEN 23
|
||||
#define MAX3420_REG_GPINPOL 24
|
||||
#define MAX3420_REG_HIRQ 25
|
||||
#define MAX3420_REG_HIEN 26
|
||||
#define MAX3420_REG_MODE 27
|
||||
#define MAX3420_REG_PERADDR 28
|
||||
#define MAX3420_REG_HCTL 29
|
||||
#define MAX3420_REG_HXFR 30
|
||||
#define MAX3420_REG_HRSL 31
|
||||
|
||||
struct max3420_req {
|
||||
struct usb_request usb_req;
|
||||
struct list_head queue;
|
||||
struct max3420_ep *ep;
|
||||
};
|
||||
|
||||
struct max3420_ep {
|
||||
struct max3420_udc *udc;
|
||||
struct list_head queue;
|
||||
char name[EPNAME_SIZE];
|
||||
unsigned int maxpacket;
|
||||
struct usb_ep ep_usb;
|
||||
int halted;
|
||||
int id;
|
||||
};
|
||||
|
||||
struct max3420_udc {
|
||||
struct max3420_ep ep[MAX3420_MAX_EPS];
|
||||
struct usb_gadget_driver *driver;
|
||||
bool softconnect;
|
||||
struct usb_ctrlrequest setup;
|
||||
struct max3420_req ep0req;
|
||||
struct usb_gadget gadget;
|
||||
struct spi_slave *slave;
|
||||
struct udevice *dev;
|
||||
u8 ep0buf[64];
|
||||
int remote_wkp;
|
||||
bool suspended;
|
||||
};
|
||||
|
||||
#define to_max3420_req(r) container_of((r), struct max3420_req, usb_req)
|
||||
#define to_max3420_ep(e) container_of((e), struct max3420_ep, ep_usb)
|
||||
#define to_udc(g) container_of((g), struct max3420_udc, gadget)
|
||||
|
||||
static void spi_ack_ctrl(struct max3420_udc *udc)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[1];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_ACK_MASK, 1);
|
||||
spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_ONCE);
|
||||
}
|
||||
|
||||
static u8 spi_rd8_ack(struct max3420_udc *udc, u8 reg, int ackstat)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[2], rxdata[2];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
|
||||
FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_RD) |
|
||||
FIELD_PREP(MAX3420_SPI_ACK_MASK, ackstat ? 1 : 0);
|
||||
|
||||
rxdata[0] = 0;
|
||||
rxdata[1] = 0;
|
||||
spi_xfer(slave, sizeof(txdata), txdata, rxdata, SPI_XFER_ONCE);
|
||||
|
||||
return rxdata[1];
|
||||
}
|
||||
|
||||
static u8 spi_rd8(struct max3420_udc *udc, u8 reg)
|
||||
{
|
||||
return spi_rd8_ack(udc, reg, 0);
|
||||
}
|
||||
|
||||
static void spi_wr8_ack(struct max3420_udc *udc, u8 reg, u8 val, int ackstat)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[2];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
|
||||
FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_WR) |
|
||||
FIELD_PREP(MAX3420_SPI_ACK_MASK, ackstat ? 1 : 0);
|
||||
txdata[1] = val;
|
||||
|
||||
spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_ONCE);
|
||||
}
|
||||
|
||||
static void spi_wr8(struct max3420_udc *udc, u8 reg, u8 val)
|
||||
{
|
||||
spi_wr8_ack(udc, reg, val, 0);
|
||||
}
|
||||
|
||||
static void spi_rd_buf(struct max3420_udc *udc, u8 reg, void *buf, u8 len)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[1];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
|
||||
FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_RD);
|
||||
|
||||
spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_BEGIN);
|
||||
spi_xfer(slave, len * 8, NULL, buf, SPI_XFER_END);
|
||||
}
|
||||
|
||||
static void spi_wr_buf(struct max3420_udc *udc, u8 reg, void *buf, u8 len)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[1];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
|
||||
FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_WR);
|
||||
|
||||
spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_BEGIN);
|
||||
spi_xfer(slave, len * 8, buf, NULL, SPI_XFER_END);
|
||||
}
|
||||
|
||||
/* 0 if not-connected */
|
||||
int g_dnl_board_usb_cable_connected(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void spi_max3420_enable(struct max3420_ep *ep, int enable)
|
||||
{
|
||||
struct max3420_udc *udc = ep->udc;
|
||||
u8 epdis, epien;
|
||||
|
||||
if (ep->id == 0)
|
||||
return;
|
||||
|
||||
epien = spi_rd8(udc, MAX3420_REG_EPIEN);
|
||||
epdis = spi_rd8(udc, MAX3420_REG_CLRTOGS);
|
||||
|
||||
if (enable) {
|
||||
epdis &= ~BIT(ep->id + 4);
|
||||
epien |= BIT(ep->id + 1);
|
||||
} else {
|
||||
epdis |= BIT(ep->id + 4);
|
||||
epien &= ~BIT(ep->id + 1);
|
||||
}
|
||||
|
||||
spi_wr8(udc, MAX3420_REG_CLRTOGS, epdis);
|
||||
spi_wr8(udc, MAX3420_REG_EPIEN, epien);
|
||||
}
|
||||
|
||||
static int
|
||||
max3420_ep_enable(struct usb_ep *_ep,
|
||||
const struct usb_endpoint_descriptor *desc)
|
||||
{
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
|
||||
_ep->desc = desc;
|
||||
_ep->maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
|
||||
|
||||
spi_max3420_enable(ep, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void max3420_req_done(struct max3420_req *req, int status)
|
||||
{
|
||||
struct max3420_ep *ep = req->ep;
|
||||
|
||||
if (req->usb_req.status == -EINPROGRESS)
|
||||
req->usb_req.status = status;
|
||||
else
|
||||
status = req->usb_req.status;
|
||||
|
||||
if (status && status != -ESHUTDOWN)
|
||||
dev_err(ep->udc->dev, "%s done %p, status %d\n",
|
||||
ep->ep_usb.name, req, status);
|
||||
|
||||
if (req->usb_req.complete)
|
||||
req->usb_req.complete(&ep->ep_usb, &req->usb_req);
|
||||
}
|
||||
|
||||
static void max3420_ep_nuke(struct max3420_ep *ep, int status)
|
||||
{
|
||||
struct max3420_req *req, *r;
|
||||
|
||||
list_for_each_entry_safe(req, r, &ep->queue, queue) {
|
||||
list_del_init(&req->queue);
|
||||
max3420_req_done(req, status);
|
||||
}
|
||||
}
|
||||
|
||||
static int max3420_ep_disable(struct usb_ep *_ep)
|
||||
{
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
|
||||
_ep->desc = NULL;
|
||||
max3420_ep_nuke(ep, -ESHUTDOWN);
|
||||
spi_max3420_enable(ep, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct usb_request *
|
||||
max3420_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
|
||||
{
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
struct max3420_req *req = kzalloc(sizeof(*req), gfp_flags);
|
||||
|
||||
if (!req)
|
||||
return NULL;
|
||||
|
||||
req->ep = ep;
|
||||
INIT_LIST_HEAD(&req->queue);
|
||||
|
||||
return &req->usb_req;
|
||||
}
|
||||
|
||||
static void
|
||||
max3420_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
|
||||
{
|
||||
kfree(to_max3420_req(_req));
|
||||
}
|
||||
|
||||
static int
|
||||
max3420_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
||||
{
|
||||
struct max3420_req *req = to_max3420_req(_req);
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
|
||||
_req->status = -EINPROGRESS;
|
||||
_req->actual = 0;
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
||||
{
|
||||
struct max3420_req *req = to_max3420_req(_req);
|
||||
|
||||
list_del_init(&req->queue);
|
||||
max3420_req_done(req, -ECONNRESET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_ep_set_halt(struct usb_ep *_ep, int halt)
|
||||
{
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
struct max3420_udc *udc = ep->udc;
|
||||
u8 epstalls;
|
||||
|
||||
if (ep->id == 0) /* can't stall EP0 */
|
||||
return 0;
|
||||
|
||||
epstalls = spi_rd8(udc, MAX3420_REG_EPSTALLS);
|
||||
if (halt) {
|
||||
ep->halted = 1;
|
||||
epstalls |= BIT(ep->id + 1);
|
||||
} else {
|
||||
u8 clrtogs;
|
||||
|
||||
ep->halted = 0;
|
||||
epstalls &= ~BIT(ep->id + 1);
|
||||
clrtogs = spi_rd8(udc, MAX3420_REG_CLRTOGS);
|
||||
clrtogs |= BIT(ep->id + 1);
|
||||
spi_wr8(udc, MAX3420_REG_CLRTOGS, clrtogs);
|
||||
}
|
||||
spi_wr8(udc, MAX3420_REG_EPSTALLS, epstalls | bACKSTAT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct usb_ep_ops max3420_ep_ops = {
|
||||
.enable = max3420_ep_enable,
|
||||
.disable = max3420_ep_disable,
|
||||
.alloc_request = max3420_ep_alloc_request,
|
||||
.free_request = max3420_ep_free_request,
|
||||
.queue = max3420_ep_queue,
|
||||
.dequeue = max3420_ep_dequeue,
|
||||
.set_halt = max3420_ep_set_halt,
|
||||
};
|
||||
|
||||
static void __max3420_stop(struct max3420_udc *udc)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
/* Disable IRQ to CPU */
|
||||
spi_wr8(udc, MAX3420_REG_CPUCTL, 0);
|
||||
|
||||
val = spi_rd8(udc, MAX3420_REG_USBCTL);
|
||||
val |= bPWRDOWN;
|
||||
val |= bHOSCSTEN;
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, val);
|
||||
}
|
||||
|
||||
static void __max3420_start(struct max3420_udc *udc)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
/* configure SPI */
|
||||
spi_wr8(udc, MAX3420_REG_PINCTL, bFDUPSPI);
|
||||
|
||||
/* Chip Reset */
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, bCHIPRES);
|
||||
mdelay(5);
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, 0);
|
||||
|
||||
/* Poll for OSC to stabilize */
|
||||
while (1) {
|
||||
val = spi_rd8(udc, MAX3420_REG_USBIRQ);
|
||||
if (val & bOSCOKIRQ)
|
||||
break;
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
/* Enable PULL-UP only when Vbus detected */
|
||||
val = spi_rd8(udc, MAX3420_REG_USBCTL);
|
||||
val |= bVBGATE | bCONNECT;
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, val);
|
||||
|
||||
val = bURESDNIRQ | bURESIRQ;
|
||||
spi_wr8(udc, MAX3420_REG_USBIEN, val);
|
||||
|
||||
/* Enable only EP0 interrupts */
|
||||
val = bIN0BAVIRQ | bOUT0DAVIRQ | bSUDAVIRQ;
|
||||
spi_wr8(udc, MAX3420_REG_EPIEN, val);
|
||||
|
||||
/* Enable IRQ to CPU */
|
||||
spi_wr8(udc, MAX3420_REG_CPUCTL, bIE);
|
||||
}
|
||||
|
||||
static int max3420_udc_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct max3420_udc *udc = to_udc(gadget);
|
||||
|
||||
udc->driver = driver;
|
||||
udc->remote_wkp = 0;
|
||||
udc->softconnect = true;
|
||||
|
||||
__max3420_start(udc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_udc_stop(struct usb_gadget *gadget)
|
||||
{
|
||||
struct max3420_udc *udc = to_udc(gadget);
|
||||
|
||||
udc->driver = NULL;
|
||||
udc->softconnect = false;
|
||||
|
||||
__max3420_stop(udc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_wakeup(struct usb_gadget *gadget)
|
||||
{
|
||||
struct max3420_udc *udc = to_udc(gadget);
|
||||
u8 usbctl;
|
||||
|
||||
/* Only if wakeup allowed by host */
|
||||
if (!udc->remote_wkp || !udc->suspended)
|
||||
return 0;
|
||||
|
||||
/* Set Remote-Wakeup Signal*/
|
||||
usbctl = spi_rd8(udc, MAX3420_REG_USBCTL);
|
||||
usbctl |= bSIGRWU;
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, usbctl);
|
||||
|
||||
mdelay(5);
|
||||
|
||||
/* Clear Remote-WkUp Signal*/
|
||||
usbctl = spi_rd8(udc, MAX3420_REG_USBCTL);
|
||||
usbctl &= ~bSIGRWU;
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, usbctl);
|
||||
|
||||
udc->suspended = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct usb_gadget_ops max3420_udc_ops = {
|
||||
.udc_start = max3420_udc_start,
|
||||
.udc_stop = max3420_udc_stop,
|
||||
.wakeup = max3420_wakeup,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor ep0_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_CONTROL,
|
||||
.wMaxPacketSize = cpu_to_le16(EP_MAX_PACKET),
|
||||
};
|
||||
|
||||
static void max3420_getstatus(struct max3420_udc *udc)
|
||||
{
|
||||
struct max3420_ep *ep;
|
||||
u16 status = 0;
|
||||
|
||||
switch (udc->setup.bRequestType & USB_RECIP_MASK) {
|
||||
case USB_RECIP_DEVICE:
|
||||
/* Get device status */
|
||||
status = 0 << USB_DEVICE_SELF_POWERED;
|
||||
status |= (udc->remote_wkp << USB_DEVICE_REMOTE_WAKEUP);
|
||||
break;
|
||||
case USB_RECIP_INTERFACE:
|
||||
if (udc->driver->setup(&udc->gadget, &udc->setup) < 0)
|
||||
goto stall;
|
||||
break;
|
||||
case USB_RECIP_ENDPOINT:
|
||||
ep = &udc->ep[udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK];
|
||||
if (ep->halted)
|
||||
status = 1 << USB_ENDPOINT_HALT;
|
||||
break;
|
||||
default:
|
||||
goto stall;
|
||||
}
|
||||
|
||||
status = cpu_to_le16(status);
|
||||
spi_wr_buf(udc, MAX3420_REG_EP0FIFO, &status, 2);
|
||||
spi_wr8_ack(udc, MAX3420_REG_EP0BC, 2, 1);
|
||||
return;
|
||||
stall:
|
||||
dev_err(udc->dev, "Can't respond to getstatus request\n");
|
||||
spi_wr8(udc, MAX3420_REG_EPSTALLS, bSTLEP0IN | bSTLEP0OUT | bSTLSTAT);
|
||||
}
|
||||
|
||||
static void max3420_set_clear_feature(struct max3420_udc *udc)
|
||||
{
|
||||
int set = udc->setup.bRequest == USB_REQ_SET_FEATURE;
|
||||
struct max3420_ep *ep;
|
||||
int id;
|
||||
|
||||
switch (udc->setup.bRequestType) {
|
||||
case USB_RECIP_DEVICE:
|
||||
if (udc->setup.wValue != USB_DEVICE_REMOTE_WAKEUP)
|
||||
break;
|
||||
|
||||
if (udc->setup.bRequest == USB_REQ_SET_FEATURE)
|
||||
udc->remote_wkp = 1;
|
||||
else
|
||||
udc->remote_wkp = 0;
|
||||
|
||||
return spi_ack_ctrl(udc);
|
||||
|
||||
case USB_RECIP_ENDPOINT:
|
||||
if (udc->setup.wValue != USB_ENDPOINT_HALT)
|
||||
break;
|
||||
|
||||
id = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK;
|
||||
ep = &udc->ep[id];
|
||||
|
||||
max3420_ep_set_halt(&ep->ep_usb, set);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dev_err(udc->dev, "Can't respond to SET/CLEAR FEATURE\n");
|
||||
spi_wr8(udc, MAX3420_REG_EPSTALLS, bSTLEP0IN | bSTLEP0OUT | bSTLSTAT);
|
||||
}
|
||||
|
||||
static void max3420_handle_setup(struct max3420_udc *udc)
|
||||
{
|
||||
struct usb_ctrlrequest setup;
|
||||
u8 addr;
|
||||
|
||||
spi_rd_buf(udc, MAX3420_REG_SUDFIFO, (void *)&setup, 8);
|
||||
|
||||
udc->setup = setup;
|
||||
udc->setup.wValue = cpu_to_le16(setup.wValue);
|
||||
udc->setup.wIndex = cpu_to_le16(setup.wIndex);
|
||||
udc->setup.wLength = cpu_to_le16(setup.wLength);
|
||||
|
||||
switch (udc->setup.bRequest) {
|
||||
case USB_REQ_GET_STATUS:
|
||||
/* Data+Status phase form udc */
|
||||
if ((udc->setup.bRequestType &
|
||||
(USB_DIR_IN | USB_TYPE_MASK)) !=
|
||||
(USB_DIR_IN | USB_TYPE_STANDARD)) {
|
||||
break;
|
||||
}
|
||||
return max3420_getstatus(udc);
|
||||
case USB_REQ_SET_ADDRESS:
|
||||
/* Status phase from udc */
|
||||
if (udc->setup.bRequestType != (USB_DIR_OUT |
|
||||
USB_TYPE_STANDARD | USB_RECIP_DEVICE))
|
||||
break;
|
||||
addr = spi_rd8_ack(udc, MAX3420_REG_FNADDR, 1);
|
||||
dev_dbg(udc->dev, "Assigned Address=%d/%d\n",
|
||||
udc->setup.wValue, addr);
|
||||
return;
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
case USB_REQ_SET_FEATURE:
|
||||
/* Requests with no data phase, status phase from udc */
|
||||
if ((udc->setup.bRequestType & USB_TYPE_MASK)
|
||||
!= USB_TYPE_STANDARD)
|
||||
break;
|
||||
return max3420_set_clear_feature(udc);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (udc->driver->setup(&udc->gadget, &setup) < 0) {
|
||||
/* Stall EP0 */
|
||||
spi_wr8(udc, MAX3420_REG_EPSTALLS,
|
||||
bSTLEP0IN | bSTLEP0OUT | bSTLSTAT);
|
||||
}
|
||||
}
|
||||
|
||||
static int do_data(struct max3420_udc *udc, int ep_id, int in)
|
||||
{
|
||||
struct max3420_ep *ep = &udc->ep[ep_id];
|
||||
struct max3420_req *req;
|
||||
int done, length, psz;
|
||||
void *buf;
|
||||
|
||||
if (list_empty(&ep->queue))
|
||||
return 0;
|
||||
|
||||
req = list_first_entry(&ep->queue, struct max3420_req, queue);
|
||||
buf = req->usb_req.buf + req->usb_req.actual;
|
||||
|
||||
psz = ep->ep_usb.maxpacket;
|
||||
length = req->usb_req.length - req->usb_req.actual;
|
||||
length = min(length, psz);
|
||||
|
||||
if (length == 0) {
|
||||
done = 1;
|
||||
goto xfer_done;
|
||||
}
|
||||
|
||||
done = 0;
|
||||
if (in) {
|
||||
spi_wr_buf(udc, MAX3420_REG_EP0FIFO + ep_id, buf, length);
|
||||
spi_wr8(udc, MAX3420_REG_EP0BC + ep_id, length);
|
||||
if (length < psz)
|
||||
done = 1;
|
||||
} else {
|
||||
psz = spi_rd8(udc, MAX3420_REG_EP0BC + ep_id);
|
||||
length = min(length, psz);
|
||||
spi_rd_buf(udc, MAX3420_REG_EP0FIFO + ep_id, buf, length);
|
||||
if (length < ep->ep_usb.maxpacket)
|
||||
done = 1;
|
||||
}
|
||||
|
||||
req->usb_req.actual += length;
|
||||
|
||||
if (req->usb_req.actual == req->usb_req.length)
|
||||
done = 1;
|
||||
|
||||
xfer_done:
|
||||
if (done) {
|
||||
list_del_init(&req->queue);
|
||||
|
||||
if (ep_id == 0)
|
||||
spi_ack_ctrl(udc);
|
||||
|
||||
max3420_req_done(req, 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int max3420_handle_irqs(struct max3420_udc *udc)
|
||||
{
|
||||
u8 epien, epirq, usbirq, usbien, reg[4];
|
||||
int ret = 0;
|
||||
|
||||
spi_rd_buf(udc, MAX3420_REG_EPIRQ, reg, 4);
|
||||
epirq = reg[0];
|
||||
epien = reg[1];
|
||||
usbirq = reg[2];
|
||||
usbien = reg[3];
|
||||
|
||||
usbirq &= usbien;
|
||||
epirq &= epien;
|
||||
|
||||
if (epirq & bSUDAVIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_EPIRQ, bSUDAVIRQ);
|
||||
max3420_handle_setup(udc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bVBUSIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bVBUSIRQ);
|
||||
dev_dbg(udc->dev, "Cable plugged in\n");
|
||||
g_dnl_clear_detach();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bNOVBUSIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bNOVBUSIRQ);
|
||||
dev_dbg(udc->dev, "Cable pulled out\n");
|
||||
g_dnl_trigger_detach();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bURESIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bURESIRQ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bURESDNIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bURESDNIRQ);
|
||||
spi_wr8(udc, MAX3420_REG_USBIEN, bURESDNIRQ | bURESIRQ);
|
||||
spi_wr8(udc, MAX3420_REG_EPIEN, bSUDAVIRQ
|
||||
| bIN0BAVIRQ | bOUT0DAVIRQ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bSUSPIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bSUSPIRQ);
|
||||
dev_dbg(udc->dev, "USB Suspend - Enter\n");
|
||||
udc->suspended = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bBUSACTIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bBUSACTIRQ);
|
||||
dev_dbg(udc->dev, "USB Suspend - Exit\n");
|
||||
udc->suspended = false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bRWUDNIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bRWUDNIRQ);
|
||||
dev_dbg(udc->dev, "Asked Host to wakeup\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bOSCOKIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bOSCOKIRQ);
|
||||
dev_dbg(udc->dev, "Osc stabilized, start work\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (epirq & bOUT0DAVIRQ && do_data(udc, 0, 0)) {
|
||||
spi_wr8_ack(udc, MAX3420_REG_EPIRQ, bOUT0DAVIRQ, 1);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (epirq & bIN0BAVIRQ && do_data(udc, 0, 1))
|
||||
ret = 1;
|
||||
|
||||
if (epirq & bOUT1DAVIRQ && do_data(udc, 1, 0)) {
|
||||
spi_wr8_ack(udc, MAX3420_REG_EPIRQ, bOUT1DAVIRQ, 1);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (epirq & bIN2BAVIRQ && do_data(udc, 2, 1))
|
||||
ret = 1;
|
||||
|
||||
if (epirq & bIN3BAVIRQ && do_data(udc, 3, 1))
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max3420_irq(struct max3420_udc *udc)
|
||||
{
|
||||
do_data(udc, 0, 1); /* get done with the EP0 ZLP */
|
||||
|
||||
return max3420_handle_irqs(udc);
|
||||
}
|
||||
|
||||
static void max3420_setup_eps(struct max3420_udc *udc)
|
||||
{
|
||||
int i;
|
||||
|
||||
INIT_LIST_HEAD(&udc->gadget.ep_list);
|
||||
INIT_LIST_HEAD(&udc->ep[0].ep_usb.ep_list);
|
||||
|
||||
for (i = 0; i < MAX3420_MAX_EPS; i++) {
|
||||
struct max3420_ep *ep = &udc->ep[i];
|
||||
|
||||
INIT_LIST_HEAD(&ep->queue);
|
||||
|
||||
ep->id = i;
|
||||
ep->udc = udc;
|
||||
ep->ep_usb.ops = &max3420_ep_ops;
|
||||
ep->ep_usb.name = ep->name;
|
||||
ep->ep_usb.maxpacket = EP_MAX_PACKET;
|
||||
|
||||
if (i == 0) {
|
||||
ep->ep_usb.desc = &ep0_desc;
|
||||
snprintf(ep->name, EPNAME_SIZE, "ep0");
|
||||
continue;
|
||||
}
|
||||
|
||||
list_add_tail(&ep->ep_usb.ep_list, &udc->gadget.ep_list);
|
||||
|
||||
if (i == 1)
|
||||
snprintf(ep->name, EPNAME_SIZE, "ep1out-bulk");
|
||||
else
|
||||
snprintf(ep->name, EPNAME_SIZE, "ep%din-bulk", i);
|
||||
};
|
||||
}
|
||||
|
||||
static void max3420_setup_spi(struct max3420_udc *udc)
|
||||
{
|
||||
u8 reg[8];
|
||||
|
||||
spi_claim_bus(udc->slave);
|
||||
spi_rd_buf(udc, MAX3420_REG_EPIRQ, reg, 8);
|
||||
/* configure SPI */
|
||||
spi_wr8(udc, MAX3420_REG_PINCTL, bFDUPSPI);
|
||||
}
|
||||
|
||||
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
|
||||
{
|
||||
struct max3420_udc *udc = dev_get_priv(dev);
|
||||
|
||||
return max3420_irq(udc);
|
||||
}
|
||||
|
||||
static int max3420_udc_probe(struct udevice *dev)
|
||||
{
|
||||
struct max3420_udc *udc = dev_get_priv(dev);
|
||||
struct dm_spi_slave_platdata *slave_pdata;
|
||||
struct udevice *bus = dev->parent;
|
||||
int busnum = bus->seq;
|
||||
unsigned int cs;
|
||||
uint speed, mode;
|
||||
struct udevice *spid;
|
||||
|
||||
slave_pdata = dev_get_parent_platdata(dev);
|
||||
cs = slave_pdata->cs;
|
||||
speed = slave_pdata->max_hz;
|
||||
mode = slave_pdata->mode;
|
||||
spi_get_bus_and_cs(busnum, cs, speed, mode, "spi_generic_drv",
|
||||
NULL, &spid, &udc->slave);
|
||||
|
||||
udc->dev = dev;
|
||||
udc->gadget.ep0 = &udc->ep[0].ep_usb;
|
||||
udc->gadget.max_speed = USB_SPEED_FULL;
|
||||
udc->gadget.speed = USB_SPEED_FULL;
|
||||
udc->gadget.is_dualspeed = 0;
|
||||
udc->gadget.ops = &max3420_udc_ops;
|
||||
udc->gadget.name = "max3420-udc";
|
||||
|
||||
max3420_setup_eps(udc);
|
||||
max3420_setup_spi(udc);
|
||||
|
||||
usb_add_gadget_udc((struct device *)dev, &udc->gadget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_udc_remove(struct udevice *dev)
|
||||
{
|
||||
struct max3420_udc *udc = dev_get_priv(dev);
|
||||
|
||||
usb_del_gadget_udc(&udc->gadget);
|
||||
|
||||
spi_release_bus(udc->slave);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id max3420_ids[] = {
|
||||
{ .compatible = "maxim,max3421-udc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(max3420_generic_udc) = {
|
||||
.name = "max3420-udc",
|
||||
.id = UCLASS_USB_GADGET_GENERIC,
|
||||
.of_match = max3420_ids,
|
||||
.probe = max3420_udc_probe,
|
||||
.remove = max3420_udc_remove,
|
||||
.priv_auto_alloc_size = sizeof(struct max3420_udc),
|
||||
};
|
|
@ -411,6 +411,24 @@ int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int usb_remove_ehci_gadget(struct ehci_ctrl **ctlrp)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
/* Find the old device and remove it */
|
||||
ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = device_remove(dev, DM_REMOVE_NORMAL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*ctlrp = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns 0 if no match, 1 if match */
|
||||
static int usb_match_device(const struct usb_device_descriptor *desc,
|
||||
const struct usb_device_id *id)
|
||||
|
|
|
@ -79,7 +79,7 @@ struct nand_internal_data {
|
|||
};
|
||||
|
||||
struct ram_internal_data {
|
||||
void *start;
|
||||
unsigned long start;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ enum {
|
|||
FASTBOOT_COMMAND_CONTINUE,
|
||||
FASTBOOT_COMMAND_REBOOT,
|
||||
FASTBOOT_COMMAND_REBOOT_BOOTLOADER,
|
||||
FASTBOOT_COMMAND_REBOOT_FASTBOOTD,
|
||||
FASTBOOT_COMMAND_REBOOT_RECOVERY,
|
||||
FASTBOOT_COMMAND_SET_ACTIVE,
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
|
||||
FASTBOOT_COMMAND_OEM_FORMAT,
|
||||
|
@ -40,6 +42,25 @@ enum {
|
|||
FASTBOOT_COMMAND_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* Reboot reasons
|
||||
*/
|
||||
enum fastboot_reboot_reason {
|
||||
FASTBOOT_REBOOT_REASON_BOOTLOADER,
|
||||
FASTBOOT_REBOOT_REASON_FASTBOOTD,
|
||||
FASTBOOT_REBOOT_REASON_RECOVERY,
|
||||
FASTBOOT_REBOOT_REASONS_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* BCB boot commands
|
||||
*/
|
||||
static const char * const fastboot_boot_cmds[] = {
|
||||
[FASTBOOT_REBOOT_REASON_BOOTLOADER] = "bootonce-bootloader",
|
||||
[FASTBOOT_REBOOT_REASON_FASTBOOTD] = "boot-fastboot",
|
||||
[FASTBOOT_REBOOT_REASON_RECOVERY] = "boot-recovery"
|
||||
};
|
||||
|
||||
/**
|
||||
* fastboot_response() - Writes a response of the form "$tag$reason".
|
||||
*
|
||||
|
@ -77,7 +98,7 @@ void fastboot_okay(const char *reason, char *response);
|
|||
* which sets whatever flag your board specific Android bootloader flow
|
||||
* requires in order to re-enter the bootloader.
|
||||
*/
|
||||
int fastboot_set_reboot_flag(void);
|
||||
int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason);
|
||||
|
||||
/**
|
||||
* fastboot_set_progress_callback() - set progress callback
|
||||
|
|
|
@ -921,6 +921,15 @@ struct ehci_ctrl;
|
|||
*/
|
||||
int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp);
|
||||
|
||||
/**
|
||||
* usb_remove_ehci_gadget() - Remove a gadget USB device
|
||||
*
|
||||
* TODO(sjg@chromium.org): Tidy this up when USB gadgets can use driver model
|
||||
*
|
||||
* This provides a way to tell a controller to remove a USB device
|
||||
*/
|
||||
int usb_remove_ehci_gadget(struct ehci_ctrl **ctlrp);
|
||||
|
||||
/**
|
||||
* usb_stor_reset() - Prepare to scan USB storage devices
|
||||
*
|
||||
|
|
|
@ -25,7 +25,7 @@ struct ums {
|
|||
struct blk_desc block_dev;
|
||||
};
|
||||
|
||||
int fsg_init(struct ums *ums_devs, int count);
|
||||
int fsg_init(struct ums *ums_devs, int count, unsigned int controller_idx);
|
||||
void fsg_cleanup(void);
|
||||
int fsg_main_thread(void *);
|
||||
int fsg_add(struct usb_configuration *c);
|
||||
|
|
|
@ -227,6 +227,8 @@ static void fastboot_send(struct fastboot_header header, char *fastboot_data,
|
|||
|
||||
case FASTBOOT_COMMAND_REBOOT:
|
||||
case FASTBOOT_COMMAND_REBOOT_BOOTLOADER:
|
||||
case FASTBOOT_COMMAND_REBOOT_FASTBOOTD:
|
||||
case FASTBOOT_COMMAND_REBOOT_RECOVERY:
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue