mirror of
https://github.com/akuker/RASCSI.git
synced 2024-11-22 01:31:25 +00:00
Optimize setting the data gpio bits (#1022)
Co-authored-by: Tony Kuker <akuker@gmail.com>
This commit is contained in:
parent
52c2aa474f
commit
09ba19a24f
@ -77,6 +77,8 @@ bool GPIOBUS_BananaM2p::Init(mode_e mode)
|
|||||||
|
|
||||||
InitializeGpio();
|
InitializeGpio();
|
||||||
|
|
||||||
|
MakeTable();
|
||||||
|
|
||||||
// SetupSelEvent needs to be called AFTER Initialize GPIO. This function
|
// SetupSelEvent needs to be called AFTER Initialize GPIO. This function
|
||||||
// reconfigures the SEL signal.
|
// reconfigures the SEL signal.
|
||||||
if (!SetupSelEvent()) {
|
if (!SetupSelEvent()) {
|
||||||
@ -533,8 +535,8 @@ void GPIOBUS_BananaM2p::SetREQ(bool ast)
|
|||||||
uint8_t GPIOBUS_BananaM2p::GetDAT()
|
uint8_t GPIOBUS_BananaM2p::GetDAT()
|
||||||
{
|
{
|
||||||
GPIO_FUNCTION_TRACE
|
GPIO_FUNCTION_TRACE
|
||||||
(void)Acquire();
|
|
||||||
// TODO: This is inefficient, but it works...
|
Acquire();
|
||||||
uint32_t data =
|
uint32_t data =
|
||||||
((GetSignal(BPI_PIN_DT0) ? 0x01 : 0x00) << 0) | ((GetSignal(BPI_PIN_DT1) ? 0x01 : 0x00) << 1) |
|
((GetSignal(BPI_PIN_DT0) ? 0x01 : 0x00) << 0) | ((GetSignal(BPI_PIN_DT1) ? 0x01 : 0x00) << 1) |
|
||||||
((GetSignal(BPI_PIN_DT2) ? 0x01 : 0x00) << 2) | ((GetSignal(BPI_PIN_DT3) ? 0x01 : 0x00) << 3) |
|
((GetSignal(BPI_PIN_DT2) ? 0x01 : 0x00) << 2) | ((GetSignal(BPI_PIN_DT3) ? 0x01 : 0x00) << 3) |
|
||||||
@ -549,27 +551,27 @@ void GPIOBUS_BananaM2p::SetDAT(uint8_t dat)
|
|||||||
{
|
{
|
||||||
GPIO_FUNCTION_TRACE
|
GPIO_FUNCTION_TRACE
|
||||||
|
|
||||||
SetMode(BPI_PIN_DT0, OUT);
|
array<uint32_t, 12> gpio_reg_values = {0};
|
||||||
SetMode(BPI_PIN_DT1, OUT);
|
|
||||||
SetMode(BPI_PIN_DT2, OUT);
|
|
||||||
SetMode(BPI_PIN_DT3, OUT);
|
|
||||||
SetMode(BPI_PIN_DT4, OUT);
|
|
||||||
SetMode(BPI_PIN_DT5, OUT);
|
|
||||||
SetMode(BPI_PIN_DT6, OUT);
|
|
||||||
SetMode(BPI_PIN_DT7, OUT);
|
|
||||||
SetMode(BPI_PIN_DP, OUT);
|
|
||||||
|
|
||||||
// TODO: This is inefficient, but it works...
|
for (size_t gpio_num = 0; gpio_num < pintbl.size(); gpio_num++) {
|
||||||
PinSetSignal(BPI_PIN_DT0, (dat & (1 << 0)) == 0); // NOSONAR: GCC 10 doesn't support shift operations on std::byte
|
bool value;
|
||||||
PinSetSignal(BPI_PIN_DT1, (dat & (1 << 1)) == 0); // NOSONAR: GCC 10 doesn't support shift operations on std::byte
|
if (gpio_num < 8) {
|
||||||
PinSetSignal(BPI_PIN_DT2, (dat & (1 << 2)) == 0); // NOSONAR: GCC 10 doesn't support shift operations on std::byte
|
// data bits
|
||||||
PinSetSignal(BPI_PIN_DT3, (dat & (1 << 3)) == 0); // NOSONAR: GCC 10 doesn't support shift operations on std::byte
|
value = !(dat & (1 << gpio_num)); // NOSONAR: GCC 10 doesn't support shift operations on std::byte
|
||||||
PinSetSignal(BPI_PIN_DT4, (dat & (1 << 4)) == 0); // NOSONAR: GCC 10 doesn't support shift operations on std::byte
|
} else {
|
||||||
PinSetSignal(BPI_PIN_DT5, (dat & (1 << 5)) == 0); // NOSONAR: GCC 10 doesn't support shift operations on std::byte
|
// parity bit
|
||||||
PinSetSignal(BPI_PIN_DT6, (dat & (1 << 6)) == 0); // NOSONAR: GCC 10 doesn't support shift operations on std::byte
|
value = (__builtin_parity(dat) == 1);
|
||||||
PinSetSignal(BPI_PIN_DT7, (dat & (1 << 7)) == 0); // NOSONAR: GCC 10 doesn't support shift operations on std::byte
|
}
|
||||||
|
|
||||||
PinSetSignal(BPI_PIN_DP, __builtin_parity(dat) == 1);
|
if (value) {
|
||||||
|
uint32_t this_gpio = pintbl[gpio_num];
|
||||||
|
int bank = SunXI::GPIO_BANK(this_gpio);
|
||||||
|
int offset = SunXI::GPIO_NUM(this_gpio);
|
||||||
|
gpio_reg_values[bank] |= (1 << offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sunxi_set_all_gpios(gpio_data_masks, gpio_reg_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@ -589,89 +591,12 @@ const array<int, 19> GPIOBUS_BananaM2p::SignalTable = {BPI_PIN_DT0, BPI_PIN_DT1,
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void GPIOBUS_BananaM2p::MakeTable(void)
|
void GPIOBUS_BananaM2p::MakeTable(void)
|
||||||
{
|
{
|
||||||
const array<int, 9> pintbl = {BPI_PIN_DT0, BPI_PIN_DT1, BPI_PIN_DT2, BPI_PIN_DT3, BPI_PIN_DT4,
|
for (auto this_gpio : pintbl) {
|
||||||
BPI_PIN_DT5, BPI_PIN_DT6, BPI_PIN_DT7, BPI_PIN_DP};
|
int bank = SunXI::GPIO_BANK(this_gpio);
|
||||||
|
int offset = (SunXI::GPIO_NUM(this_gpio));
|
||||||
|
|
||||||
array<bool, 256> tblParity;
|
gpio_data_masks[bank] |= (1 << offset);
|
||||||
|
|
||||||
// Create parity table
|
|
||||||
for (uint32_t i = 0; i < 0x100; i++) {
|
|
||||||
uint32_t bits = i;
|
|
||||||
uint32_t parity = 0;
|
|
||||||
for (int j = 0; j < 8; j++) {
|
|
||||||
parity ^= bits & 1;
|
|
||||||
bits >>= 1;
|
|
||||||
}
|
|
||||||
parity = ~parity;
|
|
||||||
tblParity[i] = parity & 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SIGNAL_CONTROL_MODE == 0
|
|
||||||
// Mask and setting data generation
|
|
||||||
for (auto &tbl : tblDatMsk) {
|
|
||||||
tbl.fill(-1);
|
|
||||||
}
|
|
||||||
for (auto &tbl : tblDatSet) {
|
|
||||||
tbl.fill(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 0x100; i++) {
|
|
||||||
// Bit string for inspection
|
|
||||||
uint32_t bits = i;
|
|
||||||
|
|
||||||
// Get parity
|
|
||||||
if (tblParity[i]) {
|
|
||||||
bits |= (1 << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bit check
|
|
||||||
for (int j = 0; j < 9; j++) {
|
|
||||||
// Index and shift amount calculation
|
|
||||||
int index = pintbl[j] / 10;
|
|
||||||
int shift = (pintbl[j] % 10) * 3;
|
|
||||||
|
|
||||||
// Mask data
|
|
||||||
tblDatMsk[index][i] &= ~(0x7 << shift);
|
|
||||||
|
|
||||||
// Setting data
|
|
||||||
if (bits & 1) {
|
|
||||||
tblDatSet[index][i] |= (1 << shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
bits >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (uint32_t i = 0; i < 0x100; i++) {
|
|
||||||
// Bit string for inspection
|
|
||||||
uint32_t bits = i;
|
|
||||||
|
|
||||||
// Get parity
|
|
||||||
if (tblParity[i]) {
|
|
||||||
bits |= (1 << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SIGNAL_CONTROL_MODE == 1
|
|
||||||
// Negative logic is inverted
|
|
||||||
bits = ~bits;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Create GPIO register information
|
|
||||||
uint32_t gpclr = 0;
|
|
||||||
uint32_t gpset = 0;
|
|
||||||
for (int j = 0; j < 9; j++) {
|
|
||||||
if (bits & 1) {
|
|
||||||
gpset |= (1 << pintbl[j]);
|
|
||||||
} else {
|
|
||||||
gpclr |= (1 << pintbl[j]);
|
|
||||||
}
|
|
||||||
bits >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tblDatMsk[i] = gpclr;
|
|
||||||
tblDatSet[i] = gpset;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPIOBUS_BananaM2p::GetDP() const
|
bool GPIOBUS_BananaM2p::GetDP() const
|
||||||
@ -1058,6 +983,28 @@ void GPIOBUS_BananaM2p::sunxi_output_gpio(int pin, int value)
|
|||||||
pio->DAT |= (1 << num);
|
pio->DAT |= (1 << num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPIOBUS_BananaM2p::sunxi_set_all_gpios(array<uint32_t, 12> &mask, array<uint32_t, 12> &value)
|
||||||
|
{
|
||||||
|
GPIO_FUNCTION_TRACE
|
||||||
|
for (size_t bank = 0; bank < mask.size(); bank++) {
|
||||||
|
if (mask[bank] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile SunXI::sunxi_gpio_t *pio;
|
||||||
|
if (bank < 11) {
|
||||||
|
pio = &(pio_map->gpio_bank[bank]);
|
||||||
|
} else {
|
||||||
|
pio = &(r_pio_map->gpio_bank[bank - 11]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t reg_val = pio->DAT;
|
||||||
|
reg_val &= ~mask[bank];
|
||||||
|
reg_val |= value[bank];
|
||||||
|
pio->DAT = reg_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int GPIOBUS_BananaM2p::sunxi_input_gpio(int pin) const
|
int GPIOBUS_BananaM2p::sunxi_input_gpio(int pin) const
|
||||||
{
|
{
|
||||||
GPIO_FUNCTION_TRACE
|
GPIO_FUNCTION_TRACE
|
||||||
|
@ -124,7 +124,7 @@ class GPIOBUS_BananaM2p : public GPIOBUS
|
|||||||
// Set SCSI I/O mode
|
// Set SCSI I/O mode
|
||||||
int GetMode(int pin) override;
|
int GetMode(int pin) override;
|
||||||
|
|
||||||
bool GetSignal(int pin) const override;
|
inline bool GetSignal(int pin) const override;
|
||||||
|
|
||||||
// Set SCSI output signal value
|
// Set SCSI output signal value
|
||||||
void SetSignal(int pin, bool ast) override;
|
void SetSignal(int pin, bool ast) override;
|
||||||
@ -153,35 +153,12 @@ class GPIOBUS_BananaM2p : public GPIOBUS
|
|||||||
|
|
||||||
bool SetupSelEvent();
|
bool SetupSelEvent();
|
||||||
|
|
||||||
#if !defined(__x86_64__) && !defined(__X86__)
|
|
||||||
uint32_t baseaddr = 0; // Base address
|
|
||||||
#endif
|
|
||||||
|
|
||||||
volatile uint32_t *gpio_map = nullptr;
|
volatile uint32_t *gpio_map = nullptr;
|
||||||
|
|
||||||
// Timer control register
|
// Timer control register
|
||||||
volatile uint32_t *tmr_ctrl;
|
volatile uint32_t *tmr_ctrl;
|
||||||
|
|
||||||
#if !defined(__x86_64__) && !defined(__X86__)
|
|
||||||
volatile uint32_t *gicd = nullptr; // GIC Interrupt distributor register
|
|
||||||
#endif
|
|
||||||
|
|
||||||
volatile uint32_t *gicc = nullptr; // GIC CPU interface register
|
|
||||||
|
|
||||||
array<uint32_t, 4> gpfsel; // GPFSEL0-4 backup values
|
|
||||||
|
|
||||||
array<uint32_t, 12> signals = {0}; // All bus signals
|
array<uint32_t, 12> signals = {0}; // All bus signals
|
||||||
|
|
||||||
#if SIGNAL_CONTROL_MODE == 0
|
|
||||||
array<array<uint32_t, 256>, 3> tblDatMsk; // Data mask table
|
|
||||||
|
|
||||||
array<array<uint32_t, 256>, 3> tblDatSet; // Data setting table
|
|
||||||
#else
|
|
||||||
array<uint32_t, 256> tblDatMsk = {}; // Data mask table
|
|
||||||
|
|
||||||
array<uint32_t, 256> tblDatSet = {}; // Table setting table
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int sunxi_setup(void);
|
int sunxi_setup(void);
|
||||||
|
|
||||||
void sunxi_set_pullupdn(int gpio, int pud);
|
void sunxi_set_pullupdn(int gpio, int pud);
|
||||||
@ -206,13 +183,19 @@ class GPIOBUS_BananaM2p : public GPIOBUS
|
|||||||
|
|
||||||
SBC_Version::sbc_version_type sbc_version;
|
SBC_Version::sbc_version_type sbc_version;
|
||||||
|
|
||||||
SunXI::sunxi_gpio_reg_t saved_gpio_config;
|
|
||||||
|
|
||||||
static const array<int, 19> SignalTable;
|
static const array<int, 19> SignalTable;
|
||||||
|
|
||||||
void InitializeGpio();
|
void InitializeGpio();
|
||||||
std::vector<int> gpio_banks;
|
std::vector<int> gpio_banks;
|
||||||
|
|
||||||
|
// Note: These MUST be in order from bit 0 to bit 7 with parity as the last item in the array
|
||||||
|
const array<int, 9> pintbl = {BPI_PIN_DT0, BPI_PIN_DT1, BPI_PIN_DT2, BPI_PIN_DT3, BPI_PIN_DT4,
|
||||||
|
BPI_PIN_DT5, BPI_PIN_DT6, BPI_PIN_DT7, BPI_PIN_DP};
|
||||||
|
|
||||||
|
void sunxi_set_all_gpios(array<uint32_t, 12> &mask, array<uint32_t, 12> &value);
|
||||||
|
|
||||||
|
array<uint32_t, 12> gpio_data_masks = {0};
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__X86__) || defined(__aarch64__)
|
#if defined(__x86_64__) || defined(__X86__) || defined(__aarch64__)
|
||||||
// The SEL_EVENT functions need to do something to prevent SonarCloud from
|
// The SEL_EVENT functions need to do something to prevent SonarCloud from
|
||||||
// claiming they should be const
|
// claiming they should be const
|
||||||
|
Loading…
Reference in New Issue
Block a user