// 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 <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/binding.h>
#include <ddk/io-buffer.h>
#include <ddk/protocol/bcm-bus.h>
#include <ddk/protocol/display.h>
#include <ddk/protocol/platform-device.h>

#include <zircon/syscalls.h>
#include <zircon/assert.h>

#include <bcm/bcm28xx.h>
#include <bcm/ioctl.h>

typedef struct {
    uint32_t phys_width;    //request
    uint32_t phys_height;   //request
    uint32_t virt_width;    //request
    uint32_t virt_height;   //request
    uint32_t pitch;         //response
    uint32_t depth;         //request
    uint32_t virt_x_offs;   //request
    uint32_t virt_y_offs;   //request
    uint32_t fb_p;          //response
    uint32_t fb_size;       //response
} bcm_fb_desc_t;

typedef struct {
    bcm_bus_protocol_t bus_proto;
    zx_display_info_t disp_info;
    bcm_fb_desc_t fb_desc;
    io_buffer_t buffer;
    uint8_t* framebuffer;
} bcm_display_t;

static zx_status_t vc_set_mode(void* ctx, zx_display_info_t* info) {
    return ZX_OK;
}

static zx_status_t vc_get_mode(void* ctx, zx_display_info_t* info) {
    if (!info) return ZX_ERR_INVALID_ARGS;
    bcm_display_t* display = ctx;
    memcpy(info, &display->disp_info, sizeof(zx_display_info_t));
    return ZX_OK;
}

static zx_status_t vc_get_framebuffer(void* ctx, void** framebuffer) {
    if (!framebuffer) return ZX_ERR_INVALID_ARGS;
    bcm_display_t* display = ctx;
    (*framebuffer) = display->framebuffer;
    return ZX_OK;
}

static void vc_flush_framebuffer(void* ctx) {
    bcm_display_t* display = ctx;
    zx_cache_flush(display->framebuffer, display->fb_desc.fb_size, ZX_CACHE_FLUSH_DATA);
}

static display_protocol_ops_t vc_display_proto = {
    .set_mode = vc_set_mode,
    .get_mode = vc_get_mode,
    .get_framebuffer = vc_get_framebuffer,
    .flush = vc_flush_framebuffer
};

static zx_protocol_device_t empty_device_proto = {
    .version = DEVICE_OPS_VERSION,
};

static zx_status_t bcm_vc_get_framebuffer(bcm_display_t* display, bcm_fb_desc_t* fb_desc) {
    zx_status_t ret = ZX_OK;
    iotxn_t* txn;

    if (!display->framebuffer) {
        // buffer needs to be aligned on 16 byte boundary, pad the alloc to make sure we have room to adjust
        const size_t txnsize = sizeof(bcm_fb_desc_t) + 16;
        ret = iotxn_alloc(&txn, IOTXN_ALLOC_CONTIGUOUS | IOTXN_ALLOC_POOL, txnsize);
        if (ret < 0)
            return ret;

        iotxn_physmap(txn);
        ZX_DEBUG_ASSERT(txn->phys_count == 1);
        zx_paddr_t phys = iotxn_phys(txn);

        // calculate offset in buffer that will provide 16 byte alignment (physical)
        uint32_t offset = (16 - (phys % 16)) % 16;

        iotxn_copyto(txn, fb_desc, sizeof(bcm_fb_desc_t), offset);
        iotxn_cacheop(txn, IOTXN_CACHE_CLEAN, 0, txnsize);

        ret = bcm_bus_set_framebuffer(&display->bus_proto, phys + offset);
        if (ret != ZX_OK) {
            printf("bcm_bus_set_framebuffer failed %d\n", ret);
            return ret;
        }

        iotxn_cacheop(txn, IOTXN_CACHE_INVALIDATE, 0, txnsize);
        iotxn_copyfrom(txn, &display->fb_desc, sizeof(bcm_fb_desc_t), offset);

        // map framebuffer into userspace
        ret = io_buffer_init_physical(&display->buffer, display->fb_desc.fb_p & 0x3fffffff,
                                      display->fb_desc.fb_size, get_root_resource(),
                                      ZX_CACHE_POLICY_CACHED);
        iotxn_release(txn);

        if (ret != ZX_OK) {
            printf("bcm_vc_get_framebuffer: io_buffer_init_physical failed %d\n", ret);
            return ret;
        }
        display->framebuffer = (uint8_t*)io_buffer_virt(&display->buffer);
        memset(display->framebuffer, 0x00, display->fb_desc.fb_size);
    }
    memcpy(fb_desc, &display->fb_desc, sizeof(bcm_fb_desc_t));
    return ZX_OK;
}

zx_status_t bcm_display_bind(void* ctx, zx_device_t* parent, void** cookie) {
    bcm_display_t* display = calloc(1, sizeof(bcm_display_t));
    if (!display) {
        return ZX_ERR_NO_MEMORY;
    }

   platform_device_protocol_t pdev;
    zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_DEV, &pdev);
    if (status !=  ZX_OK) {
        free(display);
        return status;
    }

    status = pdev_get_protocol(&pdev, ZX_PROTOCOL_BCM_BUS, &display->bus_proto);
    if (status != ZX_OK) {
        printf("bcm_display_bind can't find ZX_PROTOCOL_BCM_BUS\n");
        free(display);
        return status;
    }

    bcm_fb_desc_t framebuff_descriptor;

    // For now these are set to work with the rpi 5" lcd didsplay
    // TODO: add a mechanisms to specify and change settings outside the driver

    framebuff_descriptor.phys_width = 800;
    framebuff_descriptor.phys_height = 480;
    framebuff_descriptor.virt_width = 800;
    framebuff_descriptor.virt_height = 480;
    framebuff_descriptor.pitch = 0;
    framebuff_descriptor.depth = 32;
    framebuff_descriptor.virt_x_offs = 0;
    framebuff_descriptor.virt_y_offs = 0;
    framebuff_descriptor.fb_p = 0;
    framebuff_descriptor.fb_size = 0;

    if (bcm_vc_get_framebuffer(display, &framebuff_descriptor) != ZX_OK) {
        free(display);
        return status;
    }

    display->disp_info.format = ZX_PIXEL_FORMAT_ARGB_8888;
    display->disp_info.width = 800;
    display->disp_info.height = 480;
    display->disp_info.stride = 800;

    zx_set_framebuffer(get_root_resource(), display->framebuffer,
                       display->fb_desc.fb_size, display->disp_info.format,
                       display->disp_info.width, display->disp_info.height,
                       display->disp_info.stride);

    device_add_args_t vc_fbuff_args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "bcm-vc-fbuff",
        .ctx = display,
        .ops = &empty_device_proto,
        .proto_id = ZX_PROTOCOL_DISPLAY,
        .proto_ops = &vc_display_proto,
    };

    status = device_add(parent, &vc_fbuff_args, NULL);
    if (status != ZX_OK) {
        free(display);
    }
    return status;
}

static zx_driver_ops_t bcm_display_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = bcm_display_bind,
};

ZIRCON_DRIVER_BEGIN(bcm_display, bcm_display_driver_ops, "zircon", "0.1", 3)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PLATFORM_DEV),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_BROADCOMM),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_BROADCOMM_DISPLAY),
ZIRCON_DRIVER_END(bcm_display)
