Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.17-rc1 114 lines 3.0 kB view raw
1/* 2 * DaVinci DA850 AHCI SATA platform driver 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2, or (at your option) 7 * any later version. 8 */ 9 10#include <linux/kernel.h> 11#include <linux/module.h> 12#include <linux/pm.h> 13#include <linux/device.h> 14#include <linux/platform_device.h> 15#include <linux/libata.h> 16#include <linux/ahci_platform.h> 17#include "ahci.h" 18 19/* SATA PHY Control Register offset from AHCI base */ 20#define SATA_P0PHYCR_REG 0x178 21 22#define SATA_PHY_MPY(x) ((x) << 0) 23#define SATA_PHY_LOS(x) ((x) << 6) 24#define SATA_PHY_RXCDR(x) ((x) << 10) 25#define SATA_PHY_RXEQ(x) ((x) << 13) 26#define SATA_PHY_TXSWING(x) ((x) << 19) 27#define SATA_PHY_ENPLL(x) ((x) << 31) 28 29/* 30 * The multiplier needed for 1.5GHz PLL output. 31 * 32 * NOTE: This is currently hardcoded to be suitable for 100MHz crystal 33 * frequency (which is used by DA850 EVM board) and may need to be changed 34 * if you would like to use this driver on some other board. 35 */ 36#define DA850_SATA_CLK_MULTIPLIER 7 37 38static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg, 39 void __iomem *ahci_base) 40{ 41 unsigned int val; 42 43 /* Enable SATA clock receiver */ 44 val = readl(pwrdn_reg); 45 val &= ~BIT(0); 46 writel(val, pwrdn_reg); 47 48 val = SATA_PHY_MPY(DA850_SATA_CLK_MULTIPLIER + 1) | SATA_PHY_LOS(1) | 49 SATA_PHY_RXCDR(4) | SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) | 50 SATA_PHY_ENPLL(1); 51 52 writel(val, ahci_base + SATA_P0PHYCR_REG); 53} 54 55static const struct ata_port_info ahci_da850_port_info = { 56 .flags = AHCI_FLAG_COMMON, 57 .pio_mask = ATA_PIO4, 58 .udma_mask = ATA_UDMA6, 59 .port_ops = &ahci_platform_ops, 60}; 61 62static int ahci_da850_probe(struct platform_device *pdev) 63{ 64 struct device *dev = &pdev->dev; 65 struct ahci_host_priv *hpriv; 66 struct resource *res; 67 void __iomem *pwrdn_reg; 68 int rc; 69 70 hpriv = ahci_platform_get_resources(pdev); 71 if (IS_ERR(hpriv)) 72 return PTR_ERR(hpriv); 73 74 rc = ahci_platform_enable_resources(hpriv); 75 if (rc) 76 return rc; 77 78 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 79 if (!res) 80 goto disable_resources; 81 82 pwrdn_reg = devm_ioremap(dev, res->start, resource_size(res)); 83 if (!pwrdn_reg) 84 goto disable_resources; 85 86 da850_sata_init(dev, pwrdn_reg, hpriv->mmio); 87 88 rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info); 89 if (rc) 90 goto disable_resources; 91 92 return 0; 93disable_resources: 94 ahci_platform_disable_resources(hpriv); 95 return rc; 96} 97 98static SIMPLE_DEV_PM_OPS(ahci_da850_pm_ops, ahci_platform_suspend, 99 ahci_platform_resume); 100 101static struct platform_driver ahci_da850_driver = { 102 .probe = ahci_da850_probe, 103 .remove = ata_platform_remove_one, 104 .driver = { 105 .name = "ahci_da850", 106 .owner = THIS_MODULE, 107 .pm = &ahci_da850_pm_ops, 108 }, 109}; 110module_platform_driver(ahci_da850_driver); 111 112MODULE_DESCRIPTION("DaVinci DA850 AHCI SATA platform driver"); 113MODULE_AUTHOR("Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>"); 114MODULE_LICENSE("GPL");