From patchwork Thu Jan 16 08:11:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mingming lee X-Patchwork-Id: 239646 List-Id: U-Boot discussion From: mingming.lee at mediatek.com (mingming lee) Date: Thu, 16 Jan 2020 16:11:37 +0800 Subject: [PATCH v2 1/6] usb: musb-new: mt85xx: add musb-new gadget driver. In-Reply-To: <20200116081142.4849-1-mingming.lee@mediatek.com> References: <20200116081142.4849-1-mingming.lee@mediatek.com> Message-ID: <20200116081142.4849-2-mingming.lee@mediatek.com> Using musb-new structure for mt85xx gadget driver. Add gadget driver dts for mt8518 SoCs. Signed-off-by: mingming lee --- arch/arm/dts/mt8518.dtsi | 13 ++ drivers/usb/musb-new/Kconfig | 11 +- drivers/usb/musb-new/Makefile | 1 + drivers/usb/musb-new/mt85xx.c | 417 ++++++++++++++++++++++++++++++++++ 4 files changed, 441 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/musb-new/mt85xx.c diff --git a/arch/arm/dts/mt8518.dtsi b/arch/arm/dts/mt8518.dtsi index c2d17fda4a..56da91a9fe 100644 --- a/arch/arm/dts/mt8518.dtsi +++ b/arch/arm/dts/mt8518.dtsi @@ -74,6 +74,19 @@ }; }; + usb0: usb at 11100000 { + compatible = "mediatek,mt8518-musb"; + reg = <0x11100000 0x1000>; + reg-names = "control"; + clocks = <&topckgen CLK_TOP_USB20_48M>, + <&topckgen CLK_TOP_USBIF>, + <&topckgen CLK_TOP_USB>; + clock-names = "usbpll", "usbmcu", "usb"; + interrupts = ; + interrupt-names = "mc"; + status = "okay"; + }; + mmc0: mmc at 11120000 { compatible = "mediatek,mt8516-mmc"; reg = <0x11120000 0x1000>; diff --git a/drivers/usb/musb-new/Kconfig b/drivers/usb/musb-new/Kconfig index 79ad14ef66..6cf8a2b60b 100644 --- a/drivers/usb/musb-new/Kconfig +++ b/drivers/usb/musb-new/Kconfig @@ -47,6 +47,15 @@ config USB_MUSB_DSPS bool "TI DSPS platforms" if USB_MUSB_HOST || USB_MUSB_GADGET +config USB_MUSB_MT85XX + bool "Enable Mediatek MT85XX DRC USB controller" + depends on DM_USB && ARCH_MEDIATEK + default n + help + Say y to enable Mediatek MT85XX USB DRC controller support + if it is available on your Mediatek MUSB IP based platform. + DMA controllers are ignored. This driver follow musb-new + driver and usb gadget framework. config USB_MUSB_PIC32 bool "Enable Microchip PIC32 DRC USB controller" @@ -76,7 +85,7 @@ endif config USB_MUSB_PIO_ONLY bool "Disable DMA (always use PIO)" - default y if USB_MUSB_AM35X || USB_MUSB_PIC32 || USB_MUSB_OMAP2PLUS || USB_MUSB_DSPS || USB_MUSB_SUNXI + default y if USB_MUSB_AM35X || USB_MUSB_PIC32 || USB_MUSB_OMAP2PLUS || USB_MUSB_DSPS || USB_MUSB_SUNXI || USB_MUSB_MT85XX help All data is copied between memory and FIFO by the CPU. DMA controllers are ignored. diff --git a/drivers/usb/musb-new/Makefile b/drivers/usb/musb-new/Makefile index ec7852ce94..6355eb12dd 100644 --- a/drivers/usb/musb-new/Makefile +++ b/drivers/usb/musb-new/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_USB_MUSB_HOST) += musb_host.o musb_core.o musb_uboot.o obj-$(CONFIG_USB_MUSB_DSPS) += musb_dsps.o obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o +obj-$(CONFIG_USB_MUSB_MT85XX) += mt85xx.o obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o obj-$(CONFIG_USB_MUSB_PIC32) += pic32.o obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o diff --git a/drivers/usb/musb-new/mt85xx.c b/drivers/usb/musb-new/mt85xx.c new file mode 100644 index 0000000000..131fd7dd79 --- /dev/null +++ b/drivers/usb/musb-new/mt85xx.c @@ -0,0 +1,417 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek "glue layer" + * + * Copyright (C) 2019-2021 by Mediatek + * Based on the AllWinner SUNXI "glue layer" code. + * Copyright (C) 2015 Hans de Goede + * Copyright (C) 2013 Jussi Kivilinna + * + * This file is part of the Inventra Controller Driver for Linux. + */ +#include +#include +#include +#include +#include +#include +#include +#include "linux-compat.h" +#include "musb_core.h" +#include "musb_uboot.h" + +#define DBG_I(fmt, ...) \ + pr_info(fmt, ##__VA_ARGS__) + +struct mtk_musb_config { + struct musb_hdrc_config *config; +}; + +struct mtk_musb_glue { + struct musb_host_data mdata; + struct clk usbpllclk; + struct clk usbmcuclk; + struct clk usbclk; + struct mtk_musb_config *cfg; + struct device dev; +}; + +#define to_mtk_musb_glue(d) container_of(d, struct mtk_musb_glue, dev) + +/****************************************************************************** + * phy settings + ******************************************************************************/ +#define USB20_PHY_BASE 0x11110800 +#define USBPHY_READ8(offset) \ + readb((void *)(USB20_PHY_BASE + (offset))) +#define USBPHY_WRITE8(offset, value) \ + writeb(value, (void *)(USB20_PHY_BASE + (offset))) +#define USBPHY_SET8(offset, mask) \ + USBPHY_WRITE8(offset, (USBPHY_READ8(offset)) | (mask)) +#define USBPHY_CLR8(offset, mask) \ + USBPHY_WRITE8(offset, (USBPHY_READ8(offset)) & (~(mask))) + +static void mt_usb_phy_poweron(void) +{ + /* + * switch to USB function. + * (system register, force ip into usb mode). + */ + USBPHY_CLR8(0x6b, 0x04); + USBPHY_CLR8(0x6e, 0x01); + USBPHY_CLR8(0x21, 0x03); + + /* RG_USB20_BC11_SW_EN = 1'b0 */ + USBPHY_SET8(0x22, 0x04); + USBPHY_CLR8(0x1a, 0x80); + + /* RG_USB20_DP_100K_EN = 1'b0 */ + /* RG_USB20_DP_100K_EN = 1'b0 */ + USBPHY_CLR8(0x22, 0x03); + + /*OTG enable*/ + USBPHY_SET8(0x20, 0x10); + /* release force suspendm */ + USBPHY_CLR8(0x6a, 0x04); + + mdelay(800); + + /* force enter device mode */ + USBPHY_CLR8(0x6c, 0x10); + USBPHY_SET8(0x6c, 0x2E); + USBPHY_SET8(0x6d, 0x3E); +} + +static void mt_usb_phy_savecurrent(void) +{ + /* + * switch to USB function. + * (system register, force ip into usb mode). + */ + USBPHY_CLR8(0x6b, 0x04); + USBPHY_CLR8(0x6e, 0x01); + USBPHY_CLR8(0x21, 0x03); + + /* release force suspendm */ + USBPHY_CLR8(0x6a, 0x04); + USBPHY_SET8(0x68, 0x04); + /* RG_DPPULLDOWN./RG_DMPULLDOWN. */ + USBPHY_SET8(0x68, 0xc0); + /* RG_XCVRSEL[1:0] = 2'b01 */ + USBPHY_CLR8(0x68, 0x30); + USBPHY_SET8(0x68, 0x10); + /* RG_TERMSEL = 1'b1 */ + USBPHY_SET8(0x68, 0x04); + /* RG_DATAIN[3:0] = 4'b0000 */ + USBPHY_CLR8(0x69, 0x3c); + + /* + * force_dp_pulldown, force_dm_pulldown, + * force_xcversel, force_termsel. + */ + USBPHY_SET8(0x6a, 0xba); + + /* RG_USB20_BC11_SW_EN = 1'b0 */ + USBPHY_CLR8(0x1a, 0x80); + /* RG_USB20_OTG_VBUSSCMP_EN = 1'b0 */ + USBPHY_CLR8(0x1a, 0x10); + + mdelay(800); + + USBPHY_CLR8(0x6a, 0x04); + /* rg_usb20_pll_stable = 1 */ + //USBPHY_SET8(0x63, 0x02); + + mdelay(1); + + /* force suspendm = 1 */ + //USBPHY_SET8(0x6a, 0x04); +} + +static void mt_usb_phy_recover(void) +{ + /* clean PUPD_BIST_EN */ + /* PUPD_BIST_EN = 1'b0 */ + /* PMIC will use it to detect charger type */ + USBPHY_CLR8(0x1d, 0x10); + + /* force_uart_en = 1'b0 */ + USBPHY_CLR8(0x6b, 0x04); + /* RG_UART_EN = 1'b0 */ + USBPHY_CLR8(0x6e, 0x01); + /* force_uart_en = 1'b0 */ + USBPHY_CLR8(0x6a, 0x04); + + USBPHY_CLR8(0x21, 0x03); + USBPHY_CLR8(0x68, 0xf4); + + /* RG_DATAIN[3:0] = 4'b0000 */ + USBPHY_CLR8(0x69, 0x3c); + + USBPHY_CLR8(0x6a, 0xba); + + /* RG_USB20_BC11_SW_EN = 1'b0 */ + USBPHY_CLR8(0x1a, 0x80); + /* RG_USB20_OTG_VBUSSCMP_EN = 1'b1 */ + USBPHY_SET8(0x1a, 0x10); + + //HQA adjustment + USBPHY_CLR8(0x18, 0x08); + USBPHY_SET8(0x18, 0x06); + mdelay(800); + + /* force enter device mode */ + //USBPHY_CLR8(0x6c, 0x10); + //USBPHY_SET8(0x6c, 0x2E); + //USBPHY_SET8(0x6d, 0x3E); + + /* enable VRT internal R architecture */ + /* RG_USB20_INTR_EN = 1'b1 */ + USBPHY_SET8(0x00, 0x20); +} + +/****************************************************************************** + * MUSB Glue code + ******************************************************************************/ + +static irqreturn_t mtk_musb_interrupt(int irq, void *__hci) +{ + struct musb *musb = __hci; + irqreturn_t retval = IRQ_NONE; + + /* read and flush interrupts */ + musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); +// last_int_usb = musb->int_usb; + if (musb->int_usb) + musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb); + musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); + if (musb->int_tx) + musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx); + musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); + if (musb->int_rx) + musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx); + + if (musb->int_usb || musb->int_tx || musb->int_rx) + retval |= musb_interrupt(musb); + + return retval; +} + +/* musb_core does not call enable / disable in a balanced manner */ +static bool enabled; + +static int mtk_musb_enable(struct musb *musb) +{ + struct mtk_musb_glue *glue = to_mtk_musb_glue(musb->controller); + + DBG_I("%s():\n", __func__); + + musb_ep_select(musb->mregs, 0); + musb_writeb(musb->mregs, MUSB_FADDR, 0); + + if (enabled) + return 0; + + mt_usb_phy_recover(); + + enabled = true; + + return 0; +} + +static void mtk_musb_disable(struct musb *musb) +{ + struct mtk_musb_glue *glue = to_mtk_musb_glue(musb->controller); + int ret; + + DBG_I("%s():\n", __func__); + + if (!enabled) + return; + + mt_usb_phy_savecurrent(); + + enabled = false; +} + +static int mtk_musb_init(struct musb *musb) +{ + struct mtk_musb_glue *glue = to_mtk_musb_glue(musb->controller); + int ret; + + DBG_I("%s():\n", __func__); + + ret = clk_enable(&glue->usbpllclk); + if (ret) { + dev_err(dev, "failed to enable usbpll clock\n"); + return ret; + } + ret = clk_enable(&glue->usbmcuclk); + if (ret) { + dev_err(dev, "failed to enable usbmcu clock\n"); + return ret; + } + ret = clk_enable(&glue->usbclk); + if (ret) { + dev_err(dev, "failed to enable usb clock\n"); + return ret; + } + + musb->isr = mtk_musb_interrupt; + + return 0; +} + +static int mtk_musb_exit(struct musb *musb) +{ + struct mtk_musb_glue *glue = to_mtk_musb_glue(musb->controller); + + clk_disable(&glue->usbclk); + clk_disable(&glue->usbmcuclk); + clk_disable(&glue->usbpllclk); + + return 0; +} + +static const struct musb_platform_ops mtk_musb_ops = { + .init = mtk_musb_init, + .exit = mtk_musb_exit, + .enable = mtk_musb_enable, + .disable = mtk_musb_disable, +}; + +/* MTK OTG supports up to 7 endpoints */ +#define MTK_MUSB_MAX_EP_NUM 8 +#define MTK_MUSB_RAM_BITS 16 + +static struct musb_fifo_cfg mtk_musb_mode_cfg[] = { + MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(2, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(3, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(3, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(4, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(4, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(5, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(5, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(6, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(6, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(7, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(7, FIFO_RX, 512), +}; + +static struct musb_hdrc_config musb_config = { + .fifo_cfg = mtk_musb_mode_cfg, + .fifo_cfg_size = ARRAY_SIZE(mtk_musb_mode_cfg), + .multipoint = true, + .dyn_fifo = true, + .num_eps = MTK_MUSB_MAX_EP_NUM, + .ram_bits = MTK_MUSB_RAM_BITS, +}; + +static int musb_usb_probe(struct udevice *dev) +{ + struct mtk_musb_glue *glue = dev_get_priv(dev); + struct musb_host_data *host = &glue->mdata; + struct musb_hdrc_platform_data pdata; + void *base = dev_read_addr_ptr(dev); + int ret; + + DBG_I("%s():\n", __func__); + +#ifdef CONFIG_USB_MUSB_HOST + struct usb_bus_priv *priv = dev_get_uclass_priv(dev); +#endif + + if (!base) + return -EINVAL; + + glue->cfg = (struct mtk_musb_config *)dev_get_driver_data(dev); + if (!glue->cfg) + return -EINVAL; + + ret = clk_get_by_name(dev, "usbpll", &glue->usbpllclk); + if (ret) { + dev_err(dev, "failed to get usbpll clock\n"); + return ret; + } + ret = clk_get_by_name(dev, "usbmcu", &glue->usbmcuclk); + if (ret) { + dev_err(dev, "failed to get usbmcu clock\n"); + return ret; + } + ret = clk_get_by_name(dev, "usb", &glue->usbclk); + if (ret) { + dev_err(dev, "failed to get usb clock\n"); + return ret; + } + + memset(&pdata, 0, sizeof(pdata)); + pdata.power = (u8)400; + pdata.platform_ops = &mtk_musb_ops; + pdata.config = glue->cfg->config; + +#ifdef CONFIG_USB_MUSB_HOST + priv->desc_before_addr = true; + + pdata.mode = MUSB_HOST; + host->host = musb_init_controller(&pdata, &glue->dev, base); + if (!host->host) + return -EIO; + + ret = musb_lowlevel_init(host); + if (!ret) + printf("MTK MUSB OTG (Host)\n"); +#else + pdata.mode = MUSB_PERIPHERAL; + host->host = musb_register(&pdata, &glue->dev, base); + if (!host->host) + return -EIO; + + printf("MTK MUSB OTG (Peripheral)\n"); +#endif + + mt_usb_phy_poweron(); + + return ret; +} + +static int musb_usb_remove(struct udevice *dev) +{ + struct mtk_musb_glue *glue = dev_get_priv(dev); + struct musb_host_data *host = &glue->mdata; + + musb_stop(host->host); + free(host->host); + host->host = NULL; + + return 0; +} + +static const struct mtk_musb_config mt8518_cfg = { + .config = &musb_config, +}; + +static const struct udevice_id mtk_musb_ids[] = { + { .compatible = "mediatek,mt8518-musb", + .data = (ulong)&mt8518_cfg }, + { } +}; + +U_BOOT_DRIVER(mtk_musb) = { + .name = "mtk_musb", +#ifdef CONFIG_USB_MUSB_HOST + .id = UCLASS_USB, +#else + .id = UCLASS_USB_GADGET_GENERIC, +#endif + .of_match = mtk_musb_ids, + .probe = musb_usb_probe, + .remove = musb_usb_remove, +#ifdef CONFIG_USB_MUSB_HOST + .ops = &musb_usb_ops, +#endif + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct mtk_musb_glue), +}; From patchwork Thu Jan 16 08:11:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mingming lee X-Patchwork-Id: 239647 List-Id: U-Boot discussion From: mingming.lee at mediatek.com (mingming lee) Date: Thu, 16 Jan 2020 16:11:38 +0800 Subject: [PATCH v2 2/6] ARM: Mediatek: Add board_late_init to init usb gadget driver In-Reply-To: <20200116081142.4849-1-mingming.lee@mediatek.com> References: <20200116081142.4849-1-mingming.lee@mediatek.com> Message-ID: <20200116081142.4849-3-mingming.lee@mediatek.com> Add board_late_init function to init usb gadget driver for mt8518 Signed-off-by: mingming lee --- board/mediatek/mt8518/mt8518_ap1.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/board/mediatek/mt8518/mt8518_ap1.c b/board/mediatek/mt8518/mt8518_ap1.c index 9710907fe2..2ac7c6cd18 100644 --- a/board/mediatek/mt8518/mt8518_ap1.c +++ b/board/mediatek/mt8518/mt8518_ap1.c @@ -16,3 +16,21 @@ int board_init(void) debug("gd->fdt_blob is %p\n", gd->fdt_blob); return 0; } + +int board_late_init(void) +{ +#ifdef CONFIG_USB_GADGET + struct udevice *dev; + int ret; +#endif + +#ifdef CONFIG_USB_GADGET + ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev); + if (ret) { + pr_err("%s: Cannot find USB device\n", __func__); + return ret; + } +#endif + + return 0; +} From patchwork Thu Jan 16 08:11:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mingming lee X-Patchwork-Id: 239644 List-Id: U-Boot discussion From: mingming.lee at mediatek.com (mingming lee) Date: Thu, 16 Jan 2020 16:11:39 +0800 Subject: [PATCH v2 3/6] configs: mt8518: set global variables for fastboot In-Reply-To: <20200116081142.4849-1-mingming.lee@mediatek.com> References: <20200116081142.4849-1-mingming.lee@mediatek.com> Message-ID: <20200116081142.4849-4-mingming.lee@mediatek.com> set common fastboot variables for mt8518 Signed-off-by: mingming lee --- include/configs/mt8518.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/configs/mt8518.h b/include/configs/mt8518.h index 8906245a62..9bc9c04e66 100644 --- a/include/configs/mt8518.h +++ b/include/configs/mt8518.h @@ -11,9 +11,6 @@ #include -#define CONFIG_ENV_SIZE SZ_4K - -/* Machine ID */ #define CONFIG_SYS_NONCACHED_MEMORY SZ_1M #define CONFIG_CPU_ARMV8 @@ -39,7 +36,7 @@ /* ENV Setting */ #if defined(CONFIG_MMC_MTK) #define CONFIG_SYS_MMC_ENV_DEV 0 -#define CONFIG_ENV_OFFSET 0x4E60000 + #define CONFIG_ENV_OVERWRITE /* MMC offset in block unit,and block size is 0x200 */ @@ -58,10 +55,15 @@ #define ENV_BOOT_CMD \ "mtk_boot=run boot_rd_img;bootm;\0" +#define ENV_FASTBOOT \ + "serial#=1234567890ABCDEF\0" \ + "board=mt8518\0" + #define CONFIG_EXTRA_ENV_SETTINGS \ "fdt_high=0x6c000000\0" \ ENV_DEVICE_SETTINGS \ ENV_BOOT_READ_IMAGE \ + ENV_FASTBOOT \ ENV_BOOT_CMD \ "bootcmd=run mtk_boot;\0" \ From patchwork Thu Jan 16 08:11:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mingming lee X-Patchwork-Id: 239642 List-Id: U-Boot discussion From: mingming.lee at mediatek.com (mingming lee) Date: Thu, 16 Jan 2020 16:11:40 +0800 Subject: [PATCH v2 4/6] configs: mt8518: enable usb gadget driver In-Reply-To: <20200116081142.4849-1-mingming.lee@mediatek.com> References: <20200116081142.4849-1-mingming.lee@mediatek.com> Message-ID: <20200116081142.4849-5-mingming.lee@mediatek.com> Enable board_late_init and usb gadget for mt8518 Signed-off-by: mingming lee --- configs/mt8518_ap1_emmc_defconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configs/mt8518_ap1_emmc_defconfig b/configs/mt8518_ap1_emmc_defconfig index dd42076f4d..9857b7b776 100644 --- a/configs/mt8518_ap1_emmc_defconfig +++ b/configs/mt8518_ap1_emmc_defconfig @@ -39,3 +39,13 @@ CONFIG_DM_MMC=y CONFIG_MMC_MTK=y CONFIG_MMC_HS200_SUPPORT=y # CONFIG_ENV_IS_IN_MMC is not set +CONFIG_BOARD_LATE_INIT=y +CONFIG_USB=y +CONFIG_USB_GADGET=y +CONFIG_DM_USB=y +CONFIG_USB_MUSB_GADGET=y +CONFIG_USB_MUSB_MT85XX=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_GADGET_VENDOR_NUM=0x0bb4 +CONFIG_USB_GADGET_PRODUCT_NUM=0x0c01 +CONFIG_USB_GADGET_MANUFACTURER="Mediatek." \ No newline at end of file From patchwork Thu Jan 16 08:11:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mingming lee X-Patchwork-Id: 239643 List-Id: U-Boot discussion From: mingming.lee at mediatek.com (mingming lee) Date: Thu, 16 Jan 2020 16:11:41 +0800 Subject: [PATCH v2 5/6] configs: mt8518: Enable fastboot related configs In-Reply-To: <20200116081142.4849-1-mingming.lee@mediatek.com> References: <20200116081142.4849-1-mingming.lee@mediatek.com> Message-ID: <20200116081142.4849-6-mingming.lee@mediatek.com> Enable EFI module. Enable fastboot. Signed-off-by: mingming lee --- configs/mt8518_ap1_emmc_defconfig | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/configs/mt8518_ap1_emmc_defconfig b/configs/mt8518_ap1_emmc_defconfig index 9857b7b776..714fd8e087 100644 --- a/configs/mt8518_ap1_emmc_defconfig +++ b/configs/mt8518_ap1_emmc_defconfig @@ -34,6 +34,7 @@ CONFIG_WDT_MTK=y CONFIG_CLK=y CONFIG_TIMER=y CONFIG_MTK_TIMER=y +CONFIG_MMC=y CONFIG_CMD_MMC=y CONFIG_DM_MMC=y CONFIG_MMC_MTK=y @@ -48,4 +49,14 @@ CONFIG_USB_MUSB_MT85XX=y CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_USB_GADGET_VENDOR_NUM=0x0bb4 CONFIG_USB_GADGET_PRODUCT_NUM=0x0c01 -CONFIG_USB_GADGET_MANUFACTURER="Mediatek." \ No newline at end of file +CONFIG_USB_GADGET_MANUFACTURER="Mediatek." +CONFIG_EFI_PARTITION=y +CONFIG_FASTBOOT_GPT_NAME=GPT +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT=y +CONFIG_CMD_FASTBOOT=y +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_BUF_ADDR=0x56000000 +CONFIG_FASTBOOT_BUF_SIZE=0x1E00000 From patchwork Thu Jan 16 08:11:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mingming lee X-Patchwork-Id: 239645 List-Id: U-Boot discussion From: mingming.lee at mediatek.com (mingming lee) Date: Thu, 16 Jan 2020 16:11:42 +0800 Subject: [PATCH v2 6/6] fastboot: mt85xx: add command to flash/erase emmc hwpart In-Reply-To: <20200116081142.4849-1-mingming.lee@mediatek.com> References: <20200116081142.4849-1-mingming.lee@mediatek.com> Message-ID: <20200116081142.4849-7-mingming.lee@mediatek.com> This patch includes the following: 1. Add fastboot command to erase the whole EMMC_USER 2. Add fastboot command to flash image at EMMC_BOOT1 3. Add fastboot command to erase the whole EMMC_BOOT1 4. Enale CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT for mt8518 Signed-off-by: mingming lee --- Changes for v2: - Limit the config in this patch depends on ARCH_MEDIATEK - config include all the added function,avoid affect other IC config --- configs/mt8518_ap1_emmc_defconfig | 1 + drivers/fastboot/Kconfig | 30 +++++++++ drivers/fastboot/fb_mmc.c | 102 ++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) diff --git a/configs/mt8518_ap1_emmc_defconfig b/configs/mt8518_ap1_emmc_defconfig index 714fd8e087..e929d40d75 100644 --- a/configs/mt8518_ap1_emmc_defconfig +++ b/configs/mt8518_ap1_emmc_defconfig @@ -60,3 +60,4 @@ CONFIG_FASTBOOT_FLASH_MMC=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_FASTBOOT_BUF_ADDR=0x56000000 CONFIG_FASTBOOT_BUF_SIZE=0x1E00000 +CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT=y \ No newline at end of file diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index 433ea0dc3b..aab8288930 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -104,6 +104,36 @@ config FASTBOOT_FLASH_NAND_TRIMFFS When flashing NAND enable the DROP_FFS flag to drop trailing all-0xff pages. +config FASTBOOT_MMC_BOOT1_SUPPORT + bool "Enable EMMC_BOOT1 flash/erase" + depends on FASTBOOT_FLASH_MMC && EFI_PARTITION && ARCH_MEDIATEK + help + The fastboot "flash" and "erase" commands normally does operations + on EMMC userdata. Define this to enable the special commands to + flash/erase EMMC_BOOT1. + The default target name for updating EMMC_BOOT1 is "mmc0boot0". + +config FASTBOOT_MMC_BOOT1_NAME + string "Target name for updating EMMC_BOOT1" + depends on FASTBOOT_MMC_BOOT1_SUPPORT + default "mmc0boot0" + help + The fastboot "flash" and "erase" commands support operations on + EMMC_BOOT1. This occurs when the specified "EMMC_BOOT1 name" on + the "fastboot flash" and "fastboot erase" commands match the value + defined here. + The default target name for updating EMMC_BOOT1 is "mmc0boot0". + +config FASTBOOT_MMC_USER_NAME + string "Target name for erasing EMMC_USER" + depends on FASTBOOT_FLASH_MMC && EFI_PARTITION && ARCH_MEDIATEK + default "mmc0" + help + The fastboot "erase" command supports erasing EMMC_USER. This occurs + when the specified "EMMC_USER name" on the "fastboot erase" commands + match the value defined here. + The default target name for erasing EMMC_USER is "mmc0". + config FASTBOOT_GPT_NAME string "Target name for updating GPT" depends on FASTBOOT_FLASH_MMC && EFI_PARTITION diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index b0b19c5762..d7cf9f4aac 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -129,6 +129,76 @@ static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info, fastboot_okay(NULL, response); } +#ifdef CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT +static int fb_mmc_erase_mmc_hwpart(struct blk_desc *dev_desc) +{ + lbaint_t blks; + + debug("Start Erasing mmc hwpart[%u]...\n", dev_desc->hwpart); + + blks = fb_mmc_blk_write(dev_desc, 0, dev_desc->lba, NULL); + + if (blks != dev_desc->lba) { + pr_err("Failed to erase mmc hwpart[%u]\n", dev_desc->hwpart); + return 1; + } + + printf("........ erased %lu bytes from mmc hwpart[%u]\n", + dev_desc->lba * dev_desc->blksz, dev_desc->hwpart); + + return 0; +} + +static void fb_mmc_boot1_ops(struct blk_desc *dev_desc, void *buffer, + u32 buff_sz, char *response) +{ + lbaint_t blkcnt; + lbaint_t blks; + unsigned long blksz; + + // To operate on EMMC_BOOT1 (mmc0boot0), we first change the hwpart + if (blk_dselect_hwpart(dev_desc, 1)) { + pr_err("Failed to select hwpart\n"); + fastboot_fail("Failed to select hwpart", response); + return; + } + + if (buffer) { /* flash */ + + /* determine number of blocks to write */ + blksz = dev_desc->blksz; + blkcnt = ((buff_sz + (blksz - 1)) & ~(blksz - 1)); + blkcnt = lldiv(blkcnt, blksz); + + if (blkcnt > dev_desc->lba) { + pr_err("Image size too large\n"); + fastboot_fail("Image size too large", response); + return; + } + + debug("Start Flashing Image to EMMC_BOOT1...\n"); + + blks = fb_mmc_blk_write(dev_desc, 0, blkcnt, buffer); + + if (blks != blkcnt) { + pr_err("Failed to write EMMC_BOOT1\n"); + fastboot_fail("Failed to write EMMC_BOOT1", response); + return; + } + + printf("........ wrote %lu bytes to EMMC_BOOT1\n", + blkcnt * blksz); + } else { /* erase */ + if (fb_mmc_erase_mmc_hwpart(dev_desc)) { + fastboot_fail("Failed to erase EMMC_BOOT1", response); + return; + } + } + + fastboot_okay(NULL, response); +} +#endif + #ifdef CONFIG_ANDROID_BOOT_IMAGE /** * Read Android boot image header from boot partition. @@ -345,8 +415,21 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer, return; } +#ifdef CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT + if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) { + fb_mmc_boot1_ops(dev_desc, download_buffer, + download_bytes, response); + return; + } +#endif + #if CONFIG_IS_ENABLED(EFI_PARTITION) +#ifndef CONFIG_FASTBOOT_MMC_USER_NAME if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) { +#else + if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0 || + strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) { +#endif printf("%s: updating MBR, Primary and Backup GPT(s)\n", __func__); if (is_valid_gpt_buf(dev_desc, download_buffer)) { @@ -457,6 +540,25 @@ void fastboot_mmc_erase(const char *cmd, char *response) return; } +#ifdef CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT + if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) { + /* erase EMMC boot1 */ + fb_mmc_boot1_ops(dev_desc, NULL, 0, response); + return; + } +#endif + +#ifdef CONFIG_FASTBOOT_MMC_USER_NAME + if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) { + /* erase EMMC userdata */ + if (fb_mmc_erase_mmc_hwpart(dev_desc)) + fastboot_fail("Failed to erase EMMC_USER", response); + else + fastboot_okay(NULL, response); + return; + } +#endif + ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info); if (ret < 0) { pr_err("cannot find partition: '%s'\n", cmd);