1*4882a593Smuzhiyun/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ 2*4882a593Smuzhiyun/* 3*4882a593Smuzhiyun * Copyright (c) 2023 Rockchip Electronics Co., Ltd. 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun#include <linux/linkage.h> 7*4882a593Smuzhiyun#include <asm/assembler.h> 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun#include "rv1106_pm.h" 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun#define RV1106_GPIO0_INT_ST 0xff380050 12*4882a593Smuzhiyun#define RV1106_PMUGRF_OS_REG10 0xff020228 13*4882a593Smuzhiyun#define RV1106_PMUGRF_SOC_CON4 0xff020010 14*4882a593Smuzhiyun#define RV1106_CRU_GLB_SRST_FST 0xff3b0c08 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun#if RV1106_SLEEP_DEBUG 17*4882a593Smuzhiyun/********************* console used for sleep.S ******************************/ 18*4882a593Smuzhiyun#define UART_REG_DLL (0x00) 19*4882a593Smuzhiyun#define UART_REG_DLH (0x04) 20*4882a593Smuzhiyun#define UART_REG_IER (0x04) 21*4882a593Smuzhiyun#define UART_REG_FCR (0x08) 22*4882a593Smuzhiyun#define UART_REG_LCR (0x0c) 23*4882a593Smuzhiyun#define UART_REG_MCR (0x10) 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun#define UARTLCR_DLAB (1 << 7) 26*4882a593Smuzhiyun#define UARTFCR_DMAEN (1 << 3) 27*4882a593Smuzhiyun#define UARTFCR_FIFOEN (1 << 0) 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun#define CONSOLE_UART_BASE 0xff4c0000 30*4882a593Smuzhiyun#define CONSOLE_CLKRATE 24000000 31*4882a593Smuzhiyun#define CONSOLE_BAUDRATE 115200 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun#define GPIO1_B_IOMUX 0xff538008 34*4882a593Smuzhiyun#define GRF_GPIO1D_VAL 0xff002200 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun.macro early_console_init 37*4882a593Smuzhiyun ldr r0, =GPIO1_B_IOMUX 38*4882a593Smuzhiyun ldr r1, =GRF_GPIO1D_VAL 39*4882a593Smuzhiyun str r1, [r0] 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun ldr r0, =CONSOLE_UART_BASE 42*4882a593Smuzhiyun ldr r1, =CONSOLE_CLKRATE 43*4882a593Smuzhiyun ldr r2, =CONSOLE_BAUDRATE 44*4882a593Smuzhiyun /* Program the baudrate */ 45*4882a593Smuzhiyun /* Divisor = Uart clock / (16 * baudrate) */ 46*4882a593Smuzhiyun mov r1, #0xd 47*4882a593Smuzhiyun mov r2, #0x0 48*4882a593Smuzhiyun ldr r3, [r0, #UART_REG_LCR] 49*4882a593Smuzhiyun orr r3, r3, #UARTLCR_DLAB 50*4882a593Smuzhiyun str r3, [r0, #UART_REG_LCR] /* enable DLL, DLH programming */ 51*4882a593Smuzhiyun str r1, [r0, #UART_REG_DLL] /* program DLL */ 52*4882a593Smuzhiyun str r2, [r0, #UART_REG_DLH] /* program DLH */ 53*4882a593Smuzhiyun mov r2, #~UARTLCR_DLAB 54*4882a593Smuzhiyun and r3, r3, r2 55*4882a593Smuzhiyun str r3, [r0, #UART_REG_LCR] /* disable DLL, DLH programming */ 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun /* 8n1 */ 58*4882a593Smuzhiyun mov r3, #3 59*4882a593Smuzhiyun str r3, [r0, #UART_REG_LCR] 60*4882a593Smuzhiyun /* no interrupt */ 61*4882a593Smuzhiyun mov r3, #0 62*4882a593Smuzhiyun str r3, [r0, #UART_REG_IER] 63*4882a593Smuzhiyun /* enable fifo, DMA */ 64*4882a593Smuzhiyun mov r3, #(UARTFCR_FIFOEN | UARTFCR_DMAEN) 65*4882a593Smuzhiyun str r3, [r0, #UART_REG_FCR] 66*4882a593Smuzhiyun /* DTR + RTS */ 67*4882a593Smuzhiyun mov r3, #3 68*4882a593Smuzhiyun str r3, [r0, #UART_REG_MCR] 69*4882a593Smuzhiyun mov r0, #1 70*4882a593Smuzhiyun dsb sy 71*4882a593Smuzhiyun.endm 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun.macro early_console_putc ch 74*4882a593Smuzhiyun ldr r0, =CONSOLE_UART_BASE 75*4882a593Smuzhiyun mov r1, #\ch 76*4882a593Smuzhiyun str r1, [r0] 77*4882a593Smuzhiyun.endm 78*4882a593Smuzhiyun/********************* console used for sleep.S ******************************/ 79*4882a593Smuzhiyun#endif 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun.align 2 82*4882a593Smuzhiyun.arm 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun 85*4882a593SmuzhiyunENTRY(rockchip_slp_cpu_resume) 86*4882a593Smuzhiyun#if RV1106_SLEEP_DEBUG 87*4882a593Smuzhiyun early_console_init 88*4882a593Smuzhiyun /* print 'A' */ 89*4882a593Smuzhiyun early_console_putc 0x41 90*4882a593Smuzhiyun#endif 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set svc, irqs off 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun#if RV1106_WAKEUP_TO_SYSTEM_RESET 95*4882a593Smuzhiyun /* save gpio wakeup src */ 96*4882a593Smuzhiyun ldr r0, =RV1106_PMUGRF_OS_REG10 97*4882a593Smuzhiyun ldr r1, =RV1106_GPIO0_INT_ST 98*4882a593Smuzhiyun ldr r1, [r1] 99*4882a593Smuzhiyun str r1, [r0] 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun /* clear pmu reset hold */ 102*4882a593Smuzhiyun ldr r0, =RV1106_PMUGRF_SOC_CON4 103*4882a593Smuzhiyun ldr r1, =0xffff0000 104*4882a593Smuzhiyun str r1, [r0] 105*4882a593Smuzhiyun add r0, r0, #4 106*4882a593Smuzhiyun str r1, [r0] 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun /* first reset */ 109*4882a593Smuzhiyun ldr r0, =RV1106_CRU_GLB_SRST_FST 110*4882a593Smuzhiyun mov r1, #0xfdb9 111*4882a593Smuzhiyun str r1, [r0] 112*4882a593Smuzhiyun b . 113*4882a593Smuzhiyun#endif 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun ldr r3, rkpm_bootdata_l2ctlr_f 116*4882a593Smuzhiyun cmp r3, #0 117*4882a593Smuzhiyun beq sp_set 118*4882a593Smuzhiyun ldr r3, rkpm_bootdata_l2ctlr 119*4882a593Smuzhiyun mcr p15, 1, r3, c9, c0, 2 120*4882a593Smuzhiyunsp_set: 121*4882a593Smuzhiyun ldr sp, rkpm_bootdata_cpusp 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun ldr r0, rkpm_ddr_data 124*4882a593Smuzhiyun ldr r1, rkpm_ddr_func 125*4882a593Smuzhiyun cmp r1, #0 126*4882a593Smuzhiyun beq boot 127*4882a593Smuzhiyun blx r1 128*4882a593Smuzhiyun 129*4882a593Smuzhiyunboot: 130*4882a593Smuzhiyun ldr r1, rkpm_bootdata_cpu_code 131*4882a593Smuzhiyun bx r1 132*4882a593SmuzhiyunENDPROC(rockchip_slp_cpu_resume) 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun/* Parameters filled in by the kernel */ 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun/* Flag for whether to restore L2CTLR on resume */ 137*4882a593Smuzhiyun .global rkpm_bootdata_l2ctlr_f 138*4882a593Smuzhiyunrkpm_bootdata_l2ctlr_f: 139*4882a593Smuzhiyun .long 0 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun/* Saved L2CTLR to restore on resume */ 142*4882a593Smuzhiyun .global rkpm_bootdata_l2ctlr 143*4882a593Smuzhiyunrkpm_bootdata_l2ctlr: 144*4882a593Smuzhiyun .long 0 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun/* CPU resume SP addr */ 147*4882a593Smuzhiyun .globl rkpm_bootdata_cpusp 148*4882a593Smuzhiyunrkpm_bootdata_cpusp: 149*4882a593Smuzhiyun .long 0 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun/* CPU resume function (physical address) */ 152*4882a593Smuzhiyun .globl rkpm_bootdata_cpu_code 153*4882a593Smuzhiyunrkpm_bootdata_cpu_code: 154*4882a593Smuzhiyun .long 0 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun/* ddr resume data */ 157*4882a593Smuzhiyun .globl rkpm_ddr_data 158*4882a593Smuzhiyunrkpm_ddr_data: 159*4882a593Smuzhiyun .long 0 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun/* ddr resume function (physical address) */ 162*4882a593Smuzhiyun .globl rkpm_ddr_func 163*4882a593Smuzhiyunrkpm_ddr_func: 164*4882a593Smuzhiyun .long 0 165*4882a593Smuzhiyun 166*4882a593SmuzhiyunENTRY(rv1106_bootram_sz) 167*4882a593Smuzhiyun .word . - rockchip_slp_cpu_resume 168