blob: d4e92b2dd01e4702cc229880d5d93b5cce431fb1 [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/*
2<:copyright-BRCM:2016:DUAL/GPL:standard
3
4 Broadcom Proprietary and Confidential.(c) 2016 Broadcom
5 All Rights Reserved
6
7Unless you and Broadcom execute a separate written software license
8agreement governing use of this software, this software is licensed
9to you under the terms of the GNU General Public License version 2
10(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
11with the following added to such license:
12
13 As a special exception, the copyright holders of this software give
14 you permission to link this software with independent modules, and
15 to copy and distribute the resulting executable under terms of your
16 choice, provided that you also meet, for each linked independent
17 module, the terms and conditions of the license of that module.
18 An independent module is a module which is not derived from this
19 software. The special exception does not apply to any modifications
20 of the software.
21
22Not withstanding the above, under no circumstances may you combine
23this software in any way with any other Broadcom software provided
24under a license other than the GPL, without Broadcom's express prior
25written consent.
26
27:>
28 */
29
30#include "bcmolt_fld.h"
31#ifdef TX_ENABLE_EVENT_TRACE
32#include "bcmolt_llpcie.h"
33#endif
34
35/* internal data base */
36static uint32_t max_bcm68620_device = 0;
37static bcm_fld_device_info *bcm68620_info = NULL;
38
39#define SRAM_ADDRESS(device,offset) (uint32_t *)(bcm68620_info[device].soc_sram_base + offset)
40
41bcmos_errno bcm_fld_init(uint32_t max_devices)
42{
43 max_bcm68620_device = max_devices;
44 bcm68620_info = (bcm_fld_device_info *)bcmos_alloc(max_devices * sizeof(bcm_fld_device_info));
45 if (!bcm68620_info)
46 return BCM_ERR_NOMEM;
47 memset(bcm68620_info, 0, max_devices * sizeof(bcm_fld_device_info));
48
49 return BCM_ERR_OK;
50}
51
52void bcm_fld_clear_comm_area(uint32_t device)
53{
54 memset((char *)SRAM_ADDRESS(device,BCM_FLD_COMMUNICATION_AREA_BASE), 0 ,BCM_FLD_COMMUNICATION_AREA_SIZE);
55#if defined(TX_ENABLE_EVENT_TRACE) && defined(DEBUG_TRACE_INIT)
56 bcm_ll_pcie_setrace(device);
57#endif
58}
59
60bcmos_errno bcm_fld_exit(void)
61{
62 if (bcm68620_info)
63 bcmos_free(bcm68620_info);
64
65 bcm68620_info = NULL;
66
67 return BCM_ERR_OK;
68}
69
70/* register a device to driver
71 returns the driver index, instead the user's
72 store the user,s information about the device */
73bcmos_errno bcm_fld_register(uint32_t device, bcm_fld_device_info *info)
74{
75 if (!info)
76 return BCM_ERR_PARM;
77
78 if (!bcm68620_info)
79 return BCM_ERR_NORES;
80
81 if (device >= max_bcm68620_device)
82 return BCM_ERR_RANGE;
83
84 if (bcm68620_info[device].soc_sram_base)
85 return BCM_ERR_ALREADY;
86
87 /* copy the information received from the user to uint32_ternal data base */
88 bcm68620_info[device].soc_sram_base = info->soc_sram_base;
89 bcm68620_info[device].soc_ddr_base = info->soc_ddr_base;
90 bcm68620_info[device].soc_regs_base = info->soc_regs_base;
91 bcm68620_info[device].soc_ddr_length = info->soc_ddr_length;
92
93 return BCM_ERR_OK;
94}
95
96/* remove a device from uint32_ternal data base */
97bcmos_errno bcm_fld_unregister(uint32_t device)
98{
99 if (!bcm68620_info)
100 return BCM_ERR_NORES;
101
102 if (device >= max_bcm68620_device)
103 return BCM_ERR_RANGE;
104
105 /* clear the uint32_ternal data base for the given device */
106 bcm68620_info[device].soc_sram_base = 0;
107 bcm68620_info[device].soc_ddr_base = 0;
108 bcm68620_info[device].soc_ddr_length = 0;
109 bcm68620_info[device].soc_crt_length = 0;
110 bcm68620_info[device].soc_regs_base = 0;
111
112 return BCM_ERR_OK;
113}
114
115/* read from communication area and return the soc state
116 reset reason and protocol version */
117bcmos_errno bcm_fld_get_device_status(uint32_t device, bcm_fld_device_stat *debug_state)
118{
119 if (!debug_state)
120 return BCM_ERR_PARM;
121
122 if (!bcm68620_info)
123 return BCM_ERR_NORES;
124
125 if (device >= max_bcm68620_device)
126 return BCM_ERR_RANGE;
127
128 /* read from SRAM os entry offset, CPU status, reason and protocol version */
129 debug_state->protocol_version = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_BOOT_PROTOCOL_VERSION_OFFSET));
130 debug_state->state = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_CPU_STATE_OFFSET));
131 debug_state->reason = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_CPU_RESET_REASON_OFFSET));
132 debug_state->os_entry_offset = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_OS_ENTRY_OFFSET));
133
134 return BCM_ERR_OK;
135}
136
137/* returns the last soc state */
138bcmos_errno bcm_fld_get_device_loading_state(uint32_t device, BCM_FLD_CPU_STATE *cpu_state)
139{
140 uint32_t temp;
141 volatile uint32_t value;
142
143 if (!cpu_state)
144 return BCM_ERR_PARM;
145
146 if (!bcm68620_info)
147 return BCM_ERR_NORES;
148
149 if (device >= max_bcm68620_device)
150 return BCM_ERR_RANGE;
151
152 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_CPU_STATE_OFFSET));
153 temp = value & BCM_FLD_CPU_READY_MASK;
154 if (temp)
155 *cpu_state = BCM_FLD_CPU_READY;
156 else
157 {
158 temp = value & BCM_FLD_CPU_FINISH_BOOTLOADER_MASK;
159 if (temp)
160 *cpu_state = BCM_FLD_CPU_FINISH_BOOTLOADER;
161 else
162 *cpu_state = BCM_FLD_CPU_STATE_UNKNOWN;
163 }
164
165 return BCM_ERR_OK;
166}
167
168/* write in communication area the current host status during loading process */
169bcmos_errno bcm_fld_host_finish_write_ddr(uint32_t device, uint32_t os_entry_address)
170{
171 if (!bcm68620_info)
172 return BCM_ERR_NORES;
173
174 if (device >= max_bcm68620_device)
175 return BCM_ERR_RANGE;
176
177 /* write os_entry address of the code from DDR */
178 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_OS_ENTRY_OFFSET), os_entry_address);
179 /* run code from DDR */
180 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_HOST_STATE_OFFSET), BCM_FLD_HOST_FINISH_WRITE_DDR_MASK);
181
182 return BCM_ERR_OK;
183}
184
185/* return the logs area */
186bcmos_errno bcm_fld_get_logs(uint32_t device, char **log_area, int *length)
187{
188 if (!log_area || !length)
189 return BCM_ERR_PARM;
190
191 if (!bcm68620_info)
192 return BCM_ERR_NORES;
193
194 if (device >= max_bcm68620_device)
195 return BCM_ERR_RANGE;
196
197 *log_area = (char *)SRAM_ADDRESS(device, BCM_FLD_LOGGER_BASE);
198 *length = BCM_FLD_LOGGER_TOP;
199
200 return BCM_ERR_OK;
201}
202
203/* write the received buffer to memory according to offset and type */
204bcmos_errno bcm_fld_write(uint32_t device, char *buff, uint32_t buff_size, uint32_t offset_in_image, bcmolt_device_image_type image_type)
205{
206 unsigned long address = 0;
207 int i;
208#ifndef PCIE_BYTE_COPY
209 uint32_t size, rest;
210 uint32_t* buff_32;
211 uint32_t* addr_32;
212#endif
213
214 if (!buff)
215 return BCM_ERR_PARM;
216
217 if (!bcm68620_info)
218 return BCM_ERR_NORES;
219
220 if (device >= max_bcm68620_device)
221 return BCM_ERR_RANGE;
222
223 if (image_type == BCMOLT_DEVICE_IMAGE_TYPE_BOOTLOADER)
224 {
225 address = bcm68620_info[device].soc_sram_base + offset_in_image;
226 if ((offset_in_image + buff_size) > BCM_FLD_COMMUNICATION_AREA_BASE)
227 return BCM_ERR_OVERFLOW;
228 }
229 else if (image_type == BCMOLT_DEVICE_IMAGE_TYPE_APPLICATION)
230 {
231 address = bcm68620_info[device].soc_ddr_base + offset_in_image;
232 if ((offset_in_image + buff_size) > bcm68620_info[device].soc_ddr_length)
233 return BCM_ERR_OVERFLOW;
234 bcm68620_info[device].soc_crt_length += buff_size;
235 }
236 else
237 {
238 return BCM_ERR_PARM;
239 }
240
241#ifndef PCIE_BYTE_COPY
242 size = buff_size / sizeof(*buff_32);
243 rest = buff_size & (sizeof(*buff_32) -1);
244
245 buff_32 = (uint32_t*)buff;
246 addr_32 = (uint32_t*)address;
247
248 if (rest)
249 size++;
250 for(i = 0; i < size; i++)
251 bcm_pci_write32((addr_32 + i),BCMOS_ENDIAN_CPU_TO_LITTLE_U32(*(buff_32 +i)));
252#else
253 for (i = 0; i < buff_size; i++)
254 *(uint8_t *)(address + i) = buff[i];
255#endif
256
257 bcmos_barrier();
258
259 return BCM_ERR_OK;
260}
261
262/* read to the received buffer from memory according to offset and type */
263bcmos_errno bcm_fld_read(uint32_t device, char *buff, uint32_t *buff_size, uint32_t offset_in_image, bcmolt_device_image_type image_type)
264{
265 unsigned long address = 0;
266 uint32_t i;
267#ifndef PCIE_BYTE_COPY
268 uint32_t size, rest;
269 uint32_t* buff_32;
270 uint32_t* addr_32;
271#endif
272
273 if (!buff || !buff_size)
274 return BCM_ERR_PARM;
275
276 if (!bcm68620_info)
277 return BCM_ERR_NORES;
278
279 if (device >= max_bcm68620_device)
280 return BCM_ERR_RANGE;
281
282 if(image_type == BCMOLT_DEVICE_IMAGE_TYPE_BOOTLOADER)
283 address = bcm68620_info[device].soc_sram_base + offset_in_image;
284 else if (image_type == BCMOLT_DEVICE_IMAGE_TYPE_APPLICATION)
285 address = bcm68620_info[device].soc_ddr_base + offset_in_image;
286 else
287 return BCM_ERR_PARM;
288
289 /* temporary for test , consider to integrate in future */
290#ifndef PCIE_BYTE_COPY
291 size = *buff_size /sizeof(*buff_32);
292 rest = *buff_size & (sizeof(*buff_32) -1);
293 buff_32 = (uint32_t*)buff;
294 addr_32 = (uint32_t*)address;
295
296 if (rest)
297 size++;
298 for(i = 0; i < size; i++)
299 *(buff_32 +i)= BCMOS_ENDIAN_CPU_TO_LITTLE_U32(bcm_pci_read32((uint32_t *)(addr_32 + i)));
300#else
301 for (i = 0; i < *buff_size; i++)
302 buff[i] = *(uint8_t *)(address + i);
303
304#endif
305
306 bcmos_barrier();
307
308 return BCM_ERR_OK;
309}
310
311
312/*********** PMC definitions ****************/
313#define PMC_QUEUE_0_DATA_UNRESET0 0x401c00U
314#define PMC_QUEUE_0_DATA_UNRESET1 0x401c04U
315#define PMC_QUEUE_0_DATA_UNRESET2 0x401c08U
316#define PMC_QUEUE_0_DATA_UNRESET3 0x401c0cU
317
318#define PMC_QUEUE_1_DATA_UNRESET0 0x401c10U
319#define PMC_QUEUE_1_DATA_UNRESET1 0x401c14U
320#define PMC_QUEUE_1_DATA_UNRESET2 0x401c18U
321#define PMC_QUEUE_1_DATA_UNRESET3 0x401c1cU
322
323#define PMC_CNTRL_HOST_MBOX_IN 0x401028U
324#define PMC_HOST_MBOX_MASK 0x2
325#define PMC_PMB_CNTRL 0x4800c0U
326/* The below value is the swap of ((1 << 31) | (1<<20) | (4 << 12) | (0x0C)) */
327#define PMC_PMB_CMD 0x0C401080
328#define PMC_PMB_WRITE 0x4800c4U
329/* The below value is the swap of 0x1*/
330#define PMC_PMB_ADDRESS 0x1000000
331
332/* PMC command to take ARM out of reset */
333#define ARM_OUT_OF_RESET 35
334/********************************************/
335
336bcmos_errno bcm_fld_start_bootloader(uint32_t device, uint32_t test_ddr)
337{
338/* temporary disabled: just for A0, should be enabled in B0
339#ifdef BCM_PMC_EXIST
340 volatile uint32_t readval;
341#endif
342*/
343 if (!bcm68620_info)
344 return BCM_ERR_NORES;
345
346 if (device >= max_bcm68620_device)
347 return BCM_ERR_RANGE;
348
349 bcm_pci_write32(SRAM_ADDRESS(device, BCM_FLD_HOST_STATE_OFFSET), test_ddr);
350 /* start processor */
351 bcm_fld_set_host_debug_status(device, BCM_FLD_HOST_START_CPU);
352/* Temporary disabled - should be enabled in B0
353#ifndef BCM_PMC_EXIST */
354 bcm_pci_read32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_PMB_CNTRL));
355 bcm_pci_write32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_PMB_WRITE), PMC_PMB_ADDRESS);
356 bcm_pci_read32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_PMB_WRITE));
357 bcm_pci_write32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_PMB_CNTRL), PMC_PMB_CMD);
358 bcm_pci_read32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_PMB_CNTRL));
359/*
360#else
361 readval = bcm_pci_read32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_CNTRL_HOST_MBOX_IN));
362 if (!(readval & PMC_HOST_MBOX_MASK))
363 return BCM_ERR_NOT_CONNECTED;
364
365 bcm_pci_write32((bcm68620_info[device].soc_regs_base + PMC_QUEUE_0_DATA_UNRESET0), BCMOS_ENDIAN_CPU_TO_LITTLE_U32(ARM_OUT_OF_RESET));
366 bcm_pci_write32((bcm68620_info[device].soc_regs_base + PMC_QUEUE_0_DATA_UNRESET1), BCMOS_ENDIAN_CPU_TO_LITTLE_U32(0));
367 bcm_pci_write32((bcm68620_info[device].soc_regs_base + PMC_QUEUE_0_DATA_UNRESET2), BCMOS_ENDIAN_CPU_TO_LITTLE_U32(0));
368 bcm_pci_write32((bcm68620_info[device].soc_regs_base + PMC_QUEUE_0_DATA_UNRESET3), BCMOS_ENDIAN_CPU_TO_LITTLE_U32(0));
369 bcmos_usleep(10000); // 10 msec
370 // read PMC response, to clean the queue
371 bcm_pci_read32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_QUEUE_1_DATA_UNRESET0));
372 bcm_pci_read32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_QUEUE_1_DATA_UNRESET1));
373 bcm_pci_read32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_QUEUE_1_DATA_UNRESET2));
374 bcm_pci_read32((uint32_t *)(bcm68620_info[device].soc_regs_base + PMC_QUEUE_1_DATA_UNRESET3));
375#endif
376*/
377
378 return BCM_ERR_OK;
379}
380
381bcmos_bool bcm_fld_is_bootloader_done(uint32_t device)
382{
383 volatile uint32_t value;
384
385 if (!bcm68620_info)
386 return BCMOS_FALSE;
387
388 if (device >= max_bcm68620_device)
389 return BCMOS_FALSE;
390
391 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_CPU_STATE_OFFSET));
392 if (value & BCM_FLD_CPU_FINISH_BOOTLOADER_MASK)
393 return BCMOS_TRUE;
394
395 return BCMOS_FALSE;
396}
397
398bcmos_bool bcm_fld_is_ddr_test_done(uint32_t device)
399{
400 uint32_t value = bcm_pci_read32(SRAM_ADDRESS(device, BCM_FLD_CPU_STATE_OFFSET));
401 return 0 != (value & BCM_FLD_DDR_TEST_DONE_MASK);
402}
403
404bcmos_bool bcm_fld_test_device_bootrecord_flag(uint32_t device)
405{
406 volatile uint32_t value;
407
408 if (!bcm68620_info)
409 return BCMOS_FALSE;
410
411 if (device >= max_bcm68620_device)
412 return BCMOS_FALSE;
413
414 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_CPU_BOOTREC_STATE_OFFSET));
415 if (value & BCM_FLD_CPU_PRM_VALID_MASK)
416 return BCMOS_TRUE;
417
418 return BCMOS_FALSE;
419}
420
421bcmos_errno bcm_fld_get_device_bootrecord(uint32_t device, uint32_t *opaque_data)
422{
423 uint32_t *addr, *temp;
424 int32_t i;
425
426 if (!opaque_data)
427 return BCM_ERR_PARM;
428
429 if (!bcm68620_info)
430 return BCM_ERR_NORES;
431
432 if (device >= max_bcm68620_device)
433 return BCM_ERR_RANGE;
434
435 temp = opaque_data;
436 addr = SRAM_ADDRESS(device,BCM_FLD_CPU_BOOTRECORD_OFFSET);
437 for (i = 0; i < PCIE_OPAQUE_DATA_SIZE / 4; i++)
438 {
439 *temp++ = bcm_pci_read32(addr++);
440 }
441
442 return BCM_ERR_OK;
443}
444
445bcmos_errno bcm_fld_clear_device_bootrecord_flag(uint32_t device)
446{
447 volatile uint32_t value;
448
449 if (!bcm68620_info)
450 return BCM_ERR_NORES;
451
452 if (device >= max_bcm68620_device)
453 return BCM_ERR_RANGE;
454
455 /* clear SoC prm valid bit */
456 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_CPU_BOOTREC_STATE_OFFSET));
457 value &= ~BCM_FLD_CPU_PRM_VALID_MASK;
458 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_CPU_BOOTREC_STATE_OFFSET), value);
459
460 return BCM_ERR_OK;
461}
462
463bcmos_errno bcm_fld_set_host_bootrecord_flag(uint32_t device)
464{
465 volatile uint32_t value;
466
467 if (!bcm68620_info)
468 return BCM_ERR_NORES;
469
470 if (device >= max_bcm68620_device)
471 return BCM_ERR_RANGE;
472
473 /* set host prm valid bit */
474 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_HOST_BOOTREC_STATE_OFFSET));
475 value |= ((1 << BCM_FLD_HOST_PRM_VALID_SHIFT) & BCM_FLD_HOST_PRM_VALID_MASK);
476 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_HOST_BOOTREC_STATE_OFFSET), value);
477
478 return BCM_ERR_OK;
479}
480
481bcmos_bool bcm_fld_test_host_bootrecord_flag(uint32_t device)
482{
483 volatile uint32_t value;
484
485 if (!bcm68620_info)
486 return BCMOS_FALSE;
487
488 if (device >= max_bcm68620_device)
489 return BCMOS_FALSE;
490
491 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_HOST_BOOTREC_STATE_OFFSET));
492 if (value & BCM_FLD_HOST_PRM_VALID_MASK)
493 return BCMOS_TRUE;
494
495 return BCMOS_FALSE;
496}
497
498bcmos_errno bcm_fld_set_rings_size(uint32_t device, uint32_t host_tx_size, uint32_t host_rx_size)
499{
500 volatile uint32_t value;
501
502 if (!bcm68620_info)
503 return BCM_ERR_NORES;
504
505 if (device >= max_bcm68620_device)
506 return BCM_ERR_RANGE;
507
508 /* write host_pd_ring_size to communication area - SoC will use it in first stages of application */
509 /* device tx ring size is the same as host rx queue */
510 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_HOST_RX_QUEUE_SIZE_OFFSET), host_rx_size);
511 /* device rx ring size is the same as host tx queue */
512 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_CPU_RX_QUEUE_SIZE_OFFSET), host_tx_size);
513 /* set host queue valid bit */
514 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_CPU_SET_QUEUES_SIZE));
515 value |= ((1 << BCM_FLD_CPU_QUEUE_VALID_SHIFT) & BCM_FLD_CPU_QUEUE_VALID_MASK);
516 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_CPU_SET_QUEUES_SIZE), value);
517
518 return BCM_ERR_OK;
519}
520
521bcmos_errno bcm_fld_get_exception_state(uint32_t device, uint32_t *state0, uint32_t *state1)
522{
523 if (!bcm68620_info)
524 return BCM_ERR_NORES;
525
526 if (device >= max_bcm68620_device)
527 return BCM_ERR_RANGE;
528
529 if (!state0 || !state1)
530 return BCM_ERR_PARM;
531
532 *state0 = bcm_pci_read32(SRAM_ADDRESS(device, BCM_FLD_CPU0_POSTMORTEM_STATE));
533 *state1 = bcm_pci_read32(SRAM_ADDRESS(device, BCM_FLD_CPU1_POSTMORTEM_STATE));
534
535 return BCM_ERR_OK;
536}
537
538bcmos_errno bcm_fld_clear_exception_state(uint32_t device, uint32_t cpuid)
539{
540
541 uint32_t offset = cpuid ? BCM_FLD_CPU1_POSTMORTEM_STATE : BCM_FLD_CPU0_POSTMORTEM_STATE;
542
543 if (!bcm68620_info)
544 return BCM_ERR_NORES;
545
546 if ((device >= max_bcm68620_device) || (cpuid > 1))
547 return BCM_ERR_RANGE;
548
549 bcm_pci_write32(SRAM_ADDRESS(device, offset), 0);
550
551 return BCM_ERR_OK;
552}
553
554bcmos_errno bcm_fld_copy_exception_log(uint32_t device, uint32_t cpuid, char *buffer, int *length)
555{
556 BCM_FLD_POSTMORTEM_LOG *exlog;
557 uint32_t offset = cpuid ? BCM_FLD_CPU1_POSTMORTEM_BUF_OFFSET : BCM_FLD_CPU0_POSTMORTEM_BUF_OFFSET;
558
559 if (!bcm68620_info)
560 return BCM_ERR_NORES;
561
562 if ((device >= max_bcm68620_device) || (cpuid > 1))
563 return BCM_ERR_RANGE;
564
565 if (!buffer || !length)
566 return BCM_ERR_PARM;
567
568 exlog = (BCM_FLD_POSTMORTEM_LOG *)SRAM_ADDRESS(device, offset);
569 if (exlog->magic != BCM_FLD_POSTMORTEM_LOG_MAGIC)
570 *length = 0;
571 else
572 {
573 int i;
574 *length = exlog->msg_len;
575 /* if host is 64 bit and bigendian memcpy does not work correctly */
576 for (i=0; i < exlog->msg_len; i++)
577 {
578 buffer[i] = exlog->msg[i];
579 }
580 }
581 buffer[*length] = '\0';
582
583 return BCM_ERR_OK;
584}
585
586/**
587* \Debug states and functions
588*/
589bcmos_errno bcm_fld_get_device_debug_status(uint32_t device, bcm_fld_device_debug_state *info)
590{
591 volatile uint32_t value;
592
593 if (!info)
594 return BCM_ERR_PARM;
595
596 if (!bcm68620_info)
597 return BCM_ERR_NORES;
598
599 if (device >= max_bcm68620_device)
600 return BCM_ERR_RANGE;
601
602 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_CPU_DEBUG_STATE_OFFSET));
603 info->boot_from_sram_states = (value & BCM_FLD_CPU_BOOT_FROM_SRAM_STATES_MASK) >> BCM_FLD_CPU_BOOT_FROM_SRAM_STATES_SHIFT;
604 info->boot_from_sram_errors = (value & BCM_FLD_CPU_BOOT_FROM_SRAM_ERRORS_MASK) >> BCM_FLD_CPU_BOOT_FROM_SRAM_ERRORS_SHIFT;
605 info->boot_from_sram_exception = (value & BCM_FLD_CPU_BOOT_FROM_SRAM_EXCEPTION_MASK) >> BCM_FLD_CPU_BOOT_FROM_SRAM_EXCEPTION_SHIFT;
606 info->run_from_ddr_state = (value & BCM_FLD_CPU_RUN_FROM_DDR_STATES_MASK) >> BCM_FLD_CPU_RUN_FROM_DDR_STATES_SHIFT;
607
608 return BCM_ERR_OK;
609}
610
611bcmos_errno bcm_fld_get_host_debug_status(uint32_t device, bcm_fld_host_debug_state *info)
612{
613 volatile uint32_t value;
614
615 if (!info)
616 return BCM_ERR_PARM;
617
618 if (!bcm68620_info)
619 return BCM_ERR_NORES;
620
621 if (device >= max_bcm68620_device)
622 return BCM_ERR_RANGE;
623
624 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_HOST_DEBUG_STATE_OFFSET));
625 info->write_sram = (value & BCM_FLD_HOST_WRITE_SRAM_MASK) >> BCM_FLD_HOST_WRITE_SRAM_SHIFT;
626 info->start_device = (value & BCM_FLD_HOST_START_CPU_MASK) >> BCM_FLD_HOST_START_CPU_SHIFT;
627 info->write_ddr = (value & BCM_FLD_HOST_WRITE_DDR_MASK) >> BCM_FLD_HOST_WRITE_DDR_SHIFT;
628 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_HOST_STATE_OFFSET));
629 info->finish_ddr = (value & BCM_FLD_HOST_FINISH_WRITE_DDR_MASK) >> BCM_FLD_HOST_FINISH_WRITE_DDR_SHIFT;
630
631 return BCM_ERR_OK;
632}
633
634bcmos_errno bcm_fld_set_host_debug_status(uint32_t device, BCM_FLD_HOST_DEBUG_VALUES stat)
635{
636 volatile uint32_t value = 0;
637
638 if (!bcm68620_info)
639 return BCM_ERR_NORES;
640
641 if (device >= max_bcm68620_device)
642 return BCM_ERR_RANGE;
643
644 if (stat == BCM_FLD_HOST_WRITE_SRAM)
645 value = ((1 << BCM_FLD_HOST_WRITE_SRAM_SHIFT) & BCM_FLD_HOST_WRITE_SRAM_MASK);
646 else
647 {
648 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_HOST_DEBUG_STATE_OFFSET));
649 if (stat == BCM_FLD_HOST_START_CPU)
650 value |= ((1 << BCM_FLD_HOST_START_CPU_SHIFT) & BCM_FLD_HOST_START_CPU_MASK);
651 else if (stat == BCM_FLD_HOST_WRITE_DDR)
652 value |= ((1 << BCM_FLD_HOST_WRITE_DDR_SHIFT) & BCM_FLD_HOST_WRITE_DDR_MASK);
653 else
654 return BCM_ERR_PARM;
655 }
656 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_HOST_DEBUG_STATE_OFFSET), value);
657
658 return BCM_ERR_OK;
659}
660
661bcmos_errno bcm_fld_set_ras_mode_set(uint32_t device, uint32_t ras, uint32_t mode)
662{
663 uint32_t offset = ras ? BCM_FLD_RAS_1_SETTINGS :BCM_FLD_RAS_0_SETTINGS;
664
665 bcm_pci_write32(SRAM_ADDRESS(device, offset), mode);
666
667 return BCM_ERR_OK;
668}
669
670bcmos_errno bcm_fld_set_host_event(uint32_t device, uint32_t event)
671{
672 if (!bcm68620_info)
673 return BCM_ERR_NORES;
674
675 if (device >= max_bcm68620_device)
676 return BCM_ERR_RANGE;
677
678 bcm_pci_write32(SRAM_ADDRESS(device, BCM_FLD_HOST_EVENT), event);
679
680 return BCM_ERR_OK;
681}
682
683bcmos_bool bcm_fld_test_queues_flag(uint32_t device)
684{
685 volatile uint32_t value;
686
687 if (!bcm68620_info)
688 return BCMOS_FALSE;
689
690 if (device >= max_bcm68620_device)
691 return BCMOS_FALSE;
692
693 value = bcm_pci_read32(SRAM_ADDRESS(device,BCM_FLD_CPU_SET_QUEUES_SIZE));
694 if (value & BCM_FLD_CPU_QUEUE_VALID_MASK)
695 return BCMOS_TRUE;
696
697 return BCMOS_FALSE;
698}
699
700bcmos_bool bcm_fld_regs_swap_needed(uint32_t device)
701{
702 uint32_t value;
703
704 value = *(volatile uint32_t *)(bcm68620_info[device].soc_regs_base + PCIE_REVISION_REGISTER_OFFSET);
705 if ((value & 0xffff) != 0x0302)
706 return BCMOS_TRUE;
707
708 return BCMOS_FALSE;
709}
710
711bcmos_bool bcm_fld_sram_swap_needed(uint32_t device)
712{
713 uint32_t value;
714 uint8_t charvalue;
715
716 value = 0xaabbccdd;
717 *(volatile uint32_t *)bcm68620_info[device].soc_sram_base = value;
718 charvalue = *(volatile uint8_t *)bcm68620_info[device].soc_sram_base;
719 if (charvalue != *(uint8_t *)&value)
720 return BCMOS_TRUE;
721
722 return BCMOS_FALSE;
723}
724
725bcmos_bool bcm_fld_ddr_swap_needed(uint32_t device)
726{
727 uint32_t value;
728 volatile uint32_t *address;
729 uint8_t charvalue;
730
731 value = 0xaabbccdd;
732 address = (uint32_t *)(bcm68620_info[device].soc_ddr_base + bcm68620_info[device].soc_crt_length);
733 *address = value;
734 charvalue = *address;
735 if (charvalue != *&value)
736 return BCMOS_TRUE;
737
738 return BCMOS_FALSE;
739}
740
741#ifdef TX_ENABLE_EVENT_TRACE
742bcmos_errno bcm_fld_set_event_trace(uint32_t device)
743{
744 if (!bcm68620_info)
745 return BCM_ERR_NORES;
746
747 if (device >= max_bcm68620_device)
748 return BCM_ERR_RANGE;
749
750 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_EVENT_TRACE_OFFSET), 0x1);
751
752 return BCM_ERR_OK;
753}
754bcmos_errno bcm_fld_clear_event_trace(uint32_t device)
755{
756 if (!bcm68620_info)
757 return BCM_ERR_NORES;
758
759 if (device >= max_bcm68620_device)
760 return BCM_ERR_RANGE;
761
762 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_EVENT_TRACE_OFFSET), 0x0);
763
764 return BCM_ERR_OK;
765}
766#endif
767#ifdef DMA_STUB
768bcmos_errno bcm_fld_set_device_bootrecord_flag(uint32_t device)
769{
770 volatile uint32_t value;
771
772 value = BCM_FLD_CPU_PRM_VALID_MASK;
773 bcm_pci_write32(SRAM_ADDRESS(device,BCM_FLD_CPU_BOOTREC_STATE_OFFSET), value);
774
775 return BCM_ERR_OK;
776}
777
778bcmos_errno bcm_fld_set_device_bootrecord(uint32_t device, uint32_t *opaque_data)
779{
780 uint32_t *addr, *temp;
781 int32_t i;
782
783 temp = opaque_data;
784 addr = SRAM_ADDRESS(device,BCM_FLD_CPU_BOOTRECORD_OFFSET);
785 for (i = 0; i < PCIE_OPAQUE_DATA_SIZE / 4; i++)
786 {
787 bcm_pci_write32(addr++,*temp++);
788 }
789
790 return BCM_ERR_OK;
791}
792#endif
793
794bcmos_errno bcm_fld_set_avs_cont(uint32_t device, uint32_t value)
795{
796 bcm_pci_write32(SRAM_ADDRESS(device, BCM_FLD_AVS_SETTINGS), value);
797
798 return BCM_ERR_OK;
799}
800
801void *bcm_fld_get_sw_error_table(uint32_t device, uint32_t *size)
802{
803 *size = BCM_FLD_SW_ERROR_TABLE_SIZE;
804 return SRAM_ADDRESS(device, BCM_FLD_SW_ERROR_TABLE);
805}
806
807uint32_t bcm_fld_ddr_test_result_get(uint32_t device, uint32_t word)
808{
809 return bcm_pci_read32(SRAM_ADDRESS(device, BCM_FLD_DDR_TEST_RESULTS + (word * COMM_WORD_SIZE)));
810}
811
812#ifdef __KERNEL__
813EXPORT_SYMBOL(bcm_fld_init);
814EXPORT_SYMBOL(bcm_fld_clear_comm_area);
815EXPORT_SYMBOL(bcm_fld_exit);
816EXPORT_SYMBOL(bcm_fld_register);
817EXPORT_SYMBOL(bcm_fld_unregister);
818EXPORT_SYMBOL(bcm_fld_get_device_status);
819EXPORT_SYMBOL(bcm_fld_get_device_loading_state);
820EXPORT_SYMBOL(bcm_fld_host_finish_write_ddr);
821EXPORT_SYMBOL(bcm_fld_get_logs);
822EXPORT_SYMBOL(bcm_fld_write);
823EXPORT_SYMBOL(bcm_fld_read);
824EXPORT_SYMBOL(bcm_fld_start_bootloader);
825EXPORT_SYMBOL(bcm_fld_is_bootloader_done);
826EXPORT_SYMBOL(bcm_fld_set_rings_size);
827EXPORT_SYMBOL(bcm_fld_get_device_bootrecord);
828EXPORT_SYMBOL(bcm_fld_test_device_bootrecord_flag);
829EXPORT_SYMBOL(bcm_fld_clear_device_bootrecord_flag);
830EXPORT_SYMBOL(bcm_fld_set_host_bootrecord_flag);
831EXPORT_SYMBOL(bcm_fld_test_host_bootrecord_flag);
832EXPORT_SYMBOL(bcm_fld_test_queues_flag);
833EXPORT_SYMBOL(bcm_fld_get_device_debug_status);
834EXPORT_SYMBOL(bcm_fld_get_host_debug_status);
835EXPORT_SYMBOL(bcm_fld_set_host_debug_status);
836EXPORT_SYMBOL(bcm_fld_set_ras_mode_set);
837EXPORT_SYMBOL(bcm_fld_set_host_event);
838EXPORT_SYMBOL(bcm_fld_get_exception_state);
839EXPORT_SYMBOL(bcm_fld_clear_exception_state);
840EXPORT_SYMBOL(bcm_fld_copy_exception_log);
841EXPORT_SYMBOL(bcm_fld_regs_swap_needed);
842EXPORT_SYMBOL(bcm_fld_sram_swap_needed);
843EXPORT_SYMBOL(bcm_fld_ddr_swap_needed);
844#ifdef TX_ENABLE_EVENT_TRACE
845EXPORT_SYMBOL(bcm_fld_set_event_trace);
846EXPORT_SYMBOL(bcm_fld_clear_event_trace);
847#endif
848EXPORT_SYMBOL(bcm_fld_set_avs_cont);
849EXPORT_SYMBOL(bcm_fld_get_sw_error_table);
850#endif