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

devices.c (8546B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * linux/arch/arm/mach-mmp/devices.c
      4 */
      5
      6#include <linux/init.h>
      7#include <linux/platform_device.h>
      8#include <linux/dma-mapping.h>
      9#include <linux/delay.h>
     10
     11#include <asm/irq.h>
     12#include "irqs.h"
     13#include "devices.h"
     14#include <linux/soc/mmp/cputype.h>
     15#include "regs-usb.h"
     16
     17int __init mmp_register_device(struct mmp_device_desc *desc,
     18				void *data, size_t size)
     19{
     20	struct platform_device *pdev;
     21	struct resource res[2 + MAX_RESOURCE_DMA];
     22	int i, ret = 0, nres = 0;
     23
     24	pdev = platform_device_alloc(desc->drv_name, desc->id);
     25	if (pdev == NULL)
     26		return -ENOMEM;
     27
     28	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
     29
     30	memset(res, 0, sizeof(res));
     31
     32	if (desc->start != -1ul && desc->size > 0) {
     33		res[nres].start	= desc->start;
     34		res[nres].end	= desc->start + desc->size - 1;
     35		res[nres].flags	= IORESOURCE_MEM;
     36		nres++;
     37	}
     38
     39	if (desc->irq != NO_IRQ) {
     40		res[nres].start	= desc->irq;
     41		res[nres].end	= desc->irq;
     42		res[nres].flags	= IORESOURCE_IRQ;
     43		nres++;
     44	}
     45
     46	for (i = 0; i < MAX_RESOURCE_DMA; i++, nres++) {
     47		if (desc->dma[i] == 0)
     48			break;
     49
     50		res[nres].start	= desc->dma[i];
     51		res[nres].end	= desc->dma[i];
     52		res[nres].flags	= IORESOURCE_DMA;
     53	}
     54
     55	ret = platform_device_add_resources(pdev, res, nres);
     56	if (ret) {
     57		platform_device_put(pdev);
     58		return ret;
     59	}
     60
     61	if (data && size) {
     62		ret = platform_device_add_data(pdev, data, size);
     63		if (ret) {
     64			platform_device_put(pdev);
     65			return ret;
     66		}
     67	}
     68
     69	return platform_device_add(pdev);
     70}
     71
     72#if IS_ENABLED(CONFIG_USB) || IS_ENABLED(CONFIG_USB_GADGET)
     73#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV)
     74#if IS_ENABLED(CONFIG_CPU_PXA910) || IS_ENABLED(CONFIG_CPU_PXA168)
     75
     76/*****************************************************************************
     77 * The registers read/write routines
     78 *****************************************************************************/
     79
     80static unsigned int u2o_get(void __iomem *base, unsigned int offset)
     81{
     82	return readl_relaxed(base + offset);
     83}
     84
     85static void u2o_set(void __iomem *base, unsigned int offset,
     86		unsigned int value)
     87{
     88	u32 reg;
     89
     90	reg = readl_relaxed(base + offset);
     91	reg |= value;
     92	writel_relaxed(reg, base + offset);
     93	readl_relaxed(base + offset);
     94}
     95
     96static void u2o_clear(void __iomem *base, unsigned int offset,
     97		unsigned int value)
     98{
     99	u32 reg;
    100
    101	reg = readl_relaxed(base + offset);
    102	reg &= ~value;
    103	writel_relaxed(reg, base + offset);
    104	readl_relaxed(base + offset);
    105}
    106
    107static void u2o_write(void __iomem *base, unsigned int offset,
    108		unsigned int value)
    109{
    110	writel_relaxed(value, base + offset);
    111	readl_relaxed(base + offset);
    112}
    113
    114
    115static DEFINE_MUTEX(phy_lock);
    116static int phy_init_cnt;
    117
    118static int usb_phy_init_internal(void __iomem *base)
    119{
    120	int loops;
    121
    122	pr_info("Init usb phy!!!\n");
    123
    124	/* Initialize the USB PHY power */
    125	if (cpu_is_pxa910()) {
    126		u2o_set(base, UTMI_CTRL, (1<<UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
    127			| (1<<UTMI_CTRL_PU_REF_SHIFT));
    128	}
    129
    130	u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
    131	u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
    132
    133	/* UTMI_PLL settings */
    134	u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
    135		| UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
    136		| UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
    137		| UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);
    138
    139	u2o_set(base, UTMI_PLL, 0xee<<UTMI_PLL_FBDIV_SHIFT
    140		| 0xb<<UTMI_PLL_REFDIV_SHIFT | 3<<UTMI_PLL_PLLVDD18_SHIFT
    141		| 3<<UTMI_PLL_PLLVDD12_SHIFT | 3<<UTMI_PLL_PLLCALI12_SHIFT
    142		| 1<<UTMI_PLL_ICP_SHIFT | 3<<UTMI_PLL_KVCO_SHIFT);
    143
    144	/* UTMI_TX */
    145	u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK
    146		| UTMI_TX_TXVDD12_MASK | UTMI_TX_CK60_PHSEL_MASK
    147		| UTMI_TX_IMPCAL_VTH_MASK | UTMI_TX_REG_EXT_FS_RCAL_MASK
    148		| UTMI_TX_AMP_MASK);
    149	u2o_set(base, UTMI_TX, 3<<UTMI_TX_TXVDD12_SHIFT
    150		| 4<<UTMI_TX_CK60_PHSEL_SHIFT | 4<<UTMI_TX_IMPCAL_VTH_SHIFT
    151		| 8<<UTMI_TX_REG_EXT_FS_RCAL_SHIFT | 3<<UTMI_TX_AMP_SHIFT);
    152
    153	/* UTMI_RX */
    154	u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
    155		| UTMI_REG_SQ_LENGTH_MASK);
    156	u2o_set(base, UTMI_RX, 7<<UTMI_RX_SQ_THRESH_SHIFT
    157		| 2<<UTMI_REG_SQ_LENGTH_SHIFT);
    158
    159	/* UTMI_IVREF */
    160	if (cpu_is_pxa168())
    161		/* fixing Microsoft Altair board interface with NEC hub issue -
    162		 * Set UTMI_IVREF from 0x4a3 to 0x4bf */
    163		u2o_write(base, UTMI_IVREF, 0x4bf);
    164
    165	/* toggle VCOCAL_START bit of UTMI_PLL */
    166	udelay(200);
    167	u2o_set(base, UTMI_PLL, VCOCAL_START);
    168	udelay(40);
    169	u2o_clear(base, UTMI_PLL, VCOCAL_START);
    170
    171	/* toggle REG_RCAL_START bit of UTMI_TX */
    172	udelay(400);
    173	u2o_set(base, UTMI_TX, REG_RCAL_START);
    174	udelay(40);
    175	u2o_clear(base, UTMI_TX, REG_RCAL_START);
    176	udelay(400);
    177
    178	/* Make sure PHY PLL is ready */
    179	loops = 0;
    180	while ((u2o_get(base, UTMI_PLL) & PLL_READY) == 0) {
    181		mdelay(1);
    182		loops++;
    183		if (loops > 100) {
    184			printk(KERN_WARNING "calibrate timeout, UTMI_PLL %x\n",
    185				u2o_get(base, UTMI_PLL));
    186			break;
    187		}
    188	}
    189
    190	if (cpu_is_pxa168()) {
    191		u2o_set(base, UTMI_RESERVE, 1 << 5);
    192		/* Turn on UTMI PHY OTG extension */
    193		u2o_write(base, UTMI_OTG_ADDON, 1);
    194	}
    195
    196	return 0;
    197}
    198
    199static int usb_phy_deinit_internal(void __iomem *base)
    200{
    201	pr_info("Deinit usb phy!!!\n");
    202
    203	if (cpu_is_pxa168())
    204		u2o_clear(base, UTMI_OTG_ADDON, UTMI_OTG_ADDON_OTG_ON);
    205
    206	u2o_clear(base, UTMI_CTRL, UTMI_CTRL_RXBUF_PDWN);
    207	u2o_clear(base, UTMI_CTRL, UTMI_CTRL_TXBUF_PDWN);
    208	u2o_clear(base, UTMI_CTRL, UTMI_CTRL_USB_CLK_EN);
    209	u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
    210	u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
    211
    212	return 0;
    213}
    214
    215int pxa_usb_phy_init(void __iomem *phy_reg)
    216{
    217	mutex_lock(&phy_lock);
    218	if (phy_init_cnt++ == 0)
    219		usb_phy_init_internal(phy_reg);
    220	mutex_unlock(&phy_lock);
    221	return 0;
    222}
    223
    224void pxa_usb_phy_deinit(void __iomem *phy_reg)
    225{
    226	WARN_ON(phy_init_cnt == 0);
    227
    228	mutex_lock(&phy_lock);
    229	if (--phy_init_cnt == 0)
    230		usb_phy_deinit_internal(phy_reg);
    231	mutex_unlock(&phy_lock);
    232}
    233#endif
    234#endif
    235#endif
    236
    237#if IS_ENABLED(CONFIG_USB_SUPPORT)
    238static u64 __maybe_unused usb_dma_mask = ~(u32)0;
    239
    240#if IS_ENABLED(CONFIG_PHY_PXA_USB)
    241struct resource pxa168_usb_phy_resources[] = {
    242	[0] = {
    243		.start	= PXA168_U2O_PHYBASE,
    244		.end	= PXA168_U2O_PHYBASE + USB_PHY_RANGE,
    245		.flags	= IORESOURCE_MEM,
    246	},
    247};
    248
    249struct platform_device pxa168_device_usb_phy = {
    250	.name		= "pxa-usb-phy",
    251	.id		= -1,
    252	.resource	= pxa168_usb_phy_resources,
    253	.num_resources	= ARRAY_SIZE(pxa168_usb_phy_resources),
    254	.dev		=  {
    255		.dma_mask	= &usb_dma_mask,
    256		.coherent_dma_mask = 0xffffffff,
    257	}
    258};
    259#endif /* CONFIG_PHY_PXA_USB */
    260
    261#if IS_ENABLED(CONFIG_USB_MV_UDC)
    262struct resource pxa168_u2o_resources[] = {
    263	/* regbase */
    264	[0] = {
    265		.start	= PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
    266		.end	= PXA168_U2O_REGBASE + USB_REG_RANGE,
    267		.flags	= IORESOURCE_MEM,
    268		.name	= "capregs",
    269	},
    270	/* phybase */
    271	[1] = {
    272		.start	= PXA168_U2O_PHYBASE,
    273		.end	= PXA168_U2O_PHYBASE + USB_PHY_RANGE,
    274		.flags	= IORESOURCE_MEM,
    275		.name	= "phyregs",
    276	},
    277	[2] = {
    278		.start	= IRQ_PXA168_USB1,
    279		.end	= IRQ_PXA168_USB1,
    280		.flags	= IORESOURCE_IRQ,
    281	},
    282};
    283
    284struct platform_device pxa168_device_u2o = {
    285	.name		= "mv-udc",
    286	.id		= -1,
    287	.resource	= pxa168_u2o_resources,
    288	.num_resources	= ARRAY_SIZE(pxa168_u2o_resources),
    289	.dev		=  {
    290		.dma_mask	= &usb_dma_mask,
    291		.coherent_dma_mask = 0xffffffff,
    292	}
    293};
    294#endif /* CONFIG_USB_MV_UDC */
    295
    296#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
    297struct resource pxa168_u2oehci_resources[] = {
    298	[0] = {
    299		.start	= PXA168_U2O_REGBASE,
    300		.end	= PXA168_U2O_REGBASE + USB_REG_RANGE,
    301		.flags	= IORESOURCE_MEM,
    302	},
    303	[1] = {
    304		.start	= IRQ_PXA168_USB1,
    305		.end	= IRQ_PXA168_USB1,
    306		.flags	= IORESOURCE_IRQ,
    307	},
    308};
    309
    310struct platform_device pxa168_device_u2oehci = {
    311	.name		= "pxa-u2oehci",
    312	.id		= -1,
    313	.dev		= {
    314		.dma_mask		= &usb_dma_mask,
    315		.coherent_dma_mask	= 0xffffffff,
    316	},
    317
    318	.num_resources	= ARRAY_SIZE(pxa168_u2oehci_resources),
    319	.resource	= pxa168_u2oehci_resources,
    320};
    321#endif
    322
    323#if IS_ENABLED(CONFIG_USB_MV_OTG)
    324struct resource pxa168_u2ootg_resources[] = {
    325	/* regbase */
    326	[0] = {
    327		.start	= PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
    328		.end	= PXA168_U2O_REGBASE + USB_REG_RANGE,
    329		.flags	= IORESOURCE_MEM,
    330		.name	= "capregs",
    331	},
    332	/* phybase */
    333	[1] = {
    334		.start	= PXA168_U2O_PHYBASE,
    335		.end	= PXA168_U2O_PHYBASE + USB_PHY_RANGE,
    336		.flags	= IORESOURCE_MEM,
    337		.name	= "phyregs",
    338	},
    339	[2] = {
    340		.start	= IRQ_PXA168_USB1,
    341		.end	= IRQ_PXA168_USB1,
    342		.flags	= IORESOURCE_IRQ,
    343	},
    344};
    345
    346struct platform_device pxa168_device_u2ootg = {
    347	.name		= "mv-otg",
    348	.id		= -1,
    349	.dev  = {
    350		.dma_mask          = &usb_dma_mask,
    351		.coherent_dma_mask = 0xffffffff,
    352	},
    353
    354	.num_resources	= ARRAY_SIZE(pxa168_u2ootg_resources),
    355	.resource      = pxa168_u2ootg_resources,
    356};
    357#endif /* CONFIG_USB_MV_OTG */
    358
    359#endif