| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <fbl/auto_lock.h> |
| |
| #include "src/devices/usb/drivers/dwc3/dwc3-regs.h" |
| #include "src/devices/usb/drivers/dwc3/dwc3.h" |
| |
| namespace dwc3 { |
| |
| void Dwc3::CmdStartNewConfig(const Endpoint& ep, uint32_t rsrc_id) { |
| fbl::AutoLock lock(&lock_); |
| |
| auto* mmio = get_mmio(); |
| const uint8_t ep_num = ep.ep_num; |
| |
| DEPCMDPAR0::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMDPAR1::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMDPAR2::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMD::Get(ep_num) |
| .FromValue(0) |
| .set_CMDTYP(DEPCMD::DEPSTARTCFG) |
| .set_COMMANDPARAM(rsrc_id) |
| .set_CMDACT(1) |
| .WriteTo(mmio); |
| } |
| |
| void Dwc3::CmdEpSetConfig(const Endpoint& ep, bool modify) { |
| fbl::AutoLock lock(&lock_); |
| |
| auto* mmio = get_mmio(); |
| const uint8_t ep_num = ep.ep_num; |
| |
| // fifo number is zero for OUT endpoints and EP0_IN |
| const uint32_t fifo_num = (ep.IsOutput() || (ep_num == kEp0In)) ? 0 : ep_num >> 1; |
| const uint32_t action = |
| modify ? DEPCFG_DEPCMDPAR0::ACTION_MODIFY : DEPCFG_DEPCMDPAR0::ACTION_INITIALIZE; |
| |
| DEPCFG_DEPCMDPAR0::Get(ep_num) |
| .FromValue(0) |
| .set_FIFO_NUM(fifo_num) |
| .set_MAX_PACKET_SIZE(ep.max_packet_size) |
| .set_EP_TYPE(ep.type) |
| .set_ACTION(action) |
| .WriteTo(mmio); |
| DEPCFG_DEPCMDPAR1::Get(ep_num) |
| .FromValue(0) |
| .set_EP_NUMBER(ep_num) |
| .set_INTERVAL(ep.interval) |
| .set_XFER_NOT_READY_EN(1) |
| .set_XFER_COMPLETE_EN(1) |
| .set_INTR_NUM(0) |
| .WriteTo(mmio); |
| DEPCMDPAR2::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMD::Get(ep_num).FromValue(0).set_CMDTYP(DEPCMD::DEPCFG).set_CMDACT(1).WriteTo(mmio); |
| } |
| |
| void Dwc3::CmdEpTransferConfig(const Endpoint& ep) { |
| fbl::AutoLock lock(&lock_); |
| auto* mmio = get_mmio(); |
| const uint8_t ep_num = ep.ep_num; |
| |
| DEPCMDPAR0::Get(ep_num).FromValue(0).set_PARAMETER(1).WriteTo(mmio); |
| DEPCMDPAR1::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMDPAR2::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMD::Get(ep_num).FromValue(0).set_CMDTYP(DEPCMD::DEPXFERCFG).set_CMDACT(1).WriteTo(mmio); |
| } |
| |
| void Dwc3::CmdEpStartTransfer(const Endpoint& ep, zx_paddr_t trb_phys) { |
| fbl::AutoLock lock(&lock_); |
| auto* mmio = get_mmio(); |
| const uint8_t ep_num = ep.ep_num; |
| |
| DEPCMDPAR0::Get(ep_num) |
| .FromValue(0) |
| .set_PARAMETER(static_cast<uint32_t>(trb_phys >> 32)) |
| .WriteTo(mmio); |
| DEPCMDPAR1::Get(ep_num).FromValue(0).set_PARAMETER(static_cast<uint32_t>(trb_phys)).WriteTo(mmio); |
| DEPCMDPAR2::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMD::Get(ep_num) |
| .FromValue(0) |
| .set_CMDTYP(DEPCMD::DEPSTRTXFER) |
| .set_CMDACT(1) |
| .set_CMDIOC(1) |
| .WriteTo(mmio); |
| |
| while (DEPCMD::Get(ep_num).ReadFrom(mmio).CMDACT()) { |
| usleep(1000); |
| } |
| } |
| |
| void Dwc3::CmdEpEndTransfer(const Endpoint& ep) { |
| fbl::AutoLock lock(&lock_); |
| auto* mmio = get_mmio(); |
| |
| const uint32_t ep_num = ep.ep_num; |
| const uint32_t rsrc_id = ep.rsrc_id; |
| |
| DEPCMDPAR0::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMDPAR1::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMDPAR2::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMD::Get(ep_num) |
| .FromValue(0) |
| .set_CMDTYP(DEPCMD::DEPENDXFER) |
| .set_COMMANDPARAM(rsrc_id) |
| .set_CMDACT(1) |
| .set_CMDIOC(1) |
| .set_HIPRI_FORCERM(1) |
| .WriteTo(mmio); |
| |
| while (DEPCMD::Get(ep_num).ReadFrom(mmio).CMDACT()) { |
| usleep(1000); |
| } |
| } |
| |
| void Dwc3::CmdEpSetStall(const Endpoint& ep) { |
| fbl::AutoLock lock(&lock_); |
| auto* mmio = get_mmio(); |
| |
| const uint32_t ep_num = ep.ep_num; |
| |
| DEPCMDPAR0::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMDPAR1::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMDPAR2::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMD::Get(ep_num) |
| .FromValue(0) |
| .set_CMDTYP(DEPCMD::DEPSSTALL) |
| .set_CMDACT(1) |
| .set_CMDIOC(1) |
| .WriteTo(mmio); |
| |
| while (DEPCMD::Get(ep_num).ReadFrom(mmio).CMDACT()) { |
| usleep(1000); |
| } |
| } |
| |
| void Dwc3::CmdEpClearStall(const Endpoint& ep) { |
| fbl::AutoLock lock(&lock_); |
| auto* mmio = get_mmio(); |
| |
| const uint32_t ep_num = ep.ep_num; |
| |
| DEPCMDPAR0::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMDPAR1::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMDPAR2::Get(ep_num).FromValue(0).WriteTo(mmio); |
| DEPCMD::Get(ep_num) |
| .FromValue(0) |
| .set_CMDTYP(DEPCMD::DEPCSTALL) |
| .set_CMDACT(1) |
| .set_CMDIOC(1) |
| .WriteTo(mmio); |
| |
| while (DEPCMD::Get(ep_num).ReadFrom(mmio).CMDACT()) { |
| usleep(1000); |
| } |
| } |
| |
| } // namespace dwc3 |