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