45d5ecf831ede3165b0404d38c0426c0d2651a6a
[litex.git] / litex / tools / litex_json2dts.py
1 #!/usr/bin/env python3
2
3 import sys
4 import json
5 import argparse
6
7
8 def generate_dts(d):
9
10 kB = 1024
11 mB = kB*1024
12
13 aliases = {}
14
15 # Header -------------------------------------------------------------------------------------------
16
17 dts = """
18 /dts-v1/;
19
20 / {
21 #address-cells = <1>;
22 #size-cells = <1>;
23 compatible = "enjoy-digital,litex-vexriscv-soclinux";
24 model = "VexRiscv SoCLinux";
25
26 """
27
28 # Boot Arguments -----------------------------------------------------------------------------------
29
30 dts += """
31 chosen {{
32 bootargs = "mem={main_ram_size_mb}M@0x{main_ram_base:x} rootwait console=liteuart earlycon=sbi root=/dev/ram0 init=/sbin/init swiotlb=32";
33 linux,initrd-start = <0x{linux_initrd_start:x}>;
34 linux,initrd-end = <0x{linux_initrd_end:x}>;
35 }};
36 """.format(main_ram_base=d["memories"]["main_ram"]["base"],
37 main_ram_size=d["memories"]["main_ram"]["size"],
38 main_ram_size_mb=d["memories"]["main_ram"]["size"] // mB,
39 linux_initrd_start=d["memories"]["main_ram"]["base"] + 8*mB,
40 linux_initrd_end=d["memories"]["main_ram"]["base"] + 16*mB)
41
42 # CPU ----------------------------------------------------------------------------------------------
43
44 dts += """
45 cpus {{
46 #address-cells = <1>;
47 #size-cells = <0>;
48 timebase-frequency = <{sys_clk_freq}>;
49 cpu@0 {{
50 clock-frequency = <0x0>;
51 compatible = "spinalhdl,vexriscv", "sifive,rocket0", "riscv";
52 d-cache-block-size = <0x40>;
53 d-cache-sets = <0x40>;
54 d-cache-size = <0x8000>;
55 d-tlb-sets = <0x1>;
56 d-tlb-size = <0x20>;
57 device_type = "cpu";
58 i-cache-block-size = <0x40>;
59 i-cache-sets = <0x40>;
60 i-cache-size = <0x8000>;
61 i-tlb-sets = <0x1>;
62 i-tlb-size = <0x20>;
63 mmu-type = "riscv,sv32";
64 reg = <0x0>;
65 riscv,isa = "rv32ima";
66 sifive,itim = <0x1>;
67 status = "okay";
68 tlb-split;
69 }};
70 }};
71 """.format(sys_clk_freq=int(50e6) if "sim" in d["constants"] else d["constants"]["config_clock_frequency"])
72
73 # Memory -------------------------------------------------------------------------------------------
74
75 dts += """
76 memory@{main_ram_base:x} {{
77 device_type = "memory";
78 reg = <0x{main_ram_base:x} 0x{main_ram_size:x}>;
79 }};
80 """.format(main_ram_base=d["memories"]["main_ram"]["base"],
81 main_ram_size=d["memories"]["main_ram"]["size"])
82
83 if "emulator" in d["memories"]:
84 dts += """
85
86 reserved-memory {{
87 #address-cells = <1>;
88 #size-cells = <1>;
89 ranges;
90 vexriscv_emulator@{emulator_base:x} {{
91 reg = <0x{emulator_base:x} 0x{emulator_size:x}>;
92 }};
93 }};
94 """.format(emulator_base=d["memories"]["emulator"]["base"],
95 emulator_size=d["memories"]["emulator"]["size"])
96
97 # SoC ----------------------------------------------------------------------------------------------
98
99 dts += """
100 soc {
101 #address-cells = <1>;
102 #size-cells = <1>;
103 compatible = "simple-bus";
104 ranges;
105 """
106
107 # Interrupt controller -----------------------------------------------------------------------------
108
109 dts += """
110 intc0: interrupt-controller {
111 interrupt-controller;
112 #interrupt-cells = <1>;
113 compatible = "vexriscv,intc0";
114 status = "okay";
115 };
116 """
117
118 # SoC Controller -----------------------------------------------------------------------------------
119
120 dts += """
121 soc_ctrl0: soc_controller@{soc_ctrl_csr_base:x} {{
122 compatible = "litex,soc_controller";
123 reg = <0x{soc_ctrl_csr_base:x} 0xc>;
124 status = "okay";
125 }};
126 """.format(soc_ctrl_csr_base=d["csr_bases"]["ctrl"])
127
128 # UART ---------------------------------------------------------------------------------------------
129
130 if "uart" in d["csr_bases"]:
131
132 aliases["serial0"] = "liteuart0"
133
134 dts += """
135 liteuart0: serial@{uart_csr_base:x} {{
136 device_type = "serial";
137 compatible = "litex,liteuart";
138 reg = <0x{uart_csr_base:x} 0x100>;
139 status = "okay";
140 }};
141 """.format(uart_csr_base=d["csr_bases"]["uart"])
142
143 # Ethernet MAC -------------------------------------------------------------------------------------
144
145 if "ethphy" in d["csr_bases"] and "ethmac" in d["csr_bases"]:
146
147 dts += """
148 mac0: mac@{ethmac_csr_base:x} {{
149 compatible = "litex,liteeth";
150 reg = <0x{ethmac_csr_base:x} 0x7c
151 0x{ethphy_csr_base:x} 0x0a
152 0x{ethmac_mem_base:x} 0x2000>;
153 tx-fifo-depth = <{ethmac_tx_slots}>;
154 rx-fifo-depth = <{ethmac_rx_slots}>;
155 }};
156 """.format(ethphy_csr_base=d["csr_bases"]["ethphy"],
157 ethmac_csr_base=d["csr_bases"]["ethmac"],
158 ethmac_mem_base=d["memories"]["ethmac"]["base"],
159 ethmac_tx_slots=d["constants"]["ethmac_tx_slots"],
160 ethmac_rx_slots=d["constants"]["ethmac_rx_slots"])
161
162 # Leds ---------------------------------------------------------------------------------------------
163
164 if "leds" in d["csr_bases"]:
165
166 dts += """
167 leds: gpio@{leds_csr_base:x} {{
168 compatible = "litex,gpio";
169 reg = <0x{leds_csr_base:x} 0x4>;
170 litex,direction = "out";
171 status = "disabled";
172 }};
173 """.format(leds_csr_base=d["csr_bases"]["leds"])
174
175 # RGB Led ------------------------------------------------------------------------------------------
176
177 for name in ["rgb_led_r0", "rgb_led_g0", "rgb_led_b0"]:
178 if name in d["csr_bases"]:
179
180 dts += """
181 {pwm_name}: pwm@{pwm_csr_base:x} {{
182 compatible = "litex,pwm";
183 reg = <0x{pwm_csr_base:x} 0x24>;
184 clock = <100000000>;
185 #pwm-cells = <3>;
186 status = "okay";
187 }};
188 """.format(pwm_name=name,
189 pwm_csr_base=d["csr_bases"][name])
190
191 # Switches -----------------------------------------------------------------------------------------
192
193 if "switches" in d["csr_bases"]:
194
195 dts += """
196 switches: gpio@{switches_csr_base:x} {{
197 compatible = "litex,gpio";
198 reg = <0x{switches_csr_base:x} 0x4>;
199 litex,direction = "in";
200 status = "disabled";
201 }};
202 """.format(switches_csr_base=d["csr_bases"]["switches"])
203
204 # SPI ----------------------------------------------------------------------------------------------
205
206 if "spi" in d["csr_bases"]:
207
208 aliases["spi0"] = "litespi0"
209
210 dts += """
211 litespi0: spi@{spi_csr_base:x} {{
212 compatible = "litex,litespi";
213 reg = <0x{spi_csr_base:x} 0x100>;
214 status = "okay";
215
216 litespi,max-bpw = <8>;
217 litespi,sck-frequency = <1000000>;
218 litespi,num-cs = <1>;
219
220 #address-cells = <1>;
221 #size-cells = <1>;
222
223 spidev0: spidev@0 {{
224 compatible = "linux,spidev";
225 reg = <0>;
226 spi-max-frequency = <1000000>;
227 status = "okay";
228 }};
229 }};
230 """.format(spi_csr_base=d["csr_bases"]["spi"])
231
232 # SPIFLASH -------------------------------------------------------------------------------------------
233
234 if "spiflash" in d["csr_bases"]:
235
236 aliases["spiflash"] = "litespiflash"
237
238 dts += """
239 litespiflash: spiflash@{spiflash_csr_base:x} {{
240 #address-cells = <1>;
241 #size-cells = <1>;
242 compatible = "litex,spiflash";
243 reg = <0x{spiflash_csr_base:x} 0x100>;
244 flash: flash@0 {{
245 compatible = "jedec,spi-nor";
246 reg = <0x0 0x{spiflash_size:x}>;
247 }};
248 }};
249 """.format(spiflash_csr_base=d["csr_bases"]["spiflash"],
250 spiflash_size=d["memories"]["spiflash"]["size"])
251
252 # SPISDCARD ----------------------------------------------------------------------------------------
253
254 if "spisdcard" in d["csr_bases"]:
255
256 aliases["sdcard0"] = "litespisdcard0"
257
258 dts += """
259 litespisdcard0: spi@{spisdcard_csr_base:x} {{
260 compatible = "litex,litespi";
261 reg = <0x{spisdcard_csr_base:x} 0x100>;
262 status = "okay";
263
264 litespi,max-bpw = <8>;
265 litespi,sck-frequency = <1500000>;
266 litespi,num-cs = <1>;
267
268 #address-cells = <1>;
269 #size-cells = <1>;
270
271 mmc-slot@0 {{
272 compatible = "mmc-spi-slot";
273 reg = <0>;
274 voltage-ranges = <3300 3300>;
275 spi-max-frequency = <1500000>;
276 status = "okay";
277 }};
278 }};
279 """.format(spisdcard_csr_base=d["csr_bases"]["spisdcard"])
280
281 # I2C ----------------------------------------------------------------------------------------------
282
283 if "i2c0" in d["csr_bases"]:
284
285 dts += """
286 i2c0: i2c@{i2c0_csr_base:x} {{
287 compatible = "litex,i2c";
288 reg = <0x{i2c0_csr_base:x} 0x5>;
289 status = "okay";
290 }};
291 """.format(i2c0_csr_base=d["csr_bases"]["i2c0"])
292
293 # XADC ---------------------------------------------------------------------------------------------
294
295 if "xadc" in d["csr_bases"]:
296
297 dts += """
298 hwmon0: xadc@{xadc_csr_base:x} {{
299 compatible = "litex,hwmon-xadc";
300 reg = <0x{xadc_csr_base:x} 0x20>;
301 status = "okay";
302 }};
303 """.format(xadc_csr_base=d["csr_bases"]["xadc"])
304
305 # Framebuffer --------------------------------------------------------------------------------------
306
307 if "framebuffer" in d["csr_bases"]:
308
309 # FIXME: dynamic framebuffer base and size
310 framebuffer_base = 0xc8000000
311 framebuffer_width = d["constants"]["litevideo_h_active"]
312 framebuffer_height = d["constants"]["litevideo_v_active"]
313 dts += """
314 framebuffer0: framebuffer@f0000000 {{
315 compatible = "simple-framebuffer";
316 reg = <0x{framebuffer_base:x} 0x{framebuffer_size:x}>;
317 width = <{framebuffer_width}>;
318 height = <{framebuffer_height}>;
319 stride = <{framebuffer_stride}>;
320 format = "a8b8g8r8";
321 }};
322 """.format(framebuffer_base=framebuffer_base,
323 framebuffer_width=framebuffer_width,
324 framebuffer_height=framebuffer_height,
325 framebuffer_size=framebuffer_width * framebuffer_height * 4,
326 framebuffer_stride=framebuffer_width * 4)
327
328 dts += """
329 litevideo0: gpu@{litevideo_base:x} {{
330 compatible = "litex,litevideo";
331 reg = <0x{litevideo_base:x} 0x100>;
332 litevideo,pixel-clock = <{litevideo_pixel_clock}>;
333 litevideo,h-active = <{litevideo_h_active}>;
334 litevideo,h-blanking = <{litevideo_h_blanking}>;
335 litevideo,h-sync = <{litevideo_h_sync}>;
336 litevideo,h-front-porch = <{litevideo_h_front_porch}>;
337 litevideo,v-active = <{litevideo_v_active}>;
338 litevideo,v-blanking = <{litevideo_v_blanking}>;
339 litevideo,v-sync = <{litevideo_v_sync}>;
340 litevideo,v-front-porch = <{litevideo_v_front_porch}>;
341 litevideo,dma-offset = <0x{litevideo_dma_offset:x}>;
342 litevideo,dma-length = <0x{litevideo_dma_length:x}>;
343 }};
344 """.format(litevideo_base=d["csr_bases"]["framebuffer"],
345 litevideo_pixel_clock=int(d["constants"]["litevideo_pix_clk"] / 1e3),
346 litevideo_h_active=d["constants"]["litevideo_h_active"],
347 litevideo_h_blanking=d["constants"]["litevideo_h_blanking"],
348 litevideo_h_sync=d["constants"]["litevideo_h_sync"],
349 litevideo_h_front_porch=d["constants"]["litevideo_h_front_porch"],
350 litevideo_v_active=d["constants"]["litevideo_v_active"],
351 litevideo_v_blanking=d["constants"]["litevideo_v_blanking"],
352 litevideo_v_sync=d["constants"]["litevideo_v_sync"],
353 litevideo_v_front_porch=d["constants"]["litevideo_v_front_porch"],
354 litevideo_dma_offset=framebuffer_base - d["memories"]["main_ram"]["base"],
355 litevideo_dma_length=framebuffer_width * framebuffer_height * 4)
356
357 # ICAPBitstream ------------------------------------------------------------------------------------
358
359 if "icap_bit" in d["csr_bases"]:
360
361 dts += """
362 fpga0: icap@{icap_csr_base:x} {{
363 compatible = "litex,fpga-icap";
364 reg = <0x{icap_csr_base:x} 0x14>;
365 status = "okay";
366 }};
367 """.format(icap_csr_base=d["csr_bases"]["icap_bit"])
368
369 # CLK ----------------------------------------------------------------------------------------------
370
371 def add_clkout(clkout_nr, clk_f, clk_p, clk_dn, clk_dd, clk_margin, clk_margin_exp):
372 return """
373 CLKOUT{clkout_nr}: CLKOUT{clkout_nr} {{
374 compatible = "litex,clk";
375 #clock-cells = <0>;
376 clock-output-names = "CLKOUT{clkout_nr}";
377 reg = <{clkout_nr}>;
378 litex,clock-frequency = <{clk_f}>;
379 litex,clock-phase = <{clk_p}>;
380 litex,clock-duty-num = <{clk_dn}>;
381 litex,clock-duty-den = <{clk_dd}>;
382 litex,clock-margin = <{clk_margin}>;
383 litex,clock-margin-exp = <{clk_margin_exp}>;
384 }};
385 """.format(clkout_nr=clkout_nr,
386 clk_f=clk_f,
387 clk_p=clk_p,
388 clk_dn=clk_dn,
389 clk_dd=clk_dd,
390 clk_margin=clk_margin,
391 clk_margin_exp=clk_margin_exp)
392
393 if "mmcm" in d["csr_bases"]:
394 nclkout = d["constants"]["nclkout"]
395
396 dts += """
397 clk0: clk@{mmcm_csr_base:x} {{
398 compatible = "litex,clk";
399 reg = <0x{mmcm_csr_base:x} 0x100>;
400 #clock-cells = <1>;
401 #address-cells = <1>;
402 #size-cells = <0>;
403 clock-output-names =
404 """.format(mmcm_csr_base=d["csr_bases"]["mmcm"])
405
406 for clkout_nr in range(nclkout - 1):
407
408 dts += """
409 "CLKOUT{clkout_nr}",
410 """.format(clkout_nr=clkout_nr)
411
412 dts += """
413 "CLKOUT{nclkout}";
414 """.format(nclkout=(nclkout - 1))
415
416 dts += """
417 litex,lock-timeout = <{mmcm_lock_timeout}>;
418 litex,drdy-timeout = <{mmcm_drdy_timeout}>;
419 litex,sys-clock-frequency = <{sys_clk}>;
420 litex,divclk-divide-min = <{divclk_divide_range[0]}>;
421 litex,divclk-divide-max = <{divclk_divide_range[1]}>;
422 litex,clkfbout-mult-min = <{clkfbout_mult_frange[0]}>;
423 litex,clkfbout-mult-max = <{clkfbout_mult_frange[1]}>;
424 litex,vco-freq-min = <{vco_freq_range[0]}>;
425 litex,vco-freq-max = <{vco_freq_range[1]}>;
426 litex,clkout-divide-min = <{clkout_divide_range[0]}>;
427 litex,clkout-divide-max = <{clkout_divide_range[1]}>;
428 litex,vco-margin = <{vco_margin}>;
429 """.format(mmcm_lock_timeout=d["constants"]["mmcm_lock_timeout"],
430 mmcm_drdy_timeout=d["constants"]["mmcm_drdy_timeout"],
431 sys_clk=d["constants"]["config_clock_frequency"],
432 divclk_divide_range=(d["constants"]["divclk_divide_range_min"], d["constants"]["divclk_divide_range_max"]),
433 clkfbout_mult_frange=(d["constants"]["clkfbout_mult_frange_min"], d["constants"]["clkfbout_mult_frange_max"]),
434 vco_freq_range=(d["constants"]["vco_freq_range_min"], d["constants"]["vco_freq_range_max"]),
435 clkout_divide_range=(d["constants"]["clkout_divide_range_min"], d["constants"]["clkout_divide_range_max"]),
436 vco_margin=d["constants"]["vco_margin"])
437
438 for clkout_nr in range(nclkout):
439 dts += add_clkout(clkout_nr,
440 d["constants"]["clkout_def_freq"],
441 d["constants"]["clkout_def_phase"],
442 d["constants"]["clkout_def_duty_num"],
443 d["constants"]["clkout_def_duty_den"],
444 d["constants"]["clkout_margin"],
445 d["constants"]["clkout_margin_exp"])
446
447 dts += """
448 };"""
449
450 # SDCARD -------------------------------------------------------------------------------------------
451
452 if "sdcore" in d["csr_bases"]:
453
454 dts += """
455 mmc0: mmc@{mmc_csr_base:x} {{
456 compatible = "litex,mmc";
457 bus-width = <4>;
458 reg = <
459 0x{sdphy_csr_base:x} 0x100
460 0x{sdcore_csr_base:x} 0x100
461 >;
462 status = "okay";
463 }};
464 """.format(mmc_csr_base=d["csr_bases"]["sdcore"],
465 sdphy_csr_base=d["csr_bases"]["sdphy"],
466 sdcore_csr_base=d["csr_bases"]["sdcore"])
467
468 dts += """
469 };
470 """
471
472 # Aliases ------------------------------------------------------------------------------------------
473
474 if aliases:
475 dts += """
476 aliases {
477 """
478 for alias in aliases:
479
480 dts += """
481 {} = &{};
482 """.format(alias, aliases[alias])
483
484 dts += """
485 };
486 """
487
488 dts += """
489 };
490 """
491
492 # Leds & switches ----------------------------------------------------------------------------------
493
494 if "leds" in d["csr_bases"]:
495 dts += """
496 &leds {
497 litex,ngpio = <4>;
498 status = "okay";
499 };
500 """
501
502 if "switches" in d["csr_bases"]:
503 dts += """
504 &switches {
505 litex,ngpio = <4>;
506 status = "okay";
507 };
508 """
509
510 return dts
511
512
513 if __name__ == "__main__":
514
515 parser = argparse.ArgumentParser(description="LiteX's CSR JSON to Linux DTS generator")
516 parser.add_argument("csr_json", help="CSR JSON file")
517 args = parser.parse_args()
518
519 d = json.load(open(args.csr_json))
520
521 print(generate_dts(d))