uboot/drivers/video/bcm2835.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2012 Stephen Warren
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <lcd.h>
   9#include <asm/arch/mbox.h>
  10#include <asm/global_data.h>
  11
  12DECLARE_GLOBAL_DATA_PTR;
  13
  14/* Global variables that lcd.c expects to exist */
  15vidinfo_t panel_info;
  16
  17static u32 bcm2835_pitch;
  18
  19struct msg_query {
  20        struct bcm2835_mbox_hdr hdr;
  21        struct bcm2835_mbox_tag_physical_w_h physical_w_h;
  22        u32 end_tag;
  23};
  24
  25struct msg_setup {
  26        struct bcm2835_mbox_hdr hdr;
  27        struct bcm2835_mbox_tag_physical_w_h physical_w_h;
  28        struct bcm2835_mbox_tag_virtual_w_h virtual_w_h;
  29        struct bcm2835_mbox_tag_depth depth;
  30        struct bcm2835_mbox_tag_pixel_order pixel_order;
  31        struct bcm2835_mbox_tag_alpha_mode alpha_mode;
  32        struct bcm2835_mbox_tag_virtual_offset virtual_offset;
  33        struct bcm2835_mbox_tag_overscan overscan;
  34        struct bcm2835_mbox_tag_allocate_buffer allocate_buffer;
  35        struct bcm2835_mbox_tag_pitch pitch;
  36        u32 end_tag;
  37};
  38
  39void lcd_ctrl_init(void *lcdbase)
  40{
  41        ALLOC_ALIGN_BUFFER(struct msg_query, msg_query, 1, 16);
  42        ALLOC_ALIGN_BUFFER(struct msg_setup, msg_setup, 1, 16);
  43        int ret;
  44        u32 w, h;
  45
  46        debug("bcm2835: Query resolution...\n");
  47
  48        BCM2835_MBOX_INIT_HDR(msg_query);
  49        BCM2835_MBOX_INIT_TAG_NO_REQ(&msg_query->physical_w_h,
  50                                        GET_PHYSICAL_W_H);
  51        ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_query->hdr);
  52        if (ret) {
  53                printf("bcm2835: Could not query display resolution\n");
  54                /* FIXME: How to disable the LCD to prevent errors? hang()? */
  55                return;
  56        }
  57
  58        w = msg_query->physical_w_h.body.resp.width;
  59        h = msg_query->physical_w_h.body.resp.height;
  60
  61        debug("bcm2835: Setting up display for %d x %d\n", w, h);
  62
  63        BCM2835_MBOX_INIT_HDR(msg_setup);
  64        BCM2835_MBOX_INIT_TAG(&msg_setup->physical_w_h, SET_PHYSICAL_W_H);
  65        msg_setup->physical_w_h.body.req.width = w;
  66        msg_setup->physical_w_h.body.req.height = h;
  67        BCM2835_MBOX_INIT_TAG(&msg_setup->virtual_w_h, SET_VIRTUAL_W_H);
  68        msg_setup->virtual_w_h.body.req.width = w;
  69        msg_setup->virtual_w_h.body.req.height = h;
  70        BCM2835_MBOX_INIT_TAG(&msg_setup->depth, SET_DEPTH);
  71        msg_setup->depth.body.req.bpp = 16;
  72        BCM2835_MBOX_INIT_TAG(&msg_setup->pixel_order, SET_PIXEL_ORDER);
  73        msg_setup->pixel_order.body.req.order = BCM2835_MBOX_PIXEL_ORDER_BGR;
  74        BCM2835_MBOX_INIT_TAG(&msg_setup->alpha_mode, SET_ALPHA_MODE);
  75        msg_setup->alpha_mode.body.req.alpha = BCM2835_MBOX_ALPHA_MODE_IGNORED;
  76        BCM2835_MBOX_INIT_TAG(&msg_setup->virtual_offset, SET_VIRTUAL_OFFSET);
  77        msg_setup->virtual_offset.body.req.x = 0;
  78        msg_setup->virtual_offset.body.req.y = 0;
  79        BCM2835_MBOX_INIT_TAG(&msg_setup->overscan, SET_OVERSCAN);
  80        msg_setup->overscan.body.req.top = 0;
  81        msg_setup->overscan.body.req.bottom = 0;
  82        msg_setup->overscan.body.req.left = 0;
  83        msg_setup->overscan.body.req.right = 0;
  84        BCM2835_MBOX_INIT_TAG(&msg_setup->allocate_buffer, ALLOCATE_BUFFER);
  85        msg_setup->allocate_buffer.body.req.alignment = 0x100;
  86        BCM2835_MBOX_INIT_TAG_NO_REQ(&msg_setup->pitch, GET_PITCH);
  87
  88        ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_setup->hdr);
  89        if (ret) {
  90                printf("bcm2835: Could not configure display\n");
  91                /* FIXME: How to disable the LCD to prevent errors? hang()? */
  92                return;
  93        }
  94
  95        w = msg_setup->physical_w_h.body.resp.width;
  96        h = msg_setup->physical_w_h.body.resp.height;
  97        bcm2835_pitch = msg_setup->pitch.body.resp.pitch;
  98
  99        debug("bcm2835: Final resolution is %d x %d\n", w, h);
 100
 101        panel_info.vl_col = w;
 102        panel_info.vl_row = h;
 103        panel_info.vl_bpix = LCD_COLOR16;
 104
 105        gd->fb_base = msg_setup->allocate_buffer.body.resp.fb_address;
 106}
 107
 108void lcd_enable(void)
 109{
 110}
 111
 112int lcd_get_size(int *line_length)
 113{
 114        *line_length = bcm2835_pitch;
 115        return *line_length * panel_info.vl_row;
 116}
 117