// Code for handling OHCI USB controllers.
//
// Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.

#include "biosvar.h" // GET_LOWFLAT
#include "config.h" // CONFIG_*
#include "malloc.h" // free
#include "memmap.h" // PAGE_SIZE
#include "output.h" // dprintf
#include "pcidevice.h" // foreachpci
#include "pci_ids.h" // PCI_CLASS_SERIAL_USB_OHCI
#include "pci_regs.h" // PCI_BASE_ADDRESS_0
#include "string.h" // memset
#include "usb.h" // struct usb_s
#include "usb-ehci.h" // ehci_wait_controllers
#include "usb-ohci.h" // struct ohci_hcca
#include "util.h" // msleep
#include "x86.h" // readl

#define FIT                     (1 << 31)

struct usb_ohci_s {
    struct usb_s usb;
    struct ohci_regs *regs;
};

struct ohci_pipe {
    struct ohci_ed ed;
    struct usb_pipe pipe;
    struct ohci_regs *regs;
    void *data;
    int count;
    struct ohci_td *tds;
};


/****************************************************************
 * Root hub
 ****************************************************************/

// Check if device attached to port
static int
ohci_hub_detect(struct usbhub_s *hub, u32 port)
{
    struct usb_ohci_s *cntl = container_of(hub->cntl, struct usb_ohci_s, usb);
    u32 sts = readl(&cntl->regs->roothub_portstatus[port]);
    return (sts & RH_PS_CCS) ? 1 : 0;
}

// Disable port
static void
ohci_hub_disconnect(struct usbhub_s *hub, u32 port)
{
    struct usb_ohci_s *cntl = container_of(hub->cntl, struct usb_ohci_s, usb);
    writel(&cntl->regs->roothub_portstatus[port], RH_PS_CCS|RH_PS_LSDA);
}

// Reset device on port
static int
ohci_hub_reset(struct usbhub_s *hub, u32 port)
{
    struct usb_ohci_s *cntl = container_of(hub->cntl, struct usb_ohci_s, usb);
    writel(&cntl->regs->roothub_portstatus[port], RH_PS_PRS);
    u32 sts;
    u32 end = timer_calc(USB_TIME_DRSTR * 2);
    for (;;) {
        sts = readl(&cntl->regs->roothub_portstatus[port]);
        if (!(sts & RH_PS_PRS))
            // XXX - need to ensure USB_TIME_DRSTR time in reset?
            break;
        if (timer_check(end)) {
            // Timeout.
            warn_timeout();
            ohci_hub_disconnect(hub, port);
            return -1;
        }
        yield();
    }

    if ((sts & (RH_PS_CCS|RH_PS_PES)) != (RH_PS_CCS|RH_PS_PES))
        // Device no longer present
        return -1;

    return !!(sts & RH_PS_LSDA);
}

static struct usbhub_op_s ohci_HubOp = {
    .detect = ohci_hub_detect,
    .reset = ohci_hub_reset,
    .disconnect = ohci_hub_disconnect,
};

// Find any devices connected to the root hub.
static int
check_ohci_ports(struct usb_ohci_s *cntl)
{
    ASSERT32FLAT();
    // Wait for ehci init - in case this is a "companion controller"
    ehci_wait_controllers();
    // Turn on power for all devices on roothub.
    u32 rha = readl(&cntl->regs->roothub_a);
    rha &= ~(RH_A_PSM | RH_A_OCPM);
    writel(&cntl->regs->roothub_status, RH_HS_LPSC);
    writel(&cntl->regs->roothub_b, RH_B_PPCM);
    msleep((rha >> 24) * 2);
    // XXX - need to sleep for USB_TIME_SIGATT if just powered up?

    struct usbhub_s hub;
    memset(&hub, 0, sizeof(hub));
    hub.cntl = &cntl->usb;
    hub.portcount = rha & RH_A_NDP;
    hub.op = &ohci_HubOp;
    usb_enumerate(&hub);
    return hub.devcount;
}


/****************************************************************
 * Setup
 ****************************************************************/

// Wait for next USB frame to start - for ensuring safe memory release.
static void
ohci_waittick(struct ohci_regs *regs)
{
    barrier();
    struct ohci_hcca *hcca = (void*)readl(&regs->hcca);
    u32 startframe = hcca->frame_no;
    u32 end = timer_calc(1000 * 5);
    for (;;) {
        if (hcca->frame_no != startframe)
            break;
        if (timer_check(end)) {
            warn_timeout();
            return;
        }
        yield();
    }
}

