// Copyright 2016 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 <ddk/binding.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/display.h>
#include <ddk/protocol/pci.h>
#include <hw/pci.h>

#include <assert.h>
#include <inttypes.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// simple framebuffer device to match against an AMD Kaveri R7 device already
// initialized from EFI
#define AMD_GFX_VID (0x1002)
#define AMD_KAVERI_R7_DID (0x130f)

typedef struct kaveri_disp_device {
    void* regs;
    uint64_t regs_size;
    zx_handle_t regs_handle;

    void* framebuffer;
    uint64_t framebuffer_size;
    zx_handle_t framebuffer_handle;

    zx_display_info_t info;
} kaveri_disp_device_t;

// implement display protocol
static zx_status_t kaveri_disp_set_mode(void* ctx, zx_display_info_t* info) {
    return ZX_ERR_NOT_SUPPORTED;
}

static zx_status_t kaveri_disp_get_mode(void* ctx, zx_display_info_t* info) {
    assert(info);
    kaveri_disp_device_t* device = ctx;

    memcpy(info, &device->info, sizeof(zx_display_info_t));
    return ZX_OK;
}

static zx_status_t kaveri_disp_get_framebuffer(void* ctx, void** framebuffer) {
    assert(framebuffer);
    kaveri_disp_device_t* device = ctx;

    (*framebuffer) = device->framebuffer;
    return ZX_OK;
}

static display_protocol_ops_t kaveri_disp_display_proto = {
    .set_mode = kaveri_disp_set_mode,
    .get_mode = kaveri_disp_get_mode,
    .get_framebuffer = kaveri_disp_get_framebuffer,
};

// implement device protocol

static void kaveri_disp_release(void* ctx) {
    kaveri_disp_device_t* device = ctx;

    if (device->regs) {
        zx_handle_close(device->regs_handle);
        device->regs_handle = -1;
    }

    if (device->framebuffer) {
        zx_handle_close(device->framebuffer_handle);
        device->framebuffer_handle = -1;
    }

    free(device);
}

static zx_protocol_device_t kaveri_disp_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .release = kaveri_disp_release,
};

// implement driver object:

static zx_status_t kaveri_disp_bind(void* ctx, zx_device_t* dev, void** cookie) {
    pci_protocol_t pci;
    zx_status_t status;

    if (device_get_protocol(dev, ZX_PROTOCOL_PCI, &pci))
        return ZX_ERR_NOT_SUPPORTED;

    // map resources and initialize the device
    kaveri_disp_device_t* device = calloc(1, sizeof(kaveri_disp_device_t));
    if (!device)
        return ZX_ERR_NO_MEMORY;

    // map register window
    // seems to be bar 5
    status = pci_map_resource(&pci, PCI_RESOURCE_BAR_5, ZX_CACHE_POLICY_UNCACHED_DEVICE,
                              &device->regs, &device->regs_size, &device->regs_handle);
    if (status != ZX_OK) {
        printf("kaveri: failed to map pci bar 5: %d\n", status);
        goto fail;
    }

    // map framebuffer window
    // seems to be bar 0
    status = pci_map_resource(&pci, PCI_RESOURCE_BAR_0, ZX_CACHE_POLICY_WRITE_COMBINING,
                              &device->framebuffer,
                              &device->framebuffer_size,
                              &device->framebuffer_handle);
    if (status != ZX_OK) {
        printf("kaveri-disp: failed to map pci bar 0: %d\n", status);
        goto fail;
    }

    zx_display_info_t* di = &device->info;
    uint32_t format, width, height, stride;
    status = zx_bootloader_fb_get_info(&format, &width, &height, &stride);
    if (status == ZX_OK) {
        di->format = format;
        di->width = width;
        di->height = height;
        di->stride = stride;
    } else {
        status = ZX_ERR_NOT_SUPPORTED;
        goto fail;
    }
    di->flags = ZX_DISPLAY_FLAG_HW_FRAMEBUFFER;

    zx_set_framebuffer(get_root_resource(), device->framebuffer, device->framebuffer_size,
                       format, width, height, stride);


    // create and add the display (char) device
   device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "amd_kaveri_disp",
        .ctx = device,
        .ops = &kaveri_disp_device_proto,
        .proto_id = ZX_PROTOCOL_DISPLAY,
        .proto_ops = &kaveri_disp_display_proto,
    };

    status = device_add(dev, &args, NULL);
    if (status != ZX_OK) {
        goto fail;
    }

    printf("initialized amd kaveri R7 display driver, reg=%p regsize=0x%" PRIx64 " fb=%p fbsize=0x%" PRIx64 "\n",
           device->regs, device->regs_size, device->framebuffer, device->framebuffer_size);
    printf("\twidth %u height %u stride %u format %u\n",
           device->info.width, device->info.height, device->info.stride, device->info.format);

    return ZX_OK;

fail:
    free(device);
    return status;
}

static zx_driver_ops_t kaveri_disp_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = kaveri_disp_bind,
};

// clang-format off
ZIRCON_DRIVER_BEGIN(kaveri_disp, kaveri_disp_driver_ops, "zircon", "0.1", 3)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PCI),
    BI_ABORT_IF(NE, BIND_PCI_VID, AMD_GFX_VID),
    BI_MATCH_IF(EQ, BIND_PCI_DID, AMD_KAVERI_R7_DID),
ZIRCON_DRIVER_END(kaveri_disp)
