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

usb-tusb6010.c (5348B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * linux/arch/arm/mach-omap2/usb-tusb6010.c
      4 *
      5 * Copyright (C) 2006 Nokia Corporation
      6 */
      7
      8#include <linux/err.h>
      9#include <linux/string.h>
     10#include <linux/types.h>
     11#include <linux/errno.h>
     12#include <linux/delay.h>
     13#include <linux/platform_device.h>
     14#include <linux/gpio.h>
     15#include <linux/export.h>
     16#include <linux/platform_data/usb-omap.h>
     17
     18#include <linux/usb/musb.h>
     19
     20#include "gpmc.h"
     21
     22static u8		async_cs, sync_cs;
     23static unsigned		refclk_psec;
     24
     25static struct gpmc_settings tusb_async = {
     26	.wait_on_read	= true,
     27	.wait_on_write	= true,
     28	.device_width	= GPMC_DEVWIDTH_16BIT,
     29	.mux_add_data	= GPMC_MUX_AD,
     30};
     31
     32static struct gpmc_settings tusb_sync = {
     33	.burst_read	= true,
     34	.burst_write	= true,
     35	.sync_read	= true,
     36	.sync_write	= true,
     37	.wait_on_read	= true,
     38	.wait_on_write	= true,
     39	.burst_len	= GPMC_BURST_16,
     40	.device_width	= GPMC_DEVWIDTH_16BIT,
     41	.mux_add_data	= GPMC_MUX_AD,
     42};
     43
     44/* NOTE:  timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
     45
     46static int tusb_set_async_mode(unsigned sysclk_ps)
     47{
     48	struct gpmc_device_timings dev_t;
     49	struct gpmc_timings	t;
     50	unsigned		t_acsnh_advnh = sysclk_ps + 3000;
     51
     52	memset(&dev_t, 0, sizeof(dev_t));
     53
     54	dev_t.t_ceasu = 8 * 1000;
     55	dev_t.t_avdasu = t_acsnh_advnh - 7000;
     56	dev_t.t_ce_avd = 1000;
     57	dev_t.t_avdp_r = t_acsnh_advnh;
     58	dev_t.t_oeasu = t_acsnh_advnh + 1000;
     59	dev_t.t_oe = 300;
     60	dev_t.t_cez_r = 7000;
     61	dev_t.t_cez_w = dev_t.t_cez_r;
     62	dev_t.t_avdp_w = t_acsnh_advnh;
     63	dev_t.t_weasu = t_acsnh_advnh + 1000;
     64	dev_t.t_wpl = 300;
     65	dev_t.cyc_aavdh_we = 1;
     66
     67	gpmc_calc_timings(&t, &tusb_async, &dev_t);
     68
     69	return gpmc_cs_set_timings(async_cs, &t, &tusb_async);
     70}
     71
     72static int tusb_set_sync_mode(unsigned sysclk_ps)
     73{
     74	struct gpmc_device_timings dev_t;
     75	struct gpmc_timings	t;
     76	unsigned		t_scsnh_advnh = sysclk_ps + 3000;
     77
     78	memset(&dev_t, 0, sizeof(dev_t));
     79
     80	dev_t.clk = 11100;
     81	dev_t.t_bacc = 1000;
     82	dev_t.t_ces = 1000;
     83	dev_t.t_ceasu = 8 * 1000;
     84	dev_t.t_avdasu = t_scsnh_advnh - 7000;
     85	dev_t.t_ce_avd = 1000;
     86	dev_t.t_avdp_r = t_scsnh_advnh;
     87	dev_t.cyc_aavdh_oe = 3;
     88	dev_t.cyc_oe = 5;
     89	dev_t.t_ce_rdyz = 7000;
     90	dev_t.t_avdp_w = t_scsnh_advnh;
     91	dev_t.cyc_aavdh_we = 3;
     92	dev_t.cyc_wpl = 6;
     93
     94	gpmc_calc_timings(&t, &tusb_sync, &dev_t);
     95
     96	return gpmc_cs_set_timings(sync_cs, &t, &tusb_sync);
     97}
     98
     99/* tusb driver calls this when it changes the chip's clocking */
    100int tusb6010_platform_retime(unsigned is_refclk)
    101{
    102	static const char	error[] =
    103		KERN_ERR "tusb6010 %s retime error %d\n";
    104
    105	unsigned	sysclk_ps;
    106	int		status;
    107
    108	if (!refclk_psec)
    109		return -ENODEV;
    110
    111	sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
    112
    113	status = tusb_set_async_mode(sysclk_ps);
    114	if (status < 0) {
    115		printk(error, "async", status);
    116		goto done;
    117	}
    118	status = tusb_set_sync_mode(sysclk_ps);
    119	if (status < 0)
    120		printk(error, "sync", status);
    121done:
    122	return status;
    123}
    124EXPORT_SYMBOL_GPL(tusb6010_platform_retime);
    125
    126static struct resource tusb_resources[] = {
    127	/* Order is significant!  The start/end fields
    128	 * are updated during setup..
    129	 */
    130	{ /* Asynchronous access */
    131		.flags	= IORESOURCE_MEM,
    132	},
    133	{ /* Synchronous access */
    134		.flags	= IORESOURCE_MEM,
    135	},
    136	{ /* IRQ */
    137		.name	= "mc",
    138		.flags	= IORESOURCE_IRQ,
    139	},
    140};
    141
    142static u64 tusb_dmamask = ~(u32)0;
    143
    144static struct platform_device tusb_device = {
    145	.name		= "musb-tusb",
    146	.id		= -1,
    147	.dev = {
    148		.dma_mask		= &tusb_dmamask,
    149		.coherent_dma_mask	= 0xffffffff,
    150	},
    151	.num_resources	= ARRAY_SIZE(tusb_resources),
    152	.resource	= tusb_resources,
    153};
    154
    155
    156/* this may be called only from board-*.c setup code */
    157int __init
    158tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
    159		unsigned ps_refclk, unsigned waitpin,
    160		unsigned async, unsigned sync,
    161		unsigned irq, unsigned dmachan)
    162{
    163	int		status;
    164	static char	error[] __initdata =
    165		KERN_ERR "tusb6010 init error %d, %d\n";
    166
    167	/* ASYNC region, primarily for PIO */
    168	status = gpmc_cs_request(async, SZ_16M, (unsigned long *)
    169				&tusb_resources[0].start);
    170	if (status < 0) {
    171		printk(error, 1, status);
    172		return status;
    173	}
    174	tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
    175	tusb_async.wait_pin = waitpin;
    176	async_cs = async;
    177
    178	status = gpmc_cs_program_settings(async_cs, &tusb_async);
    179	if (status < 0)
    180		return status;
    181
    182	/* SYNC region, primarily for DMA */
    183	status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
    184				&tusb_resources[1].start);
    185	if (status < 0) {
    186		printk(error, 2, status);
    187		return status;
    188	}
    189	tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
    190	tusb_sync.wait_pin = waitpin;
    191	sync_cs = sync;
    192
    193	status = gpmc_cs_program_settings(sync_cs, &tusb_sync);
    194	if (status < 0)
    195		return status;
    196
    197	/* IRQ */
    198	status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
    199	if (status < 0) {
    200		printk(error, 3, status);
    201		return status;
    202	}
    203	tusb_resources[2].start = gpio_to_irq(irq);
    204
    205	/* set up memory timings ... can speed them up later */
    206	if (!ps_refclk) {
    207		printk(error, 4, status);
    208		return -ENODEV;
    209	}
    210	refclk_psec = ps_refclk;
    211	status = tusb6010_platform_retime(1);
    212	if (status < 0) {
    213		printk(error, 5, status);
    214		return status;
    215	}
    216
    217	/* finish device setup ... */
    218	if (!data) {
    219		printk(error, 6, status);
    220		return -ENODEV;
    221	}
    222	tusb_device.dev.platform_data = data;
    223
    224	/* so far so good ... register the device */
    225	status = platform_device_register(&tusb_device);
    226	if (status < 0) {
    227		printk(error, 7, status);
    228		return status;
    229	}
    230	return 0;
    231}