xref: /rk3399_rockchip-uboot/board/esd/vme8349/caddy.c (revision 24b852a7a2b8eca71789100983bdb5104cc00696)
1c2e49f70SReinhard Arlt /*
2c2e49f70SReinhard Arlt  * caddy.c -- esd VME8349 support for "missing" access modes in TSI148.
3c2e49f70SReinhard Arlt  * Copyright (c) 2009 esd gmbh.
4c2e49f70SReinhard Arlt  *
5c2e49f70SReinhard Arlt  * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
6c2e49f70SReinhard Arlt  *
71a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
8c2e49f70SReinhard Arlt  */
9c2e49f70SReinhard Arlt 
10c2e49f70SReinhard Arlt #include <common.h>
11*24b852a7SSimon Glass #include <console.h>
12c2e49f70SReinhard Arlt #include <ioports.h>
13c2e49f70SReinhard Arlt #include <mpc83xx.h>
14c2e49f70SReinhard Arlt #include <asm/mpc8349_pci.h>
15c2e49f70SReinhard Arlt #include <pci.h>
16c2e49f70SReinhard Arlt #include <asm/mmu.h>
17c2e49f70SReinhard Arlt #include <asm/io.h>
18c2e49f70SReinhard Arlt 
19c2e49f70SReinhard Arlt #include "caddy.h"
20c2e49f70SReinhard Arlt 
21c2e49f70SReinhard Arlt static struct caddy_interface *caddy_interface;
22c2e49f70SReinhard Arlt 
generate_answer(struct caddy_cmd * cmd,uint32_t status,uint32_t * result)23c2e49f70SReinhard Arlt void generate_answer(struct caddy_cmd *cmd, uint32_t status, uint32_t *result)
24c2e49f70SReinhard Arlt {
25c2e49f70SReinhard Arlt 	struct caddy_answer *answer;
26c2e49f70SReinhard Arlt 	uint32_t ptr;
27c2e49f70SReinhard Arlt 
28c2e49f70SReinhard Arlt 	answer = &caddy_interface->answer[caddy_interface->answer_in];
29c2e49f70SReinhard Arlt 	memset((void *)answer, 0, sizeof(struct caddy_answer));
30c2e49f70SReinhard Arlt 	answer->answer = cmd->cmd;
31c2e49f70SReinhard Arlt 	answer->issue = cmd->issue;
32c2e49f70SReinhard Arlt 	answer->status = status;
33c2e49f70SReinhard Arlt 	memcpy(answer->par, result, 5 * sizeof(result[0]));
34c2e49f70SReinhard Arlt 	ptr = caddy_interface->answer_in + 1;
35c2e49f70SReinhard Arlt 	ptr = ptr & (ANSWER_SIZE - 1);
36c2e49f70SReinhard Arlt 	if (ptr != caddy_interface->answer_out)
37c2e49f70SReinhard Arlt 		caddy_interface->answer_in = ptr;
38c2e49f70SReinhard Arlt }
39c2e49f70SReinhard Arlt 
do_caddy(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])4054841ab5SWolfgang Denk int do_caddy(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
41c2e49f70SReinhard Arlt {
42c2e49f70SReinhard Arlt 	unsigned long base_addr;
43c2e49f70SReinhard Arlt 	uint32_t ptr;
44c2e49f70SReinhard Arlt 	struct caddy_cmd *caddy_cmd;
45c2e49f70SReinhard Arlt 	uint32_t result[5];
46c2e49f70SReinhard Arlt 	uint16_t data16;
47c2e49f70SReinhard Arlt 	uint8_t data8;
48c2e49f70SReinhard Arlt 	uint32_t status;
49c2e49f70SReinhard Arlt 	pci_dev_t dev;
50c2e49f70SReinhard Arlt 	void *pci_ptr;
51c2e49f70SReinhard Arlt 
52c2e49f70SReinhard Arlt 	if (argc < 2) {
53c2e49f70SReinhard Arlt 		puts("Missing parameter\n");
54c2e49f70SReinhard Arlt 		return 1;
55c2e49f70SReinhard Arlt 	}
56c2e49f70SReinhard Arlt 
57c2e49f70SReinhard Arlt 	base_addr = simple_strtoul(argv[1], NULL, 16);
58c2e49f70SReinhard Arlt 	caddy_interface = (struct caddy_interface *) base_addr;
59c2e49f70SReinhard Arlt 
60c2e49f70SReinhard Arlt 	memset((void *)caddy_interface, 0, sizeof(struct caddy_interface));
61c2e49f70SReinhard Arlt 	memcpy((void *)&caddy_interface->magic[0], &CADDY_MAGIC, 16);
62c2e49f70SReinhard Arlt 
63c2e49f70SReinhard Arlt 	while (ctrlc() == 0) {
64c2e49f70SReinhard Arlt 		if (caddy_interface->cmd_in != caddy_interface->cmd_out) {
65c2e49f70SReinhard Arlt 			memset(result, 0, 5 * sizeof(result[0]));
66c2e49f70SReinhard Arlt 			status = 0;
67c2e49f70SReinhard Arlt 			caddy_cmd = &caddy_interface->cmd[caddy_interface->cmd_out];
68c2e49f70SReinhard Arlt 			pci_ptr = (void *)CONFIG_SYS_PCI1_IO_PHYS +
69c2e49f70SReinhard Arlt 				(caddy_cmd->addr & 0x001fffff);
70c2e49f70SReinhard Arlt 
71c2e49f70SReinhard Arlt 			switch (caddy_cmd->cmd) {
72c2e49f70SReinhard Arlt 			case CADDY_CMD_IO_READ_8:
73c2e49f70SReinhard Arlt 				result[0] = in_8(pci_ptr);
74c2e49f70SReinhard Arlt 				break;
75c2e49f70SReinhard Arlt 
76c2e49f70SReinhard Arlt 			case CADDY_CMD_IO_READ_16:
77c2e49f70SReinhard Arlt 				result[0] = in_be16(pci_ptr);
78c2e49f70SReinhard Arlt 				break;
79c2e49f70SReinhard Arlt 
80c2e49f70SReinhard Arlt 			case CADDY_CMD_IO_READ_32:
81c2e49f70SReinhard Arlt 				result[0] = in_be32(pci_ptr);
82c2e49f70SReinhard Arlt 				break;
83c2e49f70SReinhard Arlt 
84c2e49f70SReinhard Arlt 			case CADDY_CMD_IO_WRITE_8:
85c2e49f70SReinhard Arlt 				data8 = caddy_cmd->par[0] & 0x000000ff;
86c2e49f70SReinhard Arlt 				out_8(pci_ptr, data8);
87c2e49f70SReinhard Arlt 				break;
88c2e49f70SReinhard Arlt 
89c2e49f70SReinhard Arlt 			case CADDY_CMD_IO_WRITE_16:
90c2e49f70SReinhard Arlt 				data16 = caddy_cmd->par[0] & 0x0000ffff;
91c2e49f70SReinhard Arlt 				out_be16(pci_ptr, data16);
92c2e49f70SReinhard Arlt 				break;
93c2e49f70SReinhard Arlt 
94c2e49f70SReinhard Arlt 			case CADDY_CMD_IO_WRITE_32:
95c2e49f70SReinhard Arlt 				out_be32(pci_ptr, caddy_cmd->par[0]);
96c2e49f70SReinhard Arlt 				break;
97c2e49f70SReinhard Arlt 
98c2e49f70SReinhard Arlt 			case CADDY_CMD_CONFIG_READ_8:
99c2e49f70SReinhard Arlt 				dev = PCI_BDF(caddy_cmd->par[0],
100c2e49f70SReinhard Arlt 					      caddy_cmd->par[1],
101c2e49f70SReinhard Arlt 					      caddy_cmd->par[2]);
102c2e49f70SReinhard Arlt 				status = pci_read_config_byte(dev,
103c2e49f70SReinhard Arlt 							      caddy_cmd->addr,
104c2e49f70SReinhard Arlt 							      &data8);
105c2e49f70SReinhard Arlt 				result[0] = data8;
106c2e49f70SReinhard Arlt 				break;
107c2e49f70SReinhard Arlt 
108c2e49f70SReinhard Arlt 			case CADDY_CMD_CONFIG_READ_16:
109c2e49f70SReinhard Arlt 				dev = PCI_BDF(caddy_cmd->par[0],
110c2e49f70SReinhard Arlt 					      caddy_cmd->par[1],
111c2e49f70SReinhard Arlt 					      caddy_cmd->par[2]);
112c2e49f70SReinhard Arlt 				status = pci_read_config_word(dev,
113c2e49f70SReinhard Arlt 							      caddy_cmd->addr,
114c2e49f70SReinhard Arlt 							      &data16);
115c2e49f70SReinhard Arlt 				result[0] = data16;
116c2e49f70SReinhard Arlt 				break;
117c2e49f70SReinhard Arlt 
118c2e49f70SReinhard Arlt 			case CADDY_CMD_CONFIG_READ_32:
119c2e49f70SReinhard Arlt 				dev = PCI_BDF(caddy_cmd->par[0],
120c2e49f70SReinhard Arlt 					      caddy_cmd->par[1],
121c2e49f70SReinhard Arlt 					      caddy_cmd->par[2]);
122c2e49f70SReinhard Arlt 				status = pci_read_config_dword(dev,
123c2e49f70SReinhard Arlt 							       caddy_cmd->addr,
124c2e49f70SReinhard Arlt 							       &result[0]);
125c2e49f70SReinhard Arlt 				break;
126c2e49f70SReinhard Arlt 
127c2e49f70SReinhard Arlt 			case CADDY_CMD_CONFIG_WRITE_8:
128c2e49f70SReinhard Arlt 				dev = PCI_BDF(caddy_cmd->par[0],
129c2e49f70SReinhard Arlt 					      caddy_cmd->par[1],
130c2e49f70SReinhard Arlt 					      caddy_cmd->par[2]);
131c2e49f70SReinhard Arlt 				data8 = caddy_cmd->par[3] & 0x000000ff;
132c2e49f70SReinhard Arlt 				status = pci_write_config_byte(dev,
133c2e49f70SReinhard Arlt 							       caddy_cmd->addr,
134c2e49f70SReinhard Arlt 							       data8);
135c2e49f70SReinhard Arlt 				break;
136c2e49f70SReinhard Arlt 
137c2e49f70SReinhard Arlt 			case CADDY_CMD_CONFIG_WRITE_16:
138c2e49f70SReinhard Arlt 				dev = PCI_BDF(caddy_cmd->par[0],
139c2e49f70SReinhard Arlt 					      caddy_cmd->par[1],
140c2e49f70SReinhard Arlt 					      caddy_cmd->par[2]);
141c2e49f70SReinhard Arlt 				data16 = caddy_cmd->par[3] & 0x0000ffff;
142c2e49f70SReinhard Arlt 				status = pci_write_config_word(dev,
143c2e49f70SReinhard Arlt 							       caddy_cmd->addr,
144c2e49f70SReinhard Arlt 							       data16);
145c2e49f70SReinhard Arlt 				break;
146c2e49f70SReinhard Arlt 
147c2e49f70SReinhard Arlt 			case CADDY_CMD_CONFIG_WRITE_32:
148c2e49f70SReinhard Arlt 				dev = PCI_BDF(caddy_cmd->par[0],
149c2e49f70SReinhard Arlt 					      caddy_cmd->par[1],
150c2e49f70SReinhard Arlt 					      caddy_cmd->par[2]);
151c2e49f70SReinhard Arlt 				status = pci_write_config_dword(dev,
152c2e49f70SReinhard Arlt 								caddy_cmd->addr,
153c2e49f70SReinhard Arlt 								caddy_cmd->par[3]);
154c2e49f70SReinhard Arlt 				break;
155c2e49f70SReinhard Arlt 
156c2e49f70SReinhard Arlt 			default:
157c2e49f70SReinhard Arlt 				status = 0xffffffff;
158c2e49f70SReinhard Arlt 				break;
159c2e49f70SReinhard Arlt 			}
160c2e49f70SReinhard Arlt 
161c2e49f70SReinhard Arlt 			generate_answer(caddy_cmd, status, &result[0]);
162c2e49f70SReinhard Arlt 
163c2e49f70SReinhard Arlt 			ptr = caddy_interface->cmd_out + 1;
164c2e49f70SReinhard Arlt 			ptr = ptr & (CMD_SIZE - 1);
165c2e49f70SReinhard Arlt 			caddy_interface->cmd_out = ptr;
166c2e49f70SReinhard Arlt 		}
167c2e49f70SReinhard Arlt 
168c2e49f70SReinhard Arlt 		caddy_interface->heartbeat++;
169c2e49f70SReinhard Arlt 	}
170c2e49f70SReinhard Arlt 
171c2e49f70SReinhard Arlt 	return 0;
172c2e49f70SReinhard Arlt }
173c2e49f70SReinhard Arlt 
174c2e49f70SReinhard Arlt U_BOOT_CMD(
175c2e49f70SReinhard Arlt 	caddy,	2,	0,	do_caddy,
176c2e49f70SReinhard Arlt 	"Start Caddy server.",
177c2e49f70SReinhard Arlt 	"Start Caddy server with Data structure a given addr\n"
178c2e49f70SReinhard Arlt 	);
179