diff --git a/arch/arm64/boot/dts/amlogic/g12a_pxp.dts b/arch/arm64/boot/dts/amlogic/g12a_pxp.dts index fd6ea3dcde4f..e2a41d47bd24 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_pxp.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_pxp.dts @@ -108,6 +108,50 @@ }; }; + sd_emmc_b:sd@ffe05000 { + status = "okay"; + compatible = "amlogic, meson-mmc-g12a"; + reg = <0x0 0xffe05000 0x0 0x2000>; + interrupts = <0 190 1>; + + pinctrl-names = "sd_clk_cmd_pins", "sd_all_pins"; + pinctrl-0 = <&sd_clk_cmd_pins>; + pinctrl-1 = <&sd_all_pins>; + + clocks = <&clkc CLKID_SD_EMMC_B>, + <&clkc CLKID_SD_EMMC_B_P0_COMP>, + <&clkc CLKID_FCLK_DIV2>, + <&clkc CLKID_FCLK_DIV5>; + clock-names = "core", "clkin0", "clkin1", "clkin2"; + + bus-width = <4>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <100000000>; + non-removable; + disable-wp; + sd { + pinname = "sd"; + ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */ + caps = "MMC_CAP_4_BIT_DATA", + "MMC_CAP_MMC_HIGHSPEED", + "MMC_CAP_SD_HIGHSPEED", + "MMC_CAP_NONREMOVABLE", + "MMC_CAP_UHS_SDR12", + "MMC_CAP_UHS_SDR25", + "MMC_CAP_UHS_SDR50", + "MMC_PM_KEEP_POWER", + "MMC_CAP_NONREMOVABLE"; /**ptm debug */ + f_min = <400000>; + f_max = <200000000>; + max_req_size = <0x20000>; /**128KB*/ + card_type = <5>; + /* 3:sdio device(ie:sdio-wifi), + * 4:SD combo (IO+mem) card + */ + }; + }; + canvas{ compatible = "amlogic, meson, canvas"; dev_name = "amlogic-canvas"; diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi index eb111e574f84..959d39a3112d 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi @@ -500,5 +500,28 @@ }; &pinctrl_periphs { + /* sdemmc portB */ + sd_clk_cmd_pins:sd_clk_cmd_pins { + mux { + groups = "sdcard_cmd_c", + "sdcard_clk_c"; + function = "sdcard"; + input-enable; + bias-pull-up; + }; + }; + sd_all_pins:sd_all_pins { + mux { + groups = "sdcard_d0_c", + "sdcard_d1_c", + "sdcard_d2_c", + "sdcard_d3_c", + "sdcard_cmd_c", + "sdcard_clk_c"; + function = "sdcard"; + input-enable; + bias-pull-up; + }; + }; }; diff --git a/drivers/amlogic/mmc/aml_sd_emmc.c b/drivers/amlogic/mmc/aml_sd_emmc.c index 70cd83ba318c..62bda6ce2ead 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc.c +++ b/drivers/amlogic/mmc/aml_sd_emmc.c @@ -2932,6 +2932,8 @@ static int meson_mmc_probe(struct platform_device *pdev) if (aml_card_type_sdio(pdata)) /* if sdio_wifi */ sdio_host = mmc; +#ifndef CONFIG_MESON_CPU_EMULATOR + /* disable sdcard detect irq for ptm */ /*Register card detect irq : plug in & unplug*/ if (pdata->gpio_cd && aml_card_type_non_sdio(pdata)) { mutex_init(&pdata->in_out_lock); @@ -2952,6 +2954,7 @@ static int meson_mmc_probe(struct platform_device *pdev) schedule_delayed_work(&host->cd_work, 50); #endif } +#endif /* CONFIG_MESON_CPU_EMULATOR */ pr_info("%s() : success!\n", __func__); return 0; @@ -3064,6 +3067,15 @@ static struct meson_mmc_data mmc_data_txhd = { .ds_pin_poll_bit = 11, }; +static struct meson_mmc_data mmc_data_g12a = { + .chip_type = MMC_CHIP_G12A, + .pinmux_base = 0xff634400, + .clksrc_base = 0xff63c000, + .ds_pin_poll = 0x3a, + .ds_pin_poll_en = 0x48, + .ds_pin_poll_bit = 13, +}; + static const struct of_device_id meson_mmc_of_match[] = { { .compatible = "amlogic, meson-mmc-gxbb", @@ -3101,6 +3113,10 @@ static const struct of_device_id meson_mmc_of_match[] = { .compatible = "amlogic, meson-mmc-txhd", .data = &mmc_data_txhd, }, + { + .compatible = "amlogic, meson-mmc-g12a", + .data = &mmc_data_g12a, + }, {} }; MODULE_DEVICE_TABLE(of, meson_mmc_of_match); diff --git a/drivers/amlogic/mmc/aml_sd_emmc_v3.c b/drivers/amlogic/mmc/aml_sd_emmc_v3.c index 0e718f4233d4..2f2b3c40c92e 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc_v3.c +++ b/drivers/amlogic/mmc/aml_sd_emmc_v3.c @@ -52,10 +52,11 @@ int meson_mmc_clk_init_v3(struct amlsd_host *host) struct amlsd_platform *pdata = host->pdata; writel(0, host->base + SD_EMMC_CLOCK_V3); +#ifndef SD_EMMC_CLK_CTRL ret = aml_emmc_clktree_init(host); if (ret) return ret; - +#endif /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ vclkc = 0; pclkc->div = 60; /* 400KHz */ @@ -92,11 +93,12 @@ static int meson_mmc_clk_set_rate_v3(struct amlsd_host *host, struct mmc_host *mmc = host->mmc; struct amlsd_platform *pdata = host->pdata; int ret = 0; - struct clk *src0_clk = NULL; + #ifdef SD_EMMC_CLK_CTRL u32 clk_rate, clk_div, clk_src_sel; struct amlsd_platform *pdata = host->pdata; #else + struct clk *src0_clk = NULL; u32 vcfg = 0; struct sd_emmc_config *conf = (struct sd_emmc_config *)&vcfg; #endif diff --git a/drivers/amlogic/mmc/amlsd.c b/drivers/amlogic/mmc/amlsd.c index fe6c6cd63750..178a2c9829ab 100644 --- a/drivers/amlogic/mmc/amlsd.c +++ b/drivers/amlogic/mmc/amlsd.c @@ -397,6 +397,7 @@ void aml_devm_pinctrl_put(struct amlsd_host *host) } } +#ifndef SD_EMMC_PIN_CTRL static struct pinctrl * __must_check aml_devm_pinctrl_get_select( struct amlsd_host *host, const char *name) { @@ -429,6 +430,34 @@ static struct pinctrl * __must_check aml_devm_pinctrl_get_select( } return p; } +#else /* SD_EMMC_PIN_CTRL */ +static struct pinctrl * __must_check aml_devm_pinctrl_get_select( + struct amlsd_host *host, const char *name) +{ + u32 val; + + if (!strcmp("sd_clk_cmd_pins", name)) { + val = readl(host->pinmux_base + PIN_MUX_REG9); + val &= ~0xFFFFFF; + val |= 0x110000; + writel(val, host->pinmux_base + PIN_MUX_REG9); + /* pullup status */ + pr_info("name %s -> pinmux 9 0x%x\n", name, val); + + } else if (!strcmp("sd_all_pins", name)) { + val = readl(host->pinmux_base + PIN_MUX_REG9); + val &= ~0xFFFFFF; + val |= 0x111111; + writel(val, host->pinmux_base + PIN_MUX_REG9); + /* pullup status */ + + pr_info("name %s -> pinmux 9 0x%x\n", name, val); + } else + pr_err("E: name %s do nothing.\n", name); + + return NULL; +} +#endif /* SD_EMMC_PIN_CTRL */ void of_amlsd_xfer_pre(struct mmc_host *mmc) { @@ -489,10 +518,15 @@ void of_amlsd_xfer_pre(struct mmc_host *mmc) mutex_lock(&host->pinmux_lock); ppin = aml_devm_pinctrl_get_select(host, pinctrl); mutex_unlock(&host->pinmux_lock); + /* bringup on ptm for g12 */ + #ifndef SD_EMMC_PIN_CTRL if (!IS_ERR(ppin)) { /* pdata->host->pinctrl = ppin; */ break; } + #else + break; + #endif /* else -> aml_irq_cdin_thread() *should be using one of the GPIO of card, * then we should wait here until the GPIO is free, diff --git a/include/linux/amlogic/aml_sd_emmc_internal.h b/include/linux/amlogic/aml_sd_emmc_internal.h index a004227db5c4..9d0d8635549f 100644 --- a/include/linux/amlogic/aml_sd_emmc_internal.h +++ b/include/linux/amlogic/aml_sd_emmc_internal.h @@ -40,4 +40,9 @@ extern int aml_sd_emmc_post_dma(struct amlsd_host *host, extern u32 aml_sd_emmc_tuning_transfer(struct mmc_host *mmc, u32 opcode, const u8 *blk_pattern, u8 *blk_test, u32 blksz); +void aml_mmc_clk_switch_off(struct amlsd_host *host); + +void aml_mmc_clk_switch(struct amlsd_host *host, + int clk_div, int clk_src_sel); + #endif diff --git a/include/linux/amlogic/amlsd.h b/include/linux/amlogic/amlsd.h index 7d999acbf4b6..14c0ce08c9dc 100644 --- a/include/linux/amlogic/amlsd.h +++ b/include/linux/amlogic/amlsd.h @@ -19,6 +19,12 @@ #define AMLSD_H #include +/* ptm or pxp simulation */ +#define CONFIG_MESON_CPU_EMULATOR +/* hardcode clock, for debug or bringup */ +/* #define SD_EMMC_CLK_CTRL (1) */ +/* #define SD_EMMC_PIN_CTRL (1) */ + #define AML_MMC_MAJOR_VERSION 3 #define AML_MMC_MINOR_VERSION 02 #define AML_MMC_VERSION \ diff --git a/include/linux/amlogic/sd.h b/include/linux/amlogic/sd.h index 2ffacc58e7a1..d73066e96e73 100644 --- a/include/linux/amlogic/sd.h +++ b/include/linux/amlogic/sd.h @@ -170,6 +170,7 @@ enum mmc_chip_e { MMC_CHIP_AXG = 0x25, MMC_CHIP_GXLX = 0x26, MMC_CHIP_TXHD = 0x27, + MMC_CHIP_G12A = 0x28, }; struct meson_mmc_data { @@ -1586,30 +1587,30 @@ struct sd_emmc_desc_info { u32 resp_addr; }; #define HHI_NAND_CLK_CNTL 0x97 -#define SD_EMMC_MAX_DESC_MUN 512 -#define SD_EMMC_REQ_DESC_MUN 4 -#define SD_EMMC_CLOCK_SRC_OSC 0 /* 24MHz */ -#define SD_EMMC_CLOCK_SRC_FCLK_DIV2 1 /* 1GHz */ -#define SD_EMMC_CLOCK_SRC_400MHZ 4 -#define SD_EMMC_CLOCK_SRC_MPLL 2 /* MPLL */ -#define SD_EMMC_CLOCK_SRC_DIFF_PLL 3 -#define SD_EMMC_IRQ_ALL 0x3fff -#define SD_EMMC_RESP_SRAM_OFF 0 +#define SD_EMMC_MAX_DESC_MUN 512 +#define SD_EMMC_REQ_DESC_MUN 4 +#define SD_EMMC_CLOCK_SRC_OSC 0 /* 24MHz */ +#define SD_EMMC_CLOCK_SRC_FCLK_DIV2 1 /* 1GHz */ +#define SD_EMMC_CLOCK_SRC_400MHZ 4 +#define SD_EMMC_CLOCK_SRC_MPLL 2 /* MPLL */ +#define SD_EMMC_CLOCK_SRC_DIFF_PLL 3 +#define SD_EMMC_IRQ_ALL 0x3fff +#define SD_EMMC_RESP_SRAM_OFF 0 /*#define SD_EMMC_DESC_SET_REG*/ -#define SD_EMMC_DESC_REG_CONF 0x4 -#define SD_EMMC_DESC_REG_IRQC 0xC -#define SD_EMMC_DESC_RESP_STAT 0xfff80000 +#define SD_EMMC_DESC_REG_CONF 0x4 +#define SD_EMMC_DESC_REG_IRQC 0xC +#define SD_EMMC_DESC_RESP_STAT 0xfff80000 #define SD_EMMC_IRQ_EN_ALL_INIT #define SD_EMMC_REQ_DMA_SGMAP /* #define SD_EMMC_CLK_CTRL*/ /* #define SD_EMMC_DATA_TASKLET */ -#define STAT_POLL_TIMEOUT 0xfffff -#define STAT_POLL_TIMEOUT 0xfffff +#define STAT_POLL_TIMEOUT 0xfffff +#define STAT_POLL_TIMEOUT 0xfffff -#define MMC_RSP_136_NUM 4 -#define MMC_MAX_DEVICE 3 -#define MMC_TIMEOUT 5000 +#define MMC_RSP_136_NUM 4 +#define MMC_MAX_DEVICE 3 +#define MMC_TIMEOUT 5000 /* #define pr_info(a...) */ #define DBG_LINE_INFO() \ @@ -1618,15 +1619,26 @@ struct sd_emmc_desc_info { } /* #define DBG_LINE_INFO() */ /* #define dev_err(a,s) pr_info(KERN_INFO s); */ +/* fixme, those code should not be marco as vairous on chips */ +/* reg0 for BOOT */ +#define BOOT_POLL_UP (0x3A << 2) +#define BOOT_POLL_UP_EN (0x48 << 2) +/* reg1 for GPIOC(card) */ +#define CARD_POLL_UP (0x3B << 2) +#define CARD_POLL_UP_EN (0x49 << 2) + +/* pinmux for sdcards, gpioC */ +#define PIN_MUX_REG6 (0xb6 << 2) +#define PIN_MUX_REG9 (0xb9 << 2) #define AML_MMC_DISABLED_TIMEOUT 100 #define AML_MMC_SLEEP_TIMEOUT 1000 -#define AML_MMC_OFF_TIMEOUT 8000 +#define AML_MMC_OFF_TIMEOUT 8000 #define SD_EMMC_BOUNCE_REQ_SIZE (512*1024) #define SDHC_BOUNCE_REQ_SIZE (512*1024) #define SDIO_BOUNCE_REQ_SIZE (128*1024) -#define MMC_TIMEOUT_MS 20 +#define MMC_TIMEOUT_MS (20) #define MESON_SDIO_PORT_A 0 #define MESON_SDIO_PORT_B 1 @@ -1641,12 +1653,12 @@ extern void amlsd_init_debugfs(struct mmc_host *host); extern struct mmc_host *sdio_host; -#define SPI_BOOT_FLAG 0 -#define NAND_BOOT_FLAG 1 -#define EMMC_BOOT_FLAG 2 -#define CARD_BOOT_FLAG 3 -#define SPI_NAND_FLAG 4 -#define SPI_EMMC_FLAG 5 +#define SPI_BOOT_FLAG 0 +#define NAND_BOOT_FLAG 1 +#define EMMC_BOOT_FLAG 2 +#define CARD_BOOT_FLAG 3 +#define SPI_NAND_FLAG 4 +#define SPI_EMMC_FLAG 5 #define R_BOOT_DEVICE_FLAG (aml_read_cbus(ASSIST_POR_CONFIG))