| OLD | NEW |
| 1 /* Blackfin External Bus Interface Unit (EBIU) Asynchronous Memory Controller | 1 /* Blackfin External Bus Interface Unit (EBIU) Asynchronous Memory Controller |
| 2 (AMC) model. | 2 (AMC) model. |
| 3 | 3 |
| 4 Copyright (C) 2010-2012 Free Software Foundation, Inc. | 4 Copyright (C) 2010-2012 Free Software Foundation, Inc. |
| 5 Contributed by Analog Devices, Inc. | 5 Contributed by Analog Devices, Inc. |
| 6 | 6 |
| 7 This file is part of simulators. | 7 This file is part of simulators. |
| 8 | 8 |
| 9 This program is free software; you can redistribute it and/or modify | 9 This program is free software; you can redistribute it and/or modify |
| 10 it under the terms of the GNU General Public License as published by | 10 it under the terms of the GNU General Public License as published by |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "config.h" | 22 #include "config.h" |
| 23 | 23 |
| 24 #include "sim-main.h" | 24 #include "sim-main.h" |
| 25 #include "devices.h" | 25 #include "devices.h" |
| 26 #include "dv-bfin_ebiu_amc.h" | 26 #include "dv-bfin_ebiu_amc.h" |
| 27 | 27 |
| 28 struct bfin_ebiu_amc | 28 struct bfin_ebiu_amc |
| 29 { | 29 { |
| 30 bu32 base; | 30 bu32 base; |
| 31 int type; | 31 int type; |
| 32 bu32 bank_size; | 32 bu32 bank_base, bank_size; |
| 33 unsigned (*io_write) (struct hw *, const void *, int, address_word, | 33 unsigned (*io_write) (struct hw *, const void *, int, address_word, |
| 34 unsigned, struct bfin_ebiu_amc *, bu32, bu32); | 34 unsigned, struct bfin_ebiu_amc *, bu32, bu32); |
| 35 unsigned (*io_read) (struct hw *, void *, int, address_word, unsigned, | 35 unsigned (*io_read) (struct hw *, void *, int, address_word, unsigned, |
| 36 struct bfin_ebiu_amc *, bu32, void *, bu16 *, bu32 *); | 36 struct bfin_ebiu_amc *, bu32, void *, bu16 *, bu32 *); |
| 37 struct hw *slaves[4]; | 37 struct hw *slaves[4]; |
| 38 | 38 |
| 39 /* Order after here is important -- matches hardware MMR layout. */ | 39 /* Order after here is important -- matches hardware MMR layout. */ |
| 40 bu16 BFIN_MMR_16(amgctl); | 40 bu16 BFIN_MMR_16(amgctl); |
| 41 union { | 41 union { |
| 42 struct { | 42 struct { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 bu32 amben_old, amben, addr, i; | 82 bu32 amben_old, amben, addr, i; |
| 83 | 83 |
| 84 amben_old = MIN ((amc->amgctl >> 1) & 0x7, 4); | 84 amben_old = MIN ((amc->amgctl >> 1) & 0x7, 4); |
| 85 amben = MIN ((amgctl >> 1) & 0x7, 4); | 85 amben = MIN ((amgctl >> 1) & 0x7, 4); |
| 86 | 86 |
| 87 HW_TRACE ((me, "reattaching banks: AMGCTL 0x%04x[%u] -> 0x%04x[%u]", | 87 HW_TRACE ((me, "reattaching banks: AMGCTL 0x%04x[%u] -> 0x%04x[%u]", |
| 88 amc->amgctl, amben_old, amgctl, amben)); | 88 amc->amgctl, amben_old, amgctl, amben)); |
| 89 | 89 |
| 90 for (i = 0; i < 4; ++i) | 90 for (i = 0; i < 4; ++i) |
| 91 { | 91 { |
| 92 addr = BFIN_EBIU_AMC_BASE + i * amc->bank_size; | 92 addr = amc->bank_base + i * amc->bank_size; |
| 93 | 93 |
| 94 if (i < amben_old) | 94 if (i < amben_old) |
| 95 { | 95 { |
| 96 HW_TRACE ((me, "detaching bank %u (%#x base)", i, addr)); | 96 HW_TRACE ((me, "detaching bank %u (%#x base)", i, addr)); |
| 97 sim_core_detach (hw_system (me), NULL, 0, 0, addr); | 97 sim_core_detach (hw_system (me), NULL, 0, 0, addr); |
| 98 } | 98 } |
| 99 | 99 |
| 100 if (i < amben) | 100 if (i < amben) |
| 101 { | 101 { |
| 102 struct hw *slave = amc->slaves[i]; | 102 struct hw *slave = amc->slaves[i]; |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 int space, | 328 int space, |
| 329 address_word addr, | 329 address_word addr, |
| 330 address_word nr_bytes, | 330 address_word nr_bytes, |
| 331 struct hw *client) | 331 struct hw *client) |
| 332 { | 332 { |
| 333 struct bfin_ebiu_amc *amc = hw_data (me); | 333 struct bfin_ebiu_amc *amc = hw_data (me); |
| 334 | 334 |
| 335 HW_TRACE ((me, "attach - level=%d, space=%d, addr=0x%lx, nr_bytes=%lu, client=
%s", | 335 HW_TRACE ((me, "attach - level=%d, space=%d, addr=0x%lx, nr_bytes=%lu, client=
%s", |
| 336 level, space, (unsigned long) addr, (unsigned long) nr_bytes, hw_pa
th (client))); | 336 level, space, (unsigned long) addr, (unsigned long) nr_bytes, hw_pa
th (client))); |
| 337 | 337 |
| 338 if (addr + nr_bytes > 4) | 338 if (addr + nr_bytes > ARRAY_SIZE (amc->slaves)) |
| 339 hw_abort (me, "ebiu amc attaches are done in terms of banks"); | 339 hw_abort (me, "ebiu amc attaches are done in terms of banks"); |
| 340 | 340 |
| 341 while (nr_bytes--) | 341 while (nr_bytes--) |
| 342 amc->slaves[addr + nr_bytes] = client; | 342 amc->slaves[addr + nr_bytes] = client; |
| 343 | 343 |
| 344 bfin_ebiu_amc_write_amgctl (me, amc, amc->amgctl); | 344 bfin_ebiu_amc_write_amgctl (me, amc, amc->amgctl); |
| 345 } | 345 } |
| 346 | 346 |
| 347 static void | 347 static void |
| 348 attach_bfin_ebiu_amc_regs (struct hw *me, struct bfin_ebiu_amc *amc, | 348 attach_bfin_ebiu_amc_regs (struct hw *me, struct bfin_ebiu_amc *amc, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 | 394 |
| 395 switch (amc->type) | 395 switch (amc->type) |
| 396 { | 396 { |
| 397 case 500 ... 509: | 397 case 500 ... 509: |
| 398 amc->io_write = bf50x_ebiu_amc_io_write_buffer; | 398 amc->io_write = bf50x_ebiu_amc_io_write_buffer; |
| 399 amc->io_read = bf50x_ebiu_amc_io_read_buffer; | 399 amc->io_read = bf50x_ebiu_amc_io_read_buffer; |
| 400 mmr_names = bf50x_mmr_names; | 400 mmr_names = bf50x_mmr_names; |
| 401 reg_size = sizeof (amc->bf50x) + 4; | 401 reg_size = sizeof (amc->bf50x) + 4; |
| 402 | 402 |
| 403 /* Initialize the AMC. */ | 403 /* Initialize the AMC. */ |
| 404 amc->bank_base = BFIN_EBIU_AMC_BASE; |
| 404 amc->bank_size = 1 * 1024 * 1024; | 405 amc->bank_size = 1 * 1024 * 1024; |
| 405 amgctl = 0x00F3; | 406 amgctl = 0x00F3; |
| 406 amc->bf50x.ambctl0 = 0x0000FFC2; | 407 amc->bf50x.ambctl0 = 0x0000FFC2; |
| 407 amc->bf50x.ambctl1 = 0x0000FFC2; | 408 amc->bf50x.ambctl1 = 0x0000FFC2; |
| 408 amc->bf50x.mode = 0x0001; | 409 amc->bf50x.mode = 0x0001; |
| 409 amc->bf50x.fctl = 0x0002; | 410 amc->bf50x.fctl = 0x0002; |
| 410 break; | 411 break; |
| 411 case 540 ... 549: | 412 case 540 ... 549: |
| 412 amc->io_write = bf54x_ebiu_amc_io_write_buffer; | 413 amc->io_write = bf54x_ebiu_amc_io_write_buffer; |
| 413 amc->io_read = bf54x_ebiu_amc_io_read_buffer; | 414 amc->io_read = bf54x_ebiu_amc_io_read_buffer; |
| 414 mmr_names = bf54x_mmr_names; | 415 mmr_names = bf54x_mmr_names; |
| 415 reg_size = sizeof (amc->bf54x) + 4; | 416 reg_size = sizeof (amc->bf54x) + 4; |
| 416 | 417 |
| 417 /* Initialize the AMC. */ | 418 /* Initialize the AMC. */ |
| 419 amc->bank_base = BFIN_EBIU_AMC_BASE; |
| 418 amc->bank_size = 64 * 1024 * 1024; | 420 amc->bank_size = 64 * 1024 * 1024; |
| 419 amgctl = 0x0002; | 421 amgctl = 0x0002; |
| 420 amc->bf54x.ambctl0 = 0xFFC2FFC2; | 422 amc->bf54x.ambctl0 = 0xFFC2FFC2; |
| 421 amc->bf54x.ambctl1 = 0xFFC2FFC2; | 423 amc->bf54x.ambctl1 = 0xFFC2FFC2; |
| 422 amc->bf54x.fctl = 0x0006; | 424 amc->bf54x.fctl = 0x0006; |
| 423 break; | 425 break; |
| 424 case 510 ... 519: | 426 case 510 ... 519: |
| 425 case 522 ... 527: | 427 case 522 ... 527: |
| 426 case 531 ... 533: | 428 case 531 ... 533: |
| 427 case 534: | 429 case 534: |
| 428 case 536: | 430 case 536: |
| 429 case 537: | 431 case 537: |
| 430 case 538 ... 539: | 432 case 538 ... 539: |
| 431 case 561: | 433 case 561: |
| 432 amc->io_write = bf53x_ebiu_amc_io_write_buffer; | 434 amc->io_write = bf53x_ebiu_amc_io_write_buffer; |
| 433 amc->io_read = bf53x_ebiu_amc_io_read_buffer; | 435 amc->io_read = bf53x_ebiu_amc_io_read_buffer; |
| 434 mmr_names = bf53x_mmr_names; | 436 mmr_names = bf53x_mmr_names; |
| 435 reg_size = sizeof (amc->bf53x) + 4; | 437 reg_size = sizeof (amc->bf53x) + 4; |
| 436 | 438 |
| 437 /* Initialize the AMC. */ | 439 /* Initialize the AMC. */ |
| 440 amc->bank_base = BFIN_EBIU_AMC_BASE; |
| 438 if (amc->type == 561) | 441 if (amc->type == 561) |
| 439 amc->bank_size = 64 * 1024 * 1024; | 442 amc->bank_size = 64 * 1024 * 1024; |
| 440 else | 443 else |
| 441 amc->bank_size = 1 * 1024 * 1024; | 444 amc->bank_size = 1 * 1024 * 1024; |
| 442 amgctl = 0x00F2; | 445 amgctl = 0x00F2; |
| 443 amc->bf53x.ambctl0 = 0xFFC2FFC2; | 446 amc->bf53x.ambctl0 = 0xFFC2FFC2; |
| 444 amc->bf53x.ambctl1 = 0xFFC2FFC2; | 447 amc->bf53x.ambctl1 = 0xFFC2FFC2; |
| 445 break; | 448 break; |
| 446 case 590 ... 599: /* BF59x has no AMC. */ | 449 case 590 ... 599: /* BF59x has no AMC. */ |
| 447 default: | 450 default: |
| 448 hw_abort (me, "no support for EBIU AMC on this Blackfin model yet"); | 451 hw_abort (me, "no support for EBIU AMC on this Blackfin model yet"); |
| 449 } | 452 } |
| 450 | 453 |
| 451 attach_bfin_ebiu_amc_regs (me, amc, reg_size); | 454 attach_bfin_ebiu_amc_regs (me, amc, reg_size); |
| 452 | 455 |
| 453 bfin_ebiu_amc_write_amgctl (me, amc, amgctl); | 456 bfin_ebiu_amc_write_amgctl (me, amc, amgctl); |
| 454 } | 457 } |
| 455 | 458 |
| 456 const struct hw_descriptor dv_bfin_ebiu_amc_descriptor[] = | 459 const struct hw_descriptor dv_bfin_ebiu_amc_descriptor[] = |
| 457 { | 460 { |
| 458 {"bfin_ebiu_amc", bfin_ebiu_amc_finish,}, | 461 {"bfin_ebiu_amc", bfin_ebiu_amc_finish,}, |
| 459 {NULL, NULL}, | 462 {NULL, NULL}, |
| 460 }; | 463 }; |
| OLD | NEW |