blob: 7ccd22642516b6cc6eb786d6155c79660d25ef7a [file] [log] [blame]
// 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 <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/debug.h>
#include <ddk/binding.h>
#include <ddk/io-buffer.h>
#include <ddk/protocol/platform-defs.h>
#include <ddk/protocol/platform-device.h>
#include <zircon/syscalls.h>
#include <zircon/assert.h>
#include <hw/reg.h>
#include "vim-display.h"
#include "hdmitx.h"
/* Add a framebuffer to the canvas lookup table */
bool add_canvas_entry(vim2_display_t* display, zx_paddr_t paddr, uint8_t* idx)
{
unsigned i;
for (i = 0; i < NUM_CANVAS_ENTRIES; i++) {
if ((display->canvas_entries[i / 8] & (1 << (i % 8))) == 0) {
display->canvas_entries[i / 8] |= (1 << (i % 8));
break;
}
}
if (i == NUM_CANVAS_ENTRIES) {
return false;
}
*idx = i;
uint32_t fbh = display->height;
uint32_t fbw = display->stride * ZX_PIXEL_FORMAT_BYTES(display->format);
DISP_INFO("Canvas Diminsions: w=%d h=%d\n", fbw, fbh);
// set framebuffer address in DMC, read/modify/write
WRITE32_DMC_REG(DMC_CAV_LUT_DATAL,
(((paddr + 7) >> 3) & DMC_CAV_ADDR_LMASK) |
((((fbw + 7) >> 3) & DMC_CAV_WIDTH_LMASK) << DMC_CAV_WIDTH_LBIT));
WRITE32_DMC_REG(DMC_CAV_LUT_DATAH,
((((fbw + 7) >> 3) >> DMC_CAV_WIDTH_LWID) << DMC_CAV_WIDTH_HBIT) |
((fbh & DMC_CAV_HEIGHT_MASK) << DMC_CAV_HEIGHT_BIT));
WRITE32_DMC_REG(DMC_CAV_LUT_ADDR, DMC_CAV_LUT_ADDR_WR_EN | *idx);
// read a cbus to make sure last write finish.
READ32_DMC_REG(DMC_CAV_LUT_DATAH);
return true;
}
void free_canvas_entry(vim2_display_t* display, uint8_t idx) {
display->canvas_entries[idx / 8] &= ~(1 << (idx % 8));
}