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

mediatek.c (13638B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2019 MediaTek Inc.
      4 *
      5 * Author:
      6 *  Min Guo <min.guo@mediatek.com>
      7 *  Yonglong Wu <yonglong.wu@mediatek.com>
      8 */
      9
     10#include <linux/clk.h>
     11#include <linux/dma-mapping.h>
     12#include <linux/module.h>
     13#include <linux/of_platform.h>
     14#include <linux/platform_device.h>
     15#include <linux/usb/role.h>
     16#include <linux/usb/usb_phy_generic.h>
     17#include "musb_core.h"
     18#include "musb_dma.h"
     19
     20#define USB_L1INTS		0x00a0
     21#define USB_L1INTM		0x00a4
     22#define MTK_MUSB_TXFUNCADDR	0x0480
     23
     24/* MediaTek controller toggle enable and status reg */
     25#define MUSB_RXTOG		0x80
     26#define MUSB_RXTOGEN		0x82
     27#define MUSB_TXTOG		0x84
     28#define MUSB_TXTOGEN		0x86
     29#define MTK_TOGGLE_EN		GENMASK(15, 0)
     30
     31#define TX_INT_STATUS		BIT(0)
     32#define RX_INT_STATUS		BIT(1)
     33#define USBCOM_INT_STATUS	BIT(2)
     34#define DMA_INT_STATUS		BIT(3)
     35
     36#define DMA_INTR_STATUS_MSK	GENMASK(7, 0)
     37#define DMA_INTR_UNMASK_SET_MSK	GENMASK(31, 24)
     38
     39#define MTK_MUSB_CLKS_NUM	3
     40
     41struct mtk_glue {
     42	struct device *dev;
     43	struct musb *musb;
     44	struct platform_device *musb_pdev;
     45	struct platform_device *usb_phy;
     46	struct phy *phy;
     47	struct usb_phy *xceiv;
     48	enum phy_mode phy_mode;
     49	struct clk_bulk_data clks[MTK_MUSB_CLKS_NUM];
     50	enum usb_role role;
     51	struct usb_role_switch *role_sw;
     52};
     53
     54static int mtk_musb_clks_get(struct mtk_glue *glue)
     55{
     56	struct device *dev = glue->dev;
     57
     58	glue->clks[0].id = "main";
     59	glue->clks[1].id = "mcu";
     60	glue->clks[2].id = "univpll";
     61
     62	return devm_clk_bulk_get(dev, MTK_MUSB_CLKS_NUM, glue->clks);
     63}
     64
     65static int mtk_otg_switch_set(struct mtk_glue *glue, enum usb_role role)
     66{
     67	struct musb *musb = glue->musb;
     68	u8 devctl = readb(musb->mregs + MUSB_DEVCTL);
     69	enum usb_role new_role;
     70
     71	if (role == glue->role)
     72		return 0;
     73
     74	switch (role) {
     75	case USB_ROLE_HOST:
     76		musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
     77		glue->phy_mode = PHY_MODE_USB_HOST;
     78		new_role = USB_ROLE_HOST;
     79		if (glue->role == USB_ROLE_NONE)
     80			phy_power_on(glue->phy);
     81
     82		devctl |= MUSB_DEVCTL_SESSION;
     83		musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
     84		MUSB_HST_MODE(musb);
     85		break;
     86	case USB_ROLE_DEVICE:
     87		musb->xceiv->otg->state = OTG_STATE_B_IDLE;
     88		glue->phy_mode = PHY_MODE_USB_DEVICE;
     89		new_role = USB_ROLE_DEVICE;
     90		devctl &= ~MUSB_DEVCTL_SESSION;
     91		musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
     92		if (glue->role == USB_ROLE_NONE)
     93			phy_power_on(glue->phy);
     94
     95		MUSB_DEV_MODE(musb);
     96		break;
     97	case USB_ROLE_NONE:
     98		glue->phy_mode = PHY_MODE_USB_OTG;
     99		new_role = USB_ROLE_NONE;
    100		devctl &= ~MUSB_DEVCTL_SESSION;
    101		musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
    102		if (glue->role != USB_ROLE_NONE)
    103			phy_power_off(glue->phy);
    104
    105		break;
    106	default:
    107		dev_err(glue->dev, "Invalid State\n");
    108		return -EINVAL;
    109	}
    110
    111	glue->role = new_role;
    112	phy_set_mode(glue->phy, glue->phy_mode);
    113
    114	return 0;
    115}
    116
    117static int musb_usb_role_sx_set(struct usb_role_switch *sw, enum usb_role role)
    118{
    119	return mtk_otg_switch_set(usb_role_switch_get_drvdata(sw), role);
    120}
    121
    122static enum usb_role musb_usb_role_sx_get(struct usb_role_switch *sw)
    123{
    124	struct mtk_glue *glue = usb_role_switch_get_drvdata(sw);
    125
    126	return glue->role;
    127}
    128
    129static int mtk_otg_switch_init(struct mtk_glue *glue)
    130{
    131	struct usb_role_switch_desc role_sx_desc = { 0 };
    132
    133	role_sx_desc.set = musb_usb_role_sx_set;
    134	role_sx_desc.get = musb_usb_role_sx_get;
    135	role_sx_desc.allow_userspace_control = true;
    136	role_sx_desc.fwnode = dev_fwnode(glue->dev);
    137	role_sx_desc.driver_data = glue;
    138	glue->role_sw = usb_role_switch_register(glue->dev, &role_sx_desc);
    139
    140	return PTR_ERR_OR_ZERO(glue->role_sw);
    141}
    142
    143static void mtk_otg_switch_exit(struct mtk_glue *glue)
    144{
    145	return usb_role_switch_unregister(glue->role_sw);
    146}
    147
    148static irqreturn_t generic_interrupt(int irq, void *__hci)
    149{
    150	unsigned long flags;
    151	irqreturn_t retval = IRQ_NONE;
    152	struct musb *musb = __hci;
    153
    154	spin_lock_irqsave(&musb->lock, flags);
    155	musb->int_usb = musb_clearb(musb->mregs, MUSB_INTRUSB);
    156	musb->int_rx = musb_clearw(musb->mregs, MUSB_INTRRX);
    157	musb->int_tx = musb_clearw(musb->mregs, MUSB_INTRTX);
    158
    159	if ((musb->int_usb & MUSB_INTR_RESET) && !is_host_active(musb)) {
    160		/* ep0 FADDR must be 0 when (re)entering peripheral mode */
    161		musb_ep_select(musb->mregs, 0);
    162		musb_writeb(musb->mregs, MUSB_FADDR, 0);
    163	}
    164
    165	if (musb->int_usb || musb->int_tx || musb->int_rx)
    166		retval = musb_interrupt(musb);
    167
    168	spin_unlock_irqrestore(&musb->lock, flags);
    169
    170	return retval;
    171}
    172
    173static irqreturn_t mtk_musb_interrupt(int irq, void *dev_id)
    174{
    175	irqreturn_t retval = IRQ_NONE;
    176	struct musb *musb = (struct musb *)dev_id;
    177	u32 l1_ints;
    178
    179	l1_ints = musb_readl(musb->mregs, USB_L1INTS) &
    180			musb_readl(musb->mregs, USB_L1INTM);
    181
    182	if (l1_ints & (TX_INT_STATUS | RX_INT_STATUS | USBCOM_INT_STATUS))
    183		retval = generic_interrupt(irq, musb);
    184
    185#if defined(CONFIG_USB_INVENTRA_DMA)
    186	if (l1_ints & DMA_INT_STATUS)
    187		retval = dma_controller_irq(irq, musb->dma_controller);
    188#endif
    189	return retval;
    190}
    191
    192static u32 mtk_musb_busctl_offset(u8 epnum, u16 offset)
    193{
    194	return MTK_MUSB_TXFUNCADDR + offset + 8 * epnum;
    195}
    196
    197static u8 mtk_musb_clearb(void __iomem *addr, unsigned int offset)
    198{
    199	u8 data;
    200
    201	/* W1C */
    202	data = musb_readb(addr, offset);
    203	musb_writeb(addr, offset, data);
    204	return data;
    205}
    206
    207static u16 mtk_musb_clearw(void __iomem *addr, unsigned int offset)
    208{
    209	u16 data;
    210
    211	/* W1C */
    212	data = musb_readw(addr, offset);
    213	musb_writew(addr, offset, data);
    214	return data;
    215}
    216
    217static int mtk_musb_set_mode(struct musb *musb, u8 mode)
    218{
    219	struct device *dev = musb->controller;
    220	struct mtk_glue *glue = dev_get_drvdata(dev->parent);
    221	enum phy_mode new_mode;
    222	enum usb_role new_role;
    223
    224	switch (mode) {
    225	case MUSB_HOST:
    226		new_mode = PHY_MODE_USB_HOST;
    227		new_role = USB_ROLE_HOST;
    228		break;
    229	case MUSB_PERIPHERAL:
    230		new_mode = PHY_MODE_USB_DEVICE;
    231		new_role = USB_ROLE_DEVICE;
    232		break;
    233	case MUSB_OTG:
    234		new_mode = PHY_MODE_USB_OTG;
    235		new_role = USB_ROLE_NONE;
    236		break;
    237	default:
    238		dev_err(glue->dev, "Invalid mode request\n");
    239		return -EINVAL;
    240	}
    241
    242	if (glue->phy_mode == new_mode)
    243		return 0;
    244
    245	if (musb->port_mode != MUSB_OTG) {
    246		dev_err(glue->dev, "Does not support changing modes\n");
    247		return -EINVAL;
    248	}
    249
    250	mtk_otg_switch_set(glue, new_role);
    251	return 0;
    252}
    253
    254static int mtk_musb_init(struct musb *musb)
    255{
    256	struct device *dev = musb->controller;
    257	struct mtk_glue *glue = dev_get_drvdata(dev->parent);
    258	int ret;
    259
    260	glue->musb = musb;
    261	musb->phy = glue->phy;
    262	musb->xceiv = glue->xceiv;
    263	musb->is_host = false;
    264	musb->isr = mtk_musb_interrupt;
    265
    266	/* Set TX/RX toggle enable */
    267	musb_writew(musb->mregs, MUSB_TXTOGEN, MTK_TOGGLE_EN);
    268	musb_writew(musb->mregs, MUSB_RXTOGEN, MTK_TOGGLE_EN);
    269
    270	if (musb->port_mode == MUSB_OTG) {
    271		ret = mtk_otg_switch_init(glue);
    272		if (ret)
    273			return ret;
    274	}
    275
    276	ret = phy_init(glue->phy);
    277	if (ret)
    278		goto err_phy_init;
    279
    280	ret = phy_power_on(glue->phy);
    281	if (ret)
    282		goto err_phy_power_on;
    283
    284	phy_set_mode(glue->phy, glue->phy_mode);
    285
    286#if defined(CONFIG_USB_INVENTRA_DMA)
    287	musb_writel(musb->mregs, MUSB_HSDMA_INTR,
    288		    DMA_INTR_STATUS_MSK | DMA_INTR_UNMASK_SET_MSK);
    289#endif
    290	musb_writel(musb->mregs, USB_L1INTM, TX_INT_STATUS | RX_INT_STATUS |
    291		    USBCOM_INT_STATUS | DMA_INT_STATUS);
    292	return 0;
    293
    294err_phy_power_on:
    295	phy_exit(glue->phy);
    296err_phy_init:
    297	mtk_otg_switch_exit(glue);
    298	return ret;
    299}
    300
    301static u16 mtk_musb_get_toggle(struct musb_qh *qh, int is_out)
    302{
    303	struct musb *musb = qh->hw_ep->musb;
    304	u8 epnum = qh->hw_ep->epnum;
    305	u16 toggle;
    306
    307	toggle = musb_readw(musb->mregs, is_out ? MUSB_TXTOG : MUSB_RXTOG);
    308	return toggle & (1 << epnum);
    309}
    310
    311static u16 mtk_musb_set_toggle(struct musb_qh *qh, int is_out, struct urb *urb)
    312{
    313	struct musb *musb = qh->hw_ep->musb;
    314	u8 epnum = qh->hw_ep->epnum;
    315	u16 value, toggle;
    316
    317	toggle = usb_gettoggle(urb->dev, qh->epnum, is_out);
    318
    319	if (is_out) {
    320		value = musb_readw(musb->mregs, MUSB_TXTOG);
    321		value |= toggle << epnum;
    322		musb_writew(musb->mregs, MUSB_TXTOG, value);
    323	} else {
    324		value = musb_readw(musb->mregs, MUSB_RXTOG);
    325		value |= toggle << epnum;
    326		musb_writew(musb->mregs, MUSB_RXTOG, value);
    327	}
    328
    329	return 0;
    330}
    331
    332static int mtk_musb_exit(struct musb *musb)
    333{
    334	struct device *dev = musb->controller;
    335	struct mtk_glue *glue = dev_get_drvdata(dev->parent);
    336
    337	mtk_otg_switch_exit(glue);
    338	phy_power_off(glue->phy);
    339	phy_exit(glue->phy);
    340	clk_bulk_disable_unprepare(MTK_MUSB_CLKS_NUM, glue->clks);
    341
    342	pm_runtime_put_sync(dev);
    343	pm_runtime_disable(dev);
    344	return 0;
    345}
    346
    347static const struct musb_platform_ops mtk_musb_ops = {
    348	.quirks = MUSB_DMA_INVENTRA,
    349	.init = mtk_musb_init,
    350	.get_toggle = mtk_musb_get_toggle,
    351	.set_toggle = mtk_musb_set_toggle,
    352	.exit = mtk_musb_exit,
    353#ifdef CONFIG_USB_INVENTRA_DMA
    354	.dma_init = musbhs_dma_controller_create_noirq,
    355	.dma_exit = musbhs_dma_controller_destroy,
    356#endif
    357	.clearb = mtk_musb_clearb,
    358	.clearw = mtk_musb_clearw,
    359	.busctl_offset = mtk_musb_busctl_offset,
    360	.set_mode = mtk_musb_set_mode,
    361};
    362
    363#define MTK_MUSB_MAX_EP_NUM	8
    364#define MTK_MUSB_RAM_BITS	11
    365
    366static struct musb_fifo_cfg mtk_musb_mode_cfg[] = {
    367	{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
    368	{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
    369	{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
    370	{ .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, },
    371	{ .hw_ep_num = 3, .style = FIFO_TX, .maxpacket = 512, },
    372	{ .hw_ep_num = 3, .style = FIFO_RX, .maxpacket = 512, },
    373	{ .hw_ep_num = 4, .style = FIFO_TX, .maxpacket = 512, },
    374	{ .hw_ep_num = 4, .style = FIFO_RX, .maxpacket = 512, },
    375	{ .hw_ep_num = 5, .style = FIFO_TX, .maxpacket = 512, },
    376	{ .hw_ep_num = 5, .style = FIFO_RX, .maxpacket = 512, },
    377	{ .hw_ep_num = 6, .style = FIFO_TX, .maxpacket = 1024, },
    378	{ .hw_ep_num = 6, .style = FIFO_RX, .maxpacket = 1024, },
    379	{ .hw_ep_num = 7, .style = FIFO_TX, .maxpacket = 512, },
    380	{ .hw_ep_num = 7, .style = FIFO_RX, .maxpacket = 64, },
    381};
    382
    383static const struct musb_hdrc_config mtk_musb_hdrc_config = {
    384	.fifo_cfg = mtk_musb_mode_cfg,
    385	.fifo_cfg_size = ARRAY_SIZE(mtk_musb_mode_cfg),
    386	.multipoint = true,
    387	.dyn_fifo = true,
    388	.num_eps = MTK_MUSB_MAX_EP_NUM,
    389	.ram_bits = MTK_MUSB_RAM_BITS,
    390};
    391
    392static const struct platform_device_info mtk_dev_info = {
    393	.name = "musb-hdrc",
    394	.id = PLATFORM_DEVID_AUTO,
    395	.dma_mask = DMA_BIT_MASK(32),
    396};
    397
    398static int mtk_musb_probe(struct platform_device *pdev)
    399{
    400	struct musb_hdrc_platform_data *pdata;
    401	struct mtk_glue *glue;
    402	struct platform_device_info pinfo;
    403	struct device *dev = &pdev->dev;
    404	struct device_node *np = dev->of_node;
    405	int ret;
    406
    407	glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL);
    408	if (!glue)
    409		return -ENOMEM;
    410
    411	glue->dev = dev;
    412	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
    413	if (!pdata)
    414		return -ENOMEM;
    415
    416	ret = of_platform_populate(np, NULL, NULL, dev);
    417	if (ret) {
    418		dev_err(dev, "failed to create child devices at %p\n", np);
    419		return ret;
    420	}
    421
    422	ret = mtk_musb_clks_get(glue);
    423	if (ret)
    424		return ret;
    425
    426	pdata->config = &mtk_musb_hdrc_config;
    427	pdata->platform_ops = &mtk_musb_ops;
    428	pdata->mode = usb_get_dr_mode(dev);
    429
    430	if (IS_ENABLED(CONFIG_USB_MUSB_HOST))
    431		pdata->mode = USB_DR_MODE_HOST;
    432	else if (IS_ENABLED(CONFIG_USB_MUSB_GADGET))
    433		pdata->mode = USB_DR_MODE_PERIPHERAL;
    434
    435	switch (pdata->mode) {
    436	case USB_DR_MODE_HOST:
    437		glue->phy_mode = PHY_MODE_USB_HOST;
    438		glue->role = USB_ROLE_HOST;
    439		break;
    440	case USB_DR_MODE_PERIPHERAL:
    441		glue->phy_mode = PHY_MODE_USB_DEVICE;
    442		glue->role = USB_ROLE_DEVICE;
    443		break;
    444	case USB_DR_MODE_OTG:
    445		glue->phy_mode = PHY_MODE_USB_OTG;
    446		glue->role = USB_ROLE_NONE;
    447		break;
    448	default:
    449		dev_err(&pdev->dev, "Error 'dr_mode' property\n");
    450		return -EINVAL;
    451	}
    452
    453	glue->phy = devm_of_phy_get_by_index(dev, np, 0);
    454	if (IS_ERR(glue->phy)) {
    455		dev_err(dev, "fail to getting phy %ld\n",
    456			PTR_ERR(glue->phy));
    457		return PTR_ERR(glue->phy);
    458	}
    459
    460	glue->usb_phy = usb_phy_generic_register();
    461	if (IS_ERR(glue->usb_phy)) {
    462		dev_err(dev, "fail to registering usb-phy %ld\n",
    463			PTR_ERR(glue->usb_phy));
    464		return PTR_ERR(glue->usb_phy);
    465	}
    466
    467	glue->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
    468	if (IS_ERR(glue->xceiv)) {
    469		ret = PTR_ERR(glue->xceiv);
    470		dev_err(dev, "fail to getting usb-phy %d\n", ret);
    471		goto err_unregister_usb_phy;
    472	}
    473
    474	platform_set_drvdata(pdev, glue);
    475	pm_runtime_enable(dev);
    476	pm_runtime_get_sync(dev);
    477
    478	ret = clk_bulk_prepare_enable(MTK_MUSB_CLKS_NUM, glue->clks);
    479	if (ret)
    480		goto err_enable_clk;
    481
    482	pinfo = mtk_dev_info;
    483	pinfo.parent = dev;
    484	pinfo.res = pdev->resource;
    485	pinfo.num_res = pdev->num_resources;
    486	pinfo.data = pdata;
    487	pinfo.size_data = sizeof(*pdata);
    488	pinfo.fwnode = of_fwnode_handle(np);
    489	pinfo.of_node_reused = true;
    490
    491	glue->musb_pdev = platform_device_register_full(&pinfo);
    492	if (IS_ERR(glue->musb_pdev)) {
    493		ret = PTR_ERR(glue->musb_pdev);
    494		dev_err(dev, "failed to register musb device: %d\n", ret);
    495		goto err_device_register;
    496	}
    497
    498	return 0;
    499
    500err_device_register:
    501	clk_bulk_disable_unprepare(MTK_MUSB_CLKS_NUM, glue->clks);
    502err_enable_clk:
    503	pm_runtime_put_sync(dev);
    504	pm_runtime_disable(dev);
    505err_unregister_usb_phy:
    506	usb_phy_generic_unregister(glue->usb_phy);
    507	return ret;
    508}
    509
    510static int mtk_musb_remove(struct platform_device *pdev)
    511{
    512	struct mtk_glue *glue = platform_get_drvdata(pdev);
    513	struct platform_device *usb_phy = glue->usb_phy;
    514
    515	platform_device_unregister(glue->musb_pdev);
    516	usb_phy_generic_unregister(usb_phy);
    517
    518	return 0;
    519}
    520
    521#ifdef CONFIG_OF
    522static const struct of_device_id mtk_musb_match[] = {
    523	{.compatible = "mediatek,mtk-musb",},
    524	{},
    525};
    526MODULE_DEVICE_TABLE(of, mtk_musb_match);
    527#endif
    528
    529static struct platform_driver mtk_musb_driver = {
    530	.probe = mtk_musb_probe,
    531	.remove = mtk_musb_remove,
    532	.driver = {
    533		   .name = "musb-mtk",
    534		   .of_match_table = of_match_ptr(mtk_musb_match),
    535	},
    536};
    537
    538module_platform_driver(mtk_musb_driver);
    539
    540MODULE_DESCRIPTION("MediaTek MUSB Glue Layer");
    541MODULE_AUTHOR("Min Guo <min.guo@mediatek.com>");
    542MODULE_LICENSE("GPL v2");