blob: 7dd1727789a779786f8aba710f399f73874531c2 [file] [log] [blame]
// Copyright 2019 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.
#pragma once
#include <hwreg/bitfields.h>
#include <zircon/types.h>
constexpr uint32_t kAmlSdEmmcClockOffset = 0x00;
constexpr uint32_t kAmlSdEmmcDelay1Offset = 0x04;
constexpr uint32_t kAmlSdEmmcDelay2Offset = 0x08;
constexpr uint32_t kAmlSdEmmcAdjustOffset = 0x0c;
constexpr uint32_t kAmlSdEmmcCaloutOffset = 0x10;
constexpr uint32_t kAmlSdEmmcCaloutV2Offset = 0x14;
constexpr uint32_t kAmlSdEmmcStartOffset = 0x40;
constexpr uint32_t kAmlSdEmmcCfgOffset = 0x44;
constexpr uint32_t kAmlSdEmmcStatusOffset = 0x48;
constexpr uint32_t kAmlSdEmmcIrqEnOffset = 0x4c;
constexpr uint32_t kAmlSdEmmcCmdCfgOffset = 0x50;
constexpr uint32_t kAmlSdEmmcCmdArgOffset = 0x54;
constexpr uint32_t kAmlSdEmmcCmdDatOffset = 0x58;
constexpr uint32_t kAmlSdEmmcCmdRespOffset = 0x5c;
constexpr uint32_t kAmlSdEmmcCmdResp1Offset = 0x60;
constexpr uint32_t kAmlSdEmmcCmdResp2Offset = 0x64;
constexpr uint32_t kAmlSdEmmcCmdResp3Offset = 0x68;
constexpr uint32_t kAmlSdEmmcCmdBusErrOffset = 0x6c;
constexpr uint32_t kAmlSdEmmcCurCfgOffset = 0x70;
constexpr uint32_t kAmlSdEmmcCurArgOffset = 0x74;
constexpr uint32_t kAmlSdEmmcCurDatOffset = 0x78;
constexpr uint32_t kAmlSdEmmcCurRespOffset = 0x7c;
constexpr uint32_t kAmlSdEmmcNextCfgOffset = 0x80;
constexpr uint32_t kAmlSdEmmcNextArgOffset = 0x84;
constexpr uint32_t kAmlSdEmmcNextDatOffset = 0x88;
constexpr uint32_t kAmlSdEmmcNextRespOffset = 0x8c;
constexpr uint32_t kAmlSdEmmcRxdOffset = 0x90;
constexpr uint32_t kAmlSdEmmcTxdOffset = 0x94;
constexpr uint32_t kAmlSdEmmcSramDescOffset = 0x200;
constexpr uint32_t kAmlSdEmmcPingOffset = 0x400;
constexpr uint32_t kAmlSdEmmcPongOffset = 0x600;
class AmlSdEmmcClock : public hwreg::RegisterBase<AmlSdEmmcClock, uint32_t> {
public:
static constexpr uint32_t kCtsOscinClkFreq = 24000000; // 24MHz
static constexpr uint32_t kCtsOscinClkSrc = 0;
static constexpr uint32_t kFClkDiv2Freq = 1000000000; // 24MHz
static constexpr uint32_t kFClkDiv2Src = 1;
//~Min freq attainable with DIV2 Src
static constexpr uint32_t kFClkDiv2MinFreq = 20000000; // 20MHz
static constexpr uint32_t kDefaultClkSrc = 0; // 24MHz
static constexpr uint32_t kDefaultClkDiv = 60; // Defaults to 400KHz
static constexpr uint32_t kDefaultClkCorePhase = 2;
static constexpr uint32_t kMaxClkDiv = 63;
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcClock>(kAmlSdEmmcClockOffset); }
DEF_FIELD(5, 0, cfg_div);
DEF_FIELD(7, 6, cfg_src);
DEF_FIELD(9, 8, cfg_co_phase);
DEF_FIELD(11, 10, cfg_tx_phase);
DEF_FIELD(13, 12, cfg_rx_phase);
DEF_FIELD(15, 14, cfg_sram_pd);
DEF_FIELD(21, 16, cfg_tx_delay);
DEF_FIELD(27, 22, cfg_rx_delay);
DEF_BIT(28, cfg_always_on);
DEF_BIT(29, cfg_irq_sdio_sleep);
DEF_BIT(30, cfg_irq_sdio_sleep_ds);
DEF_BIT(31, cfg_nand);
};
class AmlSdEmmcCfg : public hwreg::RegisterBase<AmlSdEmmcCfg, uint32_t> {
public:
static constexpr uint32_t kBusWidth1Bit = 0;
static constexpr uint32_t kBusWidth4Bit = 1;
static constexpr uint32_t kBusWidth8Bit = 2;
static constexpr uint32_t kDefaultBlkLen = 9; // 512 bytes
static constexpr uint32_t kDefaultRespTimeout = 8; // 256 core clock cycles
static constexpr uint32_t kDefaultRcCc = 4; // 16 core clock cycles
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCfg>(kAmlSdEmmcCfgOffset); }
DEF_FIELD(1, 0, bus_width);
DEF_BIT(2, ddr);
DEF_BIT(3, dc_ugt);
DEF_FIELD(7, 4, blk_len);
DEF_FIELD(11, 8, resp_timeout);
DEF_FIELD(15, 12, rc_cc);
DEF_BIT(16, out_fall);
DEF_BIT(17, blk_gap_ip);
DEF_BIT(18, sdclk_always_on);
DEF_BIT(19, ignore_owner);
DEF_BIT(20, chk_ds);
DEF_BIT(21, cmd_low);
DEF_BIT(22, stop_clk);
DEF_BIT(23, auto_clk);
DEF_BIT(24, txd_add_err);
DEF_BIT(25, txd_retry);
DEF_BIT(26, irq_ds);
DEF_BIT(27, err_abort);
DEF_FIELD(31, 28, ip_txd_adj);
};
class AmlSdEmmcStatus : public hwreg::RegisterBase<AmlSdEmmcStatus, uint32_t> {
public:
static constexpr uint32_t kClearStatus = 0x3fff;
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcStatus>(kAmlSdEmmcStatusOffset); }
DEF_FIELD(7, 0, rxd_err);
DEF_BIT(8, txd_err);
DEF_BIT(9, desc_err);
DEF_BIT(10, resp_err);
DEF_BIT(11, resp_timeout);
DEF_BIT(12, desc_timeout);
DEF_BIT(13, end_of_chain);
DEF_BIT(14, resp_status);
DEF_BIT(15, irq_sdio);
DEF_FIELD(23, 16, dat_i);
DEF_BIT(24, cmd_i);
DEF_BIT(25, ds);
DEF_FIELD(29, 26, bus_fsm);
DEF_BIT(30, desc_busy);
DEF_BIT(31, core_busy);
};
class AmlSdEmmcCmdCfg : public hwreg::RegisterBase<AmlSdEmmcCmdCfg, uint32_t> {
public:
static constexpr uint32_t kDefaultCmdTimeout = 0xc; // 2^12 ms.
static constexpr uint32_t kMaxBlockSize = 512; // 9 bits
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCmdCfg>(kAmlSdEmmcCmdCfgOffset); }
void set_length(uint32_t length) {
if (length >= AmlSdEmmcCmdCfg::kMaxBlockSize) {
// Controller supports 512bytes and uses 0 to denote that.
length = 0;
}
set_len(length);
}
DEF_FIELD(8, 0, len);
DEF_BIT(9, block_mode);
DEF_BIT(10, r1b);
DEF_BIT(11, end_of_chain);
DEF_FIELD(15, 12, timeout);
DEF_BIT(16, no_resp);
DEF_BIT(17, no_cmd);
DEF_BIT(18, data_io);
DEF_BIT(19, data_wr);
DEF_BIT(20, resp_no_crc);
DEF_BIT(21, resp_128);
DEF_BIT(22, resp_num);
DEF_BIT(23, data_num);
DEF_FIELD(29, 24, cmd_idx);
DEF_BIT(30, error);
DEF_BIT(31, owner);
};
class AmlSdEmmcIrqEn : public hwreg::RegisterBase<AmlSdEmmcIrqEn, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcIrqEn>(kAmlSdEmmcIrqEnOffset); }
};
class AmlSdEmmcCmdResp : public hwreg::RegisterBase<AmlSdEmmcCmdResp, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCmdResp>(kAmlSdEmmcCmdRespOffset); }
};
class AmlSdEmmcCmdResp1 : public hwreg::RegisterBase<AmlSdEmmcCmdResp1, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCmdResp1>(kAmlSdEmmcCmdResp1Offset); }
};
class AmlSdEmmcCmdResp2 : public hwreg::RegisterBase<AmlSdEmmcCmdResp2, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCmdResp2>(kAmlSdEmmcCmdResp2Offset); }
};
class AmlSdEmmcCmdResp3 : public hwreg::RegisterBase<AmlSdEmmcCmdResp3, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCmdResp3>(kAmlSdEmmcCmdResp3Offset); }
};
class AmlSdEmmcDelay1 : public hwreg::RegisterBase<AmlSdEmmcDelay1, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcDelay1>(kAmlSdEmmcDelay1Offset); }
};
class AmlSdEmmcDelay2 : public hwreg::RegisterBase<AmlSdEmmcDelay2, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcDelay2>(kAmlSdEmmcDelay2Offset); }
};
class AmlSdEmmcCalout : public hwreg::RegisterBase<AmlSdEmmcCalout, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCalout>(kAmlSdEmmcCaloutOffset); }
};
class AmlSdEmmcCmdArg : public hwreg::RegisterBase<AmlSdEmmcCmdArg, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCmdArg>(kAmlSdEmmcCmdArgOffset); }
};
class AmlSdEmmcCmdDat : public hwreg::RegisterBase<AmlSdEmmcCmdDat, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCmdDat>(kAmlSdEmmcCmdDatOffset); }
};
class AmlSdEmmcCmdBusErr : public hwreg::RegisterBase<AmlSdEmmcCmdBusErr, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCmdBusErr>(kAmlSdEmmcCmdBusErrOffset); }
};
class AmlSdEmmcCurCfg : public hwreg::RegisterBase<AmlSdEmmcCurCfg, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCurCfg>(kAmlSdEmmcCurCfgOffset); }
};
class AmlSdEmmcCurArg : public hwreg::RegisterBase<AmlSdEmmcCurArg, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCurArg>(kAmlSdEmmcCurArgOffset); }
};
class AmlSdEmmcCurDat : public hwreg::RegisterBase<AmlSdEmmcCurDat, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCurDat>(kAmlSdEmmcCurDatOffset); }
};
class AmlSdEmmcCurResp : public hwreg::RegisterBase<AmlSdEmmcCurResp, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcCurResp>(kAmlSdEmmcCurRespOffset); }
};
class AmlSdEmmcNextCfg : public hwreg::RegisterBase<AmlSdEmmcNextCfg, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcNextCfg>(kAmlSdEmmcNextCfgOffset); }
};
class AmlSdEmmcNextArg : public hwreg::RegisterBase<AmlSdEmmcNextArg, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcNextArg>(kAmlSdEmmcNextArgOffset); }
};
class AmlSdEmmcNextDat : public hwreg::RegisterBase<AmlSdEmmcNextDat, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcNextDat>(kAmlSdEmmcNextDatOffset); }
};
class AmlSdEmmcNextResp : public hwreg::RegisterBase<AmlSdEmmcNextResp, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcNextResp>(kAmlSdEmmcNextRespOffset); }
};
class AmlSdEmmcStart : public hwreg::RegisterBase<AmlSdEmmcStart, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcStart>(kAmlSdEmmcStartOffset); }
DEF_BIT(0, desc_int);
DEF_BIT(1, desc_busy);
DEF_FIELD(31, 2, desc_addr);
};
class AmlSdEmmcAdjust : public hwreg::RegisterBase<AmlSdEmmcAdjust, uint32_t> {
public:
static auto Get() { return hwreg::RegisterAddr<AmlSdEmmcAdjust>(kAmlSdEmmcAdjustOffset); }
DEF_FIELD(11, 8, cali_sel);
DEF_BIT(12, cali_enable);
DEF_BIT(13, adj_fixed);
DEF_BIT(14, cali_rise);
DEF_BIT(15, ds_enable);
DEF_FIELD(21, 16, adj_delay);
DEF_BIT(22, adj_auto);
};