]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
xhci: tegra: program SS pad per T210 BCT changes
authorJC Kuo <jckuo@nvidia.com>
Sat, 16 Aug 2014 19:08:04 +0000 (12:08 -0700)
committerTom Cherry <tcherry@nvidia.com>
Wed, 27 Aug 2014 19:08:00 +0000 (12:08 -0700)
T210 BCT has been changed for SS pad paramenters including
TX_TERM_CTRL, RX_CTLE, RX_DFE, and RX_EQ_CTRL_H.
This commit adds required programming per T210 BCT changes.

Change-Id: Ib42cd239c942726c98de42615ca7225a44bbf360
Signed-off-by: JC Kuo <jckuo@nvidia.com>
Reviewed-on: http://git-master/r/486582
Reviewed-by: Hui Fu <hfu@nvidia.com>
Tested-by: Hui Fu <hfu@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Ashutosh Jha <ajha@nvidia.com>
arch/arm/mach-tegra/include/mach/xusb.h
drivers/usb/host/Makefile
drivers/usb/host/xhci-tegra-t210-padctl.c [new file with mode: 0644]
drivers/usb/host/xhci-tegra-t210-padreg.h
drivers/usb/host/xhci-tegra.c
drivers/usb/host/xhci-tegra.h

index 29fd15800be0f9054338be01f071ac395f61b17f..4ec95dcfe0fe858a342d3bc6d68f5394b3caf071 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef _XUSB_H
 #define _XUSB_H
 
+#include <linux/types.h>
+
 /*
  * BIT0 - BIT7 : SS ports
  * BIT8 - BIT15 : USB2 UTMI ports
@@ -159,6 +161,14 @@ struct tegra_xusb_soc_config {
        const char *default_firmware_file;
        const struct tegra_xusb_padctl_regs *padctl_offsets;
        void (*check_lane_owner_by_pad) (int pad, u32 lane_owner);
+
+       /* applicable to T210 */
+       u32 tx_term_ctrl;
+       u32 rx_ctle;
+       u32 rx_dfe;
+       u32 rx_eq_ctrl_h;
+
+       /* applicable to T114/T124/T132 */
        u32 rx_wander;
        u32 rx_eq;
        u32 cdr_cntl;
index 05e1b074c406a2fa222eaa515900036c68749f93..5ff54067bc3fc461a880c32933b4a1a5efb939c9 100644 (file)
@@ -21,6 +21,10 @@ xhci-hcd-y := xhci.o xhci-mem.o
 xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o
 xhci-hcd-$(CONFIG_PCI) += xhci-pci.o
 
+ifeq ($(CONFIG_ARCH_TEGRA_21x_SOC),y)
+       xhci-hcd-y              += xhci-tegra-t210-padctl.o
+endif
+
 ifneq ($(CONFIG_USB_XHCI_PLATFORM), )
        xhci-hcd-y              += xhci-plat.o
 endif