static void
ohci_free_pipes(struct usb_ohci_s *cntl)
{
    dprintf(7, "ohci_free_pipes %p\n", cntl);

    u32 creg = readl(&cntl->regs->control);
    if (creg & (OHCI_CTRL_CLE|OHCI_CTRL_BLE)) {
        writel(&cntl->regs->control, creg & ~(OHCI_CTRL_CLE|OHCI_CTRL_BLE));
        ohci_waittick(cntl->regs);
    }

    u32 *pos = &cntl->regs->ed_controlhead;
    for (;;) {
        struct ohci_ed *next = (void*)le32_to_cpu(*pos);
        if (!next)
            break;
        struct ohci_pipe *pipe = container_of(next, struct ohci_pipe, ed);
        if (usb_is_freelist(&cntl->usb, &pipe->pipe)) {
            *pos = next->hwNextED;
            free(pipe);
        } else {
            pos = &next->hwNextED;
        }
    }

    writel(&cntl->regs->ed_controlcurrent, 0);
    writel(&cntl->regs->ed_bulkcurrent, 0);
    writel(&cntl->regs->control, creg);
    cntl->usb.freelist = NULL;
}

static int
start_ohci(struct usb_ohci_s *cntl, struct ohci_hcca *hcca)
{
    u32 oldfminterval = readl(&cntl->regs->fminterval);
    u32 oldrwc = readl(&cntl->regs->control) & OHCI_CTRL_RWC;

    // XXX - check if already running?

    // Do reset
    writel(&cntl->regs->control, OHCI_USB_RESET | oldrwc);
    readl(&cntl->regs->control); // flush writes
    msleep(USB_TIME_DRSTR);

    // Do software init (min 10us, max 2ms)
    u32 end = timer_calc_usec(10);
    writel(&cntl->regs->cmdstatus, OHCI_HCR);
    for (;;) {
        u32 status = readl(&cntl->regs->cmdstatus);
        if (! status & OHCI_HCR)
            break;
        if (timer_check(end)) {
            warn_timeout();
            return -1;
        }
    }

    // Init memory
    writel(&cntl->regs->ed_controlhead, 0);
    writel(&cntl->regs->ed_bulkhead, 0);
    writel(&cntl->regs->hcca, cpu_to_le32((u32)hcca));

    // Init fminterval
    u32 fi = oldfminterval & 0x3fff;
    writel(&cntl->regs->fminterval
           , (((oldfminterval & FIT) ^ FIT)
              | fi | (((6 * (fi - 210)) / 7) << 16)));
    writel(&cntl->regs->periodicstart, ((9 * fi) / 10) & 0x3fff);
    readl(&cntl->regs->control); // flush writes

    // XXX - verify that fminterval was setup correctly.

    // Go into operational state
    writel(&cntl->regs->control
           , (OHCI_CTRL_CBSR | OHCI_CTRL_CLE | OHCI_CTRL_BLE | OHCI_CTRL_PLE
              | OHCI_USB_OPER | oldrwc));
    readl(&cntl->regs->control); // flush writes

    return 0;
}

static void
stop_ohci(struct usb_ohci_s *cntl)
{
    u32 oldrwc = readl(&cntl->regs->control) & OHCI_CTRL_RWC;
    writel(&cntl->regs->control, oldrwc);
    readl(&cntl->regs->control); // flush writes
}

static void
configure_ohci(void *data)
{
    struct usb_ohci_s *cntl = data;

    // Allocate memory
    struct ohci_hcca *hcca = memalign_high(256, sizeof(*hcca));
    struct ohci_ed *intr_ed = malloc_high(sizeof(*intr_ed));
    if (!hcca || !intr_ed) {
        warn_noalloc();
        goto free;
    }
    memset(hcca, 0, sizeof(*hcca));
    memset(intr_ed, 0, sizeof(*intr_ed));
    intr_ed->hwINFO = cpu_to_le32(ED_SKIP);
    int i;
    for (i=0; i<ARRAY_SIZE(hcca->int_table); i++)
        hcca->int_table[i] = cpu_to_le32((u32)intr_ed);

    int ret = start_ohci(cntl, hcca);
    if (ret)
        goto err;

    int count = check_ohci_ports(cntl);
    ohci_free_pipes(cntl);
    if (! count)
        goto err;
    return;

err:
    stop_ohci(cntl);
free:
    free(hcca);
    free(intr_ed);
}

