blob: 06e4b3d181d6509dc6a3c4dbb1ef22a119b1b1f8 [file] [log] [blame]
// 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 "dwc3.h"
#include "dwc3-regs.h"
#include <fbl/auto_lock.h>
#include <stdio.h>
#include <unistd.h>
void dwc3_cmd_start_new_config(dwc3_t* dwc, unsigned ep_num, unsigned rsrc_id) {
auto* mmio = dwc3_mmio(dwc);
fbl::AutoLock lock(&dwc->lock);
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_cmd_ep_set_config(dwc3_t* dwc, unsigned ep_num, unsigned ep_type,
unsigned max_packet_size, unsigned interval, bool modify) {
auto* mmio = dwc3_mmio(dwc);
fbl::AutoLock lock(&dwc->lock);
// fifo number is zero for OUT endpoints and EP0_IN
uint32_t fifo_num = (EP_OUT(ep_num) || ep_num == EP0_IN ? 0 : ep_num >> 1);
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(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(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_cmd_ep_transfer_config(dwc3_t* dwc, unsigned ep_num) {
auto* mmio = dwc3_mmio(dwc);
fbl::AutoLock lock(&dwc->lock);
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_cmd_ep_start_transfer(dwc3_t* dwc, unsigned ep_num, zx_paddr_t trb_phys) {
auto* mmio = dwc3_mmio(dwc);
fbl::AutoLock lock(&dwc->lock);
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_cmd_ep_end_transfer(dwc3_t* dwc, unsigned ep_num) {
auto* mmio = dwc3_mmio(dwc);
fbl::AutoLock lock(&dwc->lock);
unsigned rsrc_id = dwc->eps[ep_num].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_cmd_ep_set_stall(dwc3_t* dwc, unsigned ep_num) {
auto* mmio = dwc3_mmio(dwc);
fbl::AutoLock lock(&dwc->lock);
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_cmd_ep_clear_stall(dwc3_t* dwc, unsigned ep_num) {
auto* mmio = dwc3_mmio(dwc);
fbl::AutoLock lock(&dwc->lock);
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);
}
}