801-ata-support-layerscape.patch 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. From 505eb62bdb7a4cc25b13491dd5c68d0741c5d6da Mon Sep 17 00:00:00 2001
  2. From: Yangbo Lu <[email protected]>
  3. Date: Mon, 25 Sep 2017 12:21:13 +0800
  4. Subject: [PATCH] ata: support layerscape
  5. This is a integrated patch for layerscape sata support.
  6. Signed-off-by: Tang Yuantian <[email protected]>
  7. Signed-off-by: Yangbo Lu <[email protected]>
  8. ---
  9. drivers/ata/ahci_qoriq.c | 63 ++++++++++++++++++++++++++++++++++++++++++------
  10. 1 file changed, 56 insertions(+), 7 deletions(-)
  11. --- a/drivers/ata/ahci_qoriq.c
  12. +++ b/drivers/ata/ahci_qoriq.c
  13. @@ -1,7 +1,7 @@
  14. /*
  15. * Freescale QorIQ AHCI SATA platform driver
  16. *
  17. - * Copyright 2015 Freescale, Inc.
  18. + * Copyright (C) 2015 Freescale Semiconductor, Inc.
  19. * Tang Yuantian <[email protected]>
  20. *
  21. * This program is free software; you can redistribute it and/or modify
  22. @@ -46,23 +46,32 @@
  23. #define LS1021A_AXICC_ADDR 0xC0
  24. #define SATA_ECC_DISABLE 0x00020000
  25. +#define ECC_DIS_ARMV8_CH2 0x80000000
  26. +#define ECC_DIS_LS1088A 0x40000000
  27. enum ahci_qoriq_type {
  28. AHCI_LS1021A,
  29. AHCI_LS1043A,
  30. AHCI_LS2080A,
  31. + AHCI_LS1046A,
  32. + AHCI_LS1088A,
  33. + AHCI_LS2088A,
  34. };
  35. struct ahci_qoriq_priv {
  36. struct ccsr_ahci *reg_base;
  37. enum ahci_qoriq_type type;
  38. void __iomem *ecc_addr;
  39. + bool is_dmacoherent;
  40. };
  41. static const struct of_device_id ahci_qoriq_of_match[] = {
  42. { .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A},
  43. { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
  44. { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
  45. + { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
  46. + { .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
  47. + { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
  48. {},
  49. };
  50. MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
  51. @@ -154,6 +163,8 @@ static int ahci_qoriq_phy_init(struct ah
  52. switch (qpriv->type) {
  53. case AHCI_LS1021A:
  54. + if (!qpriv->ecc_addr)
  55. + return -EINVAL;
  56. writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
  57. writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
  58. writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2);
  59. @@ -161,19 +172,56 @@ static int ahci_qoriq_phy_init(struct ah
  60. writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
  61. writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
  62. writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
  63. - writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR);
  64. + if (qpriv->is_dmacoherent)
  65. + writel(AHCI_PORT_AXICC_CFG,
  66. + reg_base + LS1021A_AXICC_ADDR);
  67. break;
  68. case AHCI_LS1043A:
  69. + if (!qpriv->ecc_addr)
  70. + return -EINVAL;
  71. + writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
  72. + qpriv->ecc_addr);
  73. writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
  74. writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
  75. - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
  76. + if (qpriv->is_dmacoherent)
  77. + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
  78. break;
  79. case AHCI_LS2080A:
  80. writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
  81. writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
  82. - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
  83. + if (qpriv->is_dmacoherent)
  84. + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
  85. + break;
  86. +
  87. + case AHCI_LS1046A:
  88. + if (!qpriv->ecc_addr)
  89. + return -EINVAL;
  90. + writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
  91. + qpriv->ecc_addr);
  92. + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
  93. + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
  94. + if (qpriv->is_dmacoherent)
  95. + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
  96. + break;
  97. +
  98. + case AHCI_LS1088A:
  99. + if (!qpriv->ecc_addr)
  100. + return -EINVAL;
  101. + writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A,
  102. + qpriv->ecc_addr);
  103. + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
  104. + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
  105. + if (qpriv->is_dmacoherent)
  106. + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
  107. + break;
  108. +
  109. + case AHCI_LS2088A:
  110. + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
  111. + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
  112. + if (qpriv->is_dmacoherent)
  113. + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
  114. break;
  115. }
  116. @@ -204,13 +252,14 @@ static int ahci_qoriq_probe(struct platf
  117. qoriq_priv->type = (enum ahci_qoriq_type)of_id->data;
  118. - if (qoriq_priv->type == AHCI_LS1021A) {
  119. - res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  120. - "sata-ecc");
  121. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  122. + "sata-ecc");
  123. + if (res) {
  124. qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res);
  125. if (IS_ERR(qoriq_priv->ecc_addr))
  126. return PTR_ERR(qoriq_priv->ecc_addr);
  127. }
  128. + qoriq_priv->is_dmacoherent = of_dma_is_coherent(np);
  129. rc = ahci_platform_enable_resources(hpriv);
  130. if (rc)