26. IOP8051

26. IOP8051

26.1 Introduction

There is an IOP (IO Processor) embedded inside SP7021 which is used as Processor for I/O control, IR decoding / IR wake-up and cooperation with CPU & PMC in power management purpose. The IOP core is DQ8051, so also named IOP8051, it supports dedicated JTAG debug pins which share with SP7021. In standby mode operation, the power spec reach 400uA.
.

26.2 Function Diagram

A generalized function diagram of IOP is shown in Figure 26-1.


Figure 26-1 IOP Functional Blocks

  • Memory management: Mainly deal with DQ8051 memory read/write access, according to its interface and address, map these operations to GPIO, registers or system memory; when access system memory can improve the performance of IOP access system memory via cache.

  • RegFile: Control registers for mapping to RBUS and IOP IDM, such as mailbox registers, addressing base control registers, etc.

  • SFR: SFR (Special Function registers) registers are used for power and GPIO controls.

  • IR: Infrared Radiation (infrared), usually used as a remote control.

  • RBUS: Main system can use this interface to control, communicate and debug IOP.

  • Power Control: System standby / resume control.

  • IDM: Internal data memory which the address is set between 0x30 ~ 0x6F (64B total)

  • XDM: External data Memory which the address is set between 0x0000 ~ 0xFFFF. This is part of the mapped to system bus, which enables the cache to speed up execution and reduce the need for main memory access



26.3 Function Descriptions

26.3.1 Timer1 and 2

Two 16-bit timers are embedded, timer period = IOP clock cycle time. The control flow are as below.

  • Set the timer in IDM: 0x3E~0x41 registers; the counter is cleared to 0x0

  • Enable the timer in IDM: 0x42 register,up-counting starts

  • When the timer counts to the time set, an interrupt to IOP is issued

  • If the interrupt is not masked, IOP enters ISR

  • IOP may clear the interrupt flag by writing "1" to the corresponding register

26.3.2 Mailbox

Mailbox is a register that can be read and written by IOP and System to exchange information with the system, faster than shared memory. The System side can be read and written by the RGST Bus. The IOP side can be accessed via the IOP_memory_management controller or via IDD memory-mapped registers - this path is still available when power down.
Note! mailbox can be read and written by System and IOP. If there is a case of writing mailbox at the same time, the write of RGST Bus is valid, and the write of IOP is ignored. Therefore, it is recommended that the use of mailbox should be one-way:
For example:
IOP Write -> System Read and Clear
System Write -> IOP Read and Clear

26.3.3 GPIO

IOP supports 128bit GPIO, which specifically supports read access to GPIO output and output enable.

26.3.4 IR

Infrared Radiation (infrared), usually used as a remote control. IR decoding is implemented by software, No hardware IR decoder is embedded

26.3.5 Reset

System may reset IOP to restart the program from the boot address. This action can be performed via RGST bus write iop_control[0]. System write 1 to iop_control[0], which asserts an IOP reset signal. This reset signal resets the IOP core, and it returns to the initial state. Caches, Timers, and other circuits are also reset.

26.3.6 Debug

  • CPU can stop IOP core with an instruction breakpoint

    • CPU writes an address to the breakpoint register iop_bp

    • CPU writes 1 to iop_control register[2], which enables the breakpoint function

    • When IOP core accesses the address that matches iop_bp, the iop_control[3] will be set to 1

  • CPU also can stop IOP core with a stall control

    • CPU writes 1 to iop_control register[1], which enables the stall function

    • IOP core halts when this stall control bit is set to 1

  • CPU uses iop_regsel to select IOP core registers for monitoring

    • CPU reads iop_regout to get the values of IOP core registers for debugging

 

26.3.7 Interrupts to IOP

Listed below is the interrupt control register (IDM 0x39), where bit 3, 4, 5 is for software monitoring. If some restrictions are violated, the corresponding interrupt will be pulled to notify.

Bit

Description

[0]

Timer B INT

[1]

Timer A INT

