linux/arch/arm/mach-nspire/clcd.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *      linux/arch/arm/mach-nspire/clcd.c
   4 *
   5 *      Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
   6 */
   7
   8#include <linux/init.h>
   9#include <linux/of.h>
  10#include <linux/amba/bus.h>
  11#include <linux/amba/clcd.h>
  12#include <linux/dma-mapping.h>
  13
  14static struct clcd_panel nspire_cx_lcd_panel = {
  15        .mode           = {
  16                .name           = "Color LCD",
  17                .refresh        = 60,
  18                .xres           = 320,
  19                .yres           = 240,
  20                .sync           = 0,
  21                .vmode          = FB_VMODE_NONINTERLACED,
  22                .pixclock       = 1,
  23                .hsync_len      = 6,
  24                .vsync_len      = 1,
  25                .right_margin   = 50,
  26                .left_margin    = 38,
  27                .lower_margin   = 3,
  28                .upper_margin   = 17,
  29        },
  30        .width          = 65, /* ~6.50 cm */
  31        .height         = 49, /* ~4.87 cm */
  32        .tim2           = TIM2_IPC,
  33        .cntl           = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
  34        .bpp            = 16,
  35        .caps           = CLCD_CAP_565,
  36};
  37
  38static struct clcd_panel nspire_classic_lcd_panel = {
  39        .mode           = {
  40                .name           = "Grayscale LCD",
  41                .refresh        = 60,
  42                .xres           = 320,
  43                .yres           = 240,
  44                .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  45                .vmode          = FB_VMODE_NONINTERLACED,
  46                .pixclock       = 1,
  47                .hsync_len      = 6,
  48                .vsync_len      = 1,
  49                .right_margin   = 6,
  50                .left_margin    = 6,
  51        },
  52        .width          = 71, /* 7.11cm */
  53        .height         = 53, /* 5.33cm */
  54        .tim2           = 0x80007d0,
  55        .cntl           = CNTL_LCDMONO8,
  56        .bpp            = 8,
  57        .grayscale      = 1,
  58        .caps           = CLCD_CAP_5551,
  59};
  60
  61int nspire_clcd_setup(struct clcd_fb *fb)
  62{
  63        struct clcd_panel *panel;
  64        size_t panel_size;
  65        const char *type;
  66        dma_addr_t dma;
  67        int err;
  68
  69        BUG_ON(!fb->dev->dev.of_node);
  70
  71        err = of_property_read_string(fb->dev->dev.of_node, "lcd-type", &type);
  72        if (err) {
  73                pr_err("CLCD: Could not find lcd-type property\n");
  74                return err;
  75        }
  76
  77        if (!strcmp(type, "cx")) {
  78                panel = &nspire_cx_lcd_panel;
  79        } else if (!strcmp(type, "classic")) {
  80                panel = &nspire_classic_lcd_panel;
  81        } else {
  82                pr_err("CLCD: Unknown lcd-type %s\n", type);
  83                return -EINVAL;
  84        }
  85
  86        panel_size = ((panel->mode.xres * panel->mode.yres) * panel->bpp) / 8;
  87        panel_size = ALIGN(panel_size, PAGE_SIZE);
  88
  89        fb->fb.screen_base = dma_alloc_wc(&fb->dev->dev, panel_size, &dma,
  90                                          GFP_KERNEL);
  91
  92        if (!fb->fb.screen_base) {
  93                pr_err("CLCD: unable to map framebuffer\n");
  94                return -ENOMEM;
  95        }
  96
  97        fb->fb.fix.smem_start = dma;
  98        fb->fb.fix.smem_len = panel_size;
  99        fb->panel = panel;
 100
 101        return 0;
 102}
 103
 104int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
 105{
 106        return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base,
 107                           fb->fb.fix.smem_start, fb->fb.fix.smem_len);
 108}
 109
 110void nspire_clcd_remove(struct clcd_fb *fb)
 111{
 112        dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base,
 113                    fb->fb.fix.smem_start);
 114}
 115