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

isp1760-core.c (23894B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Driver for the NXP ISP1760 chip
      4 *
      5 * Copyright 2021 Linaro, Rui Miguel Silva
      6 * Copyright 2014 Laurent Pinchart
      7 * Copyright 2007 Sebastian Siewior
      8 *
      9 * Contacts:
     10 *	Sebastian Siewior <bigeasy@linutronix.de>
     11 *	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
     12 *	Rui Miguel Silva <rui.silva@linaro.org>
     13 */
     14
     15#include <linux/delay.h>
     16#include <linux/gpio/consumer.h>
     17#include <linux/io.h>
     18#include <linux/kernel.h>
     19#include <linux/module.h>
     20#include <linux/regmap.h>
     21#include <linux/slab.h>
     22#include <linux/usb.h>
     23
     24#include "isp1760-core.h"
     25#include "isp1760-hcd.h"
     26#include "isp1760-regs.h"
     27#include "isp1760-udc.h"
     28
     29static int isp1760_init_core(struct isp1760_device *isp)
     30{
     31	struct isp1760_hcd *hcd = &isp->hcd;
     32	struct isp1760_udc *udc = &isp->udc;
     33	u32 otg_ctrl;
     34
     35	/* Low-level chip reset */
     36	if (isp->rst_gpio) {
     37		gpiod_set_value_cansleep(isp->rst_gpio, 1);
     38		msleep(50);
     39		gpiod_set_value_cansleep(isp->rst_gpio, 0);
     40	}
     41
     42	/*
     43	 * Reset the host controller, including the CPU interface
     44	 * configuration.
     45	 */
     46	isp1760_field_set(hcd->fields, SW_RESET_RESET_ALL);
     47	msleep(100);
     48
     49	/* Setup HW Mode Control: This assumes a level active-low interrupt */
     50	if ((isp->devflags & ISP1760_FLAG_ANALOG_OC) && hcd->is_isp1763) {
     51		dev_err(isp->dev, "isp1763 analog overcurrent not available\n");
     52		return -EINVAL;
     53	}
     54
     55	if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_16)
     56		isp1760_field_clear(hcd->fields, HW_DATA_BUS_WIDTH);
     57	if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_8)
     58		isp1760_field_set(hcd->fields, HW_DATA_BUS_WIDTH);
     59	if (isp->devflags & ISP1760_FLAG_ANALOG_OC)
     60		isp1760_field_set(hcd->fields, HW_ANA_DIGI_OC);
     61	if (isp->devflags & ISP1760_FLAG_DACK_POL_HIGH)
     62		isp1760_field_set(hcd->fields, HW_DACK_POL_HIGH);
     63	if (isp->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
     64		isp1760_field_set(hcd->fields, HW_DREQ_POL_HIGH);
     65	if (isp->devflags & ISP1760_FLAG_INTR_POL_HIGH)
     66		isp1760_field_set(hcd->fields, HW_INTR_HIGH_ACT);
     67	if (isp->devflags & ISP1760_FLAG_INTR_EDGE_TRIG)
     68		isp1760_field_set(hcd->fields, HW_INTR_EDGE_TRIG);
     69
     70	/*
     71	 * The ISP1761 has a dedicated DC IRQ line but supports sharing the HC
     72	 * IRQ line for both the host and device controllers. Hardcode IRQ
     73	 * sharing for now and disable the DC interrupts globally to avoid
     74	 * spurious interrupts during HCD registration.
     75	 */
     76	if (isp->devflags & ISP1760_FLAG_ISP1761) {
     77		isp1760_reg_write(udc->regs, ISP176x_DC_MODE, 0);
     78		isp1760_field_set(hcd->fields, HW_COMN_IRQ);
     79	}
     80
     81	/*
     82	 * PORT 1 Control register of the ISP1760 is the OTG control register
     83	 * on ISP1761.
     84	 *
     85	 * TODO: Really support OTG. For now we configure port 1 in device mode
     86	 */
     87	if (isp->devflags & ISP1760_FLAG_ISP1761) {
     88		if (isp->devflags & ISP1760_FLAG_PERIPHERAL_EN) {
     89			otg_ctrl = (ISP176x_HW_DM_PULLDOWN_CLEAR |
     90				    ISP176x_HW_DP_PULLDOWN_CLEAR |
     91				    ISP176x_HW_OTG_DISABLE);
     92		} else {
     93			otg_ctrl = (ISP176x_HW_SW_SEL_HC_DC_CLEAR |
     94				    ISP176x_HW_VBUS_DRV |
     95				    ISP176x_HW_SEL_CP_EXT);
     96		}
     97		isp1760_reg_write(hcd->regs, ISP176x_HC_OTG_CTRL, otg_ctrl);
     98	}
     99
    100	dev_info(isp->dev, "%s bus width: %u, oc: %s\n",
    101		 hcd->is_isp1763 ? "isp1763" : "isp1760",
    102		 isp->devflags & ISP1760_FLAG_BUS_WIDTH_8 ? 8 :
    103		 isp->devflags & ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32,
    104		 hcd->is_isp1763 ? "not available" :
    105		 isp->devflags & ISP1760_FLAG_ANALOG_OC ? "analog" : "digital");
    106
    107	return 0;
    108}
    109
    110void isp1760_set_pullup(struct isp1760_device *isp, bool enable)
    111{
    112	struct isp1760_udc *udc = &isp->udc;
    113
    114	if (enable)
    115		isp1760_field_set(udc->fields, HW_DP_PULLUP);
    116	else
    117		isp1760_field_set(udc->fields, HW_DP_PULLUP_CLEAR);
    118}
    119
    120/*
    121 * ISP1760/61:
    122 *
    123 * 60kb divided in:
    124 * - 32 blocks @ 256  bytes
    125 * - 20 blocks @ 1024 bytes
    126 * -  4 blocks @ 8192 bytes
    127 */
    128static const struct isp1760_memory_layout isp176x_memory_conf = {
    129	.blocks[0]		= 32,
    130	.blocks_size[0]		= 256,
    131	.blocks[1]		= 20,
    132	.blocks_size[1]		= 1024,
    133	.blocks[2]		= 4,
    134	.blocks_size[2]		= 8192,
    135
    136	.slot_num		= 32,
    137	.payload_blocks		= 32 + 20 + 4,
    138	.payload_area_size	= 0xf000,
    139};
    140
    141/*
    142 * ISP1763:
    143 *
    144 * 20kb divided in:
    145 * - 8 blocks @ 256  bytes
    146 * - 2 blocks @ 1024 bytes
    147 * - 4 blocks @ 4096 bytes
    148 */
    149static const struct isp1760_memory_layout isp1763_memory_conf = {
    150	.blocks[0]		= 8,
    151	.blocks_size[0]		= 256,
    152	.blocks[1]		= 2,
    153	.blocks_size[1]		= 1024,
    154	.blocks[2]		= 4,
    155	.blocks_size[2]		= 4096,
    156
    157	.slot_num		= 16,
    158	.payload_blocks		= 8 + 2 + 4,
    159	.payload_area_size	= 0x5000,
    160};
    161
    162static const struct regmap_range isp176x_hc_volatile_ranges[] = {
    163	regmap_reg_range(ISP176x_HC_USBCMD, ISP176x_HC_ATL_PTD_LASTPTD),
    164	regmap_reg_range(ISP176x_HC_BUFFER_STATUS, ISP176x_HC_MEMORY),
    165	regmap_reg_range(ISP176x_HC_INTERRUPT, ISP176x_HC_OTG_CTRL_CLEAR),
    166};
    167
    168static const struct regmap_access_table isp176x_hc_volatile_table = {
    169	.yes_ranges	= isp176x_hc_volatile_ranges,
    170	.n_yes_ranges	= ARRAY_SIZE(isp176x_hc_volatile_ranges),
    171};
    172
    173static const struct regmap_config isp1760_hc_regmap_conf = {
    174	.name = "isp1760-hc",
    175	.reg_bits = 16,
    176	.reg_stride = 4,
    177	.val_bits = 32,
    178	.fast_io = true,
    179	.max_register = ISP176x_HC_OTG_CTRL_CLEAR,
    180	.volatile_table = &isp176x_hc_volatile_table,
    181};
    182
    183static const struct reg_field isp1760_hc_reg_fields[] = {
    184	[HCS_PPC]		= REG_FIELD(ISP176x_HC_HCSPARAMS, 4, 4),
    185	[HCS_N_PORTS]		= REG_FIELD(ISP176x_HC_HCSPARAMS, 0, 3),
    186	[HCC_ISOC_CACHE]	= REG_FIELD(ISP176x_HC_HCCPARAMS, 7, 7),
    187	[HCC_ISOC_THRES]	= REG_FIELD(ISP176x_HC_HCCPARAMS, 4, 6),
    188	[CMD_LRESET]		= REG_FIELD(ISP176x_HC_USBCMD, 7, 7),
    189	[CMD_RESET]		= REG_FIELD(ISP176x_HC_USBCMD, 1, 1),
    190	[CMD_RUN]		= REG_FIELD(ISP176x_HC_USBCMD, 0, 0),
    191	[STS_PCD]		= REG_FIELD(ISP176x_HC_USBSTS, 2, 2),
    192	[HC_FRINDEX]		= REG_FIELD(ISP176x_HC_FRINDEX, 0, 13),
    193	[FLAG_CF]		= REG_FIELD(ISP176x_HC_CONFIGFLAG, 0, 0),
    194	[HC_ISO_PTD_DONEMAP]	= REG_FIELD(ISP176x_HC_ISO_PTD_DONEMAP, 0, 31),
    195	[HC_ISO_PTD_SKIPMAP]	= REG_FIELD(ISP176x_HC_ISO_PTD_SKIPMAP, 0, 31),
    196	[HC_ISO_PTD_LASTPTD]	= REG_FIELD(ISP176x_HC_ISO_PTD_LASTPTD, 0, 31),
    197	[HC_INT_PTD_DONEMAP]	= REG_FIELD(ISP176x_HC_INT_PTD_DONEMAP, 0, 31),
    198	[HC_INT_PTD_SKIPMAP]	= REG_FIELD(ISP176x_HC_INT_PTD_SKIPMAP, 0, 31),
    199	[HC_INT_PTD_LASTPTD]	= REG_FIELD(ISP176x_HC_INT_PTD_LASTPTD, 0, 31),
    200	[HC_ATL_PTD_DONEMAP]	= REG_FIELD(ISP176x_HC_ATL_PTD_DONEMAP, 0, 31),
    201	[HC_ATL_PTD_SKIPMAP]	= REG_FIELD(ISP176x_HC_ATL_PTD_SKIPMAP, 0, 31),
    202	[HC_ATL_PTD_LASTPTD]	= REG_FIELD(ISP176x_HC_ATL_PTD_LASTPTD, 0, 31),
    203	[PORT_OWNER]		= REG_FIELD(ISP176x_HC_PORTSC1, 13, 13),
    204	[PORT_POWER]		= REG_FIELD(ISP176x_HC_PORTSC1, 12, 12),
    205	[PORT_LSTATUS]		= REG_FIELD(ISP176x_HC_PORTSC1, 10, 11),
    206	[PORT_RESET]		= REG_FIELD(ISP176x_HC_PORTSC1, 8, 8),
    207	[PORT_SUSPEND]		= REG_FIELD(ISP176x_HC_PORTSC1, 7, 7),
    208	[PORT_RESUME]		= REG_FIELD(ISP176x_HC_PORTSC1, 6, 6),
    209	[PORT_PE]		= REG_FIELD(ISP176x_HC_PORTSC1, 2, 2),
    210	[PORT_CSC]		= REG_FIELD(ISP176x_HC_PORTSC1, 1, 1),
    211	[PORT_CONNECT]		= REG_FIELD(ISP176x_HC_PORTSC1, 0, 0),
    212	[ALL_ATX_RESET]		= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 31, 31),
    213	[HW_ANA_DIGI_OC]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 15, 15),
    214	[HW_COMN_IRQ]		= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 10, 10),
    215	[HW_DATA_BUS_WIDTH]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 8, 8),
    216	[HW_DACK_POL_HIGH]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 6, 6),
    217	[HW_DREQ_POL_HIGH]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 5, 5),
    218	[HW_INTR_HIGH_ACT]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 2, 2),
    219	[HW_INTR_EDGE_TRIG]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 1, 1),
    220	[HW_GLOBAL_INTR_EN]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 0, 0),
    221	[HC_CHIP_REV]		= REG_FIELD(ISP176x_HC_CHIP_ID, 16, 31),
    222	[HC_CHIP_ID_HIGH]	= REG_FIELD(ISP176x_HC_CHIP_ID, 8, 15),
    223	[HC_CHIP_ID_LOW]	= REG_FIELD(ISP176x_HC_CHIP_ID, 0, 7),
    224	[HC_SCRATCH]		= REG_FIELD(ISP176x_HC_SCRATCH, 0, 31),
    225	[SW_RESET_RESET_ALL]	= REG_FIELD(ISP176x_HC_RESET, 0, 0),
    226	[ISO_BUF_FILL]		= REG_FIELD(ISP176x_HC_BUFFER_STATUS, 2, 2),
    227	[INT_BUF_FILL]		= REG_FIELD(ISP176x_HC_BUFFER_STATUS, 1, 1),
    228	[ATL_BUF_FILL]		= REG_FIELD(ISP176x_HC_BUFFER_STATUS, 0, 0),
    229	[MEM_BANK_SEL]		= REG_FIELD(ISP176x_HC_MEMORY, 16, 17),
    230	[MEM_START_ADDR]	= REG_FIELD(ISP176x_HC_MEMORY, 0, 15),
    231	[HC_INTERRUPT]		= REG_FIELD(ISP176x_HC_INTERRUPT, 0, 9),
    232	[HC_ATL_IRQ_ENABLE]	= REG_FIELD(ISP176x_HC_INTERRUPT_ENABLE, 8, 8),
    233	[HC_INT_IRQ_ENABLE]	= REG_FIELD(ISP176x_HC_INTERRUPT_ENABLE, 7, 7),
    234	[HC_ISO_IRQ_MASK_OR]	= REG_FIELD(ISP176x_HC_ISO_IRQ_MASK_OR, 0, 31),
    235	[HC_INT_IRQ_MASK_OR]	= REG_FIELD(ISP176x_HC_INT_IRQ_MASK_OR, 0, 31),
    236	[HC_ATL_IRQ_MASK_OR]	= REG_FIELD(ISP176x_HC_ATL_IRQ_MASK_OR, 0, 31),
    237	[HC_ISO_IRQ_MASK_AND]	= REG_FIELD(ISP176x_HC_ISO_IRQ_MASK_AND, 0, 31),
    238	[HC_INT_IRQ_MASK_AND]	= REG_FIELD(ISP176x_HC_INT_IRQ_MASK_AND, 0, 31),
    239	[HC_ATL_IRQ_MASK_AND]	= REG_FIELD(ISP176x_HC_ATL_IRQ_MASK_AND, 0, 31),
    240	[HW_OTG_DISABLE_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 26, 26),
    241	[HW_SW_SEL_HC_DC_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 23, 23),
    242	[HW_VBUS_DRV_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 20, 20),
    243	[HW_SEL_CP_EXT_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 19, 19),
    244	[HW_DM_PULLDOWN_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 18, 18),
    245	[HW_DP_PULLDOWN_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 17, 17),
    246	[HW_DP_PULLUP_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 16, 16),
    247	[HW_OTG_DISABLE]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 10, 10),
    248	[HW_SW_SEL_HC_DC]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 7, 7),
    249	[HW_VBUS_DRV]		= REG_FIELD(ISP176x_HC_OTG_CTRL, 4, 4),
    250	[HW_SEL_CP_EXT]		= REG_FIELD(ISP176x_HC_OTG_CTRL, 3, 3),
    251	[HW_DM_PULLDOWN]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 2, 2),
    252	[HW_DP_PULLDOWN]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 1, 1),
    253	[HW_DP_PULLUP]		= REG_FIELD(ISP176x_HC_OTG_CTRL, 0, 0),
    254	/* Make sure the array is sized properly during compilation */
    255	[HC_FIELD_MAX]		= {},
    256};
    257
    258static const struct reg_field isp1763_hc_reg_fields[] = {
    259	[CMD_LRESET]		= REG_FIELD(ISP1763_HC_USBCMD, 7, 7),
    260	[CMD_RESET]		= REG_FIELD(ISP1763_HC_USBCMD, 1, 1),
    261	[CMD_RUN]		= REG_FIELD(ISP1763_HC_USBCMD, 0, 0),
    262	[STS_PCD]		= REG_FIELD(ISP1763_HC_USBSTS, 2, 2),
    263	[HC_FRINDEX]		= REG_FIELD(ISP1763_HC_FRINDEX, 0, 13),
    264	[FLAG_CF]		= REG_FIELD(ISP1763_HC_CONFIGFLAG, 0, 0),
    265	[HC_ISO_PTD_DONEMAP]	= REG_FIELD(ISP1763_HC_ISO_PTD_DONEMAP, 0, 15),
    266	[HC_ISO_PTD_SKIPMAP]	= REG_FIELD(ISP1763_HC_ISO_PTD_SKIPMAP, 0, 15),
    267	[HC_ISO_PTD_LASTPTD]	= REG_FIELD(ISP1763_HC_ISO_PTD_LASTPTD, 0, 15),
    268	[HC_INT_PTD_DONEMAP]	= REG_FIELD(ISP1763_HC_INT_PTD_DONEMAP, 0, 15),
    269	[HC_INT_PTD_SKIPMAP]	= REG_FIELD(ISP1763_HC_INT_PTD_SKIPMAP, 0, 15),
    270	[HC_INT_PTD_LASTPTD]	= REG_FIELD(ISP1763_HC_INT_PTD_LASTPTD, 0, 15),
    271	[HC_ATL_PTD_DONEMAP]	= REG_FIELD(ISP1763_HC_ATL_PTD_DONEMAP, 0, 15),
    272	[HC_ATL_PTD_SKIPMAP]	= REG_FIELD(ISP1763_HC_ATL_PTD_SKIPMAP, 0, 15),
    273	[HC_ATL_PTD_LASTPTD]	= REG_FIELD(ISP1763_HC_ATL_PTD_LASTPTD, 0, 15),
    274	[PORT_OWNER]		= REG_FIELD(ISP1763_HC_PORTSC1, 13, 13),
    275	[PORT_POWER]		= REG_FIELD(ISP1763_HC_PORTSC1, 12, 12),
    276	[PORT_LSTATUS]		= REG_FIELD(ISP1763_HC_PORTSC1, 10, 11),
    277	[PORT_RESET]		= REG_FIELD(ISP1763_HC_PORTSC1, 8, 8),
    278	[PORT_SUSPEND]		= REG_FIELD(ISP1763_HC_PORTSC1, 7, 7),
    279	[PORT_RESUME]		= REG_FIELD(ISP1763_HC_PORTSC1, 6, 6),
    280	[PORT_PE]		= REG_FIELD(ISP1763_HC_PORTSC1, 2, 2),
    281	[PORT_CSC]		= REG_FIELD(ISP1763_HC_PORTSC1, 1, 1),
    282	[PORT_CONNECT]		= REG_FIELD(ISP1763_HC_PORTSC1, 0, 0),
    283	[HW_DATA_BUS_WIDTH]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 4, 4),
    284	[HW_DACK_POL_HIGH]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 6, 6),
    285	[HW_DREQ_POL_HIGH]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 5, 5),
    286	[HW_INTF_LOCK]		= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 3, 3),
    287	[HW_INTR_HIGH_ACT]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 2, 2),
    288	[HW_INTR_EDGE_TRIG]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 1, 1),
    289	[HW_GLOBAL_INTR_EN]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 0, 0),
    290	[SW_RESET_RESET_ATX]	= REG_FIELD(ISP1763_HC_RESET, 3, 3),
    291	[SW_RESET_RESET_ALL]	= REG_FIELD(ISP1763_HC_RESET, 0, 0),
    292	[HC_CHIP_ID_HIGH]	= REG_FIELD(ISP1763_HC_CHIP_ID, 0, 15),
    293	[HC_CHIP_ID_LOW]	= REG_FIELD(ISP1763_HC_CHIP_REV, 8, 15),
    294	[HC_CHIP_REV]		= REG_FIELD(ISP1763_HC_CHIP_REV, 0, 7),
    295	[HC_SCRATCH]		= REG_FIELD(ISP1763_HC_SCRATCH, 0, 15),
    296	[ISO_BUF_FILL]		= REG_FIELD(ISP1763_HC_BUFFER_STATUS, 2, 2),
    297	[INT_BUF_FILL]		= REG_FIELD(ISP1763_HC_BUFFER_STATUS, 1, 1),
    298	[ATL_BUF_FILL]		= REG_FIELD(ISP1763_HC_BUFFER_STATUS, 0, 0),
    299	[MEM_START_ADDR]	= REG_FIELD(ISP1763_HC_MEMORY, 0, 15),
    300	[HC_DATA]		= REG_FIELD(ISP1763_HC_DATA, 0, 15),
    301	[HC_INTERRUPT]		= REG_FIELD(ISP1763_HC_INTERRUPT, 0, 10),
    302	[HC_ATL_IRQ_ENABLE]	= REG_FIELD(ISP1763_HC_INTERRUPT_ENABLE, 8, 8),
    303	[HC_INT_IRQ_ENABLE]	= REG_FIELD(ISP1763_HC_INTERRUPT_ENABLE, 7, 7),
    304	[HC_ISO_IRQ_MASK_OR]	= REG_FIELD(ISP1763_HC_ISO_IRQ_MASK_OR, 0, 15),
    305	[HC_INT_IRQ_MASK_OR]	= REG_FIELD(ISP1763_HC_INT_IRQ_MASK_OR, 0, 15),
    306	[HC_ATL_IRQ_MASK_OR]	= REG_FIELD(ISP1763_HC_ATL_IRQ_MASK_OR, 0, 15),
    307	[HC_ISO_IRQ_MASK_AND]	= REG_FIELD(ISP1763_HC_ISO_IRQ_MASK_AND, 0, 15),
    308	[HC_INT_IRQ_MASK_AND]	= REG_FIELD(ISP1763_HC_INT_IRQ_MASK_AND, 0, 15),
    309	[HC_ATL_IRQ_MASK_AND]	= REG_FIELD(ISP1763_HC_ATL_IRQ_MASK_AND, 0, 15),
    310	[HW_HC_2_DIS]		= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 15, 15),
    311	[HW_OTG_DISABLE]	= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 10, 10),
    312	[HW_SW_SEL_HC_DC]	= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 7, 7),
    313	[HW_VBUS_DRV]		= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 4, 4),
    314	[HW_SEL_CP_EXT]		= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 3, 3),
    315	[HW_DM_PULLDOWN]	= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 2, 2),
    316	[HW_DP_PULLDOWN]	= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 1, 1),
    317	[HW_DP_PULLUP]		= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 0, 0),
    318	[HW_HC_2_DIS_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 15, 15),
    319	[HW_OTG_DISABLE_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 10, 10),
    320	[HW_SW_SEL_HC_DC_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 7, 7),
    321	[HW_VBUS_DRV_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 4, 4),
    322	[HW_SEL_CP_EXT_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 3, 3),
    323	[HW_DM_PULLDOWN_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 2, 2),
    324	[HW_DP_PULLDOWN_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 1, 1),
    325	[HW_DP_PULLUP_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 0, 0),
    326	/* Make sure the array is sized properly during compilation */
    327	[HC_FIELD_MAX]		= {},
    328};
    329
    330static const struct regmap_range isp1763_hc_volatile_ranges[] = {
    331	regmap_reg_range(ISP1763_HC_USBCMD, ISP1763_HC_ATL_PTD_LASTPTD),
    332	regmap_reg_range(ISP1763_HC_BUFFER_STATUS, ISP1763_HC_DATA),
    333	regmap_reg_range(ISP1763_HC_INTERRUPT, ISP1763_HC_OTG_CTRL_CLEAR),
    334};
    335
    336static const struct regmap_access_table isp1763_hc_volatile_table = {
    337	.yes_ranges	= isp1763_hc_volatile_ranges,
    338	.n_yes_ranges	= ARRAY_SIZE(isp1763_hc_volatile_ranges),
    339};
    340
    341static const struct regmap_config isp1763_hc_regmap_conf = {
    342	.name = "isp1763-hc",
    343	.reg_bits = 8,
    344	.reg_stride = 2,
    345	.val_bits = 16,
    346	.fast_io = true,
    347	.max_register = ISP1763_HC_OTG_CTRL_CLEAR,
    348	.volatile_table = &isp1763_hc_volatile_table,
    349};
    350
    351static const struct regmap_range isp176x_dc_volatile_ranges[] = {
    352	regmap_reg_range(ISP176x_DC_EPMAXPKTSZ, ISP176x_DC_EPTYPE),
    353	regmap_reg_range(ISP176x_DC_BUFLEN, ISP176x_DC_EPINDEX),
    354};
    355
    356static const struct regmap_access_table isp176x_dc_volatile_table = {
    357	.yes_ranges	= isp176x_dc_volatile_ranges,
    358	.n_yes_ranges	= ARRAY_SIZE(isp176x_dc_volatile_ranges),
    359};
    360
    361static const struct regmap_config isp1761_dc_regmap_conf = {
    362	.name = "isp1761-dc",
    363	.reg_bits = 16,
    364	.reg_stride = 4,
    365	.val_bits = 32,
    366	.fast_io = true,
    367	.max_register = ISP176x_DC_TESTMODE,
    368	.volatile_table = &isp176x_dc_volatile_table,
    369};
    370
    371static const struct reg_field isp1761_dc_reg_fields[] = {
    372	[DC_DEVEN]		= REG_FIELD(ISP176x_DC_ADDRESS, 7, 7),
    373	[DC_DEVADDR]		= REG_FIELD(ISP176x_DC_ADDRESS, 0, 6),
    374	[DC_VBUSSTAT]		= REG_FIELD(ISP176x_DC_MODE, 8, 8),
    375	[DC_SFRESET]		= REG_FIELD(ISP176x_DC_MODE, 4, 4),
    376	[DC_GLINTENA]		= REG_FIELD(ISP176x_DC_MODE, 3, 3),
    377	[DC_CDBGMOD_ACK]	= REG_FIELD(ISP176x_DC_INTCONF, 6, 6),
    378	[DC_DDBGMODIN_ACK]	= REG_FIELD(ISP176x_DC_INTCONF, 4, 4),
    379	[DC_DDBGMODOUT_ACK]	= REG_FIELD(ISP176x_DC_INTCONF, 2, 2),
    380	[DC_INTPOL]		= REG_FIELD(ISP176x_DC_INTCONF, 0, 0),
    381	[DC_IEPRXTX_7]		= REG_FIELD(ISP176x_DC_INTENABLE, 25, 25),
    382	[DC_IEPRXTX_6]		= REG_FIELD(ISP176x_DC_INTENABLE, 23, 23),
    383	[DC_IEPRXTX_5]		= REG_FIELD(ISP176x_DC_INTENABLE, 21, 21),
    384	[DC_IEPRXTX_4]		= REG_FIELD(ISP176x_DC_INTENABLE, 19, 19),
    385	[DC_IEPRXTX_3]		= REG_FIELD(ISP176x_DC_INTENABLE, 17, 17),
    386	[DC_IEPRXTX_2]		= REG_FIELD(ISP176x_DC_INTENABLE, 15, 15),
    387	[DC_IEPRXTX_1]		= REG_FIELD(ISP176x_DC_INTENABLE, 13, 13),
    388	[DC_IEPRXTX_0]		= REG_FIELD(ISP176x_DC_INTENABLE, 11, 11),
    389	[DC_IEP0SETUP]		= REG_FIELD(ISP176x_DC_INTENABLE, 8, 8),
    390	[DC_IEVBUS]		= REG_FIELD(ISP176x_DC_INTENABLE, 7, 7),
    391	[DC_IEHS_STA]		= REG_FIELD(ISP176x_DC_INTENABLE, 5, 5),
    392	[DC_IERESM]		= REG_FIELD(ISP176x_DC_INTENABLE, 4, 4),
    393	[DC_IESUSP]		= REG_FIELD(ISP176x_DC_INTENABLE, 3, 3),
    394	[DC_IEBRST]		= REG_FIELD(ISP176x_DC_INTENABLE, 0, 0),
    395	[DC_EP0SETUP]		= REG_FIELD(ISP176x_DC_EPINDEX, 5, 5),
    396	[DC_ENDPIDX]		= REG_FIELD(ISP176x_DC_EPINDEX, 1, 4),
    397	[DC_EPDIR]		= REG_FIELD(ISP176x_DC_EPINDEX, 0, 0),
    398	[DC_CLBUF]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 4, 4),
    399	[DC_VENDP]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 3, 3),
    400	[DC_DSEN]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 2, 2),
    401	[DC_STATUS]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 1, 1),
    402	[DC_STALL]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 0, 0),
    403	[DC_BUFLEN]		= REG_FIELD(ISP176x_DC_BUFLEN, 0, 15),
    404	[DC_FFOSZ]		= REG_FIELD(ISP176x_DC_EPMAXPKTSZ, 0, 10),
    405	[DC_EPENABLE]		= REG_FIELD(ISP176x_DC_EPTYPE, 3, 3),
    406	[DC_ENDPTYP]		= REG_FIELD(ISP176x_DC_EPTYPE, 0, 1),
    407	[DC_UFRAMENUM]		= REG_FIELD(ISP176x_DC_FRAMENUM, 11, 13),
    408	[DC_FRAMENUM]		= REG_FIELD(ISP176x_DC_FRAMENUM, 0, 10),
    409	[DC_CHIP_ID_HIGH]	= REG_FIELD(ISP176x_DC_CHIPID, 16, 31),
    410	[DC_CHIP_ID_LOW]	= REG_FIELD(ISP176x_DC_CHIPID, 0, 15),
    411	[DC_SCRATCH]		= REG_FIELD(ISP176x_DC_SCRATCH, 0, 15),
    412	/* Make sure the array is sized properly during compilation */
    413	[DC_FIELD_MAX]		= {},
    414};
    415
    416static const struct regmap_range isp1763_dc_volatile_ranges[] = {
    417	regmap_reg_range(ISP1763_DC_EPMAXPKTSZ, ISP1763_DC_EPTYPE),
    418	regmap_reg_range(ISP1763_DC_BUFLEN, ISP1763_DC_EPINDEX),
    419};
    420
    421static const struct regmap_access_table isp1763_dc_volatile_table = {
    422	.yes_ranges	= isp1763_dc_volatile_ranges,
    423	.n_yes_ranges	= ARRAY_SIZE(isp1763_dc_volatile_ranges),
    424};
    425
    426static const struct reg_field isp1763_dc_reg_fields[] = {
    427	[DC_DEVEN]		= REG_FIELD(ISP1763_DC_ADDRESS, 7, 7),
    428	[DC_DEVADDR]		= REG_FIELD(ISP1763_DC_ADDRESS, 0, 6),
    429	[DC_VBUSSTAT]		= REG_FIELD(ISP1763_DC_MODE, 8, 8),
    430	[DC_SFRESET]		= REG_FIELD(ISP1763_DC_MODE, 4, 4),
    431	[DC_GLINTENA]		= REG_FIELD(ISP1763_DC_MODE, 3, 3),
    432	[DC_CDBGMOD_ACK]	= REG_FIELD(ISP1763_DC_INTCONF, 6, 6),
    433	[DC_DDBGMODIN_ACK]	= REG_FIELD(ISP1763_DC_INTCONF, 4, 4),
    434	[DC_DDBGMODOUT_ACK]	= REG_FIELD(ISP1763_DC_INTCONF, 2, 2),
    435	[DC_INTPOL]		= REG_FIELD(ISP1763_DC_INTCONF, 0, 0),
    436	[DC_IEPRXTX_7]		= REG_FIELD(ISP1763_DC_INTENABLE, 25, 25),
    437	[DC_IEPRXTX_6]		= REG_FIELD(ISP1763_DC_INTENABLE, 23, 23),
    438	[DC_IEPRXTX_5]		= REG_FIELD(ISP1763_DC_INTENABLE, 21, 21),
    439	[DC_IEPRXTX_4]		= REG_FIELD(ISP1763_DC_INTENABLE, 19, 19),
    440	[DC_IEPRXTX_3]		= REG_FIELD(ISP1763_DC_INTENABLE, 17, 17),
    441	[DC_IEPRXTX_2]		= REG_FIELD(ISP1763_DC_INTENABLE, 15, 15),
    442	[DC_IEPRXTX_1]		= REG_FIELD(ISP1763_DC_INTENABLE, 13, 13),
    443	[DC_IEPRXTX_0]		= REG_FIELD(ISP1763_DC_INTENABLE, 11, 11),
    444	[DC_IEP0SETUP]		= REG_FIELD(ISP1763_DC_INTENABLE, 8, 8),
    445	[DC_IEVBUS]		= REG_FIELD(ISP1763_DC_INTENABLE, 7, 7),
    446	[DC_IEHS_STA]		= REG_FIELD(ISP1763_DC_INTENABLE, 5, 5),
    447	[DC_IERESM]		= REG_FIELD(ISP1763_DC_INTENABLE, 4, 4),
    448	[DC_IESUSP]		= REG_FIELD(ISP1763_DC_INTENABLE, 3, 3),
    449	[DC_IEBRST]		= REG_FIELD(ISP1763_DC_INTENABLE, 0, 0),
    450	[DC_EP0SETUP]		= REG_FIELD(ISP1763_DC_EPINDEX, 5, 5),
    451	[DC_ENDPIDX]		= REG_FIELD(ISP1763_DC_EPINDEX, 1, 4),
    452	[DC_EPDIR]		= REG_FIELD(ISP1763_DC_EPINDEX, 0, 0),
    453	[DC_CLBUF]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 4, 4),
    454	[DC_VENDP]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 3, 3),
    455	[DC_DSEN]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 2, 2),
    456	[DC_STATUS]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 1, 1),
    457	[DC_STALL]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 0, 0),
    458	[DC_BUFLEN]		= REG_FIELD(ISP1763_DC_BUFLEN, 0, 15),
    459	[DC_FFOSZ]		= REG_FIELD(ISP1763_DC_EPMAXPKTSZ, 0, 10),
    460	[DC_EPENABLE]		= REG_FIELD(ISP1763_DC_EPTYPE, 3, 3),
    461	[DC_ENDPTYP]		= REG_FIELD(ISP1763_DC_EPTYPE, 0, 1),
    462	[DC_UFRAMENUM]		= REG_FIELD(ISP1763_DC_FRAMENUM, 11, 13),
    463	[DC_FRAMENUM]		= REG_FIELD(ISP1763_DC_FRAMENUM, 0, 10),
    464	[DC_CHIP_ID_HIGH]	= REG_FIELD(ISP1763_DC_CHIPID_HIGH, 0, 15),
    465	[DC_CHIP_ID_LOW]	= REG_FIELD(ISP1763_DC_CHIPID_LOW, 0, 15),
    466	[DC_SCRATCH]		= REG_FIELD(ISP1763_DC_SCRATCH, 0, 15),
    467	/* Make sure the array is sized properly during compilation */
    468	[DC_FIELD_MAX]		= {},
    469};
    470
    471static const struct regmap_config isp1763_dc_regmap_conf = {
    472	.name = "isp1763-dc",
    473	.reg_bits = 8,
    474	.reg_stride = 2,
    475	.val_bits = 16,
    476	.fast_io = true,
    477	.max_register = ISP1763_DC_TESTMODE,
    478	.volatile_table = &isp1763_dc_volatile_table,
    479};
    480
    481int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
    482		     struct device *dev, unsigned int devflags)
    483{
    484	const struct regmap_config *hc_regmap;
    485	const struct reg_field *hc_reg_fields;
    486	const struct regmap_config *dc_regmap;
    487	const struct reg_field *dc_reg_fields;
    488	struct isp1760_device *isp;
    489	struct isp1760_hcd *hcd;
    490	struct isp1760_udc *udc;
    491	struct regmap_field *f;
    492	bool udc_enabled;
    493	int ret;
    494	int i;
    495
    496	/*
    497	 * If neither the HCD not the UDC is enabled return an error, as no
    498	 * device would be registered.
    499	 */
    500	udc_enabled = ((devflags & ISP1760_FLAG_ISP1763) ||
    501		       (devflags & ISP1760_FLAG_ISP1761));
    502
    503	if ((!IS_ENABLED(CONFIG_USB_ISP1760_HCD) || usb_disabled()) &&
    504	    (!udc_enabled || !IS_ENABLED(CONFIG_USB_ISP1761_UDC)))
    505		return -ENODEV;
    506
    507	isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL);
    508	if (!isp)
    509		return -ENOMEM;
    510
    511	isp->dev = dev;
    512	isp->devflags = devflags;
    513	hcd = &isp->hcd;
    514	udc = &isp->udc;
    515
    516	hcd->is_isp1763 = !!(devflags & ISP1760_FLAG_ISP1763);
    517	udc->is_isp1763 = !!(devflags & ISP1760_FLAG_ISP1763);
    518
    519	if (!hcd->is_isp1763 && (devflags & ISP1760_FLAG_BUS_WIDTH_8)) {
    520		dev_err(dev, "isp1760/61 do not support data width 8\n");
    521		return -EINVAL;
    522	}
    523
    524	if (hcd->is_isp1763) {
    525		hc_regmap = &isp1763_hc_regmap_conf;
    526		hc_reg_fields = &isp1763_hc_reg_fields[0];
    527		dc_regmap = &isp1763_dc_regmap_conf;
    528		dc_reg_fields = &isp1763_dc_reg_fields[0];
    529	} else {
    530		hc_regmap = &isp1760_hc_regmap_conf;
    531		hc_reg_fields = &isp1760_hc_reg_fields[0];
    532		dc_regmap = &isp1761_dc_regmap_conf;
    533		dc_reg_fields = &isp1761_dc_reg_fields[0];
    534	}
    535
    536	isp->rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
    537	if (IS_ERR(isp->rst_gpio))
    538		return PTR_ERR(isp->rst_gpio);
    539
    540	hcd->base = devm_ioremap_resource(dev, mem);
    541	if (IS_ERR(hcd->base))
    542		return PTR_ERR(hcd->base);
    543
    544	hcd->regs = devm_regmap_init_mmio(dev, hcd->base, hc_regmap);
    545	if (IS_ERR(hcd->regs))
    546		return PTR_ERR(hcd->regs);
    547
    548	for (i = 0; i < HC_FIELD_MAX; i++) {
    549		f = devm_regmap_field_alloc(dev, hcd->regs, hc_reg_fields[i]);
    550		if (IS_ERR(f))
    551			return PTR_ERR(f);
    552
    553		hcd->fields[i] = f;
    554	}
    555
    556	udc->regs = devm_regmap_init_mmio(dev, hcd->base, dc_regmap);
    557	if (IS_ERR(udc->regs))
    558		return PTR_ERR(udc->regs);
    559
    560	for (i = 0; i < DC_FIELD_MAX; i++) {
    561		f = devm_regmap_field_alloc(dev, udc->regs, dc_reg_fields[i]);
    562		if (IS_ERR(f))
    563			return PTR_ERR(f);
    564
    565		udc->fields[i] = f;
    566	}
    567
    568	if (hcd->is_isp1763)
    569		hcd->memory_layout = &isp1763_memory_conf;
    570	else
    571		hcd->memory_layout = &isp176x_memory_conf;
    572
    573	ret = isp1760_init_core(isp);
    574	if (ret < 0)
    575		return ret;
    576
    577	if (IS_ENABLED(CONFIG_USB_ISP1760_HCD) && !usb_disabled()) {
    578		ret = isp1760_hcd_register(hcd, mem, irq,
    579					   irqflags | IRQF_SHARED, dev);
    580		if (ret < 0)
    581			return ret;
    582	}
    583
    584	if (udc_enabled && IS_ENABLED(CONFIG_USB_ISP1761_UDC)) {
    585		ret = isp1760_udc_register(isp, irq, irqflags);
    586		if (ret < 0) {
    587			isp1760_hcd_unregister(hcd);
    588			return ret;
    589		}
    590	}
    591
    592	dev_set_drvdata(dev, isp);
    593
    594	return 0;
    595}
    596
    597void isp1760_unregister(struct device *dev)
    598{
    599	struct isp1760_device *isp = dev_get_drvdata(dev);
    600
    601	isp1760_udc_unregister(isp);
    602	isp1760_hcd_unregister(&isp->hcd);
    603}
    604
    605MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP");
    606MODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>");
    607MODULE_LICENSE("GPL v2");