// Copyright 2018 The Fuchsia Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #pragma once //From EMMC Design documentation provided by AMLOGIC #define AML_SD_EMMC_IRQ_ALL_CLEAR 0x3fff #define AML_SD_EMMC_CTS_OSCIN_CLK_FREQ 24000000 //24MHz #define AML_SD_EMMC_CTS_OSCIN_CLK_SRC 0 #define AML_SD_EMMC_FCLK_DIV2_FREQ 1000000000 //1GHz #define AML_SD_EMMC_FCLK_DIV2_SRC 1 //~Min freq attainable with DIV2 Src #define AML_SD_EMMC_FCLK_DIV2_MIN_FREQ 20000000 //20MHz #define AML_SD_EMMC_MAX_BLK_SIZE 512 //Default values after reset.EMMC Design Docs by AMLOGIC: PG 56 #define AML_SD_EMMC_DEFAULT_BL_LEN 9 //512 bytes #define AML_SD_EMMC_DEFAULT_RESP_TIMEOUT 8 //256 core clock cycles #define AML_SD_EMMC_DEFAULT_RC_CC 4 //16 core clock cycles #define AML_SD_EMMC_DEFAULT_CLK_SRC 0 //24MHz #define AML_SD_EMMC_DEFAULT_CLK_DIV 60 //Defaults to 400KHz #define AML_SD_EMMC_DEFAULT_CLK_CORE_PHASE 2 #define AML_SD_EMMC_MAX_TUNING_TRIES 7 #define AML_SD_EMMC_ADJ_DELAY_TEST_ATTEMPTS 10 #define AML_SD_EMMC_DEFAULT_CMD_TIMEOUT 0xc //2^12 ms. #define AML_SD_EMMC_SRAM_MEMORY_BASE 0x200 #define AML_SD_EMMC_SRAM_MEMORY_SIZE 512 #define AML_SD_EMMC_PING_BUFFER_BASE 0x400 #define AML_SD_EMMC_PING_BUFFER_SIZE 512 #define AML_SD_EMMC_PONG_BUFER_BASE 0x600 #define AML_SD_EMMC_PONG_BUFFER_SIZE 512 #define AML_SD_EMMC_MAX_PIO_DESCS 32 // 16 * 32 = 512 #define AML_SD_EMMC_MAX_PIO_DATA_SIZE AML_SD_EMMC_PING_BUFFER_SIZE + \ AML_SD_EMMC_PONG_BUFFER_SIZE #define AML_SDIO_PORTB_GPIO_REG_5_VAL 0x00020000 #define AML_SDIO_PORTB_PERIPHS_PINMUX2_VAL 0x01000000 #define AML_SDIO_PORTB_PERIPHS_GPIO2_EN 0xffffffef #define AML_SDIO_PORTB_HHI_GCLK_MPEG0_VAL 0x02000000 #define AML_SDIO_PORTB_SD_EMMC_CLK_VAL 0xf181ffff static inline void update_bits(uint32_t *x, uint32_t mask, uint32_t loc, uint32_t val) { *x &= ~mask; *x |= ((val << loc) & mask); } static inline uint32_t get_bits(uint32_t x, uint32_t mask, uint32_t loc) { return (x & mask) >> loc; } static inline bool get_bit(uint32_t x, uint32_t mask) { return (x & mask) ? 1 : 0; } typedef struct { volatile uint32_t sd_emmc_clock; // 0x00 #define AML_SD_EMMC_CLOCK_CFG_DIV_LOC 0 #define AML_SD_EMMC_CLOCK_CFG_DIV_MASK 0x0000003f #define AML_SD_EMMC_CLOCK_CFG_SRC_LOC 6 #define AML_SD_EMMC_CLOCK_CFG_SRC_MASK 0x000000c0 #define AML_SD_EMMC_CLOCK_CFG_CO_PHASE_LOC 8 #define AML_SD_EMMC_CLOCK_CFG_CO_PHASE_MASK 0x00000300 #define AML_SD_EMMC_CLOCK_CFG_TX_PHASE_LOC 10 #define AML_SD_EMMC_CLOCK_CFG_TX_PHASE_MASK 0x00000c00 #define AML_SD_EMMC_CLOCK_CFG_RX_PHASE_LOC 12 #define AML_SD_EMMC_CLOCK_CFG_RX_PHASE_MASK 0x00003000 #define AML_SD_EMMC_CLOCK_CFG_SRAM_PD_LOC 14 #define AML_SD_EMMC_CLOCK_CFG_SRAM_PD_MASK 0x0000c000 #define AML_SD_EMMC_CLOCK_CFG_TX_DELAY_LOC 16 #define AML_SD_EMMC_CLOCK_CFG_TX_DELAY_MASK 0x003f0000 #define AML_SD_EMMC_CLOCK_CFG_RX_DELAY_LOC 22 #define AML_SD_EMMC_CLOCK_CFG_RX_DELAY_MASK 0x0fc00000 #define AML_SD_EMMC_CLOCK_CFG_ALWAYS_ON 0x10000000 #define AML_SD_EMMC_CLOCK_CFG_IRQ_SDIO_SLEEP 0x20000000 #define AML_SD_EMMC_CLOCK_CFG_IRQ_SDIO_SLEEP_DS 0x40000000 #define AML_SD_EMMC_CLOCK_CFG_NAND 0x80000000 volatile uint32_t sd_emmc_delay1; // 0x04 #define AML_SD_EMMC_DELAY_DATA0_LOC 0 #define AML_SD_EMMC_DELAY_DATA0_MASK 0x0000003f #define AML_SD_EMMC_DELAY_DATA1_LOC 6 #define AML_SD_EMMC_DELAY_DATA1_MASK 0x00000fc0 #define AML_SD_EMMC_DELAY_DATA2_LOC 12 #define AML_SD_EMMC_DELAY_DATA2_MASK 0x0003f000 #define AML_SD_EMMC_DELAY_DATA3_LOC 18 #define AML_SD_EMMC_DELAY_DATA3_MASK 0x00fc0000 #define AML_SD_EMMC_DELAY_DATA4_LOC 24 #define AML_SD_EMMC_DELAY_DATA4_MASK 0x3f000000 #define AML_SD_EMMC_DELAY_SPARE_LOC 30 #define AML_SD_EMMC_DELAY_SPARE_MASK 0xc0000000 volatile uint32_t sd_emmc_delay2; //0x08 volatile uint32_t sd_emmc_adjust; // 0x0c #define AML_SD_EMMC_ADJUST_CALI_SEL_LOC 8 #define AML_SD_EMMC_ADJUST_CALI_SEL_MASK 0x00000f00 #define AML_SD_EMMC_ADJUST_CALI_ENABLE 0x00001000 #define AML_SD_EMMC_ADJUST_ADJ_FIXED 0x00002000 #define AML_SD_EMMC_ADJUST_CALI_RISE 0x00004000 #define AML_SD_EMMC_ADJUST_DS_ENABLE 0x00008000 #define AML_SD_EMMC_ADJUST_ADJ_DELAY_LOC 16 #define AML_SD_EMMC_ADJUST_ADJ_DELAY_MASK 0x003f0000 #define AML_SD_EMMC_ADJUST_ADJ_AUTO 0x00400000 volatile uint32_t sd_emmc_calout; // 0x10 #define AML_SD_EMMC_CALOUT_CALI_IDX_LOC 0 #define AML_SD_EMMC_CALOUT_CALI_IDX_MASK 0x0000003f #define AML_SD_EMMC_CALOUT_CALI_VLD 0x00000040 #define AML_SD_EMMC_CALOUT_CALI_SETUP_LOC 8 #define AML_SD_EMMC_CALOUT_CALI_SETUP_MASK 0x0000ff00 volatile uint32_t sd_emmc_calout_v2[3]; // 0x14~0x1c volatile uint32_t resvd_test[6]; // 0x20~0x34 volatile uint32_t sd_emmc_intf3[2]; // 0x38, 0x39 volatile uint32_t sd_emmc_start; // 0x40 #define AML_SD_EMMC_START_DESC_INT 0x00000001 #define AML_SD_EMMC_START_DESC_BUSY 0x00000002 #define AML_SD_EMMC_START_DESC_ADDR_LOC 2 #define AML_SD_EMMC_START_DESC_ADDR_MASK 0xfffffffc volatile uint32_t sd_emmc_cfg; // 0x44 #define AML_SD_EMMC_CFG_BUS_WIDTH_LOC 0 #define AML_SD_EMMC_CFG_BUS_WIDTH_MASK 0x00000003 #define AML_SD_EMMC_CFG_BUS_WIDTH_1BIT 0x00000000 #define AML_SD_EMMC_CFG_BUS_WIDTH_4BIT 0x00000001 #define AML_SD_EMMC_CFG_BUS_WIDTH_8BIT 0x00000002 #define AML_SD_EMMC_CFG_DDR 0x00000004 #define AML_SD_EMMC_CFG_DC_UGT 0x00000008 #define AML_SD_EMMC_CFG_BL_LEN_LOC 4 #define AML_SD_EMMC_CFG_BL_LEN_MASK 0x000000f0 #define AML_SD_EMMC_CFG_RESP_TIMEOUT_LOC 8 #define AML_SD_EMMC_CFG_RESP_TIMEOUT_MASK 0x00000f00 #define AML_SD_EMMC_CFG_RC_CC_LOC 12 #define AML_SD_EMMC_CFG_RC_CC_MASK 0x0000f000 #define AML_SD_EMMC_CFG_OUT_FALL 0x00010000 #define AML_SD_EMMC_CFG_BLK_GAP_IP 0x00020000 #define AML_SD_EMMC_CFG_SDCLK_ALWAYS_ON 0x00040000 #define AML_SD_EMMC_CFG_IGNORE_OWNER 0x00080000 #define AML_SD_EMMC_CFG_CHK_DS 0x00100000 #define AML_SD_EMMC_CFG_CMD_LOW 0x00200000 #define AML_SD_EMMC_CFG_STOP_CLK 0x00400000 #define AML_SD_EMMC_CFG_AUTO_CLK 0x00800000 #define AML_SD_EMMC_CFG_TXD_ADD_ERR 0x01000000 #define AML_SD_EMMC_CFG_TXD_RETRY 0x02000000 #define AML_SD_EMMC_CFG_IRQ_DS 0x04000000 #define AML_SD_EMMC_CFG_ERR_ABORT 0x08000000 #define AML_SD_EMMC_CFG_IP_TXD_ADJ_LOC 28 #define AML_SD_EMMC_CFG_IP_TXD_ADJ_MASK 0xf0000000 volatile uint32_t sd_emmc_status; // 0x48 #define AML_SD_EMMC_STATUS_RXD_ERR_LOC 0 #define AML_SD_EMMC_STATUS_RXD_ERR_MASK 0x000000ff #define AML_SD_EMMC_STATUS_TXD_ERR 0x00000100 #define AML_SD_EMMC_STATUS_DESC_ERR 0x00000200 #define AML_SD_EMMC_STATUS_RESP_ERR 0x00000400 #define AML_SD_EMMC_STATUS_RESP_TIMEOUT 0x00000800 #define AML_SD_EMMC_STATUS_DESC_TIMEOUT 0x00001000 #define AML_SD_EMMC_STATUS_END_OF_CHAIN 0x00002000 #define AML_SD_EMMC_STATUS_RESP_STATUS 0x00004000 #define AML_SD_EMMC_STATUS_IRQ_SDIO 0x00008000 #define AML_SD_EMMC_STATUS_DAT_I_LOC 16 #define AML_SD_EMMC_STATUS_DAT_I_MASK 0x00ff0000 #define AML_SD_EMMC_STATUS_CMD_I 0x01000000 #define AML_SD_EMMC_STATUS_DS 0x02000000 #define AML_SD_EMMC_STATUS_BUS_FSM_LOC 26 #define AML_SD_EMMC_STATUS_BUS_FSM_MASK 0x3c000000 #define AML_SD_EMMC_STATUS_BUS_DESC_BUSY 0x40000000 #define AML_SD_EMMC_STATUS_BUS_CORE_BUSY 0x80000000 volatile uint32_t sd_emmc_irq_en; // 0x4c volatile uint32_t sd_emmc_cmd_cfg; // 0x50 #define AML_SD_EMMC_CMD_INFO_LEN_LOC 0 #define AML_SD_EMMC_CMD_INFO_LEN_MASK 0x000001ff #define AML_SD_EMMC_CMD_INFO_BLOCK_MODE 0x00000200 #define AML_SD_EMMC_CMD_INFO_R1B 0x00000400 #define AML_SD_EMMC_CMD_INFO_END_OF_CHAIN 0x00000800 #define AML_SD_EMMC_CMD_INFO_TIMEOUT_LOC 12 #define AML_SD_EMMC_CMD_INFO_TIMEOUT_MASK 0x0000f000 #define AML_SD_EMMC_CMD_INFO_NO_RESP 0x00010000 #define AML_SD_EMMC_CMD_INFO_NO_CMD 0x00020000 #define AML_SD_EMMC_CMD_INFO_DATA_IO 0x00040000 #define AML_SD_EMMC_CMD_INFO_DATA_WR 0x00080000 #define AML_SD_EMMC_CMD_INFO_RESP_NO_CRC 0x00100000 #define AML_SD_EMMC_CMD_INFO_RESP_128 0x00200000 #define AML_SD_EMMC_CMD_INFO_RESP_NUM 0x00400000 #define AML_SD_EMMC_CMD_INFO_DATA_NUM 0x00800000 #define AML_SD_EMMC_CMD_INFO_CMD_IDX_LOC 24 #define AML_SD_EMMC_CMD_INFO_CMD_IDX_MASK 0x3f000000 #define AML_SD_EMMC_CMD_INFO_ERROR 0x40000000 #define AML_SD_EMMC_CMD_INFO_OWNER 0x80000000 volatile uint32_t sd_emmc_cmd_arg; // 0x54 volatile uint32_t sd_emmc_cmd_dat; // 0x58 volatile uint32_t sd_emmc_cmd_rsp; // 0x5c volatile uint32_t sd_emmc_cmd_rsp1; // 0x60 volatile uint32_t sd_emmc_cmd_rsp2; // 0x64 volatile uint32_t sd_emmc_cmd_rsp3; // 0x68 volatile uint32_t bus_err; // 0x6c volatile uint32_t sd_emmc_curr_cfg; // 0x70 volatile uint32_t sd_emmc_curr_arg; // 0x74 volatile uint32_t sd_emmc_curr_dat; // 0x78 volatile uint32_t sd_emmc_curr_rsp; // 0x7c volatile uint32_t sd_emmc_next_cfg; // 0x80 volatile uint32_t sd_emmc_next_arg; // 0x84 volatile uint32_t sd_emmc_next_dat; // 0x88 volatile uint32_t sd_emmc_next_rsp; // 0x8c volatile uint32_t sd_emmc_rxd; // 0x90 volatile uint32_t sd_emmc_txd; // 0x94 volatile uint32_t resvd[90]; // 0x98~0x1fc volatile uint32_t sramDesc[128]; // 0x200 volatile uint32_t ping[128]; // 0x400 volatile uint32_t pong[128]; // 0x800 } aml_sd_emmc_regs_t; typedef struct { uint32_t cmd_info; uint32_t cmd_arg; uint32_t data_addr; uint32_t resp_addr; } aml_sd_emmc_desc_t; typedef struct { bool supports_dma; uint32_t min_freq; uint32_t max_freq; } aml_sd_emmc_config_t; static const uint8_t aml_sd_emmc_tuning_blk_pattern_4bit[64] = { 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, }; static const uint8_t aml_sd_emmc_tuning_blk_pattern_8bit[128] = { 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, };