linux/drivers/ata/ahci_tegra.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * drivers/ata/ahci_tegra.c
 *
 * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
 *
 * Author:
 *	Mikko Perttunen <[email protected]>
 */

#include <linux/ahci_platform.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>

#include <soc/tegra/fuse.h>
#include <soc/tegra/pmc.h>

#include "ahci.h"

#define DRV_NAME

#define SATA_CONFIGURATION_0
#define SATA_CONFIGURATION_0_EN_FPCI
#define SATA_CONFIGURATION_0_CLK_OVERRIDE

#define SCFG_OFFSET

#define T_SATA0_CFG_1
#define T_SATA0_CFG_1_IO_SPACE
#define T_SATA0_CFG_1_MEMORY_SPACE
#define T_SATA0_CFG_1_BUS_MASTER
#define T_SATA0_CFG_1_SERR

#define T_SATA0_CFG_9
#define T_SATA0_CFG_9_BASE_ADDRESS

#define SATA_FPCI_BAR5
#define SATA_FPCI_BAR5_START_MASK
#define SATA_FPCI_BAR5_START
#define SATA_FPCI_BAR5_ACCESS_TYPE

#define SATA_INTR_MASK
#define SATA_INTR_MASK_IP_INT_MASK

#define T_SATA0_CFG_35
#define T_SATA0_CFG_35_IDP_INDEX_MASK
#define T_SATA0_CFG_35_IDP_INDEX

#define T_SATA0_AHCI_IDP1
#define T_SATA0_AHCI_IDP1_DATA

#define T_SATA0_CFG_PHY_1
#define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN
#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN

#define T_SATA0_NVOOB
#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK
#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE
#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK
#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH

#define T_SATA_CFG_PHY_0
#define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD
#define T_SATA_CFG_PHY_0_MASK_SQUELCH

#define T_SATA0_CFG2NVOOB_2
#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK
#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW

#define T_SATA0_AHCI_HBA_CAP_BKDR
#define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP
#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP
#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP
#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM
#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ

#define T_SATA0_BKDOOR_CC
#define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK
#define T_SATA0_BKDOOR_CC_CLASS_CODE
#define T_SATA0_BKDOOR_CC_PROG_IF_MASK
#define T_SATA0_BKDOOR_CC_PROG_IF

#define T_SATA0_CFG_SATA
#define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN

#define T_SATA0_CFG_MISC

#define T_SATA0_INDEX

#define T_SATA0_CHX_PHY_CTRL1_GEN1
#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK
#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT
#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK
#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT

#define T_SATA0_CHX_PHY_CTRL1_GEN2
#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK
#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT
#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK
#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT

#define T_SATA0_CHX_PHY_CTRL2
#define T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1

#define T_SATA0_CHX_PHY_CTRL11
#define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ

#define T_SATA0_CHX_PHY_CTRL17_0
#define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1
#define T_SATA0_CHX_PHY_CTRL18_0
#define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2
#define T_SATA0_CHX_PHY_CTRL20_0
#define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1
#define T_SATA0_CHX_PHY_CTRL21_0
#define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2

/* AUX Registers */
#define SATA_AUX_MISC_CNTL_1_0
#define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE
#define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT
#define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT

#define SATA_AUX_RX_STAT_INT_0
#define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP

#define SATA_AUX_SPARE_CFG0_0
#define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID

#define FUSE_SATA_CALIB
#define FUSE_SATA_CALIB_MASK

struct sata_pad_calibration {};

static const struct sata_pad_calibration tegra124_pad_calibration[] =;

struct tegra_ahci_ops {};

struct tegra_ahci_regs {};

struct tegra_ahci_soc {};

struct tegra_ahci_priv {};

static void tegra_ahci_handle_quirks(struct ahci_host_priv *hpriv)
{}

static int tegra124_ahci_init(struct ahci_host_priv *hpriv)
{}

static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
{}

