linux/drivers/ata/ahci_da850.c
<<
>>
Prefs
   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                .pm = &ahci_da850_pm_ops,
 107        },
 108};
 109module_platform_driver(ahci_da850_driver);
 110
 111MODULE_DESCRIPTION("DaVinci DA850 AHCI SATA platform driver");
 112MODULE_AUTHOR("Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>");
 113MODULE_LICENSE("GPL");
 114
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.