mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-25 19:33:05 +00:00
Rework DBDMA logic for bidirectional channels.
This commit is contained in:
parent
98ccef732f
commit
9f4c248e4c
@ -309,9 +309,11 @@ static PATResult page_address_translation(uint32_t la, bool is_instr_fetch,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* mmu_get_dma_mem(uint32_t addr, uint32_t size)
|
uint8_t* mmu_get_dma_mem(uint32_t addr, uint32_t size, bool* is_writable)
|
||||||
{
|
{
|
||||||
if (addr >= last_dma_area.start && (addr + size) <= last_dma_area.end) {
|
if (addr >= last_dma_area.start && (addr + size) <= last_dma_area.end) {
|
||||||
|
if (is_writable)
|
||||||
|
*is_writable = last_dma_area.type & RT_RAM;
|
||||||
return last_dma_area.mem_ptr + (addr - last_dma_area.start);
|
return last_dma_area.mem_ptr + (addr - last_dma_area.start);
|
||||||
} else {
|
} else {
|
||||||
AddressMapEntry* entry = mem_ctrl_instance->find_range(addr);
|
AddressMapEntry* entry = mem_ctrl_instance->find_range(addr);
|
||||||
@ -319,6 +321,9 @@ uint8_t* mmu_get_dma_mem(uint32_t addr, uint32_t size)
|
|||||||
last_dma_area.start = entry->start;
|
last_dma_area.start = entry->start;
|
||||||
last_dma_area.end = entry->end;
|
last_dma_area.end = entry->end;
|
||||||
last_dma_area.mem_ptr = entry->mem_ptr;
|
last_dma_area.mem_ptr = entry->mem_ptr;
|
||||||
|
last_dma_area.type = entry->type;
|
||||||
|
if (is_writable)
|
||||||
|
*is_writable = entry->type & RT_RAM;
|
||||||
return last_dma_area.mem_ptr + (addr - last_dma_area.start);
|
return last_dma_area.mem_ptr + (addr - last_dma_area.start);
|
||||||
} else {
|
} else {
|
||||||
ABORT_F("SOS: DMA access to unmapped memory %08X!\n", addr);
|
ABORT_F("SOS: DMA access to unmapped memory %08X!\n", addr);
|
||||||
|
@ -102,7 +102,7 @@ enum TLBFlags : uint16_t {
|
|||||||
extern std::function<void(uint32_t bat_reg)> ibat_update;
|
extern std::function<void(uint32_t bat_reg)> ibat_update;
|
||||||
extern std::function<void(uint32_t bat_reg)> dbat_update;
|
extern std::function<void(uint32_t bat_reg)> dbat_update;
|
||||||
|
|
||||||
extern uint8_t* mmu_get_dma_mem(uint32_t addr, uint32_t size);
|
extern uint8_t* mmu_get_dma_mem(uint32_t addr, uint32_t size, bool* is_writable);
|
||||||
|
|
||||||
extern void mmu_change_mode(void);
|
extern void mmu_change_mode(void);
|
||||||
extern void mmu_pat_ctx_changed();
|
extern void mmu_pat_ctx_changed();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||||
Copyright (C) 2018-21 divingkatae and maximum
|
Copyright (C) 2018-22 divingkatae and maximum
|
||||||
(theweirdo) spatium
|
(theweirdo) spatium
|
||||||
|
|
||||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||||
@ -25,6 +25,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#include <devices/common/dbdma.h>
|
#include <devices/common/dbdma.h>
|
||||||
#include <devices/common/dmacore.h>
|
#include <devices/common/dmacore.h>
|
||||||
#include <endianswap.h>
|
#include <endianswap.h>
|
||||||
|
#include <memaccess.h>
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -36,21 +37,51 @@ void DMAChannel::set_callbacks(DbdmaCallback start_cb, DbdmaCallback stop_cb)
|
|||||||
this->stop_cb = stop_cb;
|
this->stop_cb = stop_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DMAChannel::get_next_cmd(uint32_t cmd_addr, DMACmd* p_cmd) {
|
void DMAChannel::fetch_cmd(uint32_t cmd_addr, DMACmd* p_cmd) {
|
||||||
/* load DMACmd from physical memory */
|
/* load DMACmd from physical memory */
|
||||||
memcpy((uint8_t*)p_cmd, mmu_get_dma_mem(cmd_addr, 16), 16);
|
memcpy((uint8_t*)p_cmd, mmu_get_dma_mem(cmd_addr, 16, nullptr), 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t DMAChannel::interpret_cmd() {
|
uint8_t DMAChannel::interpret_cmd() {
|
||||||
DMACmd cmd_struct;
|
DMACmd cmd_struct;
|
||||||
|
bool is_writable;
|
||||||
|
int cmd;
|
||||||
|
|
||||||
get_next_cmd(this->cmd_ptr, &cmd_struct);
|
if (this->cmd_in_progress) {
|
||||||
|
// return current command if there is data to transfer
|
||||||
|
if (this->queue_len)
|
||||||
|
return cmd;
|
||||||
|
|
||||||
|
// obtain real pointer to the descriptor of the completed command
|
||||||
|
uint8_t *curr_cmd = mmu_get_dma_mem(this->cmd_ptr - 16, 16, &is_writable);
|
||||||
|
|
||||||
|
// get command code
|
||||||
|
cmd = curr_cmd[3] >> 4;
|
||||||
|
|
||||||
|
// all commands except STOP update cmd.xferStatus
|
||||||
|
if (cmd < 7 && is_writable) {
|
||||||
|
WRITE_WORD_LE_A(&curr_cmd[14], this->ch_stat | CH_STAT_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// all INPUT and OUTPUT commands update cmd.resCount
|
||||||
|
if (cmd < 4 && is_writable) {
|
||||||
|
WRITE_WORD_LE_A(&curr_cmd[12], this->queue_len & 0xFFFFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->cmd_in_progress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_cmd(this->cmd_ptr, &cmd_struct);
|
||||||
|
|
||||||
|
cmd = cmd_struct.cmd_key >> 4;
|
||||||
|
|
||||||
this->ch_stat &= ~CH_STAT_WAKE; /* clear wake bit (DMA spec, 5.5.3.4) */
|
this->ch_stat &= ~CH_STAT_WAKE; /* clear wake bit (DMA spec, 5.5.3.4) */
|
||||||
|
|
||||||
switch (cmd_struct.cmd_key >> 4) {
|
switch (cmd_struct.cmd_key >> 4) {
|
||||||
case 0:
|
case 0: // OUTPUT_MORE
|
||||||
LOG_F(9, "Executing DMA Command OUTPUT_MORE");
|
case 1: // OUTPUT_LAST
|
||||||
|
case 2: // INPUT_MORE
|
||||||
|
case 3: // INPUT_LAST
|
||||||
if (cmd_struct.cmd_key & 7) {
|
if (cmd_struct.cmd_key & 7) {
|
||||||
LOG_F(ERROR, "Key > 0 not implemented");
|
LOG_F(ERROR, "Key > 0 not implemented");
|
||||||
break;
|
break;
|
||||||
@ -59,35 +90,10 @@ uint8_t DMAChannel::interpret_cmd() {
|
|||||||
LOG_F(ERROR, "non-zero i/b/w not implemented");
|
LOG_F(ERROR, "non-zero i/b/w not implemented");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// this->dma_cb->dma_push(
|
this->queue_data = mmu_get_dma_mem(cmd_struct.address, cmd_struct.req_count, &is_writable);
|
||||||
// mmu_get_dma_mem(cmd_struct.address, cmd_struct.req_count),
|
|
||||||
// cmd_struct.req_count);
|
|
||||||
this->queue_data = mmu_get_dma_mem(cmd_struct.address, cmd_struct.req_count);
|
|
||||||
this->queue_len = cmd_struct.req_count;
|
this->queue_len = cmd_struct.req_count;
|
||||||
this->cmd_ptr += 16;
|
this->cmd_ptr += 16;
|
||||||
break;
|
this->cmd_in_progress = true;
|
||||||
case 1:
|
|
||||||
LOG_F(9, "Executing DMA Command OUTPUT_LAST");
|
|
||||||
if (cmd_struct.cmd_key & 7) {
|
|
||||||
LOG_F(ERROR, "Key > 0 not implemented");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (cmd_struct.cmd_bits & 0x3F) {
|
|
||||||
LOG_F(ERROR, "non-zero i/b/w not implemented");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// this->dma_cb->dma_push(
|
|
||||||
// mmu_get_dma_mem(cmd_struct.address, cmd_struct.req_count),
|
|
||||||
// cmd_struct.req_count);
|
|
||||||
this->queue_data = mmu_get_dma_mem(cmd_struct.address, cmd_struct.req_count);
|
|
||||||
this->queue_len = cmd_struct.req_count;
|
|
||||||
this->cmd_ptr += 16;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
LOG_F(ERROR, "Unsupported DMA Command INPUT_MORE");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
LOG_F(ERROR, "Unsupported DMA Command INPUT_LAST");
|
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
LOG_F(ERROR, "Unsupported DMA Command STORE_QUAD");
|
LOG_F(ERROR, "Unsupported DMA Command STORE_QUAD");
|
||||||
@ -96,11 +102,11 @@ uint8_t DMAChannel::interpret_cmd() {
|
|||||||
LOG_F(ERROR, "Unsupported DMA Command LOAD_QUAD");
|
LOG_F(ERROR, "Unsupported DMA Command LOAD_QUAD");
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
LOG_F(INFO, "Unsupported DMA Command NOP");
|
LOG_F(ERROR, "Unsupported DMA Command NOP");
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
LOG_F(INFO, "DMA Command: 7 (STOP)");
|
|
||||||
this->ch_stat &= ~CH_STAT_ACTIVE;
|
this->ch_stat &= ~CH_STAT_ACTIVE;
|
||||||
|
this->cmd_in_progress = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_F(ERROR, "Unsupported DMA command 0x%X", cmd_struct.cmd_key >> 4);
|
LOG_F(ERROR, "Unsupported DMA command 0x%X", cmd_struct.cmd_key >> 4);
|
||||||
@ -149,7 +155,7 @@ void DMAChannel::reg_write(uint32_t offset, uint32_t value, int size) {
|
|||||||
case DMAReg::CH_CTRL:
|
case DMAReg::CH_CTRL:
|
||||||
mask = value >> 16;
|
mask = value >> 16;
|
||||||
new_stat = (value & mask & 0xF0FFU) | (old_stat & ~mask);
|
new_stat = (value & mask & 0xF0FFU) | (old_stat & ~mask);
|
||||||
LOG_F(INFO, "New ChannelStatus value = 0x%X", new_stat);
|
LOG_F(9, "New ChannelStatus value = 0x%X", new_stat);
|
||||||
|
|
||||||
if ((new_stat & CH_STAT_RUN) != (old_stat & CH_STAT_RUN)) {
|
if ((new_stat & CH_STAT_RUN) != (old_stat & CH_STAT_RUN)) {
|
||||||
if (new_stat & CH_STAT_RUN) {
|
if (new_stat & CH_STAT_RUN) {
|
||||||
@ -184,7 +190,7 @@ void DMAChannel::reg_write(uint32_t offset, uint32_t value, int size) {
|
|||||||
case DMAReg::CMD_PTR_LO:
|
case DMAReg::CMD_PTR_LO:
|
||||||
if (!(this->ch_stat & CH_STAT_RUN) && !(this->ch_stat & CH_STAT_ACTIVE)) {
|
if (!(this->ch_stat & CH_STAT_RUN) && !(this->ch_stat & CH_STAT_ACTIVE)) {
|
||||||
this->cmd_ptr = value;
|
this->cmd_ptr = value;
|
||||||
LOG_F(INFO, "CommandPtrLo set to 0x%X", this->cmd_ptr);
|
LOG_F(9, "CommandPtrLo set to 0x%X", this->cmd_ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -227,6 +233,33 @@ DmaPullResult DMAChannel::pull_data(uint32_t req_len, uint32_t *avail_len, uint8
|
|||||||
return DmaPullResult::NoMoreData; /* tell the caller there is no more data */
|
return DmaPullResult::NoMoreData; /* tell the caller there is no more data */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DMAChannel::push_data(const char* src_ptr, int len)
|
||||||
|
{
|
||||||
|
if (this->ch_stat & CH_STAT_DEAD || !(this->ch_stat & CH_STAT_ACTIVE)) {
|
||||||
|
LOG_F(WARNING, "DBDMA: attempt to push data to dead/idle channel");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interpret DBDMA program until we get buffer to fill in or become idle
|
||||||
|
while ((this->ch_stat & CH_STAT_ACTIVE) && !this->queue_len) {
|
||||||
|
this->interpret_cmd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->queue_len) {
|
||||||
|
len = std::min((int)this->queue_len, len);
|
||||||
|
std::memcpy(this->queue_data, src_ptr, len);
|
||||||
|
this->queue_data += len;
|
||||||
|
this->queue_len -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// proceed with the DBDMA program if the buffer became exhausted
|
||||||
|
if (!this->queue_len) {
|
||||||
|
this->interpret_cmd();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool DMAChannel::is_active()
|
bool DMAChannel::is_active()
|
||||||
{
|
{
|
||||||
if (this->ch_stat & CH_STAT_DEAD || !(this->ch_stat & CH_STAT_ACTIVE)) {
|
if (this->ch_stat & CH_STAT_DEAD || !(this->ch_stat & CH_STAT_ACTIVE)) {
|
||||||
@ -248,7 +281,8 @@ void DMAChannel::start()
|
|||||||
|
|
||||||
this->queue_len = 0;
|
this->queue_len = 0;
|
||||||
|
|
||||||
this->start_cb();
|
if (this->start_cb)
|
||||||
|
this->start_cb();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DMAChannel::resume() {
|
void DMAChannel::resume() {
|
||||||
@ -266,5 +300,6 @@ void DMAChannel::abort() {
|
|||||||
|
|
||||||
void DMAChannel::pause() {
|
void DMAChannel::pause() {
|
||||||
LOG_F(INFO, "Pausing DMA channel");
|
LOG_F(INFO, "Pausing DMA channel");
|
||||||
this->stop_cb();
|
if (this->stop_cb)
|
||||||
|
this->stop_cb();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||||
Copyright (C) 2018-21 divingkatae and maximum
|
Copyright (C) 2018-22 divingkatae and maximum
|
||||||
(theweirdo) spatium
|
(theweirdo) spatium
|
||||||
|
|
||||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||||
@ -42,7 +42,7 @@ enum DMAReg : uint32_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Channel Status bits (DBDMA spec, 5.5.3) */
|
/** Channel Status bits (DBDMA spec, 5.5.3) */
|
||||||
enum {
|
enum : uint16_t {
|
||||||
CH_STAT_ACTIVE = 0x400,
|
CH_STAT_ACTIVE = 0x400,
|
||||||
CH_STAT_DEAD = 0x800,
|
CH_STAT_DEAD = 0x800,
|
||||||
CH_STAT_WAKE = 0x1000,
|
CH_STAT_WAKE = 0x1000,
|
||||||
@ -53,18 +53,18 @@ enum {
|
|||||||
|
|
||||||
/** DBDMA command (DBDMA spec, 5.6.1) - all fields are little-endian! */
|
/** DBDMA command (DBDMA spec, 5.6.1) - all fields are little-endian! */
|
||||||
typedef struct DMACmd {
|
typedef struct DMACmd {
|
||||||
uint16_t req_count;
|
uint16_t req_count;
|
||||||
uint8_t cmd_bits;
|
uint8_t cmd_bits;
|
||||||
uint8_t cmd_key;
|
uint8_t cmd_key;
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
uint32_t cmd_arg;
|
uint32_t cmd_arg;
|
||||||
uint16_t res_count;
|
uint16_t res_count;
|
||||||
uint16_t xfer_stat;
|
uint16_t xfer_stat;
|
||||||
} DMACmd;
|
} DMACmd;
|
||||||
|
|
||||||
typedef std::function<void(void)> DbdmaCallback;
|
typedef std::function<void(void)> DbdmaCallback;
|
||||||
|
|
||||||
class DMAChannel : public DmaOutChannel {
|
class DMAChannel : public DmaBidirChannel {
|
||||||
public:
|
public:
|
||||||
DMAChannel() = default;
|
DMAChannel() = default;
|
||||||
~DMAChannel() = default;
|
~DMAChannel() = default;
|
||||||
@ -75,9 +75,10 @@ public:
|
|||||||
|
|
||||||
bool is_active();
|
bool is_active();
|
||||||
DmaPullResult pull_data(uint32_t req_len, uint32_t *avail_len, uint8_t **p_data);
|
DmaPullResult pull_data(uint32_t req_len, uint32_t *avail_len, uint8_t **p_data);
|
||||||
|
int push_data(const char* src_ptr, int len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void get_next_cmd(uint32_t cmd_addr, DMACmd* p_cmd);
|
void fetch_cmd(uint32_t cmd_addr, DMACmd* p_cmd);
|
||||||
uint8_t interpret_cmd(void);
|
uint8_t interpret_cmd(void);
|
||||||
|
|
||||||
void start(void);
|
void start(void);
|
||||||
@ -86,14 +87,15 @@ protected:
|
|||||||
void pause(void);
|
void pause(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void(void)> start_cb; // DMA channel start callback
|
std::function<void(void)> start_cb = nullptr; // DMA channel start callback
|
||||||
std::function<void(void)> stop_cb; // DMA channel stop callback
|
std::function<void(void)> stop_cb = nullptr; // DMA channel stop callback
|
||||||
|
|
||||||
uint16_t ch_stat = 0;
|
uint16_t ch_stat = 0;
|
||||||
uint32_t cmd_ptr = 0;
|
uint32_t cmd_ptr = 0;
|
||||||
|
uint32_t queue_len = 0;
|
||||||
|
uint8_t* queue_data = 0;
|
||||||
|
|
||||||
uint32_t queue_len;
|
bool cmd_in_progress = false;
|
||||||
uint8_t* queue_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DB_DMA_H */
|
#endif /* DB_DMA_H */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||||
Copyright (C) 2018-21 divingkatae and maximum
|
Copyright (C) 2018-22 divingkatae and maximum
|
||||||
(theweirdo) spatium
|
(theweirdo) spatium
|
||||||
|
|
||||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||||
@ -38,13 +38,13 @@ public:
|
|||||||
uint8_t **p_data) = 0;
|
uint8_t **p_data) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for bidirectional DMA channels.
|
class DmaInChannel {
|
||||||
class DmaBidirChannel {
|
|
||||||
public:
|
public:
|
||||||
virtual bool is_active() { return true; };
|
|
||||||
virtual int push_data(const char* src_ptr, int len) = 0;
|
virtual int push_data(const char* src_ptr, int len) = 0;
|
||||||
virtual DmaPullResult pull_data(uint32_t req_len, uint32_t *avail_len,
|
};
|
||||||
uint8_t **p_data) = 0;
|
|
||||||
|
// Base class for bidirectional DMA channels.
|
||||||
|
class DmaBidirChannel : public DmaOutChannel, public DmaInChannel {
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DMA_CORE_H
|
#endif // DMA_CORE_H
|
||||||
|
@ -491,7 +491,7 @@ DmaPullResult AmicSndOutDma::pull_data(uint32_t req_len, uint32_t *avail_len,
|
|||||||
|
|
||||||
*p_data = mmu_get_dma_mem(
|
*p_data = mmu_get_dma_mem(
|
||||||
(this->snd_buf_num ? this->out_buf1 : this->out_buf0) + this->cur_buf_pos,
|
(this->snd_buf_num ? this->out_buf1 : this->out_buf0) + this->cur_buf_pos,
|
||||||
len);
|
len, nullptr);
|
||||||
this->cur_buf_pos += len;
|
this->cur_buf_pos += len;
|
||||||
*avail_len = len;
|
*avail_len = len;
|
||||||
return DmaPullResult::MoreData;
|
return DmaPullResult::MoreData;
|
||||||
@ -524,9 +524,14 @@ void AmicFloppyDma::write_ctrl(uint8_t value)
|
|||||||
|
|
||||||
int AmicFloppyDma::push_data(const char* src_ptr, int len)
|
int AmicFloppyDma::push_data(const char* src_ptr, int len)
|
||||||
{
|
{
|
||||||
|
bool is_writable;
|
||||||
|
|
||||||
len = std::min((int)this->byte_count, len);
|
len = std::min((int)this->byte_count, len);
|
||||||
|
|
||||||
uint8_t *p_data = mmu_get_dma_mem(this->addr_ptr, len);
|
uint8_t *p_data = mmu_get_dma_mem(this->addr_ptr, len, &is_writable);
|
||||||
|
if (!is_writable) {
|
||||||
|
ABORT_F("AMIC: attempting DMA write to read-only memory");
|
||||||
|
}
|
||||||
std::memcpy(p_data, src_ptr, len);
|
std::memcpy(p_data, src_ptr, len);
|
||||||
|
|
||||||
this->addr_ptr += len;
|
this->addr_ptr += len;
|
||||||
|
@ -204,7 +204,7 @@ void PdmOnboardVideo::enable_video_internal()
|
|||||||
LOG_F(INFO, "PDM-Video: framebuffer phys base addr = 0x%X", fb_base_phys);
|
LOG_F(INFO, "PDM-Video: framebuffer phys base addr = 0x%X", fb_base_phys);
|
||||||
|
|
||||||
// set framebuffer address and pitch
|
// set framebuffer address and pitch
|
||||||
this->fb_ptr = mmu_get_dma_mem(fb_base_phys, PDM_FB_SIZE_MAX);
|
this->fb_ptr = mmu_get_dma_mem(fb_base_phys, PDM_FB_SIZE_MAX, nullptr);
|
||||||
this->active_width = new_width;
|
this->active_width = new_width;
|
||||||
this->active_height = new_height;
|
this->active_height = new_height;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user