18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Synopsys G210 Test Chip driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Authors: Joao Pinto <jpinto@synopsys.com>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/kernel.h>
118c2ecf20Sopenharmony_ci#include <linux/module.h>
128c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
138c2ecf20Sopenharmony_ci#include <linux/of.h>
148c2ecf20Sopenharmony_ci#include <linux/delay.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include "ufshcd-pltfrm.h"
178c2ecf20Sopenharmony_ci#include "ufshcd-dwc.h"
188c2ecf20Sopenharmony_ci#include "tc-dwc-g210.h"
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci/*
218c2ecf20Sopenharmony_ci * UFS DWC specific variant operations
228c2ecf20Sopenharmony_ci */
238c2ecf20Sopenharmony_cistatic struct ufs_hba_variant_ops tc_dwc_g210_20bit_pltfm_hba_vops = {
248c2ecf20Sopenharmony_ci	.name                   = "tc-dwc-g210-pltfm",
258c2ecf20Sopenharmony_ci	.link_startup_notify	= ufshcd_dwc_link_startup_notify,
268c2ecf20Sopenharmony_ci	.phy_initialization = tc_dwc_g210_config_20_bit,
278c2ecf20Sopenharmony_ci};
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic struct ufs_hba_variant_ops tc_dwc_g210_40bit_pltfm_hba_vops = {
308c2ecf20Sopenharmony_ci	.name                   = "tc-dwc-g210-pltfm",
318c2ecf20Sopenharmony_ci	.link_startup_notify	= ufshcd_dwc_link_startup_notify,
328c2ecf20Sopenharmony_ci	.phy_initialization = tc_dwc_g210_config_40_bit,
338c2ecf20Sopenharmony_ci};
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic const struct of_device_id tc_dwc_g210_pltfm_match[] = {
368c2ecf20Sopenharmony_ci	{
378c2ecf20Sopenharmony_ci		.compatible = "snps,g210-tc-6.00-20bit",
388c2ecf20Sopenharmony_ci		.data = &tc_dwc_g210_20bit_pltfm_hba_vops,
398c2ecf20Sopenharmony_ci	},
408c2ecf20Sopenharmony_ci	{
418c2ecf20Sopenharmony_ci		.compatible = "snps,g210-tc-6.00-40bit",
428c2ecf20Sopenharmony_ci		.data = &tc_dwc_g210_40bit_pltfm_hba_vops,
438c2ecf20Sopenharmony_ci	},
448c2ecf20Sopenharmony_ci	{ },
458c2ecf20Sopenharmony_ci};
468c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, tc_dwc_g210_pltfm_match);
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/**
498c2ecf20Sopenharmony_ci * tc_dwc_g210_pltfm_probe()
508c2ecf20Sopenharmony_ci * @pdev: pointer to platform device structure
518c2ecf20Sopenharmony_ci *
528c2ecf20Sopenharmony_ci */
538c2ecf20Sopenharmony_cistatic int tc_dwc_g210_pltfm_probe(struct platform_device *pdev)
548c2ecf20Sopenharmony_ci{
558c2ecf20Sopenharmony_ci	int err;
568c2ecf20Sopenharmony_ci	const struct of_device_id *of_id;
578c2ecf20Sopenharmony_ci	struct ufs_hba_variant_ops *vops;
588c2ecf20Sopenharmony_ci	struct device *dev = &pdev->dev;
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	of_id = of_match_node(tc_dwc_g210_pltfm_match, dev->of_node);
618c2ecf20Sopenharmony_ci	vops = (struct ufs_hba_variant_ops *)of_id->data;
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	/* Perform generic probe */
648c2ecf20Sopenharmony_ci	err = ufshcd_pltfrm_init(pdev, vops);
658c2ecf20Sopenharmony_ci	if (err)
668c2ecf20Sopenharmony_ci		dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	return err;
698c2ecf20Sopenharmony_ci}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci/**
728c2ecf20Sopenharmony_ci * tc_dwc_g210_pltfm_remove()
738c2ecf20Sopenharmony_ci * @pdev: pointer to platform device structure
748c2ecf20Sopenharmony_ci *
758c2ecf20Sopenharmony_ci */
768c2ecf20Sopenharmony_cistatic int tc_dwc_g210_pltfm_remove(struct platform_device *pdev)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	struct ufs_hba *hba =  platform_get_drvdata(pdev);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	pm_runtime_get_sync(&(pdev)->dev);
818c2ecf20Sopenharmony_ci	ufshcd_remove(hba);
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	return 0;
848c2ecf20Sopenharmony_ci}
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_cistatic const struct dev_pm_ops tc_dwc_g210_pltfm_pm_ops = {
878c2ecf20Sopenharmony_ci	.suspend	= ufshcd_pltfrm_suspend,
888c2ecf20Sopenharmony_ci	.resume		= ufshcd_pltfrm_resume,
898c2ecf20Sopenharmony_ci	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
908c2ecf20Sopenharmony_ci	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
918c2ecf20Sopenharmony_ci	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
928c2ecf20Sopenharmony_ci};
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistatic struct platform_driver tc_dwc_g210_pltfm_driver = {
958c2ecf20Sopenharmony_ci	.probe		= tc_dwc_g210_pltfm_probe,
968c2ecf20Sopenharmony_ci	.remove		= tc_dwc_g210_pltfm_remove,
978c2ecf20Sopenharmony_ci	.shutdown = ufshcd_pltfrm_shutdown,
988c2ecf20Sopenharmony_ci	.driver		= {
998c2ecf20Sopenharmony_ci		.name	= "tc-dwc-g210-pltfm",
1008c2ecf20Sopenharmony_ci		.pm	= &tc_dwc_g210_pltfm_pm_ops,
1018c2ecf20Sopenharmony_ci		.of_match_table	= of_match_ptr(tc_dwc_g210_pltfm_match),
1028c2ecf20Sopenharmony_ci	},
1038c2ecf20Sopenharmony_ci};
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cimodule_platform_driver(tc_dwc_g210_pltfm_driver);
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:tc-dwc-g210-pltfm");
1088c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Synopsys Test Chip G210 platform glue driver");
1098c2ecf20Sopenharmony_ciMODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>");
1108c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL");
111