diff --git a/drivers/usb/host/xhci-tegra-t210-padctl.c b/drivers/usb/host/xhci-tegra-t210-padctl.c
new file mode 100644 (file)
index 0000000..bd643a3
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * xhci-tegra-t210-padctl.c - Nvidia xHCI host padctl driver
+
+ *
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <mach/tegra_usb_pad_ctrl.h>
+#include "xhci-tegra.h"
+#include "xhci-tegra-t210-padreg.h"
+
+/* UPHY_USB3_PADx_ECTL_1 */
+#define TX_TERM_CTRL(x)        (((x) & 0x3) << 16)
+
+/* UPHY_USB3_PADx_ECTL_2 */
+#define RX_CTLE(x)             (((x) & 0xffff) << 0)
+
+/* UPHY_USB3_PADx_ECTL_3 */
+#define RX_DFE(x)              (((x) & 0xffffffff) << 0)
+
+/* UPHY_USB3_PADx_ECTL_6 */
+#define RX_EQ_CTRL_H(x)        (((x) & 0xffffffff) << 0)
+
+void t210_program_ss_pad(struct tegra_xhci_hcd *tegra, u8 port)
+{
+       u32 ctl1, ctl2, ctl3, ctl6, val;
+
+       xusb_ss_pad_init(port, GET_SS_PORTMAP(tegra->bdata->ss_portmap, port)
+                       , XUSB_HOST_MODE);
+
+       ctl1 = tegra->padregs->uphy_usb3_padX_ectlY_0[port][0];
+       ctl2 = tegra->padregs->uphy_usb3_padX_ectlY_0[port][1];
+       ctl3 = tegra->padregs->uphy_usb3_padX_ectlY_0[port][2];
+       ctl6 = tegra->padregs->uphy_usb3_padX_ectlY_0[port][5];
+
+       val = padctl_readl(tegra, ctl1);
+       val &= ~TX_TERM_CTRL(~0);
+       val |= TX_TERM_CTRL(tegra->soc_config->tx_term_ctrl);
+       padctl_writel(tegra, val, ctl1);
+
+       val = padctl_readl(tegra, ctl2);
+       val &= ~RX_CTLE(~0);
+       val |= RX_CTLE(tegra->soc_config->rx_ctle);
+       padctl_writel(tegra, val, ctl2);
+
+       val = padctl_readl(tegra, ctl3);
+       val &= ~RX_DFE(~0);
+       val |= RX_DFE(tegra->soc_config->rx_dfe);
+       padctl_writel(tegra, val, ctl3);
+
+       val = padctl_readl(tegra, ctl6);
+       val &= ~RX_EQ_CTRL_H(~0);
+       val |= RX_EQ_CTRL_H(tegra->soc_config->rx_eq_ctrl_h);
+       padctl_writel(tegra, val, ctl6);
+}
index b39211a1e6fe9e076c21ae9237c47fa4f760a296..a96596a90187ab75fcc6494f8ff376e16bee7129 100644 (file)
@@ -1,5 +1,7 @@
+#ifndef _XHCI_TEGRA_T210_PADCTL_H
+#define _XHCI_TEGRA_T210_PADCTL_H
 /*
- * xhci-tegra-T210-padreg.h - Nvidia xHCI host controller related data
+ * xhci-tegra-t210-padreg.h - Nvidia xHCI host controller related data
  *
  * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
  *
 
 /* XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL_0 0x344*/
 #define STRB_TRIM_VAL(x)       0x0
+
+void t210_program_ss_pad(struct tegra_xhci_hcd *tegra, u8 port);
+
+
+#endif /* _XHCI_TEGRA_T210_PADCTL_H */
index 3762a39172d1a1860d02492e5a01744be051b787..4f7fb1f7dff4040a9af4c458181b89d58c710f18 100644 (file)
@@ -58,8 +58,6 @@
 #else
 #include "xhci-tegra-t124-padreg.h"
 #endif
-#define NOT_SUPPORTED  0xFFFFFFFF
-#define PADCTL_REG_NONE        0xffff
 
 /* macros */
 #define FW_IOCTL_LOG_DEQUEUE_LOW       (4)
@@ -99,7 +97,6 @@
                _reg, readl(_base + _reg))
 
 #define PMC_PORTMAP_MASK(map, pad)     (((map) >> 4*(pad)) & 0xF)
-#define GET_SS_PORTMAP(map, p)         (((map) >> 4*(p)) & 0xF)
 
 #define PMC_USB_DEBOUNCE_DEL_0                 0xec
 #define   UTMIP_LINE_DEB_CNT(x)                (((x) & 0xf) << 16)
@@ -199,153 +196,6 @@ struct cfgtbl {
        u8 padding[138]; /* padding bytes to makeup 256-bytes cfgtbl */
 };
 
