提交 9bfb567e 编写于 作者: T Tom Rini

Merge branch 'master' of git://git.denx.de/u-boot-usb

- Mostly DFU fixes and r8152 fixes
......@@ -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
// 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;
}
mdelay(6);
generic_ocp_write(tp, USB_BP(0), 0xff, sizeof(zeros), zeros, type);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0);
ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0);
}
mdelay(6);
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;
}
ep_out = usb_ep_autoconfig(gadget, &out_desc);
if (!ep_out) {
rv = -ENODEV;
goto error;
}
sdp->in_ep = ep; /* Store IN EP for enabling @ setup */
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;
}
此差异已折叠。
......@@ -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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册