162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * SATA glue for Cavium Octeon III SOCs.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
662306a36Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
762306a36Sopenharmony_ci * for more details.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Copyright (C) 2010-2015 Cavium Networks
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/module.h>
1462306a36Sopenharmony_ci#include <linux/dma-mapping.h>
1562306a36Sopenharmony_ci#include <linux/platform_device.h>
1662306a36Sopenharmony_ci#include <linux/of_platform.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include <asm/octeon/octeon.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define CVMX_SATA_UCTL_SHIM_CFG		0xE8
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define SATA_UCTL_ENDIAN_MODE_BIG	1
2362306a36Sopenharmony_ci#define SATA_UCTL_ENDIAN_MODE_LITTLE	0
2462306a36Sopenharmony_ci#define SATA_UCTL_ENDIAN_MODE_MASK	3
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define SATA_UCTL_DMA_ENDIAN_MODE_SHIFT	8
2762306a36Sopenharmony_ci#define SATA_UCTL_CSR_ENDIAN_MODE_SHIFT	0
2862306a36Sopenharmony_ci#define SATA_UCTL_DMA_READ_CMD_SHIFT	12
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistatic int ahci_octeon_probe(struct platform_device *pdev)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
3362306a36Sopenharmony_ci	struct device_node *node = dev->of_node;
3462306a36Sopenharmony_ci	void __iomem *base;
3562306a36Sopenharmony_ci	u64 cfg;
3662306a36Sopenharmony_ci	int ret;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	base = devm_platform_ioremap_resource(pdev, 0);
3962306a36Sopenharmony_ci	if (IS_ERR(base))
4062306a36Sopenharmony_ci		return PTR_ERR(base);
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	cfg = cvmx_readq_csr(base + CVMX_SATA_UCTL_SHIM_CFG);
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	cfg &= ~(SATA_UCTL_ENDIAN_MODE_MASK << SATA_UCTL_DMA_ENDIAN_MODE_SHIFT);
4562306a36Sopenharmony_ci	cfg &= ~(SATA_UCTL_ENDIAN_MODE_MASK << SATA_UCTL_CSR_ENDIAN_MODE_SHIFT);
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#ifdef __BIG_ENDIAN
4862306a36Sopenharmony_ci	cfg |= SATA_UCTL_ENDIAN_MODE_BIG << SATA_UCTL_DMA_ENDIAN_MODE_SHIFT;
4962306a36Sopenharmony_ci	cfg |= SATA_UCTL_ENDIAN_MODE_BIG << SATA_UCTL_CSR_ENDIAN_MODE_SHIFT;
5062306a36Sopenharmony_ci#else
5162306a36Sopenharmony_ci	cfg |= SATA_UCTL_ENDIAN_MODE_LITTLE << SATA_UCTL_DMA_ENDIAN_MODE_SHIFT;
5262306a36Sopenharmony_ci	cfg |= SATA_UCTL_ENDIAN_MODE_LITTLE << SATA_UCTL_CSR_ENDIAN_MODE_SHIFT;
5362306a36Sopenharmony_ci#endif
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	cfg |= 1 << SATA_UCTL_DMA_READ_CMD_SHIFT;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	cvmx_writeq_csr(base + CVMX_SATA_UCTL_SHIM_CFG, cfg);
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	if (!node) {
6062306a36Sopenharmony_ci		dev_err(dev, "no device node, failed to add octeon sata\n");
6162306a36Sopenharmony_ci		return -ENODEV;
6262306a36Sopenharmony_ci	}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	ret = of_platform_populate(node, NULL, NULL, dev);
6562306a36Sopenharmony_ci	if (ret) {
6662306a36Sopenharmony_ci		dev_err(dev, "failed to add ahci-platform core\n");
6762306a36Sopenharmony_ci		return ret;
6862306a36Sopenharmony_ci	}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	return 0;
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistatic const struct of_device_id octeon_ahci_match[] = {
7462306a36Sopenharmony_ci	{ .compatible = "cavium,octeon-7130-sata-uctl", },
7562306a36Sopenharmony_ci	{ /* sentinel */ }
7662306a36Sopenharmony_ci};
7762306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, octeon_ahci_match);
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistatic struct platform_driver ahci_octeon_driver = {
8062306a36Sopenharmony_ci	.probe          = ahci_octeon_probe,
8162306a36Sopenharmony_ci	.driver         = {
8262306a36Sopenharmony_ci		.name   = "octeon-ahci",
8362306a36Sopenharmony_ci		.of_match_table = octeon_ahci_match,
8462306a36Sopenharmony_ci	},
8562306a36Sopenharmony_ci};
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cimodule_platform_driver(ahci_octeon_driver);
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ciMODULE_LICENSE("GPL");
9062306a36Sopenharmony_ciMODULE_AUTHOR("Cavium, Inc. <support@cavium.com>");
9162306a36Sopenharmony_ciMODULE_DESCRIPTION("Cavium Inc. sata config.");
92