sdio: move ADMA2_DESCR32_TABLE into SdCard

This commit is contained in:
Astro 2020-06-10 00:38:59 +02:00 committed by Gitea
parent 1586190712
commit 316ea61702
2 changed files with 51 additions and 45 deletions

View File

@ -14,10 +14,6 @@ pub struct Adma2Desc32 {
address: VolatileCell<u32>,
}
// Default::default() cannot be used as it is not a constant function...
static mut ADMA2_DESCR32_TABLE: MaybeUninit<[Adma2Desc32; 32]> = MaybeUninit::uninit();
#[allow(unused)]
const DESC_MAX_LENGTH: u32 = 65536;
register!(desc32_attribute, Desc32Attribute, VolatileCell, u16);
@ -26,45 +22,53 @@ register_bit!(desc32_attribute, int, 2);
register_bit!(desc32_attribute, end, 1);
register_bit!(desc32_attribute, valid, 0);
/// Initialize `ADMA2_DESCR32_TABLE` and setup `adma_system_address`
pub fn setup_adma2_descr32(sdio: &mut SDIO, blk_cnt: u32, buffer: &[u8]) {
let descr_table = unsafe { &mut *ADMA2_DESCR32_TABLE.as_mut_ptr() };
let blk_size = sdio
.regs
.block_size_block_count
.read()
.transfer_block_size() as u32;
pub struct Adma2DescTable(MaybeUninit<[Adma2Desc32; 32]>);
let total_desc_lines = if blk_size * blk_cnt < DESC_MAX_LENGTH {
1
} else {
blk_size * blk_cnt / DESC_MAX_LENGTH
+ if (blk_size * blk_cnt) % DESC_MAX_LENGTH == 0 {
0
} else {
1
}
} as usize;
impl Adma2DescTable {
pub fn new() -> Self {
Adma2DescTable(MaybeUninit::uninit())
}
let ptr = buffer.as_ptr() as u32;
for desc_num in 0..total_desc_lines {
descr_table[desc_num].address.set(ptr + (desc_num as u32) * DESC_MAX_LENGTH);
descr_table[desc_num].attribute.write(
Desc32Attribute::zeroed()
.trans(true)
.valid(true)
/// Initialize the table and setup `adma_system_address`
pub fn setup(&mut self, sdio: &mut SDIO, blk_cnt: u32, buffer: &[u8]) {
let descr_table = unsafe { &mut *self.0.as_mut_ptr() };
let blk_size = sdio
.regs
.block_size_block_count
.read()
.transfer_block_size() as u32;
let total_desc_lines = if blk_size * blk_cnt < DESC_MAX_LENGTH {
1
} else {
blk_size * blk_cnt / DESC_MAX_LENGTH
+ if (blk_size * blk_cnt) % DESC_MAX_LENGTH == 0 {
0
} else {
1
}
} as usize;
let ptr = buffer.as_ptr() as u32;
for desc_num in 0..total_desc_lines {
descr_table[desc_num].address.set(ptr + (desc_num as u32) * DESC_MAX_LENGTH);
descr_table[desc_num].attribute.write(
Desc32Attribute::zeroed()
.trans(true)
.valid(true)
);
// 0 is the max length (65536)
descr_table[desc_num].length.set(0);
}
descr_table[total_desc_lines - 1].attribute.modify(|_, w| w.end(true));
descr_table[total_desc_lines - 1].length.set(
(blk_cnt * blk_size - ((total_desc_lines as u32) - 1) * DESC_MAX_LENGTH) as u16,
);
// 0 is the max length (65536)
descr_table[desc_num].length.set(0);
unsafe {
sdio.regs
.adma_system_address
.write(descr_table.as_ptr() as u32);
}
cache::dcci_slice(descr_table);
}
descr_table[total_desc_lines - 1].attribute.modify(|_, w| w.end(true));
descr_table[total_desc_lines - 1].length.set(
(blk_cnt * blk_size - ((total_desc_lines as u32) - 1) * DESC_MAX_LENGTH) as u16,
);
unsafe {
sdio.regs
.adma_system_address
.write(descr_table.as_ptr() as u32);
}
cache::dcci_slice(descr_table);
}

View File

@ -1,4 +1,4 @@
use super::{adma::setup_adma2_descr32, cmd, CardType, CmdTransferError, SDIO};
use super::{adma::Adma2DescTable, cmd, CardType, CmdTransferError, SDIO};
use libcortex_a9::cache;
use libregister::{RegisterR, RegisterRW, RegisterW};
use log::debug;
@ -25,6 +25,7 @@ enum CardVersion {
pub struct SdCard {
sdio: SDIO,
adma2_desc_table: Adma2DescTable,
card_version: CardVersion,
hcs: bool,
card_id: [u32; 4],
@ -165,6 +166,7 @@ impl SdCard {
};
let mut _self = SdCard {
sdio,
adma2_desc_table: Adma2DescTable::new(),
card_version: CardVersion::SdVer1,
hcs: false,
card_id: [0, 0, 0, 0],
@ -203,7 +205,7 @@ impl SdCard {
self.sdio.set_block_size(512)?;
}
setup_adma2_descr32(&mut self.sdio, block_cnt as u32, buffer);
self.adma2_desc_table.setup(&mut self.sdio, block_cnt as u32, buffer);
// invalidate D cache, required for ZC706, not sure for Cora Z7 10
cache::dcci_slice(buffer);
@ -256,7 +258,7 @@ impl SdCard {
self.sdio.set_block_size(512)?;
}
setup_adma2_descr32(&mut self.sdio, block_cnt as u32, buffer);
self.adma2_desc_table.setup(&mut self.sdio, block_cnt as u32, buffer);
// invalidate D cache, required for ZC706, not sure for Cora Z7 10
cache::dcci_slice(buffer);
@ -303,7 +305,7 @@ impl SdCard {
.block_size_block_count
.modify(|_, w| w.transfer_block_size(blk_size));
setup_adma2_descr32(&mut self.sdio, blk_cnt as u32, buf);
self.adma2_desc_table.setup(&mut self.sdio, blk_cnt as u32, buf);
cache::dcci_slice(buf);
self.sdio.cmd_transfer_with_mode(
ACMD51,