452 lines
14 KiB
C
Executable file
452 lines
14 KiB
C
Executable file
// SPDX-License-Identifier: GPL-2.0
|
|
/**
|
|
*
|
|
* Copyright (c) 2021 Samsung Electronics Co., Ltd.
|
|
* http://www.samsung.com
|
|
*
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
//#include <lk/reg.h>
|
|
#include <linux/types.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/io.h>
|
|
#include "phy-samsung-usb-cal.h"
|
|
|
|
#include "exynos-usb-blkcon-sfr.h"
|
|
|
|
static void ready_rewa(struct exynos_usbphy_info *cal_info);
|
|
|
|
void exynos_usbcon_init_link(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base;
|
|
u32 reg;
|
|
|
|
regs_base = cal_info->regs_base;
|
|
|
|
/* LINKCTRL
|
|
* 1. Disable q-channel
|
|
* 2. Bypass debounce filter for vbus, bvalid and id
|
|
* 3. sel_sof for SOF tick when LPM L1
|
|
*/
|
|
reg = readl(regs_base + USBCON_REG_LINKCTRL);
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.dis_id0_qact = 1;
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.dis_bvalid_qact = 1;
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.dis_vbusvalid_qact = 1;
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.dis_linkgate_qact = 1;
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.force_qact = 0;
|
|
udelay(500);
|
|
writel(reg, regs_base + USBCON_REG_LINKCTRL);
|
|
udelay(500);
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.force_qact = 1;
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.bus_filter_bypass = 0xf;
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.sel_sof = 0x1;
|
|
writel(reg, regs_base + USBCON_REG_LINKCTRL);
|
|
|
|
pr_info("%s %d USBCON_REG_LINKCTRL: 0x %08x\n", __func__, __LINE__, readl(regs_base + USBCON_REG_LINKCTRL));
|
|
|
|
/* Reset Link */
|
|
reg = readl(regs_base + USBCON_REG_LINK_CLKRST);
|
|
((USBCON_REG_LINK_CLKRST_p) (®))->b.link_sw_rst = 1;
|
|
writel(reg, regs_base + USBCON_REG_LINK_CLKRST);
|
|
udelay(10);
|
|
((USBCON_REG_LINK_CLKRST_p) (®))->b.link_sw_rst = 0;
|
|
writel(reg, regs_base + USBCON_REG_LINK_CLKRST);
|
|
|
|
/* UTMI_CTRL
|
|
* 1. Set high bvalid and vbus valid */
|
|
reg = readl(regs_base + USBCON_REG_UTMI_CTRL);
|
|
((USBCON_REG_UTMI_CTRL_p) (®))->b.force_bvalid = 1;
|
|
((USBCON_REG_UTMI_CTRL_p) (®))->b.force_vbusvalid = 1;
|
|
writel(reg, regs_base + USBCON_REG_UTMI_CTRL);
|
|
|
|
/* Initilze UTMI ReWA */
|
|
if (cal_info->hs_rewa)
|
|
ready_rewa(cal_info);
|
|
|
|
}
|
|
|
|
void exynos_usbcon_detach_pipe3_phy(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base;
|
|
u32 reg;
|
|
|
|
regs_base = cal_info->regs_base;
|
|
|
|
/* force pipe3 signal for link */
|
|
reg = readl(regs_base + USBCON_REG_LINKCTRL);
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.force_pipe_en = 1;
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.force_phystatus = 0;
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.force_rxelecidle = 1;
|
|
writel(reg, regs_base + USBCON_REG_LINKCTRL);
|
|
pr_info("%s %d USBCON_REG_LINKCTRL: 0x %08x\n", __func__, __LINE__, readl(regs_base + USBCON_REG_LINKCTRL));
|
|
|
|
/* pclk to suspend clock */
|
|
reg = readl(regs_base + USBCON_REG_LINK_CLKRST);
|
|
((USBCON_REG_LINK_CLKRST_p) (®))->b.link_pclk_sel = 0;
|
|
writel(reg, regs_base + USBCON_REG_LINK_CLKRST);
|
|
}
|
|
|
|
void exynos_usbcon_disable_pipe3_phy(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base;
|
|
u32 reg;
|
|
|
|
exynos_usbcon_detach_pipe3_phy(cal_info);
|
|
|
|
regs_base = cal_info->regs_base;
|
|
|
|
/* calibrate only eUSB Phy */
|
|
reg = readl(regs_base + USBCON_REG_HSP_MISC);
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.sel_res_tune_mux = 2;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.set_req_in2 = 1;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.set_ack_in2 = 0;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.set_req_in1 = 0;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.set_ack_in1 = 0;
|
|
writel(reg, regs_base + USBCON_REG_HSP_MISC);
|
|
}
|
|
|
|
void exynos_usbcon_ready_to_pipe3_phy(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base;
|
|
u32 reg;
|
|
|
|
regs_base = cal_info->regs_base;
|
|
|
|
/* Disable forcing pipe interface */
|
|
reg = readl(regs_base + USBCON_REG_LINKCTRL);
|
|
((USBCON_REG_LINKCTRL_p) (®))->b.force_pipe_en = 0;
|
|
writel(reg, regs_base + USBCON_REG_LINKCTRL);
|
|
|
|
/* calibrate Sequence: Dual Phy */
|
|
reg = readl(regs_base + USBCON_REG_HSP_MISC);
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.sel_res_tune_mux = 1;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.set_req_in2 = 0;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.set_ack_in2 = 0;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.set_req_in1 = 0;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.set_ack_in1 = 0;
|
|
writel(reg, regs_base + USBCON_REG_HSP_MISC);
|
|
|
|
/* Pclk to pipe_clk */
|
|
reg = readl(regs_base + USBCON_REG_LINK_CLKRST);
|
|
((USBCON_REG_LINK_CLKRST_p) (®))->b.link_pclk_sel = 1;
|
|
writel(reg, regs_base + USBCON_REG_LINK_CLKRST);
|
|
}
|
|
|
|
u64 exynos_usbcon_get_logic_trace(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base;
|
|
u64 ret;
|
|
|
|
regs_base = cal_info->regs_base;
|
|
|
|
ret = readl(regs_base + USBCON_REG_LINK_DEBUG_L);
|
|
ret |= ((u64) readl(regs_base + USBCON_REG_LINK_DEBUG_H)) << 32;
|
|
|
|
return ret;
|
|
}
|
|
|
|
void exynos_usbcon_set_fsv_out_en(struct exynos_usbphy_info *cal_info, u32 en)
|
|
{
|
|
void __iomem *regs_base = cal_info->regs_base;
|
|
u32 reg;
|
|
|
|
reg = readl(regs_base + USBCON_REG_HSP_MISC);
|
|
if (en) {
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.fsvp_out_en = 1;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.fsvm_out_en = 1;
|
|
} else {
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.fsvp_out_en = 0;
|
|
((USBCON_REG_HSP_MISC_p) (®))->b.fsvm_out_en = 0;
|
|
}
|
|
writel(reg, regs_base + USBCON_REG_HSP_MISC);
|
|
}
|
|
|
|
u8 exynos_usbcon_get_fs_vplus_vminus(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base = cal_info->regs_base;
|
|
USBCON_REG_HSP_MISC_o reg;
|
|
|
|
reg.data = readl(regs_base + USBCON_REG_HSP_MISC);
|
|
|
|
return ((reg.b.fsvminus & 0x1) << 1) | (reg.b.fsvplus & 0x1);
|
|
}
|
|
|
|
static void ready_rewa(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
u32 reg;
|
|
void __iomem *regs_base = cal_info->regs_base;
|
|
|
|
/* Disable ReWA */
|
|
reg = readl(regs_base + USBCON_REG_REWA_CTL);
|
|
((USBCON_REG_REWA_CTL_p) (®))->b.hsrewa_en = 0;
|
|
writel(reg, regs_base + USBCON_REG_REWA_CTL);
|
|
|
|
/* Config ReWA Operation */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_CTL);
|
|
/* Select line state check circuit
|
|
* 0 : FSVPLUS/FSMINUS
|
|
* 1 : LINE STATE
|
|
* */
|
|
((USBCON_REG_HSREWA_CTL_p) (®))->b.dpdm_mon_sel = 1;
|
|
/* Select Drive K circuit
|
|
* 0 : Auto Resume in the PHY
|
|
* 1 : BYPASS mode by ReWA
|
|
* */
|
|
((USBCON_REG_HSREWA_CTL_p) (®))->b.dig_bypass_con_en = 0;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_CTL);
|
|
|
|
/* Set host K timeout from host K drive. */
|
|
reg = 0xFF00; // value 0xFF00 means 200ms (Nominal host K drive time is 20ms)
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_REFTO);
|
|
|
|
/* Set host K delay from device K*/
|
|
reg = 0x1; // value 1 means 30.5us
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_HSTK);
|
|
|
|
/* Mask wakeup_req and all inetrrupts */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_INTR);
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.wakeup_req_mask = 1;
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.timeout_intr_mask = 1;
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.event_intr_mask = 1;
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.wakeup_intr_mask = 1;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_INTR);
|
|
|
|
/* Mask all INT events */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_INT1_EVNT_MSK);
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.err_sus_mask = 1;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.err_dev_k_mask = 1;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.discon_mask = 1;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.bypass_dis_mask = 1;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.ret_dis_mask = 1;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.ret_en_mask = 1;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_INT1_EVNT_MSK);
|
|
}
|
|
|
|
int exynos_usbcon_enable_rewa(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base = cal_info->regs_base;
|
|
u32 reg;
|
|
int cnt;
|
|
|
|
/* Set the wakeup source mask */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_INTR);
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.wakeup_req_mask = 1;
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.timeout_intr_mask = 0;
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.event_intr_mask = 0;
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.wakeup_intr_mask = 0;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_INTR);
|
|
|
|
/* Clear the link_ready and sys_valid flag */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_CTL);
|
|
((USBCON_REG_HSREWA_CTL_p) (®))->b.hs_link_ready = 0;
|
|
((USBCON_REG_HSREWA_CTL_p) (®))->b.hs_sys_valid = 0;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_CTL);
|
|
|
|
/* Enable ReWA */
|
|
reg = readl(regs_base + USBCON_REG_REWA_CTL);
|
|
((USBCON_REG_REWA_CTL_p) (®))->b.hsrewa_en = 1;
|
|
writel(reg, regs_base + USBCON_REG_REWA_CTL);
|
|
|
|
/* Check Status : Wait ReWA Status is retention enabled */
|
|
for (cnt = 10000; cnt != 0; cnt--) {
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_INT1_EVNT);
|
|
/* non suspend status*/
|
|
if (((USBCON_REG_HSREWA_INT1_EVNT_p) (®))->b.err_sus) {
|
|
pr_info("enable_rewa-not_suspend\n");
|
|
return HS_REWA_EN_STS_NOT_SUSPEND;
|
|
}
|
|
|
|
/* Disconnect Status */
|
|
if (((USBCON_REG_HSREWA_INT1_EVNT_p) (®))->b.discon) {
|
|
pr_info("enable_rewa-discon\n");
|
|
return HS_REWA_EN_STS_DISCONNECT;
|
|
}
|
|
/* Success ReWA Enable */
|
|
if (((USBCON_REG_HSREWA_INT1_EVNT_p) (®))->b.ret_en)
|
|
break;
|
|
udelay(30);
|
|
}
|
|
if (cnt == 0) {
|
|
pr_info("enable_rewa-timeout\n");
|
|
return HS_REWA_EN_STS_NOT_SUSPEND;
|
|
}
|
|
|
|
/* Set the INT1 for detect K and Disconnect */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_INT1_EVNT_MSK);
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.err_sus_mask = 1;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.err_dev_k_mask = 0;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.discon_mask = 0;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.bypass_dis_mask = 1;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.ret_dis_mask = 1;
|
|
((USBCON_REG_HSREWA_INT1_EVNT_MSK_p) (®))->b.ret_en_mask = 1;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_INT1_EVNT_MSK);
|
|
|
|
/* Clear the wakeup source mask */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_INTR);
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.wakeup_req_mask = 0;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_INTR);
|
|
|
|
udelay(100);
|
|
pr_info("enable_rewa-done\n");
|
|
|
|
return HS_REWA_EN_STS_ENALBED;
|
|
}
|
|
|
|
int exynos_usbcon_rewa_req_sys_valid(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base = cal_info->regs_base;
|
|
u32 reg;
|
|
int cnt;
|
|
|
|
/* Set interrupt mask for prevent addtional interrupt */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_INTR);
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.wakeup_req_mask = 1;
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.timeout_intr_mask = 1;
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.event_intr_mask = 1;
|
|
((USBCON_REG_HSREWA_INTR_p) (®))->b.wakeup_intr_mask = 1;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_INTR);
|
|
|
|
/* Set the system valid flag after all System clock resumed */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_CTL);
|
|
((USBCON_REG_HSREWA_CTL_p) (®))->b.hs_sys_valid = 1;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_CTL);
|
|
|
|
/* Check Status : Wait ReWA Status is retention disabled */
|
|
for (cnt = 10000; cnt != 0; cnt--) {
|
|
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_INT1_EVNT);
|
|
|
|
/* Disconnect Status */
|
|
if (((USBCON_REG_HSREWA_INT1_EVNT_p) (®))->b.discon) {
|
|
pr_info("sysvalid-discon\n");
|
|
return HS_REWA_EN_STS_DISCONNECT;
|
|
}
|
|
|
|
/* Success ReWA Enable */
|
|
if (((USBCON_REG_HSREWA_INT1_EVNT_p) (®))->b.ret_dis)
|
|
break;
|
|
udelay(30);
|
|
}
|
|
|
|
pr_info("sysvalid-done\n");
|
|
return HS_REWA_EN_STS_DISABLED;
|
|
}
|
|
|
|
int exynos_usbcon_rewa_disable(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base = cal_info->regs_base;
|
|
u32 reg;
|
|
int cnt;
|
|
|
|
/* Check ReWA already disable
|
|
* If ReWA was disabled states, disabled sequence is already done */
|
|
reg = readl(regs_base + USBCON_REG_REWA_CTL);
|
|
if (!(((USBCON_REG_REWA_CTL_p) (®))->b.hsrewa_en)) {
|
|
pr_info("disable_rewa-already\n");
|
|
return 0;
|
|
}
|
|
|
|
/* Set the USB link_ready flag */
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_CTL);
|
|
((USBCON_REG_HSREWA_CTL_p) (®))->b.hs_link_ready = 1;
|
|
writel(reg, regs_base + USBCON_REG_HSREWA_CTL);
|
|
|
|
/* Wait for Digital bypass control signals is disabled event */
|
|
for (cnt = 10000; cnt != 0; cnt--) {
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_INT1_EVNT);
|
|
if (((USBCON_REG_HSREWA_INT1_EVNT_p) (®))->b.bypass_dis)
|
|
break;
|
|
udelay(30);
|
|
}
|
|
|
|
if (!cnt) {
|
|
pr_info("disable_rewa-timeout_bypass_dis\n");
|
|
return -1;
|
|
}
|
|
|
|
/* Wait for HS-ReWA done */
|
|
for (cnt = 1000; cnt != 0; cnt--) {
|
|
reg = readl(regs_base + USBCON_REG_HSREWA_CTL);
|
|
if (((USBCON_REG_HSREWA_CTL_p) (®))->b.hs_rewa_done)
|
|
break;
|
|
udelay(30);
|
|
}
|
|
|
|
if (!cnt) {
|
|
pr_info("disable_rewa-timeout_hs_rewa_done\n");
|
|
return -1;
|
|
}
|
|
|
|
reg = readl(regs_base + USBCON_REG_REWA_CTL);
|
|
((USBCON_REG_REWA_CTL_p) (®))->b.hsrewa_en = 0;
|
|
writel(reg, regs_base + USBCON_REG_REWA_CTL);
|
|
pr_info("disable_rewa-done\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int exynos_usbcon_rewa_cancel(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base = cal_info->regs_base;
|
|
u32 reg;
|
|
|
|
/* Check ReWA already disable
|
|
* If ReWA was disabled states, disabled sequence is already done */
|
|
reg = readl(regs_base + USBCON_REG_REWA_CTL);
|
|
if (!(((USBCON_REG_REWA_CTL_p) (®))->b.hsrewa_en)) {
|
|
pr_info("cancel_rewa-already\n");
|
|
return 0;
|
|
}
|
|
|
|
reg = readl(regs_base + USBCON_REG_REWA_CTL);
|
|
((USBCON_REG_REWA_CTL_p) (®))->b.hsrewa_en = 0;
|
|
writel(reg, regs_base + USBCON_REG_REWA_CTL);
|
|
pr_info("cancel_rewa-done\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
void exynos_usbcon_u3_rewa_enable(struct exynos_usbphy_info *cal_info, int lfps_overlap_mode)
|
|
{
|
|
void __iomem *regs_base = cal_info->regs_base;
|
|
u32 reg;
|
|
u32 lfpsresp_limit_cnt = 0x39219; // 9ms
|
|
|
|
reg = readl(regs_base + USBCON_REG_U3REWA_CTRL);
|
|
((USBCON_REG_U3REWA_CTRL_p) (®))->b.check_u3 = 0;
|
|
((USBCON_REG_U3REWA_CTRL_p) (®))->b.u3rewa_blk_en = 1;
|
|
|
|
if (!lfps_overlap_mode) {
|
|
/* Disable overlap_lfps */
|
|
((USBCON_REG_U3REWA_CTRL_p) (®))->b.overlap_lfps = 0;
|
|
} else {
|
|
/* Enable overlap_lfps */
|
|
((USBCON_REG_U3REWA_CTRL_p) (®))->b.overlap_lfps = 1;
|
|
|
|
/* Set lfpsresp_limit_cnt */
|
|
writel(lfpsresp_limit_cnt, regs_base + USBCON_REG_U3REWA_LMT_CNT);
|
|
}
|
|
|
|
writel(reg, regs_base + USBCON_REG_U3REWA_CTRL);
|
|
pr_info("enable_u3-rewa-done\n");
|
|
}
|
|
|
|
void exynos_usbcon_u3_rewa_disable(struct exynos_usbphy_info *cal_info)
|
|
{
|
|
void __iomem *regs_base = cal_info->regs_base;
|
|
u32 reg;
|
|
|
|
reg = readl(regs_base + USBCON_REG_U3REWA_CTRL);
|
|
((USBCON_REG_U3REWA_CTRL_p) (®))->b.u3rewa_blk_en = 0;
|
|
writel(reg, regs_base + USBCON_REG_U3REWA_CTRL);
|
|
pr_info("disable_u3-rewa-done\n");
|
|
}
|