scsi: hisi_sas: Add v2 hw support for different refclk
authorJohn Garry <john.garry@huawei.com>
Tue, 4 Oct 2016 11:11:11 +0000 (19:11 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 8 Nov 2016 22:29:46 +0000 (17:29 -0500)
The hip06 D03 and hip07 D05 boards have different reference clock
frequencies for the SAS controller.

Register PHY_CTRL needs to be programmed differently according to this
frequency, so add support for this.

The default register setting in PHY_CTRL is for 50MHz, so only update
this register when the refclk frequency is 66MHz.

For ACPI we expect the _RST handler to set the correct value for
PHY_CTRL (we're forced to take different approach for DT and ACPI as
ACPI does not support fixed-clock device).

Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hisi_sas/hisi_sas.h
drivers/scsi/hisi_sas/hisi_sas_main.c
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c

index 72c98522bd260eda9439d7a5c7cbb400f643b289..64046c5853a5c6412eb81391bc7db531b308e079 100644 (file)
@@ -13,6 +13,7 @@
 #define _HISI_SAS_H_
 
 #include <linux/acpi.h>
+#include <linux/clk.h>
 #include <linux/dmapool.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
@@ -183,6 +184,7 @@ struct hisi_hba {
        u32 ctrl_reset_reg;
        u32 ctrl_reset_sts_reg;
        u32 ctrl_clock_ena_reg;
+       u32 refclk_frequency_mhz;
        u8 sas_addr[SAS_ADDR_SIZE];
 
        int n_phy;
index 2f872f784e109e85b0e32af473f4920274aa953b..9afc6978cb776e72f39cb820d4d5ecad2f334658 100644 (file)
@@ -1396,6 +1396,7 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
        struct hisi_hba *hisi_hba;
        struct device *dev = &pdev->dev;
        struct device_node *np = pdev->dev.of_node;
+       struct clk *refclk;
 
        shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba));
        if (!shost)
@@ -1432,6 +1433,12 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
                        goto err_out;
        }
 
+       refclk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(refclk))
+               dev_info(dev, "no ref clk property\n");
+       else
+               hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) / 1000000;
+
        if (device_property_read_u32(dev, "phy-count", &hisi_hba->n_phy))
                goto err_out;
 
index 758e06f14d4a26343faa3f7201e45145e29c60c0..0763b4764ad52426b045955447b146a6cdde4896 100644 (file)
@@ -836,7 +836,9 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
                hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0);
                hisi_sas_phy_write32(hisi_hba, i, CHL_INT_COAL_EN, 0x0);
                hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x0);
-               hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL, 0x199B694);
+               if (hisi_hba->refclk_frequency_mhz == 66)
+                       hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL, 0x199B694);
+               /* else, do nothing -> leave it how you found it */
        }
 
        for (i = 0; i < hisi_hba->queue_count; i++) {