How to use UART3 on Hikey 960

I have setup a AOSP + OPTEE branch for hikey 960 ( The branch was downloaded in July 2019.

After booting the board, I tried the following test from the console:

The log from the normal world is using UART6 on the low speed header, so I am able to echo to /dev/ttyAMA6. When I try to echo to ttyAMA3, I get an error message.

How can I enable the use of UART3 ?

I don’t think UART3 is connected to the low speed header and configured for logging. The default is to use UART6 for logs from both normal and secure world.

I was referring to It shows UART3 on the low speed header.

My goal is to read / write data from OPTEE on UART3. But when I tried that I had some errors in OPTEE (I tried a test using the existing pl011 driver). Due to missing logs I couldn’t debug the error. So I wanted to see if UART3 is even working from normal world, and that didn’t succeed as well.

Can normal world or OPTEE read / write data on UART 3 ?

Ok, I guess it’s connected but just not configured for logging perhaps. In any case it sounds like you don’t really want to use it for logging anyway but rather for reading/writing data, so I suppose now that if you can see logs from UART6 from your other thread [1] you can try to debug the error?


Okay I will debug and let you know.

FYI the observation regarding the error when trying echo on UART device from normal world also happens when I try it on the Hikey 620 board with UART 2 (/dev/ttyAMA2). This is with the branch downloaded on Sept 8. UART 2 is on Hikey 620’s low speed header.


My guess is it’d be the same issue, i.e. both UART2 (620) and UART3 (960) aren’t configured the same as UART3 (620) and UART6 (960) to allow you to run the echo test properly. The OP-TEE patches for AOSP don’t mess with the UARTs. You’ll have to look elsewhere to make it work, e.g. kernel, device tree, bootloaders even.

For use of UART3 from OPTEE, I think the error is related to use of wrong address after physical to virtual translation.

From a related question (Physical address UART3?), UART3 is in IOMCU range. Which of the following memory regions would UART3 belong to ? Is it under MEM_AREA_IO_* ?

 * Memory area type:
 * MEM_AREA_END:      Reserved, marks the end of a table of mapping areas.
 * MEM_AREA_TEE_RAM:  core RAM (read/write/executable, secure, reserved to TEE)
 * MEM_AREA_TEE_RAM_RX:  core private read-only/executable memory (secure)
 * MEM_AREA_TEE_RAM_RO:  core private read-only/non-executable memory (secure)
 * MEM_AREA_TEE_RAM_RW:  core private read/write/non-executable memory (secure)
 * MEM_AREA_TEE_COHERENT: teecore coherent RAM (secure, reserved to TEE)
 * MEM_AREA_TEE_ASAN: core address sanitizer RAM (secure, reserved to TEE)
 * MEM_AREA_TA_RAM:   Secure RAM where teecore loads/exec TA instances.
 * MEM_AREA_NSEC_SHM: NonSecure shared RAM between NSec and TEE.
 * MEM_AREA_RAM_NSEC: NonSecure RAM storing data
 * MEM_AREA_RAM_SEC:  Secure RAM storing some secrets
 * MEM_AREA_IO_NSEC:  NonSecure HW mapped registers
 * MEM_AREA_IO_SEC:   Secure HW mapped registers
 * MEM_AREA_RES_VASPACE: Reserved virtual memory space
 * MEM_AREA_SHM_VASPACE: Virtual memory space for dynamic shared memory buffers
 * MEM_AREA_TA_VASPACE: TA va space, only used with phys_to_virt()
 * MEM_AREA_DDR_OVERALL: Overall DDR address range, candidate to dynamic shm.
 * MEM_AREA_MAXTYPE:  lower invalid 'type' value
enum teecore_memtypes {
        MEM_AREA_END = 0,

@vchong I haven’t found a solution yet. The UART calls are getting stuck as discussed in this question. Please let me know if you have any suggestion.

For using UART3, you need firstly to enable clock before access it:

                uart3: serial@ffd74000 {
                        compatible = "arm,pl011", "arm,primecell";
                        reg = <0x0 0xffd74000 0x0 0x1000>;
                        interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&crg_ctrl HI3660_FACTOR_UART3>,
                                 <&crg_ctrl HI3660_PCLK>;
                        clock-names = "uartclk", "apb_pclk";
                        pinctrl-names = "default";
                        pinctrl-0 = <&uart3_pmx_func &uart3_cfg_func>;
                        status = "disabled";

You could find the clocks “HI3660_FACTOR_UART3” and “HI3660_PCLK” in the kernel file: drivers/clk/hisilicon/clk-hi3660.c

@leo-yan I have not done this before. Is it possible you could tell me how exactly to modify the clk-hi3660.c file (or related files) to enabled the UART3 clock ? Thank you.