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