1 1.1 christos /* Blackfin External Bus Interface Unit (EBIU) Asynchronous Memory Controller 2 1.1 christos (AMC) model. 3 1.1 christos 4 1.11 christos Copyright (C) 2010-2024 Free Software Foundation, Inc. 5 1.1 christos Contributed by Analog Devices, Inc. 6 1.1 christos 7 1.1 christos This file is part of simulators. 8 1.1 christos 9 1.1 christos This program is free software; you can redistribute it and/or modify 10 1.1 christos it under the terms of the GNU General Public License as published by 11 1.1 christos the Free Software Foundation; either version 3 of the License, or 12 1.1 christos (at your option) any later version. 13 1.1 christos 14 1.1 christos This program is distributed in the hope that it will be useful, 15 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 16 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 1.1 christos GNU General Public License for more details. 18 1.1 christos 19 1.1 christos You should have received a copy of the GNU General Public License 20 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 1.1 christos 22 1.10 christos /* This must come before any other includes. */ 23 1.10 christos #include "defs.h" 24 1.1 christos 25 1.1 christos #include "sim-main.h" 26 1.1 christos #include "devices.h" 27 1.1 christos #include "dv-bfin_ebiu_amc.h" 28 1.1 christos 29 1.1 christos struct bfin_ebiu_amc 30 1.1 christos { 31 1.1 christos bu32 base; 32 1.1 christos int type; 33 1.1 christos bu32 bank_base, bank_size; 34 1.1 christos unsigned (*io_write) (struct hw *, const void *, int, address_word, 35 1.1 christos unsigned, struct bfin_ebiu_amc *, bu32, bu32); 36 1.1 christos unsigned (*io_read) (struct hw *, void *, int, address_word, unsigned, 37 1.1 christos struct bfin_ebiu_amc *, bu32, void *, bu16 *, bu32 *); 38 1.1 christos struct hw *slaves[4]; 39 1.1 christos 40 1.1 christos /* Order after here is important -- matches hardware MMR layout. */ 41 1.1 christos bu16 BFIN_MMR_16(amgctl); 42 1.1 christos union { 43 1.1 christos struct { 44 1.1 christos bu32 ambctl0, ambctl1; 45 1.1 christos bu32 _pad0[5]; 46 1.1 christos bu16 BFIN_MMR_16(mode); 47 1.1 christos bu16 BFIN_MMR_16(fctl); 48 1.1 christos } bf50x; 49 1.1 christos struct { 50 1.1 christos bu32 ambctl0, ambctl1; 51 1.1 christos } bf53x; 52 1.1 christos struct { 53 1.1 christos bu32 ambctl0, ambctl1; 54 1.1 christos bu32 mbsctl, arbstat, mode, fctl; 55 1.1 christos } bf54x; 56 1.1 christos }; 57 1.1 christos }; 58 1.1 christos #define mmr_base() offsetof(struct bfin_ebiu_amc, amgctl) 59 1.1 christos #define mmr_offset(mmr) (offsetof(struct bfin_ebiu_amc, mmr) - mmr_base()) 60 1.1 christos #define mmr_idx(mmr) (mmr_offset (mmr) / 4) 61 1.1 christos 62 1.1 christos static const char * const bf50x_mmr_names[] = 63 1.1 christos { 64 1.1 christos "EBIU_AMGCTL", "EBIU_AMBCTL0", "EBIU_AMBCTL1", 65 1.1 christos [mmr_idx (bf50x.mode)] = "EBIU_MODE", "EBIU_FCTL", 66 1.1 christos }; 67 1.1 christos static const char * const bf53x_mmr_names[] = 68 1.1 christos { 69 1.1 christos "EBIU_AMGCTL", "EBIU_AMBCTL0", "EBIU_AMBCTL1", 70 1.1 christos }; 71 1.1 christos static const char * const bf54x_mmr_names[] = 72 1.1 christos { 73 1.1 christos "EBIU_AMGCTL", "EBIU_AMBCTL0", "EBIU_AMBCTL1", 74 1.1 christos "EBIU_MSBCTL", "EBIU_ARBSTAT", "EBIU_MODE", "EBIU_FCTL", 75 1.1 christos }; 76 1.1 christos static const char * const *mmr_names; 77 1.1 christos #define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>") 78 1.1 christos 79 1.1 christos static void 80 1.1 christos bfin_ebiu_amc_write_amgctl (struct hw *me, struct bfin_ebiu_amc *amc, 81 1.1 christos bu16 amgctl) 82 1.1 christos { 83 1.1 christos bu32 amben_old, amben, addr, i; 84 1.1 christos 85 1.6 christos amben_old = min ((amc->amgctl >> 1) & 0x7, 4); 86 1.6 christos amben = min ((amgctl >> 1) & 0x7, 4); 87 1.1 christos 88 1.1 christos HW_TRACE ((me, "reattaching banks: AMGCTL 0x%04x[%u] -> 0x%04x[%u]", 89 1.1 christos amc->amgctl, amben_old, amgctl, amben)); 90 1.1 christos 91 1.1 christos for (i = 0; i < 4; ++i) 92 1.1 christos { 93 1.1 christos addr = amc->bank_base + i * amc->bank_size; 94 1.1 christos 95 1.1 christos if (i < amben_old) 96 1.1 christos { 97 1.1 christos HW_TRACE ((me, "detaching bank %u (%#x base)", i, addr)); 98 1.1 christos sim_core_detach (hw_system (me), NULL, 0, 0, addr); 99 1.1 christos } 100 1.1 christos 101 1.1 christos if (i < amben) 102 1.1 christos { 103 1.1 christos struct hw *slave = amc->slaves[i]; 104 1.1 christos 105 1.1 christos HW_TRACE ((me, "attaching bank %u (%#x base) to %s", i, addr, 106 1.1 christos slave ? hw_path (slave) : "<floating pins>")); 107 1.1 christos 108 1.1 christos sim_core_attach (hw_system (me), NULL, 0, access_read_write_exec, 109 1.1 christos 0, addr, amc->bank_size, 0, slave, NULL); 110 1.1 christos } 111 1.1 christos } 112 1.1 christos 113 1.1 christos amc->amgctl = amgctl; 114 1.1 christos } 115 1.1 christos 116 1.1 christos static unsigned 117 1.1 christos bf50x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space, 118 1.1 christos address_word addr, unsigned nr_bytes, 119 1.1 christos struct bfin_ebiu_amc *amc, bu32 mmr_off, 120 1.1 christos bu32 value) 121 1.1 christos { 122 1.1 christos switch (mmr_off) 123 1.1 christos { 124 1.1 christos case mmr_offset(amgctl): 125 1.6 christos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true)) 126 1.6 christos return 0; 127 1.1 christos bfin_ebiu_amc_write_amgctl (me, amc, value); 128 1.1 christos break; 129 1.1 christos case mmr_offset(bf50x.ambctl0): 130 1.1 christos amc->bf50x.ambctl0 = value; 131 1.1 christos break; 132 1.1 christos case mmr_offset(bf50x.ambctl1): 133 1.1 christos amc->bf50x.ambctl1 = value; 134 1.1 christos break; 135 1.1 christos case mmr_offset(bf50x.mode): 136 1.1 christos /* XXX: implement this. */ 137 1.6 christos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true)) 138 1.6 christos return 0; 139 1.1 christos break; 140 1.1 christos case mmr_offset(bf50x.fctl): 141 1.1 christos /* XXX: implement this. */ 142 1.6 christos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true)) 143 1.6 christos return 0; 144 1.1 christos break; 145 1.1 christos default: 146 1.1 christos dv_bfin_mmr_invalid (me, addr, nr_bytes, true); 147 1.6 christos return 0; 148 1.1 christos } 149 1.1 christos 150 1.1 christos return nr_bytes; 151 1.1 christos } 152 1.1 christos 153 1.1 christos static unsigned 154 1.1 christos bf53x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space, 155 1.1 christos address_word addr, unsigned nr_bytes, 156 1.1 christos struct bfin_ebiu_amc *amc, bu32 mmr_off, 157 1.1 christos bu32 value) 158 1.1 christos { 159 1.1 christos switch (mmr_off) 160 1.1 christos { 161 1.1 christos case mmr_offset(amgctl): 162 1.6 christos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true)) 163 1.6 christos return 0; 164 1.1 christos bfin_ebiu_amc_write_amgctl (me, amc, value); 165 1.1 christos break; 166 1.1 christos case mmr_offset(bf53x.ambctl0): 167 1.1 christos amc->bf53x.ambctl0 = value; 168 1.1 christos break; 169 1.1 christos case mmr_offset(bf53x.ambctl1): 170 1.1 christos amc->bf53x.ambctl1 = value; 171 1.1 christos break; 172 1.1 christos default: 173 1.1 christos dv_bfin_mmr_invalid (me, addr, nr_bytes, true); 174 1.6 christos return 0; 175 1.1 christos } 176 1.1 christos 177 1.1 christos return nr_bytes; 178 1.1 christos } 179 1.1 christos 180 1.1 christos static unsigned 181 1.1 christos bf54x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space, 182 1.1 christos address_word addr, unsigned nr_bytes, 183 1.1 christos struct bfin_ebiu_amc *amc, bu32 mmr_off, 184 1.1 christos bu32 value) 185 1.1 christos { 186 1.1 christos switch (mmr_off) 187 1.1 christos { 188 1.1 christos case mmr_offset(amgctl): 189 1.6 christos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true)) 190 1.6 christos return 0; 191 1.1 christos bfin_ebiu_amc_write_amgctl (me, amc, value); 192 1.1 christos break; 193 1.1 christos case mmr_offset(bf54x.ambctl0): 194 1.1 christos amc->bf54x.ambctl0 = value; 195 1.1 christos break; 196 1.1 christos case mmr_offset(bf54x.ambctl1): 197 1.1 christos amc->bf54x.ambctl1 = value; 198 1.1 christos break; 199 1.1 christos case mmr_offset(bf54x.mbsctl): 200 1.1 christos /* XXX: implement this. */ 201 1.1 christos break; 202 1.1 christos case mmr_offset(bf54x.arbstat): 203 1.1 christos /* XXX: implement this. */ 204 1.1 christos break; 205 1.1 christos case mmr_offset(bf54x.mode): 206 1.1 christos /* XXX: implement this. */ 207 1.1 christos break; 208 1.1 christos case mmr_offset(bf54x.fctl): 209 1.1 christos /* XXX: implement this. */ 210 1.1 christos break; 211 1.1 christos default: 212 1.1 christos dv_bfin_mmr_invalid (me, addr, nr_bytes, true); 213 1.6 christos return 0; 214 1.1 christos } 215 1.1 christos 216 1.1 christos return nr_bytes; 217 1.1 christos } 218 1.1 christos 219 1.1 christos static unsigned 220 1.1 christos bfin_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space, 221 1.1 christos address_word addr, unsigned nr_bytes) 222 1.1 christos { 223 1.1 christos struct bfin_ebiu_amc *amc = hw_data (me); 224 1.1 christos bu32 mmr_off; 225 1.1 christos bu32 value; 226 1.1 christos 227 1.6 christos /* Invalid access mode is higher priority than missing register. */ 228 1.6 christos if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true)) 229 1.6 christos return 0; 230 1.6 christos 231 1.1 christos value = dv_load_4 (source); 232 1.1 christos mmr_off = addr - amc->base; 233 1.1 christos 234 1.1 christos HW_TRACE_WRITE (); 235 1.1 christos 236 1.1 christos return amc->io_write (me, source, space, addr, nr_bytes, 237 1.1 christos amc, mmr_off, value); 238 1.1 christos } 239 1.1 christos 240 1.1 christos static unsigned 241 1.1 christos bf50x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space, 242 1.1 christos address_word addr, unsigned nr_bytes, 243 1.1 christos struct bfin_ebiu_amc *amc, bu32 mmr_off, 244 1.1 christos void *valuep, bu16 *value16, bu32 *value32) 245 1.1 christos { 246 1.1 christos switch (mmr_off) 247 1.1 christos { 248 1.1 christos case mmr_offset(amgctl): 249 1.1 christos case mmr_offset(bf50x.fctl): 250 1.6 christos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false)) 251 1.6 christos return 0; 252 1.1 christos dv_store_2 (dest, *value16); 253 1.1 christos break; 254 1.1 christos case mmr_offset(bf50x.ambctl0): 255 1.1 christos case mmr_offset(bf50x.ambctl1): 256 1.1 christos case mmr_offset(bf50x.mode): 257 1.1 christos dv_store_4 (dest, *value32); 258 1.1 christos break; 259 1.1 christos default: 260 1.1 christos dv_bfin_mmr_invalid (me, addr, nr_bytes, false); 261 1.6 christos return 0; 262 1.1 christos } 263 1.1 christos 264 1.1 christos return nr_bytes; 265 1.1 christos } 266 1.1 christos 267 1.1 christos static unsigned 268 1.1 christos bf53x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space, 269 1.1 christos address_word addr, unsigned nr_bytes, 270 1.1 christos struct bfin_ebiu_amc *amc, bu32 mmr_off, 271 1.1 christos void *valuep, bu16 *value16, bu32 *value32) 272 1.1 christos { 273 1.1 christos switch (mmr_off) 274 1.1 christos { 275 1.1 christos case mmr_offset(amgctl): 276 1.6 christos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false)) 277 1.6 christos return 0; 278 1.1 christos dv_store_2 (dest, *value16); 279 1.1 christos break; 280 1.1 christos case mmr_offset(bf53x.ambctl0): 281 1.1 christos case mmr_offset(bf53x.ambctl1): 282 1.1 christos dv_store_4 (dest, *value32); 283 1.1 christos break; 284 1.1 christos default: 285 1.1 christos dv_bfin_mmr_invalid (me, addr, nr_bytes, false); 286 1.6 christos return 0; 287 1.1 christos } 288 1.1 christos 289 1.1 christos return nr_bytes; 290 1.1 christos } 291 1.1 christos 292 1.1 christos static unsigned 293 1.1 christos bf54x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space, 294 1.1 christos address_word addr, unsigned nr_bytes, 295 1.1 christos struct bfin_ebiu_amc *amc, bu32 mmr_off, 296 1.1 christos void *valuep, bu16 *value16, bu32 *value32) 297 1.1 christos { 298 1.1 christos switch (mmr_off) 299 1.1 christos { 300 1.1 christos case mmr_offset(amgctl): 301 1.6 christos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false)) 302 1.6 christos return 0; 303 1.1 christos dv_store_2 (dest, *value16); 304 1.1 christos break; 305 1.1 christos case mmr_offset(bf54x.ambctl0): 306 1.1 christos case mmr_offset(bf54x.ambctl1): 307 1.1 christos case mmr_offset(bf54x.mbsctl): 308 1.1 christos case mmr_offset(bf54x.arbstat): 309 1.1 christos case mmr_offset(bf54x.mode): 310 1.1 christos case mmr_offset(bf54x.fctl): 311 1.1 christos dv_store_4 (dest, *value32); 312 1.1 christos break; 313 1.1 christos default: 314 1.1 christos dv_bfin_mmr_invalid (me, addr, nr_bytes, false); 315 1.6 christos return 0; 316 1.1 christos } 317 1.1 christos 318 1.1 christos return nr_bytes; 319 1.1 christos } 320 1.1 christos 321 1.1 christos static unsigned 322 1.1 christos bfin_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space, 323 1.1 christos address_word addr, unsigned nr_bytes) 324 1.1 christos { 325 1.1 christos struct bfin_ebiu_amc *amc = hw_data (me); 326 1.1 christos bu32 mmr_off; 327 1.1 christos void *valuep; 328 1.1 christos 329 1.6 christos /* Invalid access mode is higher priority than missing register. */ 330 1.6 christos if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false)) 331 1.6 christos return 0; 332 1.6 christos 333 1.1 christos mmr_off = addr - amc->base; 334 1.10 christos valuep = (void *)((uintptr_t)amc + mmr_base() + mmr_off); 335 1.1 christos 336 1.1 christos HW_TRACE_READ (); 337 1.1 christos 338 1.1 christos return amc->io_read (me, dest, space, addr, nr_bytes, amc, 339 1.1 christos mmr_off, valuep, valuep, valuep); 340 1.1 christos } 341 1.1 christos 342 1.1 christos static void 343 1.1 christos bfin_ebiu_amc_attach_address_callback (struct hw *me, 344 1.1 christos int level, 345 1.1 christos int space, 346 1.1 christos address_word addr, 347 1.1 christos address_word nr_bytes, 348 1.1 christos struct hw *client) 349 1.1 christos { 350 1.1 christos struct bfin_ebiu_amc *amc = hw_data (me); 351 1.1 christos 352 1.1 christos HW_TRACE ((me, "attach - level=%d, space=%d, addr=0x%lx, nr_bytes=%lu, client=%s", 353 1.1 christos level, space, (unsigned long) addr, (unsigned long) nr_bytes, hw_path (client))); 354 1.1 christos 355 1.1 christos if (addr + nr_bytes > ARRAY_SIZE (amc->slaves)) 356 1.1 christos hw_abort (me, "ebiu amc attaches are done in terms of banks"); 357 1.1 christos 358 1.1 christos while (nr_bytes--) 359 1.1 christos amc->slaves[addr + nr_bytes] = client; 360 1.1 christos 361 1.1 christos bfin_ebiu_amc_write_amgctl (me, amc, amc->amgctl); 362 1.1 christos } 363 1.1 christos 364 1.1 christos static void 365 1.1 christos attach_bfin_ebiu_amc_regs (struct hw *me, struct bfin_ebiu_amc *amc, 366 1.1 christos unsigned reg_size) 367 1.1 christos { 368 1.1 christos address_word attach_address; 369 1.1 christos int attach_space; 370 1.1 christos unsigned attach_size; 371 1.1 christos reg_property_spec reg; 372 1.1 christos 373 1.1 christos if (hw_find_property (me, "reg") == NULL) 374 1.1 christos hw_abort (me, "Missing \"reg\" property"); 375 1.1 christos 376 1.1 christos if (!hw_find_reg_array_property (me, "reg", 0, ®)) 377 1.1 christos hw_abort (me, "\"reg\" property must contain three addr/size entries"); 378 1.1 christos 379 1.1 christos if (hw_find_property (me, "type") == NULL) 380 1.1 christos hw_abort (me, "Missing \"type\" property"); 381 1.1 christos 382 1.1 christos hw_unit_address_to_attach_address (hw_parent (me), 383 1.1 christos ®.address, 384 1.1 christos &attach_space, &attach_address, me); 385 1.1 christos hw_unit_size_to_attach_size (hw_parent (me), ®.size, &attach_size, me); 386 1.1 christos 387 1.1 christos if (attach_size != reg_size) 388 1.1 christos hw_abort (me, "\"reg\" size must be %#x", reg_size); 389 1.1 christos 390 1.1 christos hw_attach_address (hw_parent (me), 391 1.1 christos 0, attach_space, attach_address, attach_size, me); 392 1.1 christos 393 1.1 christos amc->base = attach_address; 394 1.1 christos } 395 1.1 christos 396 1.1 christos static void 397 1.1 christos bfin_ebiu_amc_finish (struct hw *me) 398 1.1 christos { 399 1.1 christos struct bfin_ebiu_amc *amc; 400 1.1 christos bu32 amgctl; 401 1.1 christos unsigned reg_size; 402 1.1 christos 403 1.1 christos amc = HW_ZALLOC (me, struct bfin_ebiu_amc); 404 1.1 christos 405 1.1 christos set_hw_data (me, amc); 406 1.1 christos set_hw_io_read_buffer (me, bfin_ebiu_amc_io_read_buffer); 407 1.1 christos set_hw_io_write_buffer (me, bfin_ebiu_amc_io_write_buffer); 408 1.1 christos set_hw_attach_address (me, bfin_ebiu_amc_attach_address_callback); 409 1.1 christos 410 1.1 christos amc->type = hw_find_integer_property (me, "type"); 411 1.1 christos 412 1.1 christos switch (amc->type) 413 1.1 christos { 414 1.1 christos case 500 ... 509: 415 1.1 christos amc->io_write = bf50x_ebiu_amc_io_write_buffer; 416 1.1 christos amc->io_read = bf50x_ebiu_amc_io_read_buffer; 417 1.1 christos mmr_names = bf50x_mmr_names; 418 1.1 christos reg_size = sizeof (amc->bf50x) + 4; 419 1.1 christos 420 1.1 christos /* Initialize the AMC. */ 421 1.1 christos amc->bank_base = BFIN_EBIU_AMC_BASE; 422 1.1 christos amc->bank_size = 1 * 1024 * 1024; 423 1.1 christos amgctl = 0x00F3; 424 1.1 christos amc->bf50x.ambctl0 = 0x0000FFC2; 425 1.1 christos amc->bf50x.ambctl1 = 0x0000FFC2; 426 1.1 christos amc->bf50x.mode = 0x0001; 427 1.1 christos amc->bf50x.fctl = 0x0002; 428 1.1 christos break; 429 1.1 christos case 540 ... 549: 430 1.1 christos amc->io_write = bf54x_ebiu_amc_io_write_buffer; 431 1.1 christos amc->io_read = bf54x_ebiu_amc_io_read_buffer; 432 1.1 christos mmr_names = bf54x_mmr_names; 433 1.1 christos reg_size = sizeof (amc->bf54x) + 4; 434 1.1 christos 435 1.1 christos /* Initialize the AMC. */ 436 1.1 christos amc->bank_base = BFIN_EBIU_AMC_BASE; 437 1.1 christos amc->bank_size = 64 * 1024 * 1024; 438 1.1 christos amgctl = 0x0002; 439 1.1 christos amc->bf54x.ambctl0 = 0xFFC2FFC2; 440 1.1 christos amc->bf54x.ambctl1 = 0xFFC2FFC2; 441 1.1 christos amc->bf54x.fctl = 0x0006; 442 1.1 christos break; 443 1.1 christos case 510 ... 519: 444 1.1 christos case 522 ... 527: 445 1.1 christos case 531 ... 533: 446 1.1 christos case 534: 447 1.1 christos case 536: 448 1.1 christos case 537: 449 1.1 christos case 538 ... 539: 450 1.1 christos case 561: 451 1.1 christos amc->io_write = bf53x_ebiu_amc_io_write_buffer; 452 1.1 christos amc->io_read = bf53x_ebiu_amc_io_read_buffer; 453 1.1 christos mmr_names = bf53x_mmr_names; 454 1.1 christos reg_size = sizeof (amc->bf53x) + 4; 455 1.1 christos 456 1.1 christos /* Initialize the AMC. */ 457 1.1 christos amc->bank_base = BFIN_EBIU_AMC_BASE; 458 1.1 christos if (amc->type == 561) 459 1.1 christos amc->bank_size = 64 * 1024 * 1024; 460 1.1 christos else 461 1.1 christos amc->bank_size = 1 * 1024 * 1024; 462 1.1 christos amgctl = 0x00F2; 463 1.1 christos amc->bf53x.ambctl0 = 0xFFC2FFC2; 464 1.1 christos amc->bf53x.ambctl1 = 0xFFC2FFC2; 465 1.1 christos break; 466 1.1 christos case 590 ... 599: /* BF59x has no AMC. */ 467 1.1 christos default: 468 1.1 christos hw_abort (me, "no support for EBIU AMC on this Blackfin model yet"); 469 1.1 christos } 470 1.1 christos 471 1.1 christos attach_bfin_ebiu_amc_regs (me, amc, reg_size); 472 1.1 christos 473 1.1 christos bfin_ebiu_amc_write_amgctl (me, amc, amgctl); 474 1.1 christos } 475 1.1 christos 476 1.1 christos const struct hw_descriptor dv_bfin_ebiu_amc_descriptor[] = 477 1.1 christos { 478 1.1 christos {"bfin_ebiu_amc", bfin_ebiu_amc_finish,}, 479 1.1 christos {NULL, NULL}, 480 1.1 christos }; 481