// 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 <memory>

#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/scpi.h>
#include <hw/reg.h>

#include <soc/aml-s912/s912-hw.h>

#include <fbl/algorithm.h>
#include <fbl/unique_ptr.h>
#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/threads.h>

#include "vim.h"

namespace vim {

// TODO(rjascani): Remove this when not needed for testing any longer
const pbus_dev_t tee_dev = []() {
    pbus_dev_t dev;
    dev.name = "tee";
    dev.vid = PDEV_VID_GENERIC;
    dev.pid = PDEV_PID_GENERIC;
    dev.did = PDEV_DID_OPTEE;
    return dev;
}();

zx_status_t Vim::Create(void* ctx, zx_device_t* parent) {
    pbus_protocol_t pbus;
    iommu_protocol_t iommu;
    pbus_board_info_t info;

    auto status = device_get_protocol(parent, ZX_PROTOCOL_PBUS, &pbus);
    if (status != ZX_OK) {
        return status;
    }

    // Set dummy board revision to facilitate testing of platform device get_board_info support.
    info.board_revision = 1234;
    pbus_set_board_info(&pbus, &info);

    status = device_get_protocol(parent, ZX_PROTOCOL_IOMMU, &iommu);
    if (status != ZX_OK) {
        return status;
    }

    fbl::AllocChecker ac;
    auto board = std::unique_ptr<Vim>(new (&ac) Vim(parent, &pbus, &iommu));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    status = board->DdkAdd("vim", DEVICE_ADD_NON_BINDABLE);
    if (status != ZX_OK) {
        return status;
    }

    // Start up our protocol helpers and platform devices.
    status = board->Start();

    if (status == ZX_OK) {
        // devmgr is now in charge of the device.
        __UNUSED auto* dummy = board.release();
    }

    return status;
}

int Vim::Thread() {
    zx_status_t status;
    pdev_board_info_t info;

    // Fetch the board info so that we can distinguish between the "vim2" and
    // "vim2-machina" boards. The latter of which does not initialize devices.
    status = pbus_.GetBoardInfo(&info);
    if (status != ZX_OK) {
        zxlogf(ERROR, "Thread: GetBoardInfo failed: %d\n", status);
        return -1;
    }

    if (info.pid == PDEV_PID_VIM2_MACHINA) {
        return ZX_OK;
    }

    // Start protocol drivers before adding platform devices.
    // Sysmem is started early so zx_vmo_create_contiguous() works.
    if ((status = SysmemInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: SysmemInit failed: %d\n", status);
        return -1;
    }

    if ((status = GpioInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: GpioInit failed: %d\n", status);
        return -1;
    }

    if ((status = I2cInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: I2cInit failed: %d\n", status);
        return -1;
    }

    if ((status = ClkInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: ClkInit failed: %d\n", status);
        return -1;
    }

    if ((status = CanvasInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: CanvasInit failed: %d\n", status);
        return -1;
    }

    // Start platform devices.
    if ((status = UartInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: UartInit failed: %d\n", status);
        return -1;
    }

    if ((status = EmmcInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: EmmcInit failed: %d\n", status);
        return -1;
    }

    if ((status = SdioInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: SdioInit failed: %d\n", status);
        return -1;
    }

    if ((status = EthInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: EthInit failed: %d\n", status);
        return -1;
    }

    if ((status = UsbInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: UsbInit failed: %d\n", status);
        return -1;
    }

    if ((status = MaliInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: MaliInit failed: %d\n", status);
        return -1;
    }

    if ((status = ThermalInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: ThermalInit failed: %d\n", status);
        return -1;
    }

    if ((status = DisplayInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: DisplayInit failed: %d\n", status);
        return -1;
    }

    if ((status = VideoInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: VideoInit failed: %d\n", status);
        return -1;
    }

    // Remove this when not needed for testing any longer
    if ((status = pbus_.DeviceAdd(&tee_dev)) != ZX_OK) {
        zxlogf(ERROR, "vim_start_thread, could not add tee_dev: %d\n", status);
        return -1;
    }

    if ((status = SdInit()) != ZX_OK) {
        zxlogf(ERROR, "Thread: SdInit failed: %d\n", status);
        return -1;
    }

    return ZX_OK;
}

zx_status_t Vim::Start() {
    int rc = thrd_create_with_name(
        &thread_,
        [](void* arg) -> int {
            return reinterpret_cast<Vim*>(arg)->Thread();
        },
        this,
        "vim-start-thread");

    if (rc != thrd_success) {
        return ZX_ERR_INTERNAL;
    }
    return ZX_OK;
}

void Vim::DdkRelease() {
    delete this;
}
zx_driver_ops_t vim_driver_ops = []() {
    zx_driver_ops_t ops = {};
    ops.version = DRIVER_OPS_VERSION;
    ops.bind = Vim::Create;
    return ops;
}();

} // namespace vim

ZIRCON_DRIVER_BEGIN(vim, vim::vim_driver_ops, "zircon", "0.1", 4)
BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PBUS),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_KHADAS),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_VIM2),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_VIM2_MACHINA),
ZIRCON_DRIVER_END(vim)