[2]

IR INT, this bit equals (IR_IN ^ IR_IN_POLARITY)

[3]

Access CBUS in Power Down Mode (cache-miss occurs in power down mode)
In the power down mode, if a cache miss occurs (the software does not cache all the codes before entering the power down mode),

the hardware will pull the INT to notify the software that a cache miss has occurred.

[4]

Access upper 32K IOP address region(r/w iop_addr>16'h7fff) during cache flushing
After the cache flush under the software, the hardware will flush the dirty entries of IOP_ADDR>0x7fff in the cache. Before the flush is completed,

if the IOP accesses the address region greater than 0x7fff, the INT will pull up.

  • IRQ for IOP core are low-level-triggered INTs

  • The IRQ flags are cleared by writing "1" to them, except the IR INT

 

26.3.8 Interrupts from IOP

At present, the hardware directly pulls the value of this bit into SYS_INT, that is, the software fills in 1, the SYS_INT is 1, the software fills in 0, and the SYS_INT is 0. If the IOP needs to make an INT to the RISC at some point, fill in the register 1. If it is to be cleared, fill in 0.
Note: For SYS_INT registers, RISC can only perform Read and Clear operations through RGST Bus. That is, RISCx cannot set RISC_INTx to 1 by itself. Only Write 0 is valid.

26.4 System Operation

26.4.1 Initialization flow

IOP is dedicated to the processing of IO-related processors in the system, and its work needs to be controlled and coordinated by the main controllers in the system, such as RISC CPUs. The recommended software developer refers to the following IOP Core Initialization flow:


Figure 26-2 Initialization flow

26.4.2 IOP MODULE EXECUTES 8051 CODE

  • Source code should reserve SDRAM memory area for IOP module code. 8051 bin file normal code and standby code can be placed in this area. The location area can be select by user.

Normal code: Monitor CPU commands.
Standby code: For RTC wake up, cooperation with CPU&PMC in power management

  • When the system enters standby mode, 8051 bin file should be moved to I_Cache.

I_Cache has 16K only. Standby code cannot exceed 16K.

  • When the IOP module is mounted, CPU load 8051 codes (IopNormalCode[]) into memory.

Iop_base_addr_l and iop_base_addr_h specify address.
During system boot up, when the IOP is mounted, it will load 8051 normal code and start execute 8051 code.

26.4.3 Program loader

In the system, IOP can continue to work when other modules in the system enter standby / power down modes to monitor whether the system wakes up through IR. In such a situation, the IOP will not be able to access the system memory. Therefore, the program that the IOP core needs to execute at this time, or the data segment of the operation must be stored in the cache (in the always-on power domain). The program loader is used to complete the cache fill. The implementation method is to capture the required program and data segment through memory read.

26.4.4 Power control flow

IOP supports independent operation when the system is standby / power down. When the user wakes up the system through IR, the IOP will use the power control signals to inform the system to start the relevant power management or system reset.

26.5 How To Create 8051 bin file

Please follow below steps:

Step1: Install Keil C.

Step2: Install DQ8051.  (Please contact vendor(https://www.dcd.pl/product-category/cpus/) for the package)

Step3: Open project with IOP 8051 source code and edit. (Refer to figure 26-3)

Figure 26-3 Keil C with IOP 8051 source code

Please get source code at: 

 

Step4: Generated normal bin file and put it in IopNormalCode[] which under linux/kernel/drivers/misc/iop/iopnormal.c. (Refer to figure 26-4)

            When system booting, it will download this code as default setting.

Figure 26-4 Content of iopnormal.c

Step4: Generated standby bin file and put it in IopStandbyCode[] which under linux/kernel/drivers/misc/iop/iopstandby.c. 

            When system enter shutdown, IOP device will call standby code to save power.

 

26.6 IOP8051 Module Execution

Please follow below steps:

Step1: Reserved memory for IOP module. (Refer to figure 26-5/26-6)

Figure 26-5 reserve memory code

Figure 26-6 memory map

 

Step2: Load normal code. When the IOP module is mounted, system will load 8051 codes(IopNormalCode[]) into memory.

            Below is the example code which include in the linux/kernel/drivers/misc/iop/hal_iop.c .

void hal_iop_init(void __iomem *iopbase)

{

          regs_iop_t *pIopReg = (regs_iop_t *)iopbase;

          volatile unsigned int*   IOP_base =(volatile unsigned int*)SP_IOP_RESERVE_BASE;

          unsigned char * IOP_kernel_base;

         

          IOP_kernel_base = (unsigned char *)ioremap((unsigned long)IOP_base, IOP_CODE_SIZE);

          memset((unsigned char *)IOP_kernel_base,0, IOP_CODE_SIZE);

          memcpy((unsigned char *)IOP_kernel_base, IopNormalCode, IOP_CODE_SIZE);

 

          writel(0x00100010, (void __iomem *)(B_SYSTEM_BASE + 32*4*0+ 4*1));

         

          pIopReg->iop_control|=0x01;

          pIopReg->iop_control&=~(0x8000);

          pIopReg->iop_control|=0x0200;//disable watchdog event reset IOP

          pIopReg->iop_base_adr_l = (unsigned int) ((u32)(IOP_base) & 0xFFFF);

          pIopReg->iop_base_adr_h  =(unsigned int) ((u32)(IOP_base) >> 16);

          pIopReg->iop_control &=~(0x01);

}

EXPORT_SYMBOL(hal_iop_init);

 

Step3: Load standby code. When system enters standby mode, system will load 8051 codes(IopStandbyCode[]) into memory.

            Below is the example code which include in the linux/kernel/drivers/misc/iop/hal_iop.c .

void hal_iop_load_standby_code(void __iomem *iopbase)

{

          regs_iop_t *pIopReg = (regs_iop_t *)iopbase;

          volatile unsigned int*   IOP_base =(volatile unsigned int*)(SP_IOP_RESERVE_BASE+0x10000);

          unsigned char * IOP_kernel_base;

         

          IOP_kernel_base = (unsigned char *)ioremap((unsigned long)IOP_base, IOP_CODE_SIZE);

          memset((unsigned char *)IOP_kernel_base,0, IOP_CODE_SIZE);

          memcpy((unsigned char *)IOP_kernel_base, SourceCode, IOP_CODE_SIZE);

 

          writel(0x00100010, (void __iomem *)(B_SYSTEM_BASE + 32*4*0+ 4*1));

         

          pIopReg->iop_control|=0x01;      

          pIopReg->iop_control&=~(0x8000);

          pIopReg->iop_control|=0x0200;//disable watchdog event reset IOP

          pIopReg->iop_base_adr_l = (unsigned int) ((u32)(IOP_base) & 0xFFFF);

          pIopReg->iop_base_adr_h  =(unsigned int) ((u32)(IOP_base) >> 16);

          pIopReg->iop_control &=~(0x01);

}

EXPORT_SYMBOL(hal_iop_load_standby_code);

 

26.7 8051 Register Tables

26.7.1 IDM memory-mapped registers (in IOP power domain)

IDM addresses listed below are used as special function registers. The registers in 0x30~0x7F not specifically described are reserved. The other registers in 0x00~0x2F and 0x80~0xFF are for general purposes.

0x30 - 0x37 (Bank Addressing Base) 

0x30 - 0x37 (Bank Addressing Base) 

Address

Signal Name

Attribute

Reset Value

Description

0x30

IOP_IM_Base[7:0]

RO

0x0

IOP IM base address; always set to 0x0 for UVM test

0x31

IOP_IM_Base[15:8]

RO

0x0

IOP IM base address; always set to 0x0 for UVM test

0x32

IOP_IM_Base[23:16]

RO

0x0

IOP IM base address

0x33

IOP_IM_Base[31:24]

RO

0x0

IOP IM base address

0x34

reserved

 

 

 

0x35

IOP_DM_Base[23:16]

RW

0x0

IOP DM base address; XDM bank address when D-cache is enabled

0x36

IOP_DM_Base[31:24]

RW

0x0

IOP DM base address; XDM bank address when D-cache is enabled

0x37

reserved

 

 

 

0x38 - 0x3A (Interrupt)

Address

Signal Name

Attribute

Reset Value

Description

0x38[5:0]

IOP_INT_MASK_B

RW

0x0

refer to Interrupts_to_IOP

0x39[5:0]

IOP_INT_FLAG

R/W1C

0x0

refer to Interrupts_to_IOP

0x3A[0]

IOP_INT0

RW

0x0

refer to Interrupts_from_IOP

0x3A[1]

IOP_INT1

RW

0x0

refer to Interrupts_from_IOP

0x3B - 0x3C (XDM Cache Control)

Address

Signal Name

Attribute

Reset Value

Description

0x3B[6:0]

XDM Cache_Flush_LINE_NO

RW

0x7F

number of cache lines(32B) to be checked and then be flushed if dirty 0x0: none0x1: 2 lines are checked 0x7F(default): all lines of 4KB are checkedthis number has to be set before starting flush and not be modified until the end of flush

0x3C[0]

XDM Cache Disable

RW

0x0

0: cache is enabled (default) 1: cache is disabled

0x3C[1]

XDM Cache Flush

RW

0x0

0: normal mode write 1: flush read 1: flushing in progress (this bit is functionless when XDM cache is disabled)

0x3C[2]

XDM Cache_DIS_CLR_V_EN

RW

0x1

0: valid bits are not cleared 1: all valid bits are cleared when cache is disabled (0x3C[0]=1) (default)

0x3C[3]

XDM Cache_DIS_CLR_D_EN

RW

0x1

0: dirty bits are not cleared 1: all dirty bits are cleared when cache is disabled (0x3C[0]=1) (default)

0x3C[4]

XDM Cache_Flush_CLR_V_EN

RW

0x1

0: valid bits are not cleared 1: all valid bits are cleared when cache is flushed (0x3C[1]=1) (default)

0x3C[5]

XDM Cache_Flush_CLR_D_EN

RW

0x1

0: dirty bits are not cleared 1: all dirty bits are cleared when cache is flushed (0x3C[1]=1) (default)

0x3C[6]

XDM Cache_all_V_set

RW

0x0

0: normal function (default) 1: all valid bits are set
when it is set to "1", it will be cleared to "0" by HW automatically after 1T

0x3C[7]

XDM Cache_all_D_set

RW

0x0

0: normal function (default) 1: all dirty bits are set
when it is set to "1", it will be cleared to "0" by HW automatically after 1T

0x3D (IR / RTC)

Address

Signal Name

Attribute

Reset Value

Description

0x3D[0]

IR_O

RO

0x0

this bit equals IR_IN ^ IR_IN_polarity

0x3D[1]

IR_IN_polarity

RW

0x0

0: IR_O = IR_IN 1: IR_O = polarity-inverted IR_IN

0x3D[2]

PMC_IR_LATCH

RO

0x0

IR_LATCH flag from PMC 1: IR wakeup

0x3D[3]

PMC_SYS_RTC_LATCH

RO

0x0

SYS_RTC_LATCH flag from PMC 1: RTC wakeup

0x3D[4]

reserved

 

 

 

0x3D[5]

reserved

 

 

 

0x3D[6]

CLR_PMC_IR_LATCH

W1C

0x0

Clear PMC_IR_LATCH in PMC

0x3D[7]

CLR_PMC_SYS_RTC_LATCH

W1C

0x0

Clear PMC_SYS_RTC_LATCH in PMC

0x3E - 0x42 (Embedded Timer)

Address

Signal Name

Attribute

Reset Value

Description

0x3E

TIMER1[7:0]

RW

0xFF

timer1 low byte

0x3F

TIMER1[15:8]

RW

0xFF

timer1 high byte

0x40