diff options
author | Liu Gang <Gang.Liu@freescale.com> | 2011-11-12 07:02:29 -0500 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2011-11-24 03:01:34 -0500 |
commit | abc3aeae3aaa5c319d02f12649e17ea5929999aa (patch) | |
tree | 1eb64b3c01ce6ae488c9f5f0460b602d654b5a2a /arch/powerpc/sysdev/fsl_rio.c | |
parent | 6ec4bedbf153a8ef71aeba99a40efef556b57798 (diff) |
fsl-rio: Add two ports and rapidio message units support
Usually, freescale rapidio endpoint can support one or two 1x or 4X
LP-Serial link interfaces, and rapidio message transactions can be
implemented by two message units. This adds the support of two
rapidio ports and initializes message unit 0 and message unit 1. And
these ports and message units can work simultaneously.
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Jin Qing <b24347@freescale.com>
Signed-off-by: Liu Gang <Gang.Liu@freescale.com>
Acked-by: Alexandre Bounine <alexandre.bounine@idt.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/sysdev/fsl_rio.c')
-rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 391 |
1 files changed, 258 insertions, 133 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 9484484c82c3..a4c4f4a932d8 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #define RIO_PORT1_IECSR 0x10130 | 45 | #define RIO_PORT1_IECSR 0x10130 |
46 | #define RIO_PORT2_IECSR 0x101B0 | 46 | #define RIO_PORT2_IECSR 0x101B0 |
47 | 47 | ||
48 | #define RIO_ATMU_REGS_OFFSET 0x10c00 | ||
49 | #define RIO_GCCSR 0x13c | 48 | #define RIO_GCCSR 0x13c |
50 | #define RIO_ESCSR 0x158 | 49 | #define RIO_ESCSR 0x158 |
51 | #define ESCSR_CLEAR 0x07120204 | 50 | #define ESCSR_CLEAR 0x07120204 |
@@ -74,6 +73,11 @@ | |||
74 | : "b" (addr), "i" (-EFAULT), "0" (err)) | 73 | : "b" (addr), "i" (-EFAULT), "0" (err)) |
75 | 74 | ||
76 | void __iomem *rio_regs_win; | 75 | void __iomem *rio_regs_win; |
76 | void __iomem *rmu_regs_win; | ||
77 | resource_size_t rio_law_start; | ||
78 | |||
79 | struct fsl_rio_dbell *dbell; | ||
80 | struct fsl_rio_pw *pw; | ||
77 | 81 | ||
78 | #ifdef CONFIG_E500 | 82 | #ifdef CONFIG_E500 |
79 | int fsl_rio_mcheck_exception(struct pt_regs *regs) | 83 | int fsl_rio_mcheck_exception(struct pt_regs *regs) |
@@ -120,7 +124,7 @@ static int fsl_local_config_read(struct rio_mport *mport, | |||
120 | { | 124 | { |
121 | struct rio_priv *priv = mport->priv; | 125 | struct rio_priv *priv = mport->priv; |
122 | pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index, | 126 | pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index, |
123 | offset); | 127 | offset); |
124 | *data = in_be32(priv->regs_win + offset); | 128 | *data = in_be32(priv->regs_win + offset); |
125 | 129 | ||
126 | return 0; | 130 | return 0; |
@@ -173,7 +177,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, | |||
173 | pr_debug | 177 | pr_debug |
174 | ("fsl_rio_config_read:" | 178 | ("fsl_rio_config_read:" |
175 | " index %d destid %d hopcount %d offset %8.8x len %d\n", | 179 | " index %d destid %d hopcount %d offset %8.8x len %d\n", |
176 | index, destid, hopcount, offset, len); | 180 | index, destid, hopcount, offset, len); |
177 | 181 | ||
178 | /* 16MB maintenance window possible */ | 182 | /* 16MB maintenance window possible */ |
179 | /* allow only aligned access to maintenance registers */ | 183 | /* allow only aligned access to maintenance registers */ |
@@ -230,8 +234,8 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, | |||
230 | u8 *data; | 234 | u8 *data; |
231 | pr_debug | 235 | pr_debug |
232 | ("fsl_rio_config_write:" | 236 | ("fsl_rio_config_write:" |
233 | "index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", | 237 | " index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", |
234 | index, destid, hopcount, offset, len, val); | 238 | index, destid, hopcount, offset, len, val); |
235 | 239 | ||
236 | /* 16MB maintenance windows possible */ | 240 | /* 16MB maintenance windows possible */ |
237 | /* allow only aligned access to maintenance registers */ | 241 | /* allow only aligned access to maintenance registers */ |
@@ -260,7 +264,7 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, | |||
260 | return 0; | 264 | return 0; |
261 | } | 265 | } |
262 | 266 | ||
263 | void fsl_rio_port_error_handler(struct rio_mport *port, int offset) | 267 | void fsl_rio_port_error_handler(int offset) |
264 | { | 268 | { |
265 | /*XXX: Error recovery is not implemented, we just clear errors */ | 269 | /*XXX: Error recovery is not implemented, we just clear errors */ |
266 | out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0); | 270 | out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0); |
@@ -331,16 +335,21 @@ int fsl_rio_setup(struct platform_device *dev) | |||
331 | struct rio_mport *port; | 335 | struct rio_mport *port; |
332 | struct rio_priv *priv; | 336 | struct rio_priv *priv; |
333 | int rc = 0; | 337 | int rc = 0; |
334 | const u32 *dt_range, *cell; | 338 | const u32 *dt_range, *cell, *port_index; |
335 | struct resource regs; | 339 | u32 active_ports = 0; |
340 | struct resource regs, rmu_regs; | ||
341 | struct device_node *np, *rmu_node; | ||
336 | int rlen; | 342 | int rlen; |
337 | u32 ccsr; | 343 | u32 ccsr; |
338 | u64 law_start, law_size; | 344 | u64 range_start, range_size; |
339 | int paw, aw, sw; | 345 | int paw, aw, sw; |
346 | u32 i; | ||
347 | static int tmp; | ||
348 | struct device_node *rmu_np[MAX_MSG_UNIT_NUM] = {NULL}; | ||
340 | 349 | ||
341 | if (!dev->dev.of_node) { | 350 | if (!dev->dev.of_node) { |
342 | dev_err(&dev->dev, "Device OF-Node is NULL"); | 351 | dev_err(&dev->dev, "Device OF-Node is NULL"); |
343 | return -EFAULT; | 352 | return -ENODEV; |
344 | } | 353 | } |
345 | 354 | ||
346 | rc = of_address_to_resource(dev->dev.of_node, 0, ®s); | 355 | rc = of_address_to_resource(dev->dev.of_node, 0, ®s); |
@@ -353,34 +362,13 @@ int fsl_rio_setup(struct platform_device *dev) | |||
353 | dev->dev.of_node->full_name); | 362 | dev->dev.of_node->full_name); |
354 | dev_info(&dev->dev, "Regs: %pR\n", ®s); | 363 | dev_info(&dev->dev, "Regs: %pR\n", ®s); |
355 | 364 | ||
356 | dt_range = of_get_property(dev->dev.of_node, "ranges", &rlen); | 365 | rio_regs_win = ioremap(regs.start, resource_size(®s)); |
357 | if (!dt_range) { | 366 | if (!rio_regs_win) { |
358 | dev_err(&dev->dev, "Can't get %s property 'ranges'\n", | 367 | dev_err(&dev->dev, "Unable to map rio register window\n"); |
359 | dev->dev.of_node->full_name); | 368 | rc = -ENOMEM; |
360 | return -EFAULT; | 369 | goto err_rio_regs; |
361 | } | 370 | } |
362 | 371 | ||
363 | /* Get node address wide */ | ||
364 | cell = of_get_property(dev->dev.of_node, "#address-cells", NULL); | ||
365 | if (cell) | ||
366 | aw = *cell; | ||
367 | else | ||
368 | aw = of_n_addr_cells(dev->dev.of_node); | ||
369 | /* Get node size wide */ | ||
370 | cell = of_get_property(dev->dev.of_node, "#size-cells", NULL); | ||
371 | if (cell) | ||
372 | sw = *cell; | ||
373 | else | ||
374 | sw = of_n_size_cells(dev->dev.of_node); | ||
375 | /* Get parent address wide wide */ | ||
376 | paw = of_n_addr_cells(dev->dev.of_node); | ||
377 | |||
378 | law_start = of_read_number(dt_range + aw, paw); | ||
379 | law_size = of_read_number(dt_range + aw + paw, sw); | ||
380 | |||
381 | dev_info(&dev->dev, "LAW start 0x%016llx, size 0x%016llx.\n", | ||
382 | law_start, law_size); | ||
383 | |||
384 | ops = kzalloc(sizeof(struct rio_ops), GFP_KERNEL); | 372 | ops = kzalloc(sizeof(struct rio_ops), GFP_KERNEL); |
385 | if (!ops) { | 373 | if (!ops) { |
386 | rc = -ENOMEM; | 374 | rc = -ENOMEM; |
@@ -390,130 +378,267 @@ int fsl_rio_setup(struct platform_device *dev) | |||
390 | ops->lcwrite = fsl_local_config_write; | 378 | ops->lcwrite = fsl_local_config_write; |
391 | ops->cread = fsl_rio_config_read; | 379 | ops->cread = fsl_rio_config_read; |
392 | ops->cwrite = fsl_rio_config_write; | 380 | ops->cwrite = fsl_rio_config_write; |
381 | ops->dsend = fsl_rio_doorbell_send; | ||
393 | ops->pwenable = fsl_rio_pw_enable; | 382 | ops->pwenable = fsl_rio_pw_enable; |
394 | 383 | ops->open_outb_mbox = fsl_open_outb_mbox; | |
395 | port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); | 384 | ops->open_inb_mbox = fsl_open_inb_mbox; |
396 | if (!port) { | 385 | ops->close_outb_mbox = fsl_close_outb_mbox; |
386 | ops->close_inb_mbox = fsl_close_inb_mbox; | ||
387 | ops->add_outb_message = fsl_add_outb_message; | ||
388 | ops->add_inb_buffer = fsl_add_inb_buffer; | ||
389 | ops->get_inb_message = fsl_get_inb_message; | ||
390 | |||
391 | rmu_node = of_parse_phandle(dev->dev.of_node, "fsl,srio-rmu-handle", 0); | ||
392 | if (!rmu_node) | ||
393 | goto err_rmu; | ||
394 | rc = of_address_to_resource(rmu_node, 0, &rmu_regs); | ||
395 | if (rc) { | ||
396 | dev_err(&dev->dev, "Can't get %s property 'reg'\n", | ||
397 | rmu_node->full_name); | ||
398 | goto err_rmu; | ||
399 | } | ||
400 | rmu_regs_win = ioremap(rmu_regs.start, resource_size(&rmu_regs)); | ||
401 | if (!rmu_regs_win) { | ||
402 | dev_err(&dev->dev, "Unable to map rmu register window\n"); | ||
397 | rc = -ENOMEM; | 403 | rc = -ENOMEM; |
398 | goto err_port; | 404 | goto err_rmu; |
405 | } | ||
406 | for_each_compatible_node(np, NULL, "fsl,srio-msg-unit") { | ||
407 | rmu_np[tmp] = np; | ||
408 | tmp++; | ||
399 | } | 409 | } |
400 | port->index = 0; | ||
401 | 410 | ||
402 | priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL); | 411 | /*set up doobell node*/ |
403 | if (!priv) { | 412 | np = of_find_compatible_node(NULL, NULL, "fsl,srio-dbell-unit"); |
404 | printk(KERN_ERR "Can't alloc memory for 'priv'\n"); | 413 | if (!np) { |
414 | rc = -ENODEV; | ||
415 | goto err_dbell; | ||
416 | } | ||
417 | dbell = kzalloc(sizeof(struct fsl_rio_dbell), GFP_KERNEL); | ||
418 | if (!(dbell)) { | ||
419 | dev_err(&dev->dev, "Can't alloc memory for 'fsl_rio_dbell'\n"); | ||
405 | rc = -ENOMEM; | 420 | rc = -ENOMEM; |
406 | goto err_priv; | 421 | goto err_dbell; |
407 | } | 422 | } |
423 | dbell->dev = &dev->dev; | ||
424 | dbell->bellirq = irq_of_parse_and_map(np, 1); | ||
425 | dev_info(&dev->dev, "bellirq: %d\n", dbell->bellirq); | ||
408 | 426 | ||
409 | INIT_LIST_HEAD(&port->dbells); | 427 | aw = of_n_addr_cells(np); |
410 | port->iores.start = law_start; | 428 | dt_range = of_get_property(np, "reg", &rlen); |
411 | port->iores.end = law_start + law_size - 1; | 429 | if (!dt_range) { |
412 | port->iores.flags = IORESOURCE_MEM; | 430 | pr_err("%s: unable to find 'reg' property\n", |
413 | port->iores.name = "rio_io_win"; | 431 | np->full_name); |
414 | 432 | rc = -ENOMEM; | |
415 | if (request_resource(&iomem_resource, &port->iores) < 0) { | 433 | goto err_pw; |
416 | dev_err(&dev->dev, "RIO: Error requesting master port region" | 434 | } |
417 | " 0x%016llx-0x%016llx\n", | 435 | range_start = of_read_number(dt_range, aw); |
418 | (u64)port->iores.start, (u64)port->iores.end); | 436 | dbell->dbell_regs = (struct rio_dbell_regs *)(rmu_regs_win + |
419 | rc = -ENOMEM; | 437 | (u32)range_start); |
420 | goto err_res; | 438 | |
439 | /*set up port write node*/ | ||
440 | np = of_find_compatible_node(NULL, NULL, "fsl,srio-port-write-unit"); | ||
441 | if (!np) { | ||
442 | rc = -ENODEV; | ||
443 | goto err_pw; | ||
444 | } | ||
445 | pw = kzalloc(sizeof(struct fsl_rio_pw), GFP_KERNEL); | ||
446 | if (!(pw)) { | ||
447 | dev_err(&dev->dev, "Can't alloc memory for 'fsl_rio_pw'\n"); | ||
448 | rc = -ENOMEM; | ||
449 | goto err_pw; | ||
450 | } | ||
451 | pw->dev = &dev->dev; | ||
452 | pw->pwirq = irq_of_parse_and_map(np, 0); | ||
453 | dev_info(&dev->dev, "pwirq: %d\n", pw->pwirq); | ||
454 | aw = of_n_addr_cells(np); | ||
455 | dt_range = of_get_property(np, "reg", &rlen); | ||
456 | if (!dt_range) { | ||
457 | pr_err("%s: unable to find 'reg' property\n", | ||
458 | np->full_name); | ||
459 | rc = -ENOMEM; | ||
460 | goto err; | ||
421 | } | 461 | } |
462 | range_start = of_read_number(dt_range, aw); | ||
463 | pw->pw_regs = (struct rio_pw_regs *)(rmu_regs_win + (u32)range_start); | ||
464 | |||
465 | /*set up ports node*/ | ||
466 | for_each_child_of_node(dev->dev.of_node, np) { | ||
467 | port_index = of_get_property(np, "cell-index", NULL); | ||
468 | if (!port_index) { | ||
469 | dev_err(&dev->dev, "Can't get %s property 'cell-index'\n", | ||
470 | np->full_name); | ||
471 | continue; | ||
472 | } | ||
473 | |||
474 | dt_range = of_get_property(np, "ranges", &rlen); | ||
475 | if (!dt_range) { | ||
476 | dev_err(&dev->dev, "Can't get %s property 'ranges'\n", | ||
477 | np->full_name); | ||
478 | continue; | ||
479 | } | ||
422 | 480 | ||
423 | priv->pwirq = irq_of_parse_and_map(dev->dev.of_node, 0); | 481 | /* Get node address wide */ |
424 | dev_info(&dev->dev, "pwirq: %d\n", priv->pwirq); | 482 | cell = of_get_property(np, "#address-cells", NULL); |
425 | strcpy(port->name, "RIO0 mport"); | 483 | if (cell) |
426 | 484 | aw = *cell; | |
427 | priv->dev = &dev->dev; | 485 | else |
428 | 486 | aw = of_n_addr_cells(np); | |
429 | port->ops = ops; | 487 | /* Get node size wide */ |
430 | port->priv = priv; | 488 | cell = of_get_property(np, "#size-cells", NULL); |
431 | port->phys_efptr = 0x100; | 489 | if (cell) |
432 | 490 | sw = *cell; | |
433 | priv->regs_win = ioremap(regs.start, resource_size(®s)); | 491 | else |
434 | rio_regs_win = priv->regs_win; | 492 | sw = of_n_size_cells(np); |
435 | 493 | /* Get parent address wide wide */ | |
436 | /* Probe the master port phy type */ | 494 | paw = of_n_addr_cells(np); |
437 | ccsr = in_be32(priv->regs_win + RIO_CCSR); | 495 | range_start = of_read_number(dt_range + aw, paw); |
438 | port->phy_type = (ccsr & 1) ? RIO_PHY_SERIAL : RIO_PHY_PARALLEL; | 496 | range_size = of_read_number(dt_range + aw + paw, sw); |
439 | dev_info(&dev->dev, "RapidIO PHY type: %s\n", | 497 | |
440 | (port->phy_type == RIO_PHY_PARALLEL) ? "parallel" : | 498 | dev_info(&dev->dev, "%s: LAW start 0x%016llx, size 0x%016llx.\n", |
441 | ((port->phy_type == RIO_PHY_SERIAL) ? "serial" : | 499 | np->full_name, range_start, range_size); |
442 | "unknown")); | 500 | |
443 | /* Checking the port training status */ | 501 | port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); |
444 | if (in_be32((priv->regs_win + RIO_ESCSR)) & 1) { | 502 | if (!port) |
445 | dev_err(&dev->dev, "Port is not ready. " | 503 | continue; |
446 | "Try to restart connection...\n"); | 504 | |
447 | switch (port->phy_type) { | 505 | i = *port_index - 1; |
448 | case RIO_PHY_SERIAL: | 506 | port->index = (unsigned char)i; |
507 | |||
508 | priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL); | ||
509 | if (!priv) { | ||
510 | dev_err(&dev->dev, "Can't alloc memory for 'priv'\n"); | ||
511 | kfree(port); | ||
512 | continue; | ||
513 | } | ||
514 | |||
515 | INIT_LIST_HEAD(&port->dbells); | ||
516 | port->iores.start = range_start; | ||
517 | port->iores.end = port->iores.start + range_size - 1; | ||
518 | port->iores.flags = IORESOURCE_MEM; | ||
519 | port->iores.name = "rio_io_win"; | ||
520 | |||
521 | if (request_resource(&iomem_resource, &port->iores) < 0) { | ||
522 | dev_err(&dev->dev, "RIO: Error requesting master port region" | ||
523 | " 0x%016llx-0x%016llx\n", | ||
524 | (u64)port->iores.start, (u64)port->iores.end); | ||
525 | kfree(priv); | ||
526 | kfree(port); | ||
527 | continue; | ||
528 | } | ||
529 | sprintf(port->name, "RIO mport %d", i); | ||
530 | |||
531 | priv->dev = &dev->dev; | ||
532 | port->ops = ops; | ||
533 | port->priv = priv; | ||
534 | port->phys_efptr = 0x100; | ||
535 | priv->regs_win = rio_regs_win; | ||
536 | |||
537 | /* Probe the master port phy type */ | ||
538 | ccsr = in_be32(priv->regs_win + RIO_CCSR + i*0x20); | ||
539 | port->phy_type = (ccsr & 1) ? RIO_PHY_SERIAL : RIO_PHY_PARALLEL; | ||
540 | if (port->phy_type == RIO_PHY_PARALLEL) { | ||
541 | dev_err(&dev->dev, "RIO: Parallel PHY type, unsupported port type!\n"); | ||
542 | release_resource(&port->iores); | ||
543 | kfree(priv); | ||
544 | kfree(port); | ||
545 | continue; | ||
546 | } | ||
547 | dev_info(&dev->dev, "RapidIO PHY type: Serial\n"); | ||
548 | /* Checking the port training status */ | ||
549 | if (in_be32((priv->regs_win + RIO_ESCSR + i*0x20)) & 1) { | ||
550 | dev_err(&dev->dev, "Port %d is not ready. " | ||
551 | "Try to restart connection...\n", i); | ||
449 | /* Disable ports */ | 552 | /* Disable ports */ |
450 | out_be32(priv->regs_win + RIO_CCSR, 0); | 553 | out_be32(priv->regs_win |
554 | + RIO_CCSR + i*0x20, 0); | ||
451 | /* Set 1x lane */ | 555 | /* Set 1x lane */ |
452 | setbits32(priv->regs_win + RIO_CCSR, 0x02000000); | 556 | setbits32(priv->regs_win |
557 | + RIO_CCSR + i*0x20, 0x02000000); | ||
453 | /* Enable ports */ | 558 | /* Enable ports */ |
454 | setbits32(priv->regs_win + RIO_CCSR, 0x00600000); | 559 | setbits32(priv->regs_win |
455 | break; | 560 | + RIO_CCSR + i*0x20, 0x00600000); |
456 | case RIO_PHY_PARALLEL: | 561 | msleep(100); |
457 | /* Disable ports */ | 562 | if (in_be32((priv->regs_win |
458 | out_be32(priv->regs_win + RIO_CCSR, 0x22000000); | 563 | + RIO_ESCSR + i*0x20)) & 1) { |
459 | /* Enable ports */ | 564 | dev_err(&dev->dev, |
460 | out_be32(priv->regs_win + RIO_CCSR, 0x44000000); | 565 | "Port %d restart failed.\n", i); |
461 | break; | 566 | release_resource(&port->iores); |
567 | kfree(priv); | ||
568 | kfree(port); | ||
569 | continue; | ||
570 | } | ||
571 | dev_info(&dev->dev, "Port %d restart success!\n", i); | ||
462 | } | 572 | } |
463 | msleep(100); | 573 | fsl_rio_info(&dev->dev, ccsr); |
464 | if (in_be32((priv->regs_win + RIO_ESCSR)) & 1) { | ||
465 | dev_err(&dev->dev, "Port restart failed.\n"); | ||
466 | rc = -ENOLINK; | ||
467 | goto err; | ||
468 | } | ||
469 | dev_info(&dev->dev, "Port restart success!\n"); | ||
470 | } | ||
471 | fsl_rio_info(&dev->dev, ccsr); | ||
472 | 574 | ||
473 | port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR)) | 575 | port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR)) |
474 | & RIO_PEF_CTLS) >> 4; | 576 | & RIO_PEF_CTLS) >> 4; |
475 | dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", | 577 | dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", |
476 | port->sys_size ? 65536 : 256); | 578 | port->sys_size ? 65536 : 256); |
579 | |||
580 | if (rio_register_mport(port)) { | ||
581 | release_resource(&port->iores); | ||
582 | kfree(priv); | ||
583 | kfree(port); | ||
584 | continue; | ||
585 | } | ||
586 | if (port->host_deviceid >= 0) | ||
587 | out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST | | ||
588 | RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED); | ||
589 | else | ||
590 | out_be32(priv->regs_win + RIO_GCCSR, | ||
591 | RIO_PORT_GEN_MASTER); | ||
477 | 592 | ||
478 | if (rio_register_mport(port)) | 593 | priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win |
479 | goto err; | 594 | + ((i == 0) ? RIO_ATMU_REGS_PORT1_OFFSET : |
595 | RIO_ATMU_REGS_PORT2_OFFSET)); | ||
596 | |||
597 | priv->maint_atmu_regs = priv->atmu_regs + 1; | ||
480 | 598 | ||
481 | if (port->host_deviceid >= 0) | 599 | /* Set to receive any dist ID for serial RapidIO controller. */ |
482 | out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST | | 600 | if (port->phy_type == RIO_PHY_SERIAL) |
483 | RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED); | 601 | out_be32((priv->regs_win |
484 | else | 602 | + RIO_ISR_AACR + i*0x80), RIO_ISR_AACR_AA); |
485 | out_be32(priv->regs_win + RIO_GCCSR, 0x00000000); | ||
486 | 603 | ||
487 | priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win | 604 | /* Configure maintenance transaction window */ |
488 | + RIO_ATMU_REGS_OFFSET); | 605 | out_be32(&priv->maint_atmu_regs->rowbar, |
489 | priv->maint_atmu_regs = priv->atmu_regs + 1; | 606 | port->iores.start >> 12); |
607 | out_be32(&priv->maint_atmu_regs->rowar, | ||
608 | 0x80077000 | (ilog2(RIO_MAINT_WIN_SIZE) - 1)); | ||
490 | 609 | ||
491 | /* Set to receive any dist ID for serial RapidIO controller. */ | 610 | priv->maint_win = ioremap(port->iores.start, |
492 | if (port->phy_type == RIO_PHY_SERIAL) | 611 | RIO_MAINT_WIN_SIZE); |
493 | out_be32((priv->regs_win + RIO_ISR_AACR), RIO_ISR_AACR_AA); | ||
494 | 612 | ||
495 | /* Configure maintenance transaction window */ | 613 | rio_law_start = range_start; |
496 | out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12); | ||
497 | out_be32(&priv->maint_atmu_regs->rowar, | ||
498 | 0x80077000 | (ilog2(RIO_MAINT_WIN_SIZE) - 1)); | ||
499 | 614 | ||
500 | priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE); | 615 | fsl_rio_setup_rmu(port, rmu_np[i]); |
501 | 616 | ||
502 | fsl_rio_setup_rmu(port, dev->dev.of_node); | 617 | dbell->mport[i] = port; |
618 | |||
619 | active_ports++; | ||
620 | } | ||
621 | |||
622 | if (!active_ports) { | ||
623 | rc = -ENOLINK; | ||
624 | goto err; | ||
625 | } | ||
503 | 626 | ||
504 | fsl_rio_port_write_init(port); | 627 | fsl_rio_doorbell_init(dbell); |
628 | fsl_rio_port_write_init(pw); | ||
505 | 629 | ||
506 | return 0; | 630 | return 0; |
507 | err: | 631 | err: |
508 | iounmap(priv->regs_win); | 632 | kfree(pw); |
509 | release_resource(&port->iores); | 633 | err_pw: |
510 | err_res: | 634 | kfree(dbell); |
511 | kfree(priv); | 635 | err_dbell: |
512 | err_priv: | 636 | iounmap(rmu_regs_win); |
513 | kfree(port); | 637 | err_rmu: |
514 | err_port: | ||
515 | kfree(ops); | 638 | kfree(ops); |
516 | err_ops: | 639 | err_ops: |
640 | iounmap(rio_regs_win); | ||
641 | err_rio_regs: | ||
517 | return rc; | 642 | return rc; |
518 | } | 643 | } |
519 | 644 | ||
@@ -529,7 +654,7 @@ static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev) | |||
529 | 654 | ||
530 | static const struct of_device_id fsl_of_rio_rpn_ids[] = { | 655 | static const struct of_device_id fsl_of_rio_rpn_ids[] = { |
531 | { | 656 | { |
532 | .compatible = "fsl,rapidio-delta", | 657 | .compatible = "fsl,srio", |
533 | }, | 658 | }, |
534 | {}, | 659 | {}, |
535 | }; | 660 | }; |