1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
4 */
5
6#include <config.h>
7#include <asm/pci.h>
8#include <asm/post.h>
9#include <asm/arch/quark.h>
10#include <asm/arch/msg_port.h>
11
12.globl car_init
13car_init:
14	post_code(POST_CAR_START)
15
16	/*
17	 * Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is
18	 * initialized by hardware. eSRAM is the ideal place to be used
19	 * for Cache-As-RAM (CAR) before system memory is available.
20	 *
21	 * Relocate this eSRAM to a suitable location in the physical
22	 * memory map and enable it.
23	 */
24
25	/* Host Memory Bound Register P03h:R08h */
26	mov	$((MSG_PORT_HOST_BRIDGE << 16) | (HM_BOUND << 8)), %eax
27	mov	$(DRAM_BASE + DRAM_MAX_SIZE + ESRAM_SIZE), %edx
28	lea	1f, %esp
29	jmp	msg_port_write
301:
31
32	/* eSRAM Block Page Control Register P05h:R82h */
33	mov	$((MSG_PORT_MEM_MGR << 16) | (ESRAM_BLK_CTRL << 8)), %eax
34	mov	$(ESRAM_BLOCK_MODE | (CONFIG_ESRAM_BASE >> 24)), %edx
35	lea	2f, %esp
36	jmp	msg_port_write
372:
38
39	post_code(POST_CAR_CPU_CACHE)
40	jmp	car_init_ret
41
42msg_port_read:
43	/*
44	 * Parameter:
45	 *   eax[23:16] - Message Port ID
46	 *   eax[15:08] - Register Address
47	 *
48	 * Return Value:
49	 *   eax - Message Port Register value
50	 *
51	 * Return Address: esp
52	 */
53
54	or	$((MSG_OP_READ << 24) | MSG_BYTE_ENABLE), %eax
55	mov	%eax, %ebx
56
57	/* Write MCR B0:D0:F0:RD0 */
58	mov	$(PCI_CFG_EN | MSG_CTRL_REG), %eax
59	mov	$PCI_REG_ADDR, %dx
60	out	%eax, %dx
61	mov	$PCI_REG_DATA, %dx
62	mov	%ebx, %eax
63	out	%eax, %dx
64
65	/* Read MDR B0:D0:F0:RD4 */
66	mov	$(PCI_CFG_EN | MSG_DATA_REG), %eax
67	mov	$PCI_REG_ADDR, %dx
68	out	%eax, %dx
69	mov	$PCI_REG_DATA, %dx
70	in	%dx, %eax
71
72	jmp	*%esp
73
74msg_port_write:
75	/*
76	 * Parameter:
77	 *   eax[23:16] - Message Port ID
78	 *   eax[15:08] - Register Address
79	 *   edx        - Message Port Register value to write
80	 *
81	 * Return Address: esp
82	 */
83
84	or	$((MSG_OP_WRITE << 24) | MSG_BYTE_ENABLE), %eax
85	mov	%eax, %esi
86	mov	%edx, %edi
87
88	/* Write MDR B0:D0:F0:RD4 */
89	mov	$(PCI_CFG_EN | MSG_DATA_REG), %eax
90	mov	$PCI_REG_ADDR, %dx
91	out	%eax, %dx
92	mov	$PCI_REG_DATA, %dx
93	mov	%edi, %eax
94	out	%eax, %dx
95
96	/* Write MCR B0:D0:F0:RD0 */
97	mov	$(PCI_CFG_EN | MSG_CTRL_REG), %eax
98	mov	$PCI_REG_ADDR, %dx
99	out	%eax, %dx
100	mov	$PCI_REG_DATA, %dx
101	mov	%esi, %eax
102	out	%eax, %dx
103
104	jmp	*%esp
105