From 4c3979602db05bca439bfc98db88dc14a8663db0 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Wed, 17 Jan 2018 15:14:57 +0800 Subject: [PATCH 13/30] ata: support layerscape This is an integrated patch for layerscape sata support. Signed-off-by: Tang Yuantian Signed-off-by: Yangbo Lu --- drivers/ata/ahci_qoriq.c | 63 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 7 deletions(-) --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -1,7 +1,7 @@ /* * Freescale QorIQ AHCI SATA platform driver * - * Copyright 2015 Freescale, Inc. + * Copyright (C) 2015 Freescale Semiconductor, Inc. * Tang Yuantian * * This program is free software; you can redistribute it and/or modify @@ -46,23 +46,32 @@ #define LS1021A_AXICC_ADDR 0xC0 #define SATA_ECC_DISABLE 0x00020000 +#define ECC_DIS_ARMV8_CH2 0x80000000 +#define ECC_DIS_LS1088A 0x40000000 enum ahci_qoriq_type { AHCI_LS1021A, AHCI_LS1043A, AHCI_LS2080A, + AHCI_LS1046A, + AHCI_LS1088A, + AHCI_LS2088A, }; struct ahci_qoriq_priv { struct ccsr_ahci *reg_base; enum ahci_qoriq_type type; void __iomem *ecc_addr; + bool is_dmacoherent; }; static const struct of_device_id ahci_qoriq_of_match[] = { { .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A}, { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A}, { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A}, + { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A}, + { .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A}, + { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A}, {}, }; MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match); @@ -154,6 +163,8 @@ static int ahci_qoriq_phy_init(struct ah switch (qpriv->type) { case AHCI_LS1021A: + if (!qpriv->ecc_addr) + return -EINVAL; writel(SATA_ECC_DISABLE, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2); @@ -161,19 +172,56 @@ static int ahci_qoriq_phy_init(struct ah writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4); writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, + reg_base + LS1021A_AXICC_ADDR); break; case AHCI_LS1043A: + if (!qpriv->ecc_addr) + return -EINVAL; + writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, + qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; case AHCI_LS2080A: writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + break; + + case AHCI_LS1046A: + if (!qpriv->ecc_addr) + return -EINVAL; + writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, + qpriv->ecc_addr); + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + break; + + case AHCI_LS1088A: + if (!qpriv->ecc_addr) + return -EINVAL; + writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A, + qpriv->ecc_addr); + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + break; + + case AHCI_LS2088A: + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; } @@ -204,13 +252,14 @@ static int ahci_qoriq_probe(struct platf qoriq_priv->type = (enum ahci_qoriq_type)of_id->data; - if (qoriq_priv->type == AHCI_LS1021A) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "sata-ecc"); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "sata-ecc"); + if (res) { qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res); if (IS_ERR(qoriq_priv->ecc_addr)) return PTR_ERR(qoriq_priv->ecc_addr); } + qoriq_priv->is_dmacoherent = of_dma_is_coherent(np); rc = ahci_platform_enable_resources(hpriv); if (rc)