-struct xusb_save_regs {
-       u32 msi_bar_sz;
-       u32 msi_axi_barst;
-       u32 msi_fpci_barst;
-       u32 msi_vec0;
-       u32 msi_en_vec0;
-       u32 fpci_error_masks;
-       u32 intr_mask;
-       u32 ipfs_intr_enable;
-       u32 ufpci_config;
-       u32 clkgate_hysteresis;
-       u32 xusb_host_mccif_fifo_cntrl;
-
-       /* PG does not mention below */
-       u32 hs_pls;
-       u32 fs_pls;
-       u32 hs_fs_speed;
-       u32 hs_fs_pp;
-       u32 cfg_aru;
-       u32 cfg_order;
-       u32 cfg_fladj;
-       u32 cfg_sid;
-       /* DFE and CTLE */
-       u32 tap1_val[XUSB_SS_PORT_COUNT];
-       u32 amp_val[XUSB_SS_PORT_COUNT];
-       u32 ctle_z_val[XUSB_SS_PORT_COUNT];
-       u32 ctle_g_val[XUSB_SS_PORT_COUNT];
-};
-
-struct tegra_xhci_firmware {
-       void *data; /* kernel virtual address */
-       size_t size; /* firmware size */
-       dma_addr_t dma; /* dma address for controller */
-};
-
-struct tegra_xhci_firmware_log {
-       dma_addr_t phys_addr;           /* dma-able address */
-       void *virt_addr;                /* kernel va of the shared log buffer */
-       struct log_entry *dequeue;      /* current dequeue pointer (va) */
-       struct circ_buf circ;           /* big circular buffer */
-       u32 seq;                        /* log sequence number */
-
-       struct task_struct *thread;     /* a thread to consume log */
-       struct mutex mutex;
-       wait_queue_head_t read_wait;
-       wait_queue_head_t write_wait;
-       wait_queue_head_t intr_wait;
-       struct dentry *path;
-       struct dentry *log_file;
-       unsigned long flags;
-};
-
-struct tegra_xhci_hcd {
-       struct platform_device *pdev;
-       struct xhci_hcd *xhci;
-       u16 device_id;
-
-       spinlock_t lock;
-       struct mutex sync_lock;
-
-       int smi_irq;
-       int padctl_irq;
-       int usb3_irq;
-       int usb2_irq;
-
-       bool ss_wake_event;
-       bool ss_pwr_gated;
-       bool host_pwr_gated;
-       bool hs_wake_event;
-       bool host_resume_req;
-       bool lp0_exit;
-       u32 dfe_ctx_saved;
-       u32 ctle_ctx_saved;
-       unsigned long last_jiffies;
-       unsigned long host_phy_base;
-       unsigned long host_phy_size;
-       void __iomem *host_phy_virt_base;
-
-       void __iomem *padctl_base;
-       void __iomem *fpci_base;
-       void __iomem *ipfs_base;
-
-       struct tegra_xusb_platform_data *pdata;
-       struct tegra_xusb_board_data *bdata;
-       struct tegra_xusb_chip_calib *cdata;
-       struct tegra_xusb_padctl_regs *padregs;
-       const struct tegra_xusb_soc_config *soc_config;
-       u64 tegra_xusb_dmamask;
-
-       /* mailbox variables */
-       struct mutex mbox_lock;
-       u32 mbox_owner;
-       u32 cmd_type;
-       u32 cmd_data;
-
-       struct regulator **xusb_utmi_vbus_regs;
-
-       struct regulator *xusb_s1p05v_reg;
-       struct regulator *xusb_s3p3v_reg;
-       struct regulator *xusb_s1p8v_reg;
-       struct regulator *vddio_hsic_reg;
-       int vddio_hsic_refcnt;
-
-       struct work_struct mbox_work;
-       struct work_struct ss_elpg_exit_work;
-       struct work_struct host_elpg_exit_work;
-
-       struct clk *host_clk;
-       struct clk *ss_clk;
-
-       /* XUSB Falcon SuperSpeed Clock */
-       struct clk *falc_clk;
-
-       /* EMC Clock */
-       struct clk *emc_clk;
-       /* XUSB SS PI Clock */
-       struct clk *ss_src_clk;
-       /* PLLE Clock */
-       struct clk *plle_clk;
-       struct clk *pll_u_480M;
-       struct clk *clk_m;
-       /* refPLLE clk */
-       struct clk *pll_re_vco_clk;
-       /*
-        * XUSB/IPFS specific registers these need to be saved/restored in
-        * addition to spec defined registers
-        */
-       struct xusb_save_regs sregs;
-       bool usb2_rh_suspend;
-       bool usb3_rh_suspend;
-       bool hc_in_elpg;
-
-       /* otg transceiver */
-       struct usb_phy *transceiver;
-       struct notifier_block otgnb;
-
-       unsigned long usb2_rh_remote_wakeup_ports; /* one bit per port */
-       unsigned long usb3_rh_remote_wakeup_ports; /* one bit per port */
-       /* firmware loading related */
-       struct tegra_xhci_firmware firmware;
-
-       struct tegra_xhci_firmware_log log;
-       struct device_attribute hsic_power_attr[XUSB_HSIC_COUNT];
-
-       bool init_done;
-};
-
 static int tegra_xhci_probe2(struct tegra_xhci_hcd *tegra);
 static int tegra_xhci_remove(struct platform_device *pdev);
 static void init_filesystem_firmware_done(const struct firmware *fw,
@@ -364,20 +214,6 @@ module_param(firmware_file, charp, S_IRUGO);
 MODULE_PARM_DESC(firmware_file, FIRMWARE_FILE_HELP);
 
 /* functions */
-static inline u32 padctl_readl(struct tegra_xhci_hcd *tegra, u32 reg)
-{
-       if (reg == PADCTL_REG_NONE)
-               return PADCTL_REG_NONE;
-       return readl(tegra->padctl_base + reg);
-}
-
-static inline void padctl_writel(struct tegra_xhci_hcd *tegra, u32 val, u32 reg)
-{
-       if (reg == PADCTL_REG_NONE)
-               return;
-       writel(val, tegra->padctl_base + reg);
-}
-
 static inline struct tegra_xhci_hcd *hcd_to_tegra_xhci(struct usb_hcd *hcd)
 {
        return (struct tegra_xhci_hcd *) dev_get_drvdata(hcd->self.controller);
@@ -2100,6 +1936,8 @@ static inline bool xusb_use_sata_lane(struct tegra_xhci_hcd *tegra)
        return ret;
 }
 
+
+
 static void tegra_xhci_program_ss_pad(struct tegra_xhci_hcd *tegra,
        u8 port)
 {
@@ -2184,7 +2022,11 @@ tegra_xhci_padctl_portmap_and_caps(struct tegra_xhci_hcd *tegra)
                if (tegra->bdata->portmap & (1 << pad)) {
                        tegra->soc_config->check_lane_owner_by_pad(pad
                                        , tegra->bdata->lane_owner);
+#if defined(CONFIG_ARCH_TEGRA_21x_SOC)
+                       t210_program_ss_pad(tegra, pad);
+#else
                        tegra_xhci_program_ss_pad(tegra, pad);
+#endif
                } else {
                        reg = padctl_readl(tegra
                                , padregs->iophy_misc_pad_pX_ctlY_0[pad][2]);
@@ -4354,6 +4196,11 @@ static const struct tegra_xusb_soc_config tegra210_soc_config = {
        .ss_pad_count = 4,
        .padctl_offsets = &tegra210_padctl_offsets,
        .check_lane_owner_by_pad = t210_chk_lane_owner_by_pad,
+
+       .tx_term_ctrl = 0x2,
+       .rx_ctle = 0xfb,
+       .rx_dfe = 0x77f1f,
+       .rx_eq_ctrl_h = 0xfcf01368,
 };
 
 static struct of_device_id tegra_xhci_of_match[] = {
index d906c19428f421c0512de3c32c032d8afe3a1d81..e78c78f0ab581f1b0c024343dca4ccb2f87dcd0a 100644 (file)
 #ifndef __XUSB_H
 #define __XUSB_H
 
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/circ_buf.h>
+#include <linux/device.h>
+#include <linux/notifier.h>
+
+#include <mach/xusb.h>
+
 #define XUSB_CSB_MP_L2IMEMOP_TRIG                              0x00101A14
 #define XUSB_CSB_MP_APMAP                                      0x0010181C
 #define XUSB_CSB_ARU_SCRATCH0                          0x00100100
 #define XUSB_DEVICE_ID_T114                            0x0E16
 #define XUSB_DEVICE_ID_T124                            0x0FA3
 #define XUSB_DEVICE_ID_T210                            0x0FAC
+#define XUSB_IS_T114_OR_T124(t)                        \
+       ((t->device_id == XUSB_DEVICE_ID_T114) ||       \
+               (t->device_id == XUSB_DEVICE_ID_T124))
+#define XUSB_IS_T210(t)        (t->device_id == XUSB_DEVICE_ID_T114)
 
 /* TODO: Do not have the definitions of below
  * registers.
 #define ARU_ULPI_REGACCESS_CMD_MASK            0x1
 #define ARU_ULPI_REGACCESS_DATA_MASK   0xff0000
 
+#define GET_SS_PORTMAP(map, p)         (((map) >> 4*(p)) & 0xF)
+
 /*
  * FIXME: looks like no any .c requires below structure types
  * revisit and decide whether we can delete or not
@@ -241,6 +256,169 @@ struct vbus_enable_oc_map {
        u32 vbus_en1;
 };
 
+struct xusb_save_regs {
+       u32 msi_bar_sz;
+       u32 msi_axi_barst;
+       u32 msi_fpci_barst;
+       u32 msi_vec0;
+       u32 msi_en_vec0;
+       u32 fpci_error_masks;
+       u32 intr_mask;
+       u32 ipfs_intr_enable;
+       u32 ufpci_config;
+       u32 clkgate_hysteresis;
+       u32 xusb_host_mccif_fifo_cntrl;
+
+       /* PG does not mention below */
+       u32 hs_pls;
+       u32 fs_pls;
+       u32 hs_fs_speed;
+       u32 hs_fs_pp;
+       u32 cfg_aru;
+       u32 cfg_order;
+       u32 cfg_fladj;
+       u32 cfg_sid;
+       /* DFE and CTLE */
+       u32 tap1_val[XUSB_SS_PORT_COUNT];
+       u32 amp_val[XUSB_SS_PORT_COUNT];
+       u32 ctle_z_val[XUSB_SS_PORT_COUNT];
+       u32 ctle_g_val[XUSB_SS_PORT_COUNT];
+};
+
+struct tegra_xhci_firmware {
+       void *data; /* kernel virtual address */
+       size_t size; /* firmware size */
+       dma_addr_t dma; /* dma address for controller */
+};
+
+struct tegra_xhci_firmware_log {
+       dma_addr_t phys_addr;           /* dma-able address */
+       void *virt_addr;                /* kernel va of the shared log buffer */
+       struct log_entry *dequeue;      /* current dequeue pointer (va) */
+       struct circ_buf circ;           /* big circular buffer */
+       u32 seq;                        /* log sequence number */
+
+       struct task_struct *thread;     /* a thread to consume log */
+       struct mutex mutex;
+       wait_queue_head_t read_wait;
+       wait_queue_head_t write_wait;
+       wait_queue_head_t intr_wait;
+       struct dentry *path;
+       struct dentry *log_file;
+       unsigned long flags;
+};
+
+struct tegra_xhci_hcd {
+       struct platform_device *pdev;
+       struct xhci_hcd *xhci;
+       u16 device_id;
+
+       spinlock_t lock;
+       struct mutex sync_lock;
+
+       int smi_irq;
+       int padctl_irq;
+       int usb3_irq;
+       int usb2_irq;
+
+       bool ss_wake_event;
+       bool ss_pwr_gated;
+       bool host_pwr_gated;
+       bool hs_wake_event;
+       bool host_resume_req;
+       bool lp0_exit;
+       u32 dfe_ctx_saved;
+       u32 ctle_ctx_saved;
+       unsigned long last_jiffies;
+       unsigned long host_phy_base;
+       unsigned long host_phy_size;
+       void __iomem *host_phy_virt_base;
+
+       void __iomem *padctl_base;
+       void __iomem *fpci_base;
+       void __iomem *ipfs_base;
+
+       struct tegra_xusb_platform_data *pdata;
+       struct tegra_xusb_board_data *bdata;
+       struct tegra_xusb_chip_calib *cdata;
+       struct tegra_xusb_padctl_regs *padregs;
+       const struct tegra_xusb_soc_config *soc_config;
+       u64 tegra_xusb_dmamask;
+
+       /* mailbox variables */
+       struct mutex mbox_lock;
+       u32 mbox_owner;
+       u32 cmd_type;
+       u32 cmd_data;
+
+       struct regulator **xusb_utmi_vbus_regs;
+
+       struct regulator *xusb_s1p05v_reg;
+       struct regulator *xusb_s3p3v_reg;
+       struct regulator *xusb_s1p8v_reg;
+       struct regulator *vddio_hsic_reg;
+       int vddio_hsic_refcnt;
+
+       struct work_struct mbox_work;
+       struct work_struct ss_elpg_exit_work;
+       struct work_struct host_elpg_exit_work;
+
+       struct clk *host_clk;
+       struct clk *ss_clk;
+
+       /* XUSB Falcon SuperSpeed Clock */
+       struct clk *falc_clk;
+
+       /* EMC Clock */
+       struct clk *emc_clk;
+       /* XUSB SS PI Clock */
+       struct clk *ss_src_clk;
+       /* PLLE Clock */
+       struct clk *plle_clk;
+       struct clk *pll_u_480M;
+       struct clk *clk_m;
+       /* refPLLE clk */
+       struct clk *pll_re_vco_clk;
+       /*
+        * XUSB/IPFS specific registers these need to be saved/restored in
+        * addition to spec defined registers
+        */
+       struct xusb_save_regs sregs;
+       bool usb2_rh_suspend;
+       bool usb3_rh_suspend;
+       bool hc_in_elpg;
+
+       /* otg transceiver */
+       struct usb_phy *transceiver;
+       struct notifier_block otgnb;
+
+       unsigned long usb2_rh_remote_wakeup_ports; /* one bit per port */
+       unsigned long usb3_rh_remote_wakeup_ports; /* one bit per port */
+       /* firmware loading related */
+       struct tegra_xhci_firmware firmware;
+
+       struct tegra_xhci_firmware_log log;
+       struct device_attribute hsic_power_attr[XUSB_HSIC_COUNT];
+
+       bool init_done;
+};
+
+#define NOT_SUPPORTED  0xFFFFFFFF
+#define PADCTL_REG_NONE        0xffff
+static inline u32 padctl_readl(struct tegra_xhci_hcd *tegra, u32 reg)
+{
+       if (reg == PADCTL_REG_NONE)
+               return PADCTL_REG_NONE;
+       return readl(tegra->padctl_base + reg);
+}
+
+static inline void padctl_writel(struct tegra_xhci_hcd *tegra, u32 val, u32 reg)
+{
+       if (reg == PADCTL_REG_NONE)
+               return;
+       writel(val, tegra->padctl_base + reg);
+}
+
 /**
  * port_to_hsic_pad - given "port number", return with hsic pad number
  * @_port:     (zero-based) index to portsc registers array.