1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <ddk/io-buffer.h> 6#include <string.h> 7 8#pragma once 9 10//From EMMC Design documentation provided by AMLOGIC 11#define AML_SD_EMMC_IRQ_ALL_CLEAR 0x3fff 12#define AML_SD_EMMC_CTS_OSCIN_CLK_FREQ 24000000 //24MHz 13#define AML_SD_EMMC_CTS_OSCIN_CLK_SRC 0 14#define AML_SD_EMMC_FCLK_DIV2_FREQ 1000000000 //1GHz 15#define AML_SD_EMMC_FCLK_DIV2_SRC 1 16//~Min freq attainable with DIV2 Src 17#define AML_SD_EMMC_FCLK_DIV2_MIN_FREQ 20000000 //20MHz 18 19#define AML_SD_EMMC_MAX_BLK_SIZE 512 20 21//Default values after reset.EMMC Design Docs by AMLOGIC: PG 56 22#define AML_SD_EMMC_DEFAULT_BL_LEN 9 //512 bytes 23#define AML_SD_EMMC_DEFAULT_RESP_TIMEOUT 8 //256 core clock cycles 24#define AML_SD_EMMC_DEFAULT_RC_CC 4 //16 core clock cycles 25#define AML_SD_EMMC_DEFAULT_CLK_SRC 0 //24MHz 26#define AML_SD_EMMC_DEFAULT_CLK_DIV 60 //Defaults to 400KHz 27#define AML_SD_EMMC_DEFAULT_CLK_CORE_PHASE 3 28#define AML_SD_EMMC_MAX_TUNING_TRIES 7 29#define AML_SD_EMMC_ADJ_DELAY_TEST_ATTEMPTS 10 30 31#define AML_SD_EMMC_DEFAULT_CMD_TIMEOUT 0xc //2^12 ms. 32 33#define AML_SD_EMMC_SRAM_MEMORY_BASE 0x200 34#define AML_SD_EMMC_SRAM_MEMORY_SIZE 512 35#define AML_SD_EMMC_PING_BUFFER_BASE 0x400 36#define AML_SD_EMMC_PING_BUFFER_SIZE 512 37#define AML_SD_EMMC_PONG_BUFER_BASE 0x600 38#define AML_SD_EMMC_PONG_BUFFER_SIZE 512 39#define AML_SD_EMMC_MAX_PIO_DESCS 32 // 16 * 32 = 512 40#define AML_SD_EMMC_MAX_PIO_DATA_SIZE AML_SD_EMMC_PING_BUFFER_SIZE + \ 41 AML_SD_EMMC_PONG_BUFFER_SIZE 42static inline void update_bits(uint32_t *x, uint32_t mask, uint32_t loc, uint32_t val) { 43 *x &= ~mask; 44 *x |= ((val << loc) & mask); 45} 46 47static inline uint32_t get_bits(uint32_t x, uint32_t mask, uint32_t loc) { 48 return (x & mask) >> loc; 49} 50 51static inline bool get_bit(uint32_t x, uint32_t mask) { 52 return (x & mask) ? 1 : 0; 53} 54 55typedef struct { 56 volatile uint32_t sd_emmc_clock; // 0x00 57#define AML_SD_EMMC_CLOCK_CFG_DIV_LOC 0 58#define AML_SD_EMMC_CLOCK_CFG_DIV_MASK 0x0000003f 59#define AML_SD_EMMC_CLOCK_CFG_SRC_LOC 6 60#define AML_SD_EMMC_CLOCK_CFG_SRC_MASK 0x000000c0 61#define AML_SD_EMMC_CLOCK_CFG_CO_PHASE_LOC 8 62#define AML_SD_EMMC_CLOCK_CFG_CO_PHASE_MASK 0x00000300 63#define AML_SD_EMMC_CLOCK_CFG_TX_PHASE_LOC 10 64#define AML_SD_EMMC_CLOCK_CFG_TX_PHASE_MASK 0x00000c00 65#define AML_SD_EMMC_CLOCK_CFG_RX_PHASE_LOC 12 66#define AML_SD_EMMC_CLOCK_CFG_RX_PHASE_MASK 0x00003000 67#define AML_SD_EMMC_CLOCK_CFG_SRAM_PD_LOC 14 68#define AML_SD_EMMC_CLOCK_CFG_SRAM_PD_MASK 0x0000c000 69#define AML_SD_EMMC_CLOCK_CFG_TX_DELAY_LOC 16 70#define AML_SD_EMMC_CLOCK_CFG_TX_DELAY_MASK 0x003f0000 71#define AML_SD_EMMC_CLOCK_CFG_RX_DELAY_LOC 22 72#define AML_SD_EMMC_CLOCK_CFG_RX_DELAY_MASK 0x0fc00000 73#define AML_SD_EMMC_CLOCK_CFG_ALWAYS_ON 0x10000000 74#define AML_SD_EMMC_CLOCK_CFG_IRQ_SDIO_SLEEP 0x20000000 75#define AML_SD_EMMC_CLOCK_CFG_IRQ_SDIO_SLEEP_DS 0x40000000 76#define AML_SD_EMMC_CLOCK_CFG_NAND 0x80000000 77 78 volatile uint32_t sd_emmc_delay1; // 0x04 79#define AML_SD_EMMC_DELAY_DATA0_LOC 0 80#define AML_SD_EMMC_DELAY_DATA0_MASK 0x0000003f 81#define AML_SD_EMMC_DELAY_DATA1_LOC 6 82#define AML_SD_EMMC_DELAY_DATA1_MASK 0x00000fc0 83#define AML_SD_EMMC_DELAY_DATA2_LOC 12 84#define AML_SD_EMMC_DELAY_DATA2_MASK 0x0003f000 85#define AML_SD_EMMC_DELAY_DATA3_LOC 18 86#define AML_SD_EMMC_DELAY_DATA3_MASK 0x00fc0000 87#define AML_SD_EMMC_DELAY_DATA4_LOC 24 88#define AML_SD_EMMC_DELAY_DATA4_MASK 0x3f000000 89#define AML_SD_EMMC_DELAY_SPARE_LOC 30 90#define AML_SD_EMMC_DELAY_SPARE_MASK 0xc0000000 91 92 volatile uint32_t sd_emmc_delay2; //0x08 93 94 volatile uint32_t sd_emmc_adjust; // 0x0c 95#define AML_SD_EMMC_ADJUST_CALI_SEL_LOC 8 96#define AML_SD_EMMC_ADJUST_CALI_SEL_MASK 0x00000f00 97#define AML_SD_EMMC_ADJUST_CALI_ENABLE 0x00001000 98#define AML_SD_EMMC_ADJUST_ADJ_FIXED 0x00002000 99#define AML_SD_EMMC_ADJUST_CALI_RISE 0x00004000 100#define AML_SD_EMMC_ADJUST_DS_ENABLE 0x00008000 101#define AML_SD_EMMC_ADJUST_ADJ_DELAY_LOC 16 102#define AML_SD_EMMC_ADJUST_ADJ_DELAY_MASK 0x003f0000 103#define AML_SD_EMMC_ADJUST_ADJ_AUTO 0x00400000 104 105 volatile uint32_t sd_emmc_calout; // 0x10 106#define AML_SD_EMMC_CALOUT_CALI_IDX_LOC 0 107#define AML_SD_EMMC_CALOUT_CALI_IDX_MASK 0x0000003f 108#define AML_SD_EMMC_CALOUT_CALI_VLD 0x00000040 109#define AML_SD_EMMC_CALOUT_CALI_SETUP_LOC 8 110#define AML_SD_EMMC_CALOUT_CALI_SETUP_MASK 0x0000ff00 111 112 volatile uint32_t sd_emmc_calout_v2[3]; // 0x14~0x1c 113 volatile uint32_t resvd_test[6]; // 0x20~0x34 114 volatile uint32_t sd_emmc_intf3[2]; // 0x38, 0x39 115 116 volatile uint32_t sd_emmc_start; // 0x40 117#define AML_SD_EMMC_START_DESC_INT 0x00000001 118#define AML_SD_EMMC_START_DESC_BUSY 0x00000002 119#define AML_SD_EMMC_START_DESC_ADDR_LOC 2 120#define AML_SD_EMMC_START_DESC_ADDR_MASK 0xfffffffc 121 122 volatile uint32_t sd_emmc_cfg; // 0x44 123#define AML_SD_EMMC_CFG_BUS_WIDTH_LOC 0 124#define AML_SD_EMMC_CFG_BUS_WIDTH_MASK 0x00000003 125#define AML_SD_EMMC_CFG_BUS_WIDTH_1BIT 0x00000000 126#define AML_SD_EMMC_CFG_BUS_WIDTH_4BIT 0x00000001 127#define AML_SD_EMMC_CFG_BUS_WIDTH_8BIT 0x00000002 128#define AML_SD_EMMC_CFG_DDR 0x00000004 129#define AML_SD_EMMC_CFG_DC_UGT 0x00000008 130#define AML_SD_EMMC_CFG_BL_LEN_LOC 4 131#define AML_SD_EMMC_CFG_BL_LEN_MASK 0x000000f0 132#define AML_SD_EMMC_CFG_RESP_TIMEOUT_LOC 8 133#define AML_SD_EMMC_CFG_RESP_TIMEOUT_MASK 0x00000f00 134#define AML_SD_EMMC_CFG_RC_CC_LOC 12 135#define AML_SD_EMMC_CFG_RC_CC_MASK 0x0000f000 136#define AML_SD_EMMC_CFG_OUT_FALL 0x00010000 137#define AML_SD_EMMC_CFG_BLK_GAP_IP 0x00020000 138#define AML_SD_EMMC_CFG_SDCLK_ALWAYS_ON 0x00040000 139#define AML_SD_EMMC_CFG_IGNORE_OWNER 0x00080000 140#define AML_SD_EMMC_CFG_CHK_DS 0x00100000 141#define AML_SD_EMMC_CFG_CMD_LOW 0x00200000 142#define AML_SD_EMMC_CFG_STOP_CLK 0x00400000 143#define AML_SD_EMMC_CFG_AUTO_CLK 0x00800000 144#define AML_SD_EMMC_CFG_TXD_ADD_ERR 0x01000000 145#define AML_SD_EMMC_CFG_TXD_RETRY 0x02000000 146#define AML_SD_EMMC_CFG_IRQ_DS 0x04000000 147#define AML_SD_EMMC_CFG_ERR_ABORT 0x08000000 148#define AML_SD_EMMC_CFG_IP_TXD_ADJ_LOC 28 149#define AML_SD_EMMC_CFG_IP_TXD_ADJ_MASK 0xf0000000 150 151 volatile uint32_t sd_emmc_status; // 0x48 152#define AML_SD_EMMC_STATUS_RXD_ERR_LOC 0 153#define AML_SD_EMMC_STATUS_RXD_ERR_MASK 0x000000ff 154#define AML_SD_EMMC_STATUS_TXD_ERR 0x00000100 155#define AML_SD_EMMC_STATUS_DESC_ERR 0x00000200 156#define AML_SD_EMMC_STATUS_RESP_ERR 0x00000400 157#define AML_SD_EMMC_STATUS_RESP_TIMEOUT 0x00000800 158#define AML_SD_EMMC_STATUS_DESC_TIMEOUT 0x00001000 159#define AML_SD_EMMC_STATUS_END_OF_CHAIN 0x00002000 160#define AML_SD_EMMC_STATUS_RESP_STATUS 0x00004000 161#define AML_SD_EMMC_STATUS_IRQ_SDIO 0x00008000 162#define AML_SD_EMMC_STATUS_DAT_I_LOC 16 163#define AML_SD_EMMC_STATUS_DAT_I_MASK 0x00ff0000 164#define AML_SD_EMMC_STATUS_CMD_I 0x01000000 165#define AML_SD_EMMC_STATUS_DS 0x02000000 166#define AML_SD_EMMC_STATUS_BUS_FSM_LOC 26 167#define AML_SD_EMMC_STATUS_BUS_FSM_MASK 0x3c000000 168#define AML_SD_EMMC_STATUS_BUS_DESC_BUSY 0x40000000 169#define AML_SD_EMMC_STATUS_BUS_CORE_BUSY 0x80000000 170 171 volatile uint32_t sd_emmc_irq_en; // 0x4c 172 173 volatile uint32_t sd_emmc_cmd_cfg; // 0x50 174#define AML_SD_EMMC_CMD_INFO_LEN_LOC 0 175#define AML_SD_EMMC_CMD_INFO_LEN_MASK 0x000001ff 176#define AML_SD_EMMC_CMD_INFO_BLOCK_MODE 0x00000200 177#define AML_SD_EMMC_CMD_INFO_R1B 0x00000400 178#define AML_SD_EMMC_CMD_INFO_END_OF_CHAIN 0x00000800 179#define AML_SD_EMMC_CMD_INFO_TIMEOUT_LOC 12 180#define AML_SD_EMMC_CMD_INFO_TIMEOUT_MASK 0x0000f000 181#define AML_SD_EMMC_CMD_INFO_NO_RESP 0x00010000 182#define AML_SD_EMMC_CMD_INFO_NO_CMD 0x00020000 183#define AML_SD_EMMC_CMD_INFO_DATA_IO 0x00040000 184#define AML_SD_EMMC_CMD_INFO_DATA_WR 0x00080000 185#define AML_SD_EMMC_CMD_INFO_RESP_NO_CRC 0x00100000 186#define AML_SD_EMMC_CMD_INFO_RESP_128 0x00200000 187#define AML_SD_EMMC_CMD_INFO_RESP_NUM 0x00400000 188#define AML_SD_EMMC_CMD_INFO_DATA_NUM 0x00800000 189#define AML_SD_EMMC_CMD_INFO_CMD_IDX_LOC 24 190#define AML_SD_EMMC_CMD_INFO_CMD_IDX_MASK 0x3f000000 191#define AML_SD_EMMC_CMD_INFO_ERROR 0x40000000 192#define AML_SD_EMMC_CMD_INFO_OWNER 0x80000000 193 194 volatile uint32_t sd_emmc_cmd_arg; // 0x54 195 volatile uint32_t sd_emmc_cmd_dat; // 0x58 196 volatile uint32_t sd_emmc_cmd_rsp; // 0x5c 197 volatile uint32_t sd_emmc_cmd_rsp1; // 0x60 198 volatile uint32_t sd_emmc_cmd_rsp2; // 0x64 199 volatile uint32_t sd_emmc_cmd_rsp3; // 0x68 200 volatile uint32_t bus_err; // 0x6c 201 volatile uint32_t sd_emmc_curr_cfg; // 0x70 202 volatile uint32_t sd_emmc_curr_arg; // 0x74 203 volatile uint32_t sd_emmc_curr_dat; // 0x78 204 volatile uint32_t sd_emmc_curr_rsp; // 0x7c 205 volatile uint32_t sd_emmc_next_cfg; // 0x80 206 volatile uint32_t sd_emmc_next_arg; // 0x84 207 volatile uint32_t sd_emmc_next_dat; // 0x88 208 volatile uint32_t sd_emmc_next_rsp; // 0x8c 209 volatile uint32_t sd_emmc_rxd; // 0x90 210 volatile uint32_t sd_emmc_txd; // 0x94 211 volatile uint32_t resvd[90]; // 0x98~0x1fc 212 volatile uint32_t sramDesc[128]; // 0x200 213 volatile uint32_t ping[128]; // 0x400 214 volatile uint32_t pong[128]; // 0x800 215} aml_sd_emmc_regs_t; 216 217typedef struct { 218 uint32_t cmd_info; 219 uint32_t cmd_arg; 220 uint32_t data_addr; 221 uint32_t resp_addr; 222} aml_sd_emmc_desc_t; 223 224typedef struct { 225 bool supports_dma; 226 uint32_t max_freq; 227 uint32_t min_freq; 228} aml_sd_emmc_config_t; 229 230static const uint8_t aml_sd_emmc_tuning_blk_pattern_4bit[64] = { 231 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 232 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, 233 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, 234 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, 235 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, 236 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, 237 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, 238 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, 239}; 240 241static const uint8_t aml_sd_emmc_tuning_blk_pattern_8bit[128] = { 242 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 243 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 244 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 245 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, 246 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 247 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 248 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 249 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, 250 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 251 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 252 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 253 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 254 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 255 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 256 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 257 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 258}; 259