static void
ohci_controller_setup(struct pci_device *pci)
{
    struct ohci_regs *regs = pci_enable_membar(pci, PCI_BASE_ADDRESS_0);
    if (!regs)
        return;

    struct usb_ohci_s *cntl = malloc_tmphigh(sizeof(*cntl));
    if (!cntl) {
        warn_noalloc();
        return;
    }
    memset(cntl, 0, sizeof(*cntl));
    cntl->usb.pci = pci;
    cntl->usb.type = USB_TYPE_OHCI;
    cntl->regs = regs;

    dprintf(1, "OHCI init on dev %pP (regs=%p)\n", pci, cntl->regs);

    pci_enable_busmaster(pci);

    // XXX - check for and disable SMM control?

    // Disable interrupts
    writel(&cntl->regs->intrdisable, ~0);
    writel(&cntl->regs->intrstatus, ~0);

    run_thread(configure_ohci, cntl);
}

void
ohci_setup(void)
{
    if (! CONFIG_USB_OHCI)
        return;
    struct pci_device *pci;
    foreachpci(pci) {
        if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_OHCI)
            ohci_controller_setup(pci);
    }
}


/****************************************************************
 * End point communication
 ****************************************************************/

// Setup fields in ed
static void
ohci_desc2pipe(struct ohci_pipe *pipe, struct usbdevice_s *usbdev
               , struct usb_endpoint_descriptor *epdesc)
{
    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
    pipe->ed.hwINFO = cpu_to_le32(
                        (ED_SKIP | usbdev->devaddr | (pipe->pipe.ep << 7)
                       | (epdesc->wMaxPacketSize << 16)
                       | (usbdev->speed ? ED_LOWSPEED : 0)));
    struct usb_ohci_s *cntl = container_of(
        usbdev->hub->cntl, struct usb_ohci_s, usb);
    pipe->regs = cntl->regs;
}

