// Copyright 2018 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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/iommu.h>
#include <ddk/protocol/platform-bus.h>
#include <ddk/protocol/platform-defs.h>
#include <ddk/protocol/platform-device.h>
#include <hw/reg.h>
#include <soc/aml-common/aml-gpu.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>

#include "s912-gpu.h"
#include "s905d2-gpu.h"

static void aml_gpu_init(aml_gpu_t* gpu) {
    uint32_t temp;
    aml_gpu_block_t* gpu_block = gpu->gpu_block;

    temp = READ32_PRESET_REG(gpu_block->reset0_mask_offset);
    temp &= ~(1 << 20);
    WRITE32_PRESET_REG(gpu_block->reset0_mask_offset, temp);

    temp = READ32_PRESET_REG(gpu_block->reset0_level_offset);
    temp &= ~(1 << 20);
    WRITE32_PRESET_REG(gpu_block->reset0_level_offset, temp);

    temp = READ32_PRESET_REG(gpu_block->reset2_mask_offset);
    temp &= ~(1 << 14);
    WRITE32_PRESET_REG(gpu_block->reset2_mask_offset, temp);

    temp = READ32_PRESET_REG(gpu_block->reset2_level_offset);
    temp &= ~(1 << 14);
    WRITE32_PRESET_REG(gpu_block->reset2_level_offset, temp);

    WRITE32_HIU_REG(gpu_block->hhi_clock_cntl_offset, gpu_block->mhz500);
    zx_nanosleep(zx_deadline_after(ZX_USEC(500)));

    temp = READ32_PRESET_REG(gpu_block->reset0_level_offset);
    temp |= 1 << 20;
    WRITE32_PRESET_REG(gpu_block->reset0_level_offset, temp);

    temp = READ32_PRESET_REG(gpu_block->reset2_level_offset);
    temp |= 1 << 14;
    WRITE32_PRESET_REG(gpu_block->reset2_level_offset, temp);

    WRITE32_GPU_REG(PWR_KEY, 0x2968A819);
    WRITE32_GPU_REG(PWR_OVERRIDE1, 0xfff | (0x20 << 16));
}

static void aml_gpu_release(void* ctx) {
    aml_gpu_t* gpu = ctx;
    io_buffer_release(&gpu->hiu_buffer);
    io_buffer_release(&gpu->preset_buffer);
    io_buffer_release(&gpu->gpu_buffer);
    free(gpu);
}

static zx_status_t aml_gpu_get_protocol(void* ctx, uint32_t proto_id, void* out_proto) {

    aml_gpu_t* gpu = ctx;
    platform_device_protocol_t* gpu_proto = out_proto;

    // Forward the underlying ops.
    gpu_proto->ops = gpu->pdev.ops;
    gpu_proto->ctx = gpu->pdev.ctx;

    return ZX_OK;
}

static zx_protocol_device_t aml_gpu_protocol = {
    .version        = DEVICE_OPS_VERSION,
    .release        = aml_gpu_release,
    .get_protocol   = aml_gpu_get_protocol,
};

static zx_status_t aml_gpu_bind(void* ctx, zx_device_t* parent) {
    zx_status_t status;
    aml_gpu_t* gpu = calloc(1, sizeof(aml_gpu_t));
    if (!gpu) {
        return ZX_ERR_NO_MEMORY;
    }

    if ((status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_DEV, &gpu->pdev)) != ZX_OK) {
        GPU_ERROR("ZX_PROTOCOL_PLATFORM_DEV not available\n");
        goto fail;
    }

    status = pdev_map_mmio_buffer(&gpu->pdev, MMIO_GPU, ZX_CACHE_POLICY_UNCACHED_DEVICE,
                                    &gpu->gpu_buffer);
    if (status != ZX_OK) {
        GPU_ERROR("pdev_map_mmio_buffer failed\n");
        goto fail;
    }

    status = pdev_map_mmio_buffer(&gpu->pdev, MMIO_HIU, ZX_CACHE_POLICY_UNCACHED_DEVICE,
                                    &gpu->hiu_buffer);
    if (status != ZX_OK) {
        GPU_ERROR("pdev_map_mmio_buffer failed\n");
        goto fail;
    }

    status = pdev_map_mmio_buffer(&gpu->pdev, MMIO_PRESET, ZX_CACHE_POLICY_UNCACHED_DEVICE,
                                    &gpu->preset_buffer);
    if (status != ZX_OK) {
        GPU_ERROR("pdev_map_mmio_buffer failed\n");
        goto fail;
    }

    pdev_device_info_t info;
    status = pdev_get_device_info(&gpu->pdev, &info);
    if (status != ZX_OK) {
        GPU_ERROR("pdev_get_device_info failed\n");
        goto fail;
    }

    switch (info.pid) {
    case PDEV_PID_AMLOGIC_S912:
        gpu->gpu_block      = &s912_gpu_blocks;
        break;
    case PDEV_PID_AMLOGIC_S905D2:
        gpu->gpu_block      = &s905d2_gpu_blocks;
        break;
    default:
        GPU_ERROR("unsupported SOC PID %u\n", info.pid);
        goto fail;
    }

    aml_gpu_init(gpu);

    zx_device_prop_t props[] = {
        {BIND_PROTOCOL, 0, ZX_PROTOCOL_PLATFORM_DEV},
        {BIND_PLATFORM_DEV_VID, 0, PDEV_VID_GENERIC},
        {BIND_PLATFORM_DEV_PID, 0, PDEV_PID_GENERIC},
        {BIND_PLATFORM_DEV_DID, 0, PDEV_DID_ARM_MALI},
    };

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "aml-gpu",
        .ctx = gpu,
        .ops = &aml_gpu_protocol,
        .props = props,
        .prop_count = countof(props),
    };

    status = device_add(parent, &args, &gpu->zxdev);
    if (status != ZX_OK) {
        goto fail;
    }

    return ZX_OK;

fail:
    aml_gpu_release(gpu);
    return status;
}

static zx_driver_ops_t aml_gpu_driver_ops = {
    .version    = DRIVER_OPS_VERSION,
    .bind       = aml_gpu_bind,
};

ZIRCON_DRIVER_BEGIN(aml_gpu, aml_gpu_driver_ops, "zircon", "0.1", 5)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PLATFORM_DEV),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_AMLOGIC),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_DID, PDEV_DID_ARM_MALI_INIT),
    // we support multiple SOC variants
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_AMLOGIC_S912),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_AMLOGIC_S905D2),
ZIRCON_DRIVER_END(aml_gpu)
