Print this page
1023 nv_sata support for NVIDIA MCP61

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/sata/adapters/nv_sata/nv_sata.c
          +++ new/usr/src/uts/common/io/sata/adapters/nv_sata/nv_sata.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24   25   */
  25   26  
  26   27  /*
  27   28   *
  28      - * nv_sata is a combo SATA HBA driver for ck804/mcp5x (mcp5x = mcp55/mcp51)
  29      - * based chipsets.
       29 + * nv_sata is a combo SATA HBA driver for CK804/MCP04 (ck804) and
       30 + * MCP55/MCP51/MCP61 (mcp5x) based chipsets.
  30   31   *
  31   32   * NCQ
  32   33   * ---
  33   34   *
  34   35   * A portion of the NCQ is in place, but is incomplete.  NCQ is disabled
  35   36   * and is likely to be revisited in the future.
  36   37   *
  37   38   *
  38   39   * Power Management
  39   40   * ----------------
↓ open down ↓ 265 lines elided ↑ open up ↑
 305  306          0, 0, 0, 0, 0, 0, 0, 0, 0, 0    /* pad out to max CDB length */
 306  307  };
 307  308  
 308  309  
 309  310  static sata_tran_hotplug_ops_t nv_hotplug_ops;
 310  311  
 311  312  extern struct mod_ops mod_driverops;
 312  313  
 313  314  static  struct modldrv modldrv = {
 314  315          &mod_driverops, /* driverops */
 315      -        "Nvidia ck804/mcp51/mcp55 HBA",
      316 +        "NVIDIA CK804/MCP04/MCP51/MCP55/MCP61 HBA",
 316  317          &nv_dev_ops,    /* driver ops */
 317  318  };
 318  319  
 319  320  static  struct modlinkage modlinkage = {
 320  321          MODREV_1,
 321  322          &modldrv,
 322  323          NULL
 323  324  };
 324  325  
 325  326  /*
↓ open down ↓ 266 lines elided ↑ open up ↑
 592  593  
 593  594                  nvc = ddi_get_soft_state(nv_statep, inst);
 594  595  
 595  596                  nvc->nvc_dip = dip;
 596  597  
 597  598                  NVLOG(NVDBG_INIT, nvc, NULL, "nv_attach(): DDI_ATTACH", NULL);
 598  599  
 599  600                  attach_state |= ATTACH_PROGRESS_STATEP_ALLOC;
 600  601  
 601  602                  if (pci_config_setup(dip, &pci_conf_handle) == DDI_SUCCESS) {
      603 +                        nvc->nvc_devid = pci_config_get16(pci_conf_handle,
      604 +                            PCI_CONF_DEVID);
 602  605                          nvc->nvc_revid = pci_config_get8(pci_conf_handle,
 603  606                              PCI_CONF_REVID);
 604  607                          NVLOG(NVDBG_INIT, nvc, NULL,
 605      -                            "inst %d: silicon revid is %x nv_debug_flags=%x",
 606      -                            inst, nvc->nvc_revid, nv_debug_flags);
      608 +                            "inst %d: devid is %x silicon revid is %x"
      609 +                            " nv_debug_flags=%x", inst, nvc->nvc_devid,
      610 +                            nvc->nvc_revid, nv_debug_flags);
 607  611                  } else {
 608  612                          break;
 609  613                  }
 610  614  
 611  615                  attach_state |= ATTACH_PROGRESS_CONF_HANDLE;
 612  616  
 613  617                  /*
 614  618                   * Set the PCI command register: enable IO/MEM/Master.
 615  619                   */
 616  620                  command = pci_config_get16(pci_conf_handle, PCI_CONF_COMM);