static void tegra_ahci_power_off(struct ahci_host_priv *hpriv)
{}

static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
{}

static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
{}

static void tegra_ahci_host_stop(struct ata_host *host)
{}

static struct ata_port_operations ahci_tegra_port_ops =;

static const struct ata_port_info ahci_tegra_port_info =;

static const char *const tegra124_supply_names[] =;

static const struct tegra_ahci_ops tegra124_ahci_ops =;

static const struct tegra_ahci_regs tegra124_ahci_regs =;

static const struct tegra_ahci_soc tegra124_ahci_soc =;

static const struct tegra_ahci_soc tegra210_ahci_soc =;

static const struct tegra_ahci_regs tegra186_ahci_regs =;

static const struct tegra_ahci_soc tegra186_ahci_soc =;

static const struct of_device_id tegra_ahci_of_match[] =;
MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);

static const struct scsi_host_template ahci_platform_sht =;

static int tegra_ahci_probe(struct platform_device *pdev)
{
	struct ahci_host_priv *hpriv;
	struct tegra_ahci_priv *tegra;
	struct resource *res;
	int ret;

	hpriv = ahci_platform_get_resources(pdev, 0);
	if (IS_ERR(hpriv))
		return PTR_ERR(hpriv);

	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
	if (!tegra)
		return -ENOMEM;

	hpriv->plat_data = tegra;

	tegra->pdev = pdev;
	tegra->soc = of_device_get_match_data(&pdev->dev);

	tegra->sata_regs = devm_platform_ioremap_resource(pdev, 1);
	if (IS_ERR(tegra->sata_regs))
		return PTR_ERR(tegra->sata_regs);

	/*
	 * AUX registers is optional.
	 */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	if (res) {
		tegra->sata_aux_regs = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(tegra->sata_aux_regs))
			return PTR_ERR(tegra->sata_aux_regs);
	}

	tegra->sata_rst = devm_reset_control_get(&pdev->dev, "sata");
	if (IS_ERR(tegra->sata_rst)) {
		dev_err(&pdev->dev, "Failed to get sata reset\n");
		return PTR_ERR(tegra->sata_rst);
	}

	if (tegra->soc->has_sata_oob_rst) {
		tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev,
							     "sata-oob");
		if (IS_ERR(tegra->sata_oob_rst)) {
			dev_err(&pdev->dev, "Failed to get sata-oob reset\n");
			return PTR_ERR(tegra->sata_oob_rst);
		}
	}

	tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");
	if (IS_ERR(tegra->sata_cold_rst)) {
		dev_err(&pdev->dev, "Failed to get sata-cold reset\n");
		return PTR_ERR(tegra->sata_cold_rst);
	}

	tegra->sata_clk = devm_clk_get(&pdev->dev, "sata");
	if (IS_ERR(tegra->sata_clk)) {
		dev_err(&pdev->dev, "Failed to get sata clock\n");
		return PTR_ERR(tegra->sata_clk);
	}

	tegra->supplies = devm_kcalloc(&pdev->dev,
				       tegra->soc->num_supplies,
				       sizeof(*tegra->supplies), GFP_KERNEL);
	if (!tegra->supplies)
		return -ENOMEM;

	regulator_bulk_set_supply_names(tegra->supplies,
					tegra->soc->supply_names,
					tegra->soc->num_supplies);

	ret = devm_regulator_bulk_get(&pdev->dev,
				      tegra->soc->num_supplies,
				      tegra->supplies);
	if (ret) {
		dev_err(&pdev->dev, "Failed to get regulators\n");
		return ret;
	}

	ret = tegra_ahci_controller_init(hpriv);
	if (ret)
		return ret;

	ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
				      &ahci_platform_sht);
	if (ret)
		goto deinit_controller;

	return 0;

deinit_controller:
	tegra_ahci_controller_deinit(hpriv);

	return ret;
};

static struct platform_driver tegra_ahci_driver =;
module_platform_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();