blob: 02ee5521167808d28664f15465b7c9054771fdef [file] [edit]
/* SPDX-License-Identifier: GPL-2.0 */
/**
* dwc3-exynos.h - Samsung EXYNOS DWC3 Specific Glue layer header
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Author: Anton Tikhomirov <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 of
* the License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __LINUX_USB_DWC3_EXYNOS_H
#define __LINUX_USB_DWC3_EXYNOS_H
#include <dwc3/core.h> /* $(srctree)/drivers/usb/dwc3/core.h */
/* Exynos Specific Register Definition */
/* LINK Registers */
#define DWC3_LU3LFPSRXTIM 0xd010
#define DWC3_LSKIPFREQ 0xd020
#define DWC3_LLUCTL 0xd024
#define DWC3_BU31RHBDBG 0xd800
/* Link Register - LLUCTL */
#define DWC3_PENDING_HP_TIMER_US(n) ((n) << 16)
#define DWC3_LLUCTL_LTSSM_TIMER_OVRRD BIT(23)
#define DWC3_EN_US_HP_TIMER BIT(15)
#define DWC3_LLUCTL_PIPE_RESET BIT(7)
#define DWC3_FORCE_GEN1 BIT(10)
#define DWC3_LLUCTL_TX_TS1_CNT(n) ((n) << 0)
#define DWC3_LLUCTL_TX_TS1_CNT_MASK DWC3_LLUCTL_TX_TS1_CNT(0x1f)
/* Link Register - LSKIPFREQ */
#define DWC3_PM_ENTRY_TIMER_US(n) ((n) << 20)
#define DWC3_PM_ENTRY_TIMER_US_MASK DWC3_PM_ENTRY_TIMER_US(0xf)
#define DWC3_PM_LC_TIMER_US(n) ((n) << 24)
#define DWC3_PM_LC_TIMER_US_MASK DWC3_PM_LC_TIMER_US(0x7)
#define DWC3_EN_PM_TIMER_US BIT(27)
/* Global User Control 1 Register */
#define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17)
#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
#define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24)
#define DWC3_GUCTL1_IP_GAP_ADD_ON(n) ((n) << 21)
#define DWC3_GUCTL1_IP_GAP_ADD_ON_MASK (DWC3_GUCTL1_IP_GAP_ADD_ON(0x7))
/* Debug Register */
#define DWC3_BU31RHBDBG_TOUTCTL (0x1 << 3)
#define DWC3_EXYNOS_IGNORE_CORE_OPS 0xff
#define USB_BUS_CLOCK_DELAY_MS 3000
#define DWC3_EXYNOS_MAX_WAIT_COUNT 250
#define DWC3_EXYNOS_DISCONNECT_COUNT 500
/* PHY Owner Bits */
#define DWC3_EXYNOS_PHY_OWNER_USB BIT(0)
#define DWC3_EXYNOS_PHY_OWNER_DP BIT(1)
struct dwc3_exynos_config { /* Exynos Specific Configuations */
bool adj_sof_accuracy;
bool is_not_vbus_pad;
bool sparse_transfer_control;
bool no_extra_delay;
bool ux_exit_in_px_quirk;
bool elastic_buf_mode_quirk;
bool force_gen1;
bool u1u2_exitfail_to_recov_quirk;
u32 usb_host_device_timeout;
u32 suspend_clk_freq;
};
struct dwc3_exynos {
struct platform_device *usb2_phy;
struct platform_device *usb3_phy;
struct device *dev;
struct dwc3 *dwc;
struct clk **clocks;
struct clk *bus_clock;
struct extcon_dev *edev;
struct notifier_block device_nb;
struct notifier_block host_nb;
struct mutex dotg_lock;
bool usb_data_enabled;
bool extra_delay;
bool gadget_state;
int idle_ip_index;
struct dwc3_otg *dotg;
struct dwc3_exynos_config config;
int force_speed;
/* Flag for setting current_dr_role peripheral */
int need_dr_role;
struct xhci_goog_dma_coherent_mem **mem;
/* bitmap of usb phy owners */
int phy_owner_bits;
};
static inline u32 dwc3_exynos_readl(void __iomem *base, u32 offset)
{
return readl(base + offset - DWC3_GLOBALS_REGS_START);
}
static inline void dwc3_exynos_writel(void __iomem *base, u32 offset, u32 value)
{
writel(value, base + offset - DWC3_GLOBALS_REGS_START);
}
int dwc3_exynos_host_event(struct device *dev, int action);
int dwc3_exynos_device_event(struct device *dev, bool action);
int dwc3_exynos_phy_enable(int owner, bool on);
extern int dwc3_exynos_set_bus_clock(struct device *dev, int clk_level);
int dwc3_exynos_core_init(struct dwc3 *dwc, struct dwc3_exynos *exynos);
int dwc3_exynos_host_init(struct dwc3_exynos *exynos);
void dwc3_exynos_host_exit(struct dwc3_exynos *exynos);
void dwc3_exynos_gadget_disconnect_proc(struct dwc3 *dwc);
int dwc3_core_susphy_set(struct dwc3 *dwc, int on);
#endif /* __LINUX_USB_DWC3_EXYNOS_H */