cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xhci-histb.c (9841B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * xHCI host controller driver for HiSilicon STB SoCs
      4 *
      5 * Copyright (C) 2017-2018 HiSilicon Co., Ltd. http://www.hisilicon.com
      6 *
      7 * Authors: Jianguo Sun <sunjianguo1@huawei.com>
      8 */
      9
     10#include <linux/clk.h>
     11#include <linux/dma-mapping.h>
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/of.h>
     15#include <linux/platform_device.h>
     16#include <linux/pm_runtime.h>
     17#include <linux/reset.h>
     18
     19#include "xhci.h"
     20
     21#define GTXTHRCFG		0xc108
     22#define GRXTHRCFG		0xc10c
     23#define REG_GUSB2PHYCFG0	0xc200
     24#define BIT_UTMI_8_16		BIT(3)
     25#define BIT_UTMI_ULPI		BIT(4)
     26#define BIT_FREECLK_EXIST	BIT(30)
     27
     28#define REG_GUSB3PIPECTL0	0xc2c0
     29#define USB3_DEEMPHASIS_MASK	GENMASK(2, 1)
     30#define USB3_DEEMPHASIS0	BIT(1)
     31#define USB3_TX_MARGIN1		BIT(4)
     32
     33struct xhci_hcd_histb {
     34	struct device		*dev;
     35	struct usb_hcd		*hcd;
     36	void __iomem		*ctrl;
     37	struct clk		*bus_clk;
     38	struct clk		*utmi_clk;
     39	struct clk		*pipe_clk;
     40	struct clk		*suspend_clk;
     41	struct reset_control	*soft_reset;
     42};
     43
     44static inline struct xhci_hcd_histb *hcd_to_histb(struct usb_hcd *hcd)
     45{
     46	return dev_get_drvdata(hcd->self.controller);
     47}
     48
     49static int xhci_histb_config(struct xhci_hcd_histb *histb)
     50{
     51	struct device_node *np = histb->dev->of_node;
     52	u32 regval;
     53
     54	if (of_property_match_string(np, "phys-names", "inno") >= 0) {
     55		/* USB2 PHY chose ulpi 8bit interface */
     56		regval = readl(histb->ctrl + REG_GUSB2PHYCFG0);
     57		regval &= ~BIT_UTMI_ULPI;
     58		regval &= ~(BIT_UTMI_8_16);
     59		regval &= ~BIT_FREECLK_EXIST;
     60		writel(regval, histb->ctrl + REG_GUSB2PHYCFG0);
     61	}
     62
     63	if (of_property_match_string(np, "phys-names", "combo") >= 0) {
     64		/*
     65		 * write 0x010c0012 to GUSB3PIPECTL0
     66		 * GUSB3PIPECTL0[5:3] = 010 : Tx Margin = 900mV ,
     67		 * decrease TX voltage
     68		 * GUSB3PIPECTL0[2:1] = 01 : Tx Deemphasis = -3.5dB,
     69		 * refer to xHCI spec
     70		 */
     71		regval = readl(histb->ctrl + REG_GUSB3PIPECTL0);
     72		regval &= ~USB3_DEEMPHASIS_MASK;
     73		regval |= USB3_DEEMPHASIS0;
     74		regval |= USB3_TX_MARGIN1;
     75		writel(regval, histb->ctrl + REG_GUSB3PIPECTL0);
     76	}
     77
     78	writel(0x23100000, histb->ctrl + GTXTHRCFG);
     79	writel(0x23100000, histb->ctrl + GRXTHRCFG);
     80
     81	return 0;
     82}
     83
     84static int xhci_histb_clks_get(struct xhci_hcd_histb *histb)
     85{
     86	struct device *dev = histb->dev;
     87
     88	histb->bus_clk = devm_clk_get(dev, "bus");
     89	if (IS_ERR(histb->bus_clk)) {
     90		dev_err(dev, "fail to get bus clk\n");
     91		return PTR_ERR(histb->bus_clk);
     92	}
     93
     94	histb->utmi_clk = devm_clk_get(dev, "utmi");
     95	if (IS_ERR(histb->utmi_clk)) {
     96		dev_err(dev, "fail to get utmi clk\n");
     97		return PTR_ERR(histb->utmi_clk);
     98	}
     99
    100	histb->pipe_clk = devm_clk_get(dev, "pipe");
    101	if (IS_ERR(histb->pipe_clk)) {
    102		dev_err(dev, "fail to get pipe clk\n");
    103		return PTR_ERR(histb->pipe_clk);
    104	}
    105
    106	histb->suspend_clk = devm_clk_get(dev, "suspend");
    107	if (IS_ERR(histb->suspend_clk)) {
    108		dev_err(dev, "fail to get suspend clk\n");
    109		return PTR_ERR(histb->suspend_clk);
    110	}
    111
    112	return 0;
    113}
    114
    115static int xhci_histb_host_enable(struct xhci_hcd_histb *histb)
    116{
    117	int ret;
    118
    119	ret = clk_prepare_enable(histb->bus_clk);
    120	if (ret) {
    121		dev_err(histb->dev, "failed to enable bus clk\n");
    122		return ret;
    123	}
    124
    125	ret = clk_prepare_enable(histb->utmi_clk);
    126	if (ret) {
    127		dev_err(histb->dev, "failed to enable utmi clk\n");
    128		goto err_utmi_clk;
    129	}
    130
    131	ret = clk_prepare_enable(histb->pipe_clk);
    132	if (ret) {
    133		dev_err(histb->dev, "failed to enable pipe clk\n");
    134		goto err_pipe_clk;
    135	}
    136
    137	ret = clk_prepare_enable(histb->suspend_clk);
    138	if (ret) {
    139		dev_err(histb->dev, "failed to enable suspend clk\n");
    140		goto err_suspend_clk;
    141	}
    142
    143	reset_control_deassert(histb->soft_reset);
    144
    145	return 0;
    146
    147err_suspend_clk:
    148	clk_disable_unprepare(histb->pipe_clk);
    149err_pipe_clk:
    150	clk_disable_unprepare(histb->utmi_clk);
    151err_utmi_clk:
    152	clk_disable_unprepare(histb->bus_clk);
    153
    154	return ret;
    155}
    156
    157static void xhci_histb_host_disable(struct xhci_hcd_histb *histb)
    158{
    159	reset_control_assert(histb->soft_reset);
    160
    161	clk_disable_unprepare(histb->suspend_clk);
    162	clk_disable_unprepare(histb->pipe_clk);
    163	clk_disable_unprepare(histb->utmi_clk);
    164	clk_disable_unprepare(histb->bus_clk);
    165}
    166
    167static void xhci_histb_quirks(struct device *dev, struct xhci_hcd *xhci)
    168{
    169	/*
    170	 * As of now platform drivers don't provide MSI support so we ensure
    171	 * here that the generic code does not try to make a pci_dev from our
    172	 * dev struct in order to setup MSI
    173	 */
    174	xhci->quirks |= XHCI_PLAT;
    175}
    176
    177/* called during probe() after chip reset completes */
    178static int xhci_histb_setup(struct usb_hcd *hcd)
    179{
    180	struct xhci_hcd_histb *histb = hcd_to_histb(hcd);
    181	int ret;
    182
    183	if (usb_hcd_is_primary_hcd(hcd)) {
    184		ret = xhci_histb_config(histb);
    185		if (ret)
    186			return ret;
    187	}
    188
    189	return xhci_gen_setup(hcd, xhci_histb_quirks);
    190}
    191
    192static const struct xhci_driver_overrides xhci_histb_overrides __initconst = {
    193	.reset = xhci_histb_setup,
    194};
    195
    196static struct hc_driver __read_mostly xhci_histb_hc_driver;
    197static int xhci_histb_probe(struct platform_device *pdev)
    198{
    199	struct device *dev = &pdev->dev;
    200	struct xhci_hcd_histb *histb;
    201	const struct hc_driver *driver;
    202	struct usb_hcd *hcd;
    203	struct xhci_hcd *xhci;
    204	struct resource *res;
    205	int irq;
    206	int ret = -ENODEV;
    207
    208	if (usb_disabled())
    209		return -ENODEV;
    210
    211	driver = &xhci_histb_hc_driver;
    212	histb = devm_kzalloc(dev, sizeof(*histb), GFP_KERNEL);
    213	if (!histb)
    214		return -ENOMEM;
    215
    216	histb->dev = dev;
    217
    218	irq = platform_get_irq(pdev, 0);
    219	if (irq < 0)
    220		return irq;
    221
    222	histb->ctrl = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
    223	if (IS_ERR(histb->ctrl))
    224		return PTR_ERR(histb->ctrl);
    225
    226	ret = xhci_histb_clks_get(histb);
    227	if (ret)
    228		return ret;
    229
    230	histb->soft_reset = devm_reset_control_get(dev, "soft");
    231	if (IS_ERR(histb->soft_reset)) {
    232		dev_err(dev, "failed to get soft reset\n");
    233		return PTR_ERR(histb->soft_reset);
    234	}
    235
    236	pm_runtime_enable(dev);
    237	pm_runtime_get_sync(dev);
    238	device_enable_async_suspend(dev);
    239
    240	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
    241	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
    242	if (ret)
    243		goto disable_pm;
    244
    245	hcd = usb_create_hcd(driver, dev, dev_name(dev));
    246	if (!hcd) {
    247		ret = -ENOMEM;
    248		goto disable_pm;
    249	}
    250
    251	hcd->regs = histb->ctrl;
    252	hcd->rsrc_start = res->start;
    253	hcd->rsrc_len = resource_size(res);
    254
    255	histb->hcd = hcd;
    256	dev_set_drvdata(hcd->self.controller, histb);
    257
    258	ret = xhci_histb_host_enable(histb);
    259	if (ret)
    260		goto put_hcd;
    261
    262	xhci = hcd_to_xhci(hcd);
    263
    264	device_wakeup_enable(hcd->self.controller);
    265
    266	xhci->main_hcd = hcd;
    267	xhci->shared_hcd = usb_create_shared_hcd(driver, dev, dev_name(dev),
    268						 hcd);
    269	if (!xhci->shared_hcd) {
    270		ret = -ENOMEM;
    271		goto disable_host;
    272	}
    273
    274	if (device_property_read_bool(dev, "usb2-lpm-disable"))
    275		xhci->quirks |= XHCI_HW_LPM_DISABLE;
    276
    277	if (device_property_read_bool(dev, "usb3-lpm-capable"))
    278		xhci->quirks |= XHCI_LPM_SUPPORT;
    279
    280	/* imod_interval is the interrupt moderation value in nanoseconds. */
    281	xhci->imod_interval = 40000;
    282	device_property_read_u32(dev, "imod-interval-ns",
    283				 &xhci->imod_interval);
    284
    285	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
    286	if (ret)
    287		goto put_usb3_hcd;
    288
    289	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
    290		xhci->shared_hcd->can_do_streams = 1;
    291
    292	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
    293	if (ret)
    294		goto dealloc_usb2_hcd;
    295
    296	device_enable_async_suspend(dev);
    297	pm_runtime_put_noidle(dev);
    298
    299	/*
    300	 * Prevent runtime pm from being on as default, users should enable
    301	 * runtime pm using power/control in sysfs.
    302	 */
    303	pm_runtime_forbid(dev);
    304
    305	return 0;
    306
    307dealloc_usb2_hcd:
    308	usb_remove_hcd(hcd);
    309put_usb3_hcd:
    310	usb_put_hcd(xhci->shared_hcd);
    311disable_host:
    312	xhci_histb_host_disable(histb);
    313put_hcd:
    314	usb_put_hcd(hcd);
    315disable_pm:
    316	pm_runtime_put_sync(dev);
    317	pm_runtime_disable(dev);
    318
    319	return ret;
    320}
    321
    322static int xhci_histb_remove(struct platform_device *dev)
    323{
    324	struct xhci_hcd_histb *histb = platform_get_drvdata(dev);
    325	struct usb_hcd *hcd = histb->hcd;
    326	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
    327	struct usb_hcd *shared_hcd = xhci->shared_hcd;
    328
    329	xhci->xhc_state |= XHCI_STATE_REMOVING;
    330
    331	usb_remove_hcd(shared_hcd);
    332	xhci->shared_hcd = NULL;
    333	device_wakeup_disable(&dev->dev);
    334
    335	usb_remove_hcd(hcd);
    336	usb_put_hcd(shared_hcd);
    337
    338	xhci_histb_host_disable(histb);
    339	usb_put_hcd(hcd);
    340	pm_runtime_put_sync(&dev->dev);
    341	pm_runtime_disable(&dev->dev);
    342
    343	return 0;
    344}
    345
    346static int __maybe_unused xhci_histb_suspend(struct device *dev)
    347{
    348	struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
    349	struct usb_hcd *hcd = histb->hcd;
    350	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
    351	int ret;
    352
    353	ret = xhci_suspend(xhci, device_may_wakeup(dev));
    354
    355	if (!device_may_wakeup(dev))
    356		xhci_histb_host_disable(histb);
    357
    358	return ret;
    359}
    360
    361static int __maybe_unused xhci_histb_resume(struct device *dev)
    362{
    363	struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
    364	struct usb_hcd *hcd = histb->hcd;
    365	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
    366
    367	if (!device_may_wakeup(dev))
    368		xhci_histb_host_enable(histb);
    369
    370	return xhci_resume(xhci, 0);
    371}
    372
    373static const struct dev_pm_ops xhci_histb_pm_ops = {
    374	SET_SYSTEM_SLEEP_PM_OPS(xhci_histb_suspend, xhci_histb_resume)
    375};
    376#define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &xhci_histb_pm_ops : NULL)
    377
    378#ifdef CONFIG_OF
    379static const struct of_device_id histb_xhci_of_match[] = {
    380	{ .compatible = "hisilicon,hi3798cv200-xhci"},
    381	{ },
    382};
    383MODULE_DEVICE_TABLE(of, histb_xhci_of_match);
    384#endif
    385
    386static struct platform_driver histb_xhci_driver = {
    387	.probe	= xhci_histb_probe,
    388	.remove	= xhci_histb_remove,
    389	.driver	= {
    390		.name = "xhci-histb",
    391		.pm = DEV_PM_OPS,
    392		.of_match_table = of_match_ptr(histb_xhci_of_match),
    393	},
    394};
    395MODULE_ALIAS("platform:xhci-histb");
    396
    397static int __init xhci_histb_init(void)
    398{
    399	xhci_init_driver(&xhci_histb_hc_driver, &xhci_histb_overrides);
    400	return platform_driver_register(&histb_xhci_driver);
    401}
    402module_init(xhci_histb_init);
    403
    404static void __exit xhci_histb_exit(void)
    405{
    406	platform_driver_unregister(&histb_xhci_driver);
    407}
    408module_exit(xhci_histb_exit);
    409
    410MODULE_DESCRIPTION("HiSilicon STB xHCI Host Controller Driver");
    411MODULE_LICENSE("GPL v2");