static struct usb_pipe *
ohci_alloc_intr_pipe(struct usbdevice_s *usbdev
                     , struct usb_endpoint_descriptor *epdesc)
{
    struct usb_ohci_s *cntl = container_of(
        usbdev->hub->cntl, struct usb_ohci_s, usb);
    int frameexp = usb_get_period(usbdev, epdesc);
    dprintf(7, "ohci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp);

    if (frameexp > 5)
        frameexp = 5;
    int maxpacket = epdesc->wMaxPacketSize;
    // Determine number of entries needed for 2 timer ticks.
    int ms = 1<<frameexp;
    int count = DIV_ROUND_UP(ticks_to_ms(2), ms) + 1;
    struct ohci_pipe *pipe = malloc_low(sizeof(*pipe));
    struct ohci_td *tds = malloc_low(sizeof(*tds) * count);
    void *data = malloc_low(maxpacket * count);
    if (!pipe || !tds || !data)
        goto err;
    memset(pipe, 0, sizeof(*pipe));
    ohci_desc2pipe(pipe, usbdev, epdesc);
    pipe->ed.hwINFO &= cpu_to_le32(~ED_SKIP);
    pipe->data = data;
    pipe->count = count;
    pipe->tds = tds;

    struct ohci_ed *ed = &pipe->ed;
    ed->hwHeadP = cpu_to_le32((u32)&tds[0]);
    ed->hwTailP = cpu_to_le32((u32)&tds[count-1]);

    int i;
    for (i=0; i<count-1; i++) {
        tds[i].hwINFO = cpu_to_le32(TD_DP_IN | TD_T_TOGGLE | TD_CC);
        tds[i].hwCBP = cpu_to_le32((u32)data + maxpacket * i);
        tds[i].hwNextTD = cpu_to_le32((u32)&tds[i+1]);
        tds[i].hwBE = cpu_to_le32(le32_to_cpu(tds[i].hwCBP) + maxpacket - 1);
    }

    // Add to interrupt schedule.
    struct ohci_hcca *hcca = (void*)readl(&cntl->regs->hcca);
    if (frameexp == 0) {
        // Add to existing interrupt entry.
        struct ohci_ed *intr_ed = (void*)le32_to_cpu(hcca->int_table[0]);
        ed->hwNextED = intr_ed->hwNextED;
        barrier();
        intr_ed->hwNextED = cpu_to_le32((u32)ed);
    } else {
        int startpos = 1<<(frameexp-1);
        ed->hwNextED = hcca->int_table[startpos];
        barrier();
        for (i=startpos; i<ARRAY_SIZE(hcca->int_table); i+=ms)
            hcca->int_table[i] = cpu_to_le32((u32)ed);
    }

    return &pipe->pipe;

err:
    free(pipe);
    free(tds);
    free(data);
    return NULL;
}

struct usb_pipe *
ohci_realloc_pipe(struct usbdevice_s *usbdev, struct usb_pipe *upipe
                  , struct usb_endpoint_descriptor *epdesc)
{
    if (! CONFIG_USB_OHCI)
        return NULL;
    usb_add_freelist(upipe);
    if (!epdesc)
        return NULL;
    u8 eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
    if (eptype == USB_ENDPOINT_XFER_INT)
        return ohci_alloc_intr_pipe(usbdev, epdesc);
    struct usb_ohci_s *cntl = container_of(
        usbdev->hub->cntl, struct usb_ohci_s, usb);
    dprintf(7, "ohci_alloc_async_pipe %p\n", &cntl->usb);

    struct usb_pipe *usbpipe = usb_get_freelist(&cntl->usb, eptype);
    if (usbpipe) {
        // Use previously allocated pipe.
        struct ohci_pipe *pipe = container_of(usbpipe, struct ohci_pipe, pipe);
        ohci_desc2pipe(pipe, usbdev, epdesc);
        return usbpipe;
    }

    // Allocate a new queue head.
    struct ohci_pipe *pipe;
    if (eptype == USB_ENDPOINT_XFER_CONTROL)
        pipe = malloc_tmphigh(sizeof(*pipe));
    else
        pipe = malloc_low(sizeof(*pipe));
    if (!pipe) {
        warn_noalloc();
        return NULL;
    }
    memset(pipe, 0, sizeof(*pipe));
    ohci_desc2pipe(pipe, usbdev, epdesc);

    // Add queue head to controller list.
    u32 *head = &cntl->regs->ed_controlhead;
    if (eptype != USB_ENDPOINT_XFER_CONTROL)
        head = &cntl->regs->ed_bulkhead;
    pipe->ed.hwNextED = *head;
    barrier();
    *head = cpu_to_le32((u32)&pipe->ed);
    return &pipe->pipe;
}

static int
wait_ed(struct ohci_ed *ed, int timeout)
{
    u32 end = timer_calc(timeout);
    for (;;) {
        if ((le32_to_cpu(ed->hwHeadP) & ~(ED_C|ED_H)) == le32_to_cpu(ed->hwTailP))
            return 0;
        if (timer_check(end)) {
            warn_timeout();
            dprintf(1, "ohci ed info=%x tail=%x head=%x next=%x\n",
                    le32_to_cpu(ed->hwINFO), le32_to_cpu(ed->hwTailP),
                    le32_to_cpu(ed->hwHeadP), le32_to_cpu(ed->hwNextED));
            return -1;
        }
        yield();
    }
}

#define STACKOTDS 18
#define OHCI_TD_ALIGN 16

int
ohci_send_pipe(struct usb_pipe *p, int dir, const void *cmd
               , void *data, int datasize)
{
    ASSERT32FLAT();
    if (! CONFIG_USB_OHCI)
        return -1;
    dprintf(7, "ohci_send_pipe %p   cmd=%p  datasize = %d   XXXXXXXXXXXXXXX\n", p, cmd, datasize);
    struct ohci_pipe *pipe = container_of(p, struct ohci_pipe, pipe);

    // Allocate tds on stack (with required alignment)
    u8 tdsbuf[sizeof(struct ohci_td) * STACKOTDS + OHCI_TD_ALIGN - 1];
    struct ohci_td *tds = (void*)ALIGN((u32)tdsbuf, OHCI_TD_ALIGN), *td = tds;
    memset(tds, 0, sizeof(*tds) * STACKOTDS);

    // Setup transfer descriptors
    u16 maxpacket = pipe->pipe.maxpacket;
    u32 toggle = 0, statuscmd = OHCI_BLF;
    if (cmd) {
        // Send setup pid on control transfers
        td->hwINFO = cpu_to_le32(TD_DP_SETUP | TD_T_DATA0 | TD_CC);
        td->hwCBP = cpu_to_le32((u32)cmd);
        td->hwNextTD = cpu_to_le32((u32)&td[1]);
        td->hwBE = cpu_to_le32((u32)cmd + USB_CONTROL_SETUP_SIZE - 1);
        td++;
        toggle = TD_T_DATA1;
        statuscmd = OHCI_CLF;
    }
    u32 dest = (u32)data, dataend = dest + datasize;
    while (dest < dataend) {
        // Send data pids
        if (td >= &tds[STACKOTDS]) {
            warn_noalloc();
            return -1;
        }
        int maxtransfer = 2*PAGE_SIZE - (dest & (PAGE_SIZE-1));
        int transfer = dataend - dest;
        if (transfer > maxtransfer)
            transfer = ALIGN_DOWN(maxtransfer, maxpacket);
        td->hwINFO = cpu_to_le32((dir ? TD_DP_IN : TD_DP_OUT) | toggle | TD_CC);
        td->hwCBP = cpu_to_le32(dest);
        td->hwNextTD = cpu_to_le32((u32)&td[1]);
        td->hwBE = cpu_to_le32(dest + transfer - 1);
        td++;
        dest += transfer;
    }
    if (cmd) {
        // Send status pid on control transfers
        if (td >= &tds[STACKOTDS]) {
            warn_noalloc();
            return -1;
        }
        td->hwINFO = cpu_to_le32((dir ? TD_DP_OUT : TD_DP_IN) | TD_T_DATA1 | TD_CC);
        td->hwCBP = 0;
        td->hwNextTD = cpu_to_le32((u32)&td[1]);
        td->hwBE = 0;
        td++;
    }

    // Transfer data
    pipe->ed.hwHeadP = cpu_to_le32((u32)tds | (le32_to_cpu(pipe->ed.hwHeadP) & ED_C));
    pipe->ed.hwTailP = cpu_to_le32((u32)td);
    barrier();
    pipe->ed.hwINFO &= cpu_to_le32(~ED_SKIP);
    writel(&pipe->regs->cmdstatus, statuscmd);

    int ret = wait_ed(&pipe->ed, usb_xfer_time(p, datasize));
    pipe->ed.hwINFO |= cpu_to_le32(ED_SKIP);
    if (ret)
        ohci_waittick(pipe->regs);
    dprintf(7, "ohci_send_pipe ENDE  XXXXXXXXXXXXXXX  ret=%d\n", ret);
    return ret;
}

int
ohci_poll_intr(struct usb_pipe *p, void *data)
{
    ASSERT16();
    if (! CONFIG_USB_OHCI)
        return -1;

    struct ohci_pipe *pipe = container_of(p, struct ohci_pipe, pipe);
    struct ohci_td *tds = GET_LOWFLAT(pipe->tds);
    struct ohci_td *head = (void*)(le32_to_cpu(GET_LOWFLAT(pipe->ed.hwHeadP)) & ~(ED_C|ED_H));
    struct ohci_td *tail = (void*)le32_to_cpu(GET_LOWFLAT(pipe->ed.hwTailP));
    int count = GET_LOWFLAT(pipe->count);
    int pos = (tail - tds + 1) % count;
    struct ohci_td *next = &tds[pos];
    if (head == next)
        // No intrs found.
        return -1;
    // XXX - check for errors.

    // Copy data.
    int maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket);
    void *pipedata = GET_LOWFLAT((pipe->data));
    void *intrdata = pipedata + maxpacket * pos;
    memcpy_far(GET_SEG(SS), data, SEG_LOW, LOWFLAT2LOW(intrdata), maxpacket);

    // Reenable this td.
    SET_LOWFLAT(tail->hwINFO, cpu_to_le32(TD_DP_IN | TD_T_TOGGLE | TD_CC));
    intrdata = pipedata + maxpacket * (tail-tds);
    SET_LOWFLAT(tail->hwCBP, cpu_to_le32((u32)intrdata));
    SET_LOWFLAT(tail->hwNextTD, cpu_to_le32((u32)next));
    SET_LOWFLAT(tail->hwBE, cpu_to_le32((u32)intrdata + maxpacket - 1));
    barrier();
    SET_LOWFLAT(pipe->ed.hwTailP, cpu_to_le32((u32)next));

    return 0;
}