↓ open down ↓ 1870 lines elided ↑ open up ↑
2487 2491                      " after %dms. serr: 0x%x", TICK_TO_MSEC(ddi_get_lbolt() -
2488 2492                      nvp->nvp_reset_time), serr);
2489 2493          }
2490 2494  
2491 2495          nvp->nvp_wait_sig  = NV_WAIT_SIG;
2492 2496          nv_setup_timeout(nvp, nvp->nvp_wait_sig);
2493 2497  }
2494 2498  
2495 2499  
2496 2500  /*
2497      - * Initialize register handling specific to mcp51/mcp55
     2501 + * Initialize register handling specific to mcp51/mcp55/mcp61
2498 2502   */
2499 2503  /* ARGSUSED */
2500 2504  static void
2501 2505  mcp5x_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2502 2506  {
2503 2507          nv_port_t *nvp;
2504 2508          uchar_t *bar5  = nvc->nvc_bar_addr[5];
2505 2509          uint8_t off, port;
2506 2510  
2507 2511          nvc->nvc_mcp5x_ctl = (uint32_t *)(bar5 + MCP5X_CTL);
↓ open down ↓ 34 lines elided ↑ open up ↑
2542 2546          nv_put32(nvc->nvc_bar_hdl[5], nvc->nvc_mcp5x_ncq, flags);
2543 2547          flags = MCP_SATA_AE_CTL_PRI_SWNCQ | MCP_SATA_AE_CTL_SEC_SWNCQ;
2544 2548          nv_put32(nvc->nvc_bar_hdl[5], nvc->nvc_mcp5x_ctl, flags);
2545 2549  #endif
2546 2550  
2547 2551          /*
2548 2552           * mcp55 rev A03 and above supports 40-bit physical addressing.
2549 2553           * Enable DMA to take advantage of that.
2550 2554           *
2551 2555           */
2552      -        if (nvc->nvc_revid >= 0xa3) {
     2556 +        if ((nvc->nvc_devid > 0x37f) ||
     2557 +            ((nvc->nvc_devid == 0x37f) && (nvc->nvc_revid >= 0xa3))) {
2553 2558                  if (nv_sata_40bit_dma == B_TRUE) {
2554 2559                          uint32_t reg32;
2555 2560                          NVLOG(NVDBG_INIT, nvp->nvp_ctlp, nvp,
2556      -                            "rev id is %X.  40-bit DMA addressing"
2557      -                            " enabled", nvc->nvc_revid);
     2561 +                            "devid is %X revid is %X. 40-bit DMA"
     2562 +                            " addressing enabled", nvc->nvc_devid,
     2563 +                            nvc->nvc_revid);
2558 2564                          nvc->dma_40bit = B_TRUE;
2559 2565  
2560 2566                          reg32 = pci_config_get32(pci_conf_handle,
2561 2567                              NV_SATA_CFG_20);
2562 2568                          pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,
2563 2569                              reg32 | NV_40BIT_PRD);
2564 2570  
2565 2571                          /*
2566 2572                           * CFG_23 bits 0-7 contain the top 8 bits (of 40
2567 2573                           * bits) for the primary PRD table, and bits 8-15
↓ open down ↓ 4 lines elided ↑ open up ↑
2572 2578                           */
2573 2579                          reg32 = pci_config_get32(pci_conf_handle,
2574 2580                              NV_SATA_CFG_23);
2575 2581                          pci_config_put32(pci_conf_handle, NV_SATA_CFG_23,
2576 2582                              reg32 & 0xffff0000);
2577 2583                  } else {
2578 2584                          NVLOG(NVDBG_INIT, nvp->nvp_ctlp, nvp,
2579 2585                              "40-bit DMA disabled by nv_sata_40bit_dma", NULL);
2580 2586                  }
2581 2587          } else {
2582      -                nv_cmn_err(CE_NOTE, nvp->nvp_ctlp, nvp, "rev id is %X and is "
2583      -                    "not capable of 40-bit DMA addressing", nvc->nvc_revid);
     2588 +                nv_cmn_err(CE_NOTE, nvp->nvp_ctlp, nvp, "devid is %X revid is"
     2589 +                    " %X. Not capable of 40-bit DMA addressing",
     2590 +                    nvc->nvc_devid, nvc->nvc_revid);
2584 2591          }
2585 2592  }
2586 2593  
2587 2594  
2588 2595  /*
2589 2596   * Initialize register handling specific to ck804
2590 2597   */
2591 2598  static void
2592 2599  ck804_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2593 2600  {
↓ open down ↓ 41 lines elided ↑ open up ↑
2635 2642  
2636 2643  /*
2637 2644   * Initialize the controller and set up driver data structures.
2638 2645   * determine if ck804 or mcp5x class.
2639 2646   */
2640 2647  static int
2641 2648  nv_init_ctl(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2642 2649  {
2643 2650          struct sata_hba_tran stran;
2644 2651          nv_port_t *nvp;
2645      -        int j, ck804;
     2652 +        int j;
2646 2653          uchar_t *cmd_addr, *ctl_addr, *bm_addr;
2647 2654          ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
2648 2655          uchar_t *bar5  = nvc->nvc_bar_addr[5];
2649 2656          uint32_t reg32;
2650 2657          uint8_t reg8, reg8_save;
2651 2658  
2652 2659          NVLOG(NVDBG_INIT, nvc, NULL, "nv_init_ctl entered", NULL);
2653 2660  
2654      -        ck804 = B_TRUE;
2655      -#ifdef SGPIO_SUPPORT
2656 2661          nvc->nvc_mcp5x_flag = B_FALSE;
2657      -#endif
2658 2662  
2659 2663          /*
2660 2664           * Need to set bit 2 to 1 at config offset 0x50
2661 2665           * to enable access to the bar5 registers.
2662 2666           */
2663 2667          reg32 = pci_config_get32(pci_conf_handle, NV_SATA_CFG_20);
2664 2668          if (!(reg32 & NV_BAR5_SPACE_EN)) {
2665 2669                  pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,
2666 2670                      reg32 | NV_BAR5_SPACE_EN);
2667 2671          }
↓ open down ↓ 10 lines elided ↑ open up ↑
2678 2682              (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X));
2679 2683  
2680 2684  
2681 2685          for (j = 1; j < 3; j++) {
2682 2686  
2683 2687                  nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), j);
2684 2688                  reg8 = nv_get8(bar5_hdl,
2685 2689                      (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X));
2686 2690  
2687 2691                  if (reg8 != j) {
2688      -                        ck804 = B_FALSE;
2689 2692                          nvc->nvc_mcp5x_flag = B_TRUE;
2690 2693                          break;
2691 2694                  }
2692 2695          }
2693 2696  
2694 2697          nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), reg8_save);
2695 2698  
2696      -        if (ck804 == B_TRUE) {
2697      -                NVLOG(NVDBG_INIT, nvc, NULL, "controller is CK804", NULL);
     2699 +        if (nvc->nvc_mcp5x_flag == B_FALSE) {
     2700 +                NVLOG(NVDBG_INIT, nvc, NULL, "controller is CK804/MCP04",
     2701 +                    NULL);
2698 2702                  nvc->nvc_interrupt = ck804_intr;
2699 2703                  nvc->nvc_reg_init = ck804_reg_init;
2700 2704                  nvc->nvc_set_intr = ck804_set_intr;
2701 2705          } else {
2702      -                NVLOG(NVDBG_INIT, nvc, NULL, "controller is MCP51/MCP55", NULL);
     2706 +                NVLOG(NVDBG_INIT, nvc, NULL, "controller is MCP51/MCP55/MCP61",
     2707 +                    NULL);
2703 2708                  nvc->nvc_interrupt = mcp5x_intr;
2704 2709                  nvc->nvc_reg_init = mcp5x_reg_init;
2705 2710                  nvc->nvc_set_intr = mcp5x_set_intr;
2706 2711          }
2707 2712  
2708 2713  
2709 2714          stran.sata_tran_hba_rev = SATA_TRAN_HBA_REV;
2710 2715          stran.sata_tran_hba_dip = nvc->nvc_dip;
2711 2716          stran.sata_tran_hba_num_cports = NV_NUM_PORTS;
2712 2717          stran.sata_tran_hba_features_support =
↓ open down ↓ 4453 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX