summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine
diff options
context:
space:
mode:
author Ryan Holtz <ryan.holtz@arrowheadgs.com>2021-01-15 19:57:50 +0100
committer Ryan Holtz <ryan.holtz@arrowheadgs.com>2021-01-15 19:58:20 +0100
commitfc17cb4dc95c1ef26afbc038812f694dd1ef15c8 (patch)
tree05b4e01369342a24a7a9c314e34be4edc804783d /src/devices/machine
parent3d49ff6d45e8beccc72af16885b245351b29f59b (diff)
- sa1110: Added skeleton handling for UDC sub-device handling. [Ryan Holtz]
- sa1111: Fixed a handful of issues related to audio DMA. [Ryan Holtz] - sed1356: Added support for Write BitBLT, Read BitBlt, and Move BitBLT Negative commands. [Ryan Holtz] - jornada: Fixed handling for some battery-related MCU commands. [Ryan Holtz]
Diffstat (limited to 'src/devices/machine')
-rw-r--r--src/devices/machine/sa1110.cpp126
-rw-r--r--src/devices/machine/sa1110.h76
-rw-r--r--src/devices/machine/sa1111.cpp20
3 files changed, 217 insertions, 5 deletions
diff --git a/src/devices/machine/sa1110.cpp b/src/devices/machine/sa1110.cpp
index 218819f44ad..480f9998131 100644
--- a/src/devices/machine/sa1110.cpp
+++ b/src/devices/machine/sa1110.cpp
@@ -27,7 +27,8 @@
#define LOG_INTC (1 << 16)
#define LOG_PPC (1 << 17)
#define LOG_DMA (1 << 18)
-#define LOG_ALL (LOG_UNKNOWN | LOG_ICP | LOG_UART3 | LOG_MCP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC | LOG_PPC | LOG_DMA)
+#define LOG_UDC (1 << 19)
+#define LOG_ALL (LOG_UNKNOWN | LOG_ICP | LOG_UART3 | LOG_MCP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC | LOG_PPC | LOG_DMA | LOG_UDC)
#define VERBOSE (0)
#include "logmacro.h"
@@ -49,6 +50,109 @@ sa1110_periphs_device::sa1110_periphs_device(const machine_config &mconfig, cons
/*
+ Intel SA-1110 UDC - USB Device Controller
+
+ pg. 235 to 258 Intel StrongARM SA-1110 Microprocessor Developer's Manual
+
+*/
+
+uint32_t sa1110_periphs_device::udc_r(offs_t offset, uint32_t mem_mask)
+{
+ switch (offset)
+ {
+ case REG_UDCCR:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC Control Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udccr, mem_mask);
+ return m_udc_regs.udccr;
+ case REG_UDCAR:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC Address Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcar, mem_mask);
+ return m_udc_regs.udcar;
+ case REG_UDCOMP:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC OUT Max Packet Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcomp, mem_mask);
+ return m_udc_regs.udcomp;
+ case REG_UDCIMP:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC IN Max Packet Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcimp, mem_mask);
+ return m_udc_regs.udcimp;
+ case REG_UDCCS0:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 0 Control/Status Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udccs0, mem_mask);
+ return m_udc_regs.udccs0;
+ case REG_UDCCS1:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 1 (OUT) Control/Status Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udccs1, mem_mask);
+ return m_udc_regs.udccs1;
+ case REG_UDCCS2:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 2 (IN) Control/Status Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udccs2, mem_mask);
+ return m_udc_regs.udccs2;
+ case REG_UDCD0:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 0 Data Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
+ return 0;
+ case REG_UDCWC:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 0 Write Count Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcwc, mem_mask);
+ return m_udc_regs.udcwc;
+ case REG_UDCDR:
+ //const uint32_t data = udc_rx_fifo_pop();
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC Data Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
+ return 0;
+ case REG_UDCSR:
+ LOGMASKED(LOG_UDC, "%s: udc_r: UDC Status/Interrupt Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcsr, mem_mask);
+ return m_udc_regs.udcsr;
+ default:
+ LOGMASKED(LOG_UDC | LOG_UNKNOWN, "%s: udc_r: Unknown address: %08x & %08x\n", machine().describe_context(), UDC_BASE_ADDR | (offset << 2), mem_mask);
+ return 0;
+ }
+}
+
+void sa1110_periphs_device::udc_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ switch (offset)
+ {
+ case REG_UDCCR:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_udc_regs.udccr);
+ break;
+ case REG_UDCAR:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC Address Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_udc_regs.udcar);
+ break;
+ case REG_UDCOMP:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC OUT Max Packet Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_udc_regs.udcomp);
+ break;
+ case REG_UDCIMP:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC IN Max Packet Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_udc_regs.udcimp);
+ break;
+ case REG_UDCCS0:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 0 Control/Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_udc_regs.udccs0);
+ break;
+ case REG_UDCCS1:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 1 (OUT) Control/Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_udc_regs.udccs1);
+ break;
+ case REG_UDCCS2:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 2 (IN) Control/Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_udc_regs.udccs2);
+ break;
+ case REG_UDCD0:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 0 Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ break;
+ case REG_UDCWC:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 0 Write Count Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_udc_regs.udcwc);
+ break;
+ case REG_UDCDR:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ return;
+ case REG_UDCSR:
+ LOGMASKED(LOG_UDC, "%s: udc_w: UDC Status/Interrupt Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ break;
+ default:
+ LOGMASKED(LOG_UDC | LOG_UNKNOWN, "%s: udc_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), UDC_BASE_ADDR | (offset << 2), data, mem_mask);
+ break;
+ }
+}
+
+/*
+
Intel SA-1110 ICP - Serial Port 2
pg. 264 to 288 Intel StrongARM SA-1110 Microprocessor Developer's Manual
@@ -2193,6 +2297,16 @@ void sa1110_periphs_device::dma_w(offs_t offset, uint32_t data, uint32_t mem_mas
void sa1110_periphs_device::device_start()
{
+ save_item(NAME(m_udc_regs.udccr));
+ save_item(NAME(m_udc_regs.udcar));
+ save_item(NAME(m_udc_regs.udcomp));
+ save_item(NAME(m_udc_regs.udcimp));
+ save_item(NAME(m_udc_regs.udccs0));
+ save_item(NAME(m_udc_regs.udccs1));
+ save_item(NAME(m_udc_regs.udccs2));
+ save_item(NAME(m_udc_regs.udcwc));
+ save_item(NAME(m_udc_regs.udcsr));
+
save_item(NAME(m_icp_regs.uart.utcr));
save_item(NAME(m_icp_regs.uart.utsr0));
save_item(NAME(m_icp_regs.uart.utsr1));
@@ -2339,6 +2453,16 @@ void sa1110_periphs_device::device_start()
void sa1110_periphs_device::device_reset()
{
+ m_udc_regs.udccr = (1 << UDCCR_SUSM_BIT) | (1 << UDCCR_UDD_BIT);
+ m_udc_regs.udcar = 0;
+ m_udc_regs.udcomp = 8;
+ m_udc_regs.udcimp = 8;
+ m_udc_regs.udccs0 = 0;
+ m_udc_regs.udccs1 = 0;
+ m_udc_regs.udccs2 = 0;
+ m_udc_regs.udcwc = 0;
+ m_udc_regs.udcsr = 0;
+
// init ICP
memset(m_icp_regs.uart.utcr, 0, sizeof(uint32_t) * 4);
m_icp_regs.uart.utsr0 = 0;
diff --git a/src/devices/machine/sa1110.h b/src/devices/machine/sa1110.h
index 64900bf163b..7693e09dfa3 100644
--- a/src/devices/machine/sa1110.h
+++ b/src/devices/machine/sa1110.h
@@ -46,6 +46,8 @@ public:
auto uart3_tx_out() { return m_uart3_tx_out.bind(); }
+ uint32_t udc_r(offs_t offset, uint32_t mem_mask = ~0);
+ void udc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t icp_r(offs_t offset, uint32_t mem_mask = ~0);
void icp_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t uart3_r(offs_t offset, uint32_t mem_mask = ~0);
@@ -154,6 +156,19 @@ protected:
// register offsets
enum
{
+ UDC_BASE_ADDR = 0x80000000,
+ REG_UDCCR = (0x00000000 >> 2),
+ REG_UDCAR = (0x00000004 >> 2),
+ REG_UDCOMP = (0x00000008 >> 2),
+ REG_UDCIMP = (0x0000000c >> 2),
+ REG_UDCCS0 = (0x00000010 >> 2),
+ REG_UDCCS1 = (0x00000014 >> 2),
+ REG_UDCCS2 = (0x00000018 >> 2),
+ REG_UDCD0 = (0x0000001c >> 2),
+ REG_UDCWC = (0x00000020 >> 2),
+ REG_UDCDR = (0x00000028 >> 2),
+ REG_UDCSR = (0x00000030 >> 2),
+
ICP_BASE_ADDR = 0x80030000,
REG_UTCR4 = (0x00000010 >> 2),
REG_HSCR0 = (0x00000060 >> 2),
@@ -253,6 +268,53 @@ protected:
// register contents
enum : uint32_t
{
+ UDCCR_UDD_BIT = 0,
+ UDCCR_UDA_BIT = 1,
+ UDCCR_RESM_BIT = 2,
+ UDCCR_EIM_BIT = 3,
+ UDCCR_RIM_BIT = 4,
+ UDCCR_TIM_BIT = 5,
+ UDCCR_SUSM_BIT = 6,
+ UDCCR_WRITE_MASK = 0x7d,
+
+ UDCAR_WRITE_MASK = 0x7f,
+
+ UDCOMP_WRITE_MASK = 0xff,
+
+ UDCIMP_WRITE_MASK = 0xff,
+
+ UDCCS0_OPR_BIT = 0,
+ UDCCS0_IPR_BIT = 1,
+ UDCCS0_SST_BIT = 2,
+ UDCCS0_FST_BIT = 3,
+ UDCCS0_DE_BIT = 4,
+ UDCCS0_SE_BIT = 5,
+ UDCCS0_SO_BIT = 6,
+ UDCCS0_SSE_BIT = 7,
+
+ UDCCS1_RFS_BIT = 0,
+ UDCCS1_RPC_BIT = 1,
+ UDCCS1_RPE_BIT = 2,
+ UDCCS1_SST_BIT = 3,
+ UDCCS1_FST_BIT = 4,
+ UDCCS1_RNE_BIT = 5,
+
+ UDCCS2_TFS_BIT = 0,
+ UDCCS2_TPC_BIT = 1,
+ UDCCS2_TPE_BIT = 2,
+ UDCCS2_TUR_BIT = 3,
+ UDCCS2_SST_BIT = 4,
+ UDCCS2_FST_BIT = 5,
+
+ UDCWC_WRITE_MASK = 0x0f,
+
+ UDCSR_EIR_BIT = 0,
+ UDCSR_RIR_BIT = 1,
+ UDCSR_TIR_BIT = 2,
+ UDCSR_SUSIR_BIT = 3,
+ UDCSR_RESIR_BIT = 4,
+ UDCSR_RSTIR_BIT = 5,
+
UART3_FIFO_PRE = 8,
UART3_FIFO_FRE = 9,
UART3_FIFO_ROR = 10,
@@ -462,6 +524,19 @@ protected:
MCP_TELECOM_OVERRUN = 7
};
+ struct udc_regs
+ {
+ uint32_t udccr;
+ uint32_t udcar;
+ uint32_t udcomp;
+ uint32_t udcimp;
+ uint32_t udccs0;
+ uint32_t udccs1;
+ uint32_t udccs2;
+ uint32_t udcwc;
+ uint32_t udcsr;
+ };
+
struct uart_regs
{
uint32_t utcr[4];
@@ -640,6 +715,7 @@ protected:
uint32_t dbt[2];
};
+ udc_regs m_udc_regs;
uart_regs m_uart_regs;
icp_regs m_icp_regs;
mcp_regs m_mcp_regs;
diff --git a/src/devices/machine/sa1111.cpp b/src/devices/machine/sa1111.cpp
index c33cf0ba23e..4fbd5545355 100644
--- a/src/devices/machine/sa1111.cpp
+++ b/src/devices/machine/sa1111.cpp
@@ -504,14 +504,16 @@ TIMER_CALLBACK_MEMBER(sa1111_device::audio_tx_dma_callback)
m_audio_regs.sadtcs ^= (1 << SADTCS_TBIU_BIT);
m_audio_regs.sadta = m_audio_regs.sadts[1 - buf];
m_audio_regs.sadtcc = m_audio_regs.sadtc[1 - buf];
+ if (!BIT(m_audio_regs.sadtcs, s_start_masks[1 - buf]))
+ {
+ m_audio_regs.tx_dma_timer->adjust(attotime::never);
+ }
}
}
TIMER_CALLBACK_MEMBER(sa1111_device::audio_tx_callback)
{
- const uint32_t data = audio_tx_fifo_pop();
- LOGMASKED(LOG_AUDIO_DMA, "audio_tx_callback: obtained data %08x, passing to codec\n", data);
- m_i2s_out(data);
+ m_i2s_out(audio_tx_fifo_pop());
}
void sa1111_device::audio_update_mode()
@@ -588,6 +590,11 @@ void sa1111_device::audio_set_tx_dma_enabled(bool enabled)
{
m_audio_regs.tx_timer->adjust(attotime::never);
m_audio_regs.tx_dma_timer->adjust(attotime::never);
+
+ set_irq_line(INT_AUDTXA, 0);
+ set_irq_line(INT_AUDTXB, 0);
+ set_irq_line(INT_AUDTFS, 0);
+ set_irq_line(INT_AUDTUR, 0);
}
}
@@ -608,6 +615,11 @@ void sa1111_device::audio_set_rx_dma_enabled(bool enabled)
{
m_audio_regs.rx_timer->adjust(attotime::never);
m_audio_regs.rx_dma_timer->adjust(attotime::never);
+
+ set_irq_line(INT_AUDRXA, 0);
+ set_irq_line(INT_AUDRXB, 0);
+ set_irq_line(INT_AUDRFS, 0);
+ set_irq_line(INT_AUDROR, 0);
}
}
@@ -621,7 +633,7 @@ void sa1111_device::audio_start_tx_dma(const uint32_t buf)
const uint32_t divisor = ((m_sk_regs.skaud & SKAUD_ACD_MASK) >> SKAUD_ACD_BIT) + 1;
const uint32_t pll_clock = clock() * 39;
- attotime clock_period = attotime::from_ticks(divisor * 256, pll_clock);
+ attotime clock_period = attotime::from_ticks(divisor * 128, pll_clock);
m_audio_regs.tx_dma_timer->adjust(clock_period, 0, clock_period);
LOGMASKED(LOG_AUDIO_DMA, "audio_start_tx_dma, setting start address to %08x, Tx clock to %d / %d\n", m_audio_regs.sadta, pll_clock, divisor);