// File: /workspace/github_c_makefile_star2_O0/xiane[P]libvphevcodec/AML_HEVCEncoder.cpp
// Function: Wave4VpuSleepWake(AMVHEVCEncHandle_s*, unsigned int, int, unsigned short const*, unsigned int, unsigned int)
AMVEnc_Status Wave4VpuSleepWake(AMVHEVCEncHandle *Handle, u32 coreIdx, int iSleepWake, const u16* code, u32 size, u32 mode) {
    u32 regVal;
    vpu_buffer_t vb;
    u32 codeBase;
    u32 codeSize;
    u32 remapSize;
    uint32_t timeoutTicks = 0;

    (void)code;
    (void)size;

    if (vdi_wait_vpu_busy(coreIdx, VPU_BUSY_CHECK_TIMEOUT, W4_VPU_BUSY_STATUS) == -1) {
        VLOG(ERR, "Wave4VpuSleepWake timeout");
        reset_error = 1;
        return AMVENC_TIMEOUT;
    }

    if (iSleepWake == 1)  //saves
            {
        VpuWriteReg(coreIdx, W4_VPU_BUSY_STATUS, 1);
        VpuWriteReg(coreIdx, W4_RET_SUCCESS, 0);  //for debug
        VpuWriteReg(coreIdx, W4_CORE_INDEX, 0);

        VpuWriteReg(coreIdx, W4_COMMAND, SLEEP_VPU);
        VpuWriteReg(coreIdx, W4_VPU_HOST_INT_REQ, 1);
        if (vdi_wait_interrupt(0, VPU_BUSY_CHECK_TIMEOUT) == -1) {
            VLOG(ERR, "Wave4VpuSleepWake interrput error time out");
            reset_error = 1;
            return AMVENC_TIMEOUT;
        }

        regVal = VpuReadReg(coreIdx, W4_RET_SUCCESS);
        if (regVal == 0) {
            uint32_t reasonCode = VpuReadReg(coreIdx, W4_RET_FAIL_REASON);
            VLOG(ERR, "VPU Sleep (W4_RET_SUCCESS) failed(%d) REASON CODE(%08x) ", regVal, reasonCode);
            reset_error = 1;
            return AMVENC_HARDWARE;
        }
        VLOG(DEBUG, "VPU SLEEP Sucess");
    } else //restore
    {
        Uint32 hwOption = 0;

        vdi_get_common_memory(coreIdx, &vb);
        codeBase = vb.phys_addr;
        /* ALIGN TO 4KB */
        codeSize = (vb.size & ~0xfff);

        regVal = 0;
        VpuWriteReg(coreIdx, W4_PO_CONF, regVal);

        /* SW_RESET_SAFETY */
        regVal = mode; //W4_RST_BLOCK_ACLK_ALL | W4_RST_BLOCK_BCLK_ALL | W4_RST_BLOCK_CCLK_ALL;
        VpuWriteReg(coreIdx, W4_VPU_RESET_REQ, regVal);    // Reset All blocks

        /* Waiting reset done */
        if (vdi_wait_vpu_busy(coreIdx, VPU_BUSY_CHECK_TIMEOUT, W4_VPU_RESET_STATUS) == -1) {
            VpuWriteReg(coreIdx, W4_VPU_RESET_REQ, 0);
            VLOG(ERR, "VPU Wake Reset timeout");
            reset_error = 1;
            return AMVENC_TIMEOUT;
        }

        VpuWriteReg(coreIdx, W4_VPU_RESET_REQ, 0);
//        if (mode & 0xff000000)
//            vdi_clear_memory(0, stack_vb.phys_addr,stack_vb.size);
        /* remap page size */
        remapSize = (codeSize >> 12) & 0x1ff;
        regVal = 0x80000000 | (W4_REMAP_CODE_INDEX << 12) | (0 << 16) | (1 << 11) | remapSize;
        VpuWriteReg(coreIdx, W4_VPU_REMAP_CTRL, regVal);
        VpuWriteReg(coreIdx, W4_VPU_REMAP_VADDR, 0x00000000); /* DO NOT CHANGE! */
        VpuWriteReg(coreIdx, W4_VPU_REMAP_PADDR, codeBase);
        VpuWriteReg(coreIdx, W4_ADDR_CODE_BASE, codeBase);
        VpuWriteReg(coreIdx, W4_CODE_SIZE, codeSize);
        VpuWriteReg(coreIdx, W4_CODE_PARAM, 0);
        VpuWriteReg(coreIdx, W4_COMMAND_OPTION, 0);
        timeoutTicks = COMMAND_TIMEOUT * VCPU_CLOCK_IN_MHZ * (1000000 >> 15);
        timeoutTicks = timeoutTicks / 120;
        if (Handle->enc_width * Handle->enc_height <= 1280 * 720)
            timeoutTicks = timeoutTicks / 16; //  /8 == 20ms  /4 == 40 ms  /16 == 10ms
        else if (Handle->enc_width * Handle->enc_height <= 1920 * 1088)
            timeoutTicks = timeoutTicks / 8;
        else
            timeoutTicks = timeoutTicks / 2;
        VpuWriteReg(coreIdx, W4_TIMEOUT_CNT, timeoutTicks);

//        codeBase = (Uint32)stack_vb.phys_addr;
//        codeSize = (Uint32)stack_vb.size;
//        VpuWriteReg(coreIdx, W4_ADDR_STACK_BASE,     codeBase);
//        VpuWriteReg(coreIdx, W4_STACK_SIZE,          codeSize);

        VpuWriteReg(coreIdx, W4_HW_OPTION, hwOption);

        /* Interrupt */
        // for encoder interrupt
        regVal = (1 << W4_INT_ENC_PIC);
        regVal |= (1 << W4_INT_SLEEP_VPU);
        regVal |= (1 << W4_INT_SET_PARAM);
        // for decoder interrupt
        regVal |= (1 << W4_INT_DEC_PIC_HDR);
        regVal |= (1 << W4_INT_DEC_PIC);
        regVal |= (1 << W4_INT_QUERY_DEC);
        regVal |= (1 << W4_INT_SLEEP_VPU);
        regVal |= (1 << W4_INT_BSBUF_EMPTY);
        regVal = 0xfffff6ff; // remove wake up int bit 11
        VpuWriteReg(coreIdx, W4_VPU_VINT_ENABLE, regVal);

        VpuWriteReg(coreIdx, W4_VPU_BUSY_STATUS, 1);
        VpuWriteReg(coreIdx, W4_RET_SUCCESS, 0);  //for debug
        VpuWriteReg(coreIdx, W4_CORE_INDEX, 0);
        VpuWriteReg(coreIdx, W4_INST_INDEX, 0);
        VpuWriteReg(coreIdx, W4_COMMAND, INIT_VPU);
        VpuWriteReg(coreIdx, W4_VPU_HOST_INT_REQ, 1);
        VpuWriteReg(coreIdx, W4_VPU_REMAP_CORE_START, 1);

        if (vdi_wait_interrupt(0, VPU_BUSY_CHECK_TIMEOUT) == -1) {
            VLOG(ERR, "VPU Wake timeout");
            reset_error = 1;
            return AMVENC_TIMEOUT;
        }

        //if (vdi_wait_vpu_busy(coreIdx, VPU_BUSY_CHECK_TIMEOUT, W4_VPU_BUSY_STATUS) == -1) {
        //    VLOG(ERR, "VPU Wake timeout");
        //    reset_error = 1;
        //    return AMVENC_TIMEOUT;
        //}
        regVal = VpuReadReg(coreIdx, W4_RET_SUCCESS);
        if (regVal == 0) {
            uint32_t reasonCode = VpuReadReg(coreIdx, W4_RET_FAIL_REASON);
            VLOG(ERR, "VPU Wake(W4_RET_SUCCESS) failed(%d) REASON CODE(%08x) ", regVal, reasonCode);
            reset_error = 1;
            return AMVENC_HARDWARE;
        }
        VLOG(DEBUG, "VPU WAKE Sucess");
    }
    return AMVENC_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movl %r9d, -0x28(%rbp)
movl $0x0, -0x60(%rbp)
movl -0x14(%rbp), %edi
movl $0x1388, %esi           # imm = 0x1388
movl $0x70, %edx
callq 0x2060
cmpl $-0x1, %eax
jne 0x4d40
jmp 0x4d0e
leaq 0x2b009(%rip), %rdi     # 0x2fd1e
movb $0x0, %al
callq 0x2050
leaq 0x2b543(%rip), %rdi     # 0x30266
movb $0x0, %al
callq 0x2050
movl $0x1, 0x2e4c0(%rip)     # 0x331f4
movl $0xffffffdc, -0x4(%rbp) # imm = 0xFFFFFFDC
jmp 0x518c
cmpl $0x1, -0x18(%rbp)
jne 0x4e4a
movl -0x14(%rbp), %edi
movl $0x70, %esi
movl $0x1, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x110, %esi            # imm = 0x110
xorl %edx, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x104, %esi            # imm = 0x104
xorl %edx, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x100, %esi            # imm = 0x100
movl $0x400, %edx            # imm = 0x400
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x38, %esi
movl $0x1, %edx
callq 0x2160
xorl %edi, %edi
movl $0x1388, %esi           # imm = 0x1388
callq 0x2340
cmpl $-0x1, %eax
jne 0x4de3
jmp 0x4db1
leaq 0x2af80(%rip), %rdi     # 0x2fd38
movb $0x0, %al
callq 0x2050
leaq 0x2b4a0(%rip), %rdi     # 0x30266
movb $0x0, %al
callq 0x2050
movl $0x1, 0x2e41d(%rip)     # 0x331f4
movl $0xffffffdc, -0x4(%rbp) # imm = 0xFFFFFFDC
jmp 0x518c
movl -0x14(%rbp), %edi
movl $0x110, %esi            # imm = 0x110
callq 0x2210
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jne 0x4e41
movl -0x14(%rbp), %edi
movl $0x114, %esi            # imm = 0x114
callq 0x2210
movl %eax, -0x64(%rbp)
movl -0x2c(%rbp), %esi
movl -0x64(%rbp), %edx
leaq 0x2af4d(%rip), %rdi     # 0x2fd63
movb $0x0, %al
callq 0x2050
leaq 0x2b442(%rip), %rdi     # 0x30266
movb $0x0, %al
callq 0x2050
movl $0x1, 0x2e3bf(%rip)     # 0x331f4
movl $0xffffffdb, -0x4(%rbp) # imm = 0xFFFFFFDB
jmp 0x518c
jmp 0x4e43
jmp 0x4e45
jmp 0x5185
movl $0x0, -0x68(%rbp)
movl -0x14(%rbp), %edi
leaq -0x50(%rbp), %rsi
callq 0x2190
movq -0x48(%rbp), %rax
movl %eax, -0x54(%rbp)
movl -0x50(%rbp), %eax
andl $0xfffff000, %eax       # imm = 0xFFFFF000
movl %eax, -0x58(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x14(%rbp), %edi
movl -0x2c(%rbp), %edx
xorl %esi, %esi
callq 0x2160
movl -0x28(%rbp), %eax
movl %eax, -0x2c(%rbp)
movl -0x14(%rbp), %edi
movl -0x2c(%rbp), %edx
movl $0x50, %esi
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x1388, %esi           # imm = 0x1388
movl $0x54, %edx
callq 0x2060
cmpl $-0x1, %eax
jne 0x4ef1
movl -0x14(%rbp), %edi
movl $0x50, %esi
xorl %edx, %edx
callq 0x2160
leaq 0x2aed6(%rip), %rdi     # 0x2fd9c
movb $0x0, %al
callq 0x2050
leaq 0x2b392(%rip), %rdi     # 0x30266
movb $0x0, %al
callq 0x2050
movl $0x1, 0x2e30f(%rip)     # 0x331f4
movl $0xffffffdc, -0x4(%rbp) # imm = 0xFFFFFFDC
jmp 0x518c
movl -0x14(%rbp), %edi
movl $0x50, %esi
xorl %edx, %edx
callq 0x2160
movl -0x58(%rbp), %eax
shrl $0xc, %eax
andl $0x1ff, %eax            # imm = 0x1FF
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
orl $0x80000800, %eax       # imm = 0x80000800
movl %eax, -0x2c(%rbp)
movl -0x14(%rbp), %edi
movl -0x2c(%rbp), %edx
movl $0x60, %esi
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x64, %esi
xorl %edx, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl -0x54(%rbp), %edx
movl $0x68, %esi
callq 0x2160
movl -0x14(%rbp), %edi
movl -0x54(%rbp), %edx
movl $0x118, %esi            # imm = 0x118
callq 0x2160
movl -0x14(%rbp), %edi
movl -0x58(%rbp), %edx
movl $0x11c, %esi            # imm = 0x11C
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x120, %esi            # imm = 0x120
xorl %edx, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x10c, %esi            # imm = 0x10C
xorl %edx, %edx
callq 0x2160
movl $0x3a980, -0x60(%rbp)   # imm = 0x3A980
movl -0x60(%rbp), %eax
movl $0x78, %ecx
xorl %edx, %edx
divl %ecx
movl %eax, -0x60(%rbp)
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
movq -0x10(%rbp), %rcx
imull 0x10(%rcx), %eax
cmpl $0xe1000, %eax          # imm = 0xE1000
ja 0x4fbd
movl -0x60(%rbp), %eax
shrl $0x4, %eax
movl %eax, -0x60(%rbp)
jmp 0x4fe8
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
movq -0x10(%rbp), %rcx
imull 0x10(%rcx), %eax
cmpl $0x1fe000, %eax         # imm = 0x1FE000
ja 0x4fde
movl -0x60(%rbp), %eax
shrl $0x3, %eax
movl %eax, -0x60(%rbp)
jmp 0x4fe6
movl -0x60(%rbp), %eax
shrl %eax
movl %eax, -0x60(%rbp)
jmp 0x4fe8
movl -0x14(%rbp), %edi
movl -0x60(%rbp), %edx
movl $0x134, %esi            # imm = 0x134
callq 0x2160
movl -0x14(%rbp), %edi
movl -0x68(%rbp), %edx
movl $0x124, %esi            # imm = 0x124
callq 0x2160
movl $0x8, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
orl $0x400, %eax            # imm = 0x400
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
orl $0x2, %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
orl $0x2, %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
orl $0x8, %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
orl $0x200, %eax            # imm = 0x200
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
orl $0x400, %eax            # imm = 0x400
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
orl $0x8000, %eax           # imm = 0x8000
movl %eax, -0x2c(%rbp)
movl $0xfffff6ff, -0x2c(%rbp) # imm = 0xFFFFF6FF
movl -0x14(%rbp), %edi
movl -0x2c(%rbp), %edx
movl $0x48, %esi
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x70, %esi
movl $0x1, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x110, %esi            # imm = 0x110
xorl %edx, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x104, %esi            # imm = 0x104
xorl %edx, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x108, %esi            # imm = 0x108
xorl %edx, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x100, %esi            # imm = 0x100
movl $0x1, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x38, %esi
movl $0x1, %edx
callq 0x2160
movl -0x14(%rbp), %edi
movl $0x6c, %esi
movl $0x1, %edx
callq 0x2160
xorl %edi, %edi
movl $0x1388, %esi           # imm = 0x1388
callq 0x2340
cmpl $-0x1, %eax
jne 0x5124
jmp 0x50f5
leaq 0x2acb7(%rip), %rdi     # 0x2fdb3
movb $0x0, %al
callq 0x2050
leaq 0x2b15c(%rip), %rdi     # 0x30266
movb $0x0, %al
callq 0x2050
movl $0x1, 0x2e0d9(%rip)     # 0x331f4
movl $0xffffffdc, -0x4(%rbp) # imm = 0xFFFFFFDC
jmp 0x518c
movl -0x14(%rbp), %edi
movl $0x110, %esi            # imm = 0x110
callq 0x2210
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jne 0x517f
movl -0x14(%rbp), %edi
movl $0x114, %esi            # imm = 0x114
callq 0x2210
movl %eax, -0x6c(%rbp)
movl -0x2c(%rbp), %esi
movl -0x6c(%rbp), %edx
leaq 0x2ac6d(%rip), %rdi     # 0x2fdc4
movb $0x0, %al
callq 0x2050
leaq 0x2b101(%rip), %rdi     # 0x30266
movb $0x0, %al
callq 0x2050
movl $0x1, 0x2e07e(%rip)     # 0x331f4
movl $0xffffffdb, -0x4(%rbp) # imm = 0xFFFFFFDB
jmp 0x518c
jmp 0x5181
jmp 0x5183
jmp 0x5185
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)