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