armadaxp_machdep.c revision 1.5 1 /* $NetBSD: armadaxp_machdep.c,v 1.5 2013/12/23 03:19:43 kiyohara Exp $ */
2 /*******************************************************************************
3 Copyright (C) Marvell International Ltd. and its affiliates
4
5 Developed by Semihalf
6
7 ********************************************************************************
8 Marvell BSD License
9
10 If you received this File from Marvell, you may opt to use, redistribute and/or
11 modify this File under the following licensing terms.
12 Redistribution and use in source and binary forms, with or without modification,
13 are permitted provided that the following conditions are met:
14
15 * Redistributions of source code must retain the above copyright notice,
16 this list of conditions and the following disclaimer.
17
18 * Redistributions in binary form must reproduce the above copyright
19 notice, this list of conditions and the following disclaimer in the
20 documentation and/or other materials provided with the distribution.
21
22 * Neither the name of Marvell nor the names of its contributors may be
23 used to endorse or promote products derived from this software without
24 specific prior written permission.
25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
37 *******************************************************************************/
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: armadaxp_machdep.c,v 1.5 2013/12/23 03:19:43 kiyohara Exp $");
41
42 #include "opt_machdep.h"
43 #include "opt_mvsoc.h"
44 #include "opt_evbarm_boardtype.h"
45 #include "opt_com.h"
46 #include "opt_ddb.h"
47 #include "opt_kgdb.h"
48 #include "opt_pci.h"
49 #include "opt_ipkdb.h"
50
51 #include <sys/bus.h>
52 #include <sys/param.h>
53 #include <sys/device.h>
54 #include <sys/systm.h>
55 #include <sys/kernel.h>
56 #include <sys/exec.h>
57 #include <sys/proc.h>
58 #include <sys/msgbuf.h>
59 #include <sys/reboot.h>
60 #include <sys/termios.h>
61 #include <sys/ksyms.h>
62
63 #include <uvm/uvm_extern.h>
64
65 #include <sys/conf.h>
66 #include <dev/cons.h>
67 #include <dev/md.h>
68
69 #include <dev/pci/pcireg.h>
70 #include <dev/pci/pcivar.h>
71 #include <machine/pci_machdep.h>
72
73 #include <machine/db_machdep.h>
74 #include <ddb/db_sym.h>
75 #include <ddb/db_extern.h>
76 #ifdef KGDB
77 #include <sys/kgdb.h>
78 #endif
79
80 #include <machine/bootconfig.h>
81 #include <machine/autoconf.h>
82 #include <machine/cpu.h>
83 #include <machine/frame.h>
84 #include <arm/armreg.h>
85 #include <arm/undefined.h>
86
87 #include <arm/arm32/machdep.h>
88
89 #include <arm/marvell/mvsocreg.h>
90 #include <arm/marvell/mvsocvar.h>
91 #include <arm/marvell/armadaxpreg.h>
92
93 #include <evbarm/marvell/marvellreg.h>
94 #include <evbarm/marvell/marvellvar.h>
95
96 #include "mvpex.h"
97 #include "com.h"
98 #if NCOM > 0
99 #include <dev/ic/comreg.h>
100 #include <dev/ic/comvar.h>
101 #endif
102
103 /*
104 * Address to call from cpu_reset() to reset the machine.
105 * This is machine architecture dependent as it varies depending
106 * on where the ROM appears when you turn the MMU off.
107 */
108
109
110 /* Define various stack sizes in pages */
111 #define IRQ_STACK_SIZE 1
112 #define ABT_STACK_SIZE 1
113 #ifdef IPKDB
114 #define UND_STACK_SIZE 2
115 #else
116 #define UND_STACK_SIZE 1
117 #endif
118
119 BootConfig bootconfig; /* Boot config storage */
120 char *boot_args = NULL;
121 char *boot_file = NULL;
122
123 extern int KERNEL_BASE_phys[];
124
125 /*extern char KERNEL_BASE_phys[];*/
126 extern char etext[], __data_start[], _edata[], __bss_start[], __bss_end__[];
127 extern char _end[];
128
129 /*
130 * Put some bogus settings of the MEMSTART and MEMSIZE
131 * if they are not defined in kernel configuration file.
132 */
133 #ifndef MEMSTART
134 #define MEMSTART 0x00000000UL
135 #endif
136 #ifndef MEMSIZE
137 #define MEMSIZE 0x40000000UL
138 #endif
139
140 #ifndef STARTUP_PAGETABLE_ADDR
141 #define STARTUP_PAGETABLE_ADDR 0x00000000UL
142 #endif
143
144 /* Physical offset of the kernel from MEMSTART */
145 #define KERNEL_OFFSET (paddr_t)&KERNEL_BASE_phys
146 /* Kernel base virtual address */
147 #define KERNEL_TEXT_BASE (KERNEL_BASE + KERNEL_OFFSET)
148
149 #define KERNEL_VM_BASE (KERNEL_BASE + 0x01000000)
150 #define KERNEL_VM_SIZE 0x10000000
151
152 /* Prototypes */
153 extern int armadaxp_l2_init(bus_addr_t);
154 extern void armadaxp_io_coherency_init(void);
155
156 void consinit(void);
157 #ifdef KGDB
158 static void kgdb_port_init(void);
159 #endif
160
161 static void axp_device_register(device_t dev, void *aux);
162
163 static void
164 axp_system_reset(void)
165 {
166 extern vaddr_t misc_base;
167
168 #define write_miscreg(r, v) (*(volatile uint32_t *)(misc_base + (r)) = (v))
169
170 cpu_reset_address = 0;
171
172 /* Unmask soft reset */
173 write_miscreg(ARMADAXP_MISC_RSTOUTNMASKR,
174 ARMADAXP_MISC_RSTOUTNMASKR_GLOBALSOFTRSTOUTEN);
175 /* Assert soft reset */
176 write_miscreg(ARMADAXP_MISC_SSRR, ARMADAXP_MISC_SSRR_GLOBALSOFTRST);
177
178 while (1);
179 }
180
181 /*
182 * Static device mappings. These peripheral registers are mapped at
183 * fixed virtual addresses very early in initarm() so that we can use
184 * them while booting the kernel, and stay at the same address
185 * throughout whole kernel's life time.
186 *
187 * We use this table twice; once with bootstrap page table, and once
188 * with kernel's page table which we build up in initarm().
189 *
190 * Since we map these registers into the bootstrap page table using
191 * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
192 * registers segment-aligned and segment-rounded in order to avoid
193 * using the 2nd page tables.
194 */
195
196 #define _A(a) ((a) & ~L1_S_OFFSET)
197 #define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
198
199 static const struct pmap_devmap devmap[] = {
200 {
201 /* Internal registers */
202 .pd_va = _A(MARVELL_INTERREGS_VBASE),
203 .pd_pa = _A(MARVELL_INTERREGS_PBASE),
204 .pd_size = _S(MARVELL_INTERREGS_SIZE),
205 .pd_prot = VM_PROT_READ|VM_PROT_WRITE,
206 .pd_cache = PTE_NOCACHE
207 },
208 {0, 0, 0, 0, 0}
209 };
210
211 #undef _A
212 #undef _S
213
214 static inline
215 pd_entry_t *
216 read_ttb(void)
217 {
218 long ttb;
219
220 __asm volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (ttb));
221
222 return (pd_entry_t *)(ttb & ~((1<<14)-1));
223 }
224
225 static int
226 axp_pcie_free_win(void)
227 {
228 int i;
229 /* Find first disabled window */
230 for (i = 0; i < ARMADAXP_MLMB_NWINDOW; i++) {
231 if ((read_mlmbreg(MVSOC_MLMB_WCR(i)) &
232 MVSOC_MLMB_WCR_WINEN) == 0) {
233 return i;
234 }
235 }
236 /* If there is no free window, return erroneous value */
237 return (-1);
238 }
239
240 static void
241 reset_axp_pcie_win(void)
242 {
243 uint32_t target, attr;
244 int memtag = 0, iotag = 0, window, i;
245 uint32_t membase;
246 uint32_t iobase;
247 uint32_t tags[] = { ARMADAXP_TAG_PEX00_MEM, ARMADAXP_TAG_PEX00_IO,
248 ARMADAXP_TAG_PEX01_MEM, ARMADAXP_TAG_PEX01_IO,
249 ARMADAXP_TAG_PEX02_MEM, ARMADAXP_TAG_PEX02_IO,
250 ARMADAXP_TAG_PEX03_MEM, ARMADAXP_TAG_PEX03_IO,
251 ARMADAXP_TAG_PEX2_MEM, ARMADAXP_TAG_PEX2_IO,
252 ARMADAXP_TAG_PEX3_MEM, ARMADAXP_TAG_PEX3_IO};
253
254 nwindow = ARMADAXP_MLMB_NWINDOW;
255 nremap = ARMADAXP_MLMB_NREMAP;
256 membase = MARVELL_PEXMEM_PBASE;
257 iobase = MARVELL_PEXIO_PBASE;
258 for (i = 0; i < __arraycount(tags) / 2; i++) {
259 memtag = tags[2 * i];
260 iotag = tags[(2 * i) + 1];
261
262 /* Reset PCI-Express space to window register. */
263 window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
264
265 /* Find free window if we've got spurious one */
266 if (window >= nwindow) {
267 window = axp_pcie_free_win();
268 /* Just break if there is no free windows left */
269 if (window < 0) {
270 aprint_error(": no free windows for PEX MEM\n");
271 break;
272 }
273 }
274 write_mlmbreg(MVSOC_MLMB_WCR(window),
275 MVSOC_MLMB_WCR_WINEN |
276 MVSOC_MLMB_WCR_TARGET(target) |
277 MVSOC_MLMB_WCR_ATTR(attr) |
278 MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
279 write_mlmbreg(MVSOC_MLMB_WBR(window),
280 membase & MVSOC_MLMB_WBR_BASE_MASK);
281 #ifdef PCI_NETBSD_CONFIGURE
282 if (window < nremap) {
283 write_mlmbreg(MVSOC_MLMB_WRLR(window),
284 membase & MVSOC_MLMB_WRLR_REMAP_MASK);
285 write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
286 }
287 #endif
288 window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
289
290 /* Find free window if we've got spurious one */
291 if (window >= nwindow) {
292 window = axp_pcie_free_win();
293 /* Just break if there is no free windows left */
294 if (window < 0) {
295 aprint_error(": no free windows for PEX I/O\n");
296 break;
297 }
298 }
299 write_mlmbreg(MVSOC_MLMB_WCR(window),
300 MVSOC_MLMB_WCR_WINEN |
301 MVSOC_MLMB_WCR_TARGET(target) |
302 MVSOC_MLMB_WCR_ATTR(attr) |
303 MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE));
304 write_mlmbreg(MVSOC_MLMB_WBR(window),
305 iobase & MVSOC_MLMB_WBR_BASE_MASK);
306 #ifdef PCI_NETBSD_CONFIGURE
307 if (window < nremap) {
308 write_mlmbreg(MVSOC_MLMB_WRLR(window),
309 iobase & MVSOC_MLMB_WRLR_REMAP_MASK);
310 write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
311 }
312 #endif
313 membase += MARVELL_PEXMEM_SIZE;
314 iobase += MARVELL_PEXIO_SIZE;
315 }
316 }
317
318 /*
319 * u_int initarm(...)
320 *
321 * Initial entry point on startup. This gets called before main() is
322 * entered.
323 * It should be responsible for setting up everything that must be
324 * in place when main is called.
325 * This includes
326 * Taking a copy of the boot configuration structure.
327 * Initialising the physical console so characters can be printed.
328 * Setting up page tables for the kernel
329 * Relocating the kernel to the bottom of physical memory
330 */
331 u_int
332 initarm(void *arg)
333 {
334 cpu_reset_address = axp_system_reset;
335
336 mvsoc_bootstrap(MARVELL_INTERREGS_VBASE);
337
338 /* Set CPU functions */
339 if (set_cpufuncs())
340 panic("cpu not recognized!");
341
342 /*
343 * Map devices into the initial page table
344 * in order to use early console during initialization process.
345 * consinit is going to use this mapping.
346 */
347 pmap_devmap_bootstrap((vaddr_t)read_ttb(), devmap);
348
349 /* Initialize system console */
350 consinit();
351
352 /* Reset PCI-Express space to window register. */
353 reset_axp_pcie_win();
354
355 /* Get CPU, system and timebase frequencies */
356 extern vaddr_t misc_base;
357 misc_base = MARVELL_INTERREGS_VBASE + ARMADAXP_MISC_BASE;
358 armadaxp_getclks();
359
360 /* Preconfigure interrupts */
361 armadaxp_intr_bootstrap(MARVELL_INTERREGS_PBASE);
362
363 #ifdef L2CACHE_ENABLE
364 /* Initialize L2 Cache */
365 (void)armadaxp_l2_init(MARVELL_INTERREGS_PBASE);
366 #endif
367
368 #ifdef AURORA_IO_CACHE_COHERENCY
369 /* Initialize cache coherency */
370 armadaxp_io_coherency_init();
371 #endif
372
373 #ifdef KGDB
374 kgdb_port_init();
375 #endif
376
377 #ifdef VERBOSE_INIT_ARM
378 /* Talk to the user */
379 #define BDSTR(s) _BDSTR(s)
380 #define _BDSTR(s) #s
381 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
382 #endif
383
384
385 #ifdef VERBOSE_INIT_ARM
386 printf("initarm: Configuring system ...\n");
387 #endif
388 /* Fake bootconfig structure for the benefit of pmap.c. */
389 bootconfig.dramblocks = 1;
390 bootconfig.dram[0].address = MEMSTART;
391 bootconfig.dram[0].pages = MEMSIZE / PAGE_SIZE;
392
393 physical_start = bootconfig.dram[0].address;
394 physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
395
396 arm32_bootmem_init(0, physical_end, (uintptr_t) KERNEL_BASE_phys);
397 arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0,
398 devmap, false);
399
400 /* we've a specific device_register routine */
401 evbarm_device_register = axp_device_register;
402
403 return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
404 }
405
406 #ifndef CONSADDR
407 #error Specify the address of the UART with the CONSADDR option.
408 #endif
409 #ifndef CONSPEED
410 #define CONSPEED B115200
411 #endif
412 #ifndef CONMODE
413 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
414 #endif
415 #ifndef CONSFREQ
416 #define CONSFREQ 250000000
417 #endif
418 static const int comcnspeed = CONSPEED;
419 static const int comcnfreq = CONSFREQ;
420 static const tcflag_t comcnmode = CONMODE;
421 static const bus_addr_t comcnaddr = (bus_addr_t)CONSADDR;
422
423 void
424 consinit(void)
425 {
426 static bool consinit_called = false;
427
428 if (consinit_called)
429 return;
430 consinit_called = true;
431
432 #if NCOM > 0
433 extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int,
434 uint32_t, int);
435
436 if (mvuart_cnattach(&mvsoc_bs_tag, comcnaddr, comcnspeed,
437 comcnfreq, comcnmode))
438 panic("Serial console can not be initialized.");
439 #endif
440 }
441
442 #ifdef KGDB
443 #ifndef KGDB_DEVADDR
444 #error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
445 #endif
446 #ifndef KGDB_DEVRATE
447 #define KGDB_DEVRATE B115200
448 #endif
449 #define MVUART_SIZE 0x20
450
451 #ifndef KGDB_DEVMODE
452 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
453 #endif
454 static const vaddr_t comkgdbaddr = KGDB_DEVADDR;
455 static const int comkgdbspeed = KGDB_DEVRATE;
456 static const int comkgdbmode = KGDB_DEVMODE;
457
458 void
459 static kgdb_port_init(void)
460 {
461 static int kgdbsinit_called = 0;
462
463 if (kgdbsinit_called != 0)
464 return;
465 kgdbsinit_called = 1;
466
467 if (com_kgdb_attach(&mvsoc_bs_tag, comkgdbaddr, comkgdbspeed,
468 MVUART_SIZE, COM_TYPE_16550_NOERS, comkgdbmode))
469 panic("KGDB uart can not be initialized.");
470 }
471 #endif
472
473 #if NMVPEX > 0
474 static void
475 marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end)
476 {
477
478 uint32_t base, size;
479 int win;
480
481 win = mvsoc_target(tag, NULL, NULL, &base, &size);
482 if (size != 0) {
483 if (win < nremap)
484 *start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) |
485 ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16);
486 else
487 *start = base;
488 *end = *start + size - 1;
489 } else
490 *start = *end = 0;
491 }
492 #endif
493
494 static void
495 axp_device_register(device_t dev, void *aux)
496 {
497 prop_dictionary_t dict = device_properties(dev);
498
499 #if NCOM > 0
500 if (device_is_a(dev, "com") &&
501 device_is_a(device_parent(dev), "mvsoc"))
502 prop_dictionary_set_uint32(dict, "frequency", mvTclk);
503 #endif
504
505 #if NMVPEX > 0
506 extern struct bus_space
507 armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag,
508 armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag,
509 armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag,
510 armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag,
511 armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag,
512 armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag;
513 extern struct arm32_pci_chipset arm32_mvpex0_chipset,
514 arm32_mvpex1_chipset, arm32_mvpex2_chipset,
515 arm32_mvpex3_chipset, arm32_mvpex4_chipset,
516 arm32_mvpex5_chipset;
517
518 struct marvell_attach_args *mva = aux;
519
520 if (device_is_a(dev, "mvpex")) {
521 struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag;
522 struct arm32_pci_chipset *arm32_mvpex_chipset;
523 prop_data_t io_bs_tag, mem_bs_tag, pc;
524 uint64_t start, end;
525 int iotag, memtag;
526
527 if (mva->mva_offset == MVSOC_PEX_BASE) {
528 mvpex_io_bs_tag = &armadaxp_pex00_io_bs_tag;
529 mvpex_mem_bs_tag = &armadaxp_pex00_mem_bs_tag;
530 arm32_mvpex_chipset = &arm32_mvpex0_chipset;
531 iotag = ARMADAXP_TAG_PEX00_IO;
532 memtag = ARMADAXP_TAG_PEX00_MEM;
533 } else if (mva->mva_offset == MVSOC_PEX_BASE + 0x4000) {
534 mvpex_io_bs_tag = &armadaxp_pex01_io_bs_tag;
535 mvpex_mem_bs_tag = &armadaxp_pex01_mem_bs_tag;
536 arm32_mvpex_chipset = &arm32_mvpex1_chipset;
537 iotag = ARMADAXP_TAG_PEX01_IO;
538 memtag = ARMADAXP_TAG_PEX01_MEM;
539 } else if (mva->mva_offset == MVSOC_PEX_BASE + 0x8000) {
540 mvpex_io_bs_tag = &armadaxp_pex02_io_bs_tag;
541 mvpex_mem_bs_tag = &armadaxp_pex02_mem_bs_tag;
542 arm32_mvpex_chipset = &arm32_mvpex2_chipset;
543 iotag = ARMADAXP_TAG_PEX02_IO;
544 memtag = ARMADAXP_TAG_PEX02_MEM;
545 } else if (mva->mva_offset == MVSOC_PEX_BASE + 0xc000) {
546 mvpex_io_bs_tag = &armadaxp_pex03_io_bs_tag;
547 mvpex_mem_bs_tag = &armadaxp_pex03_mem_bs_tag;
548 arm32_mvpex_chipset = &arm32_mvpex3_chipset;
549 iotag = ARMADAXP_TAG_PEX03_IO;
550 memtag = ARMADAXP_TAG_PEX03_MEM;
551 } else if (mva->mva_offset == MVSOC_PEX_BASE + 0x2000) {
552 mvpex_io_bs_tag = &armadaxp_pex2_io_bs_tag;
553 mvpex_mem_bs_tag = &armadaxp_pex2_mem_bs_tag;
554 arm32_mvpex_chipset = &arm32_mvpex4_chipset;
555 iotag = ARMADAXP_TAG_PEX2_IO;
556 memtag = ARMADAXP_TAG_PEX2_MEM;
557 } else {
558 mvpex_io_bs_tag = &armadaxp_pex3_io_bs_tag;
559 mvpex_mem_bs_tag = &armadaxp_pex3_mem_bs_tag;
560 arm32_mvpex_chipset = &arm32_mvpex5_chipset;
561 iotag = ARMADAXP_TAG_PEX3_IO;
562 memtag = ARMADAXP_TAG_PEX3_MEM;
563 }
564
565 arm32_mvpex_chipset->pc_conf_v = device_private(dev);
566 arm32_mvpex_chipset->pc_intr_v = device_private(dev);
567
568 io_bs_tag = prop_data_create_data_nocopy(
569 mvpex_io_bs_tag, sizeof(struct bus_space));
570 KASSERT(io_bs_tag != NULL);
571 prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
572 prop_object_release(io_bs_tag);
573 mem_bs_tag = prop_data_create_data_nocopy(
574 mvpex_mem_bs_tag, sizeof(struct bus_space));
575 KASSERT(mem_bs_tag != NULL);
576 prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
577 prop_object_release(mem_bs_tag);
578
579 pc = prop_data_create_data_nocopy(arm32_mvpex_chipset,
580 sizeof(struct arm32_pci_chipset));
581 KASSERT(pc != NULL);
582 prop_dictionary_set(dict, "pci-chipset", pc);
583 prop_object_release(pc);
584
585 marvell_startend_by_tag(iotag, &start, &end);
586 prop_dictionary_set_uint64(dict, "iostart", start);
587 prop_dictionary_set_uint64(dict, "ioend", end);
588 marvell_startend_by_tag(memtag, &start, &end);
589 prop_dictionary_set_uint64(dict, "memstart", start);
590 prop_dictionary_set_uint64(dict, "memend", end);
591 prop_dictionary_set_uint32(dict,
592 "cache-line-size", arm_dcache_align);
593 }
594 #endif
595 }
596