# HG changeset patch # User Paul Boddie # Date 1591399338 -7200 # Node ID 367867780278da99df5e9134501d046c1b6e84da # Parent 8bb3e38c7439420ee5593010fc5c34b53cd83af2 Moved JZ4780 LCD functionality into a subclass. Moved register and field enumerations into a separate header file. diff -r 8bb3e38c7439 -r 367867780278 pkg/devices/lib/lcd/include/lcd-jz4740-regs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/devices/lib/lcd/include/lcd-jz4740-regs.h Sat Jun 06 01:22:18 2020 +0200 @@ -0,0 +1,301 @@ +/* + * LCD peripheral support for the JZ4740 and related SoCs. + * + * Copyright (C) Xiangfu Liu + * Copyright (C) 2015, 2016, 2017, 2018, + * 2020 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#pragma once + + + +enum Regs : unsigned +{ + Lcd_config = 0x000, // LCD_CFG + Lcd_vsync = 0x004, // LCD_VSYNC + Lcd_hsync = 0x008, // LCD_HSYNC + Virtual_area = 0x00c, // LCD_VAT + Display_hlimits = 0x010, // LCD_DAH + Display_vlimits = 0x014, // LCD_DAV + Lcd_ps = 0x018, // LCD_PS + Lcd_cls = 0x01c, // LCD_CLS + Lcd_spl = 0x020, // LCD_SPL + Lcd_rev = 0x024, // LCD_REV + Lcd_control = 0x030, // LCD_CTRL + Lcd_status = 0x034, // LCD_STATE + Lcd_irq_id = 0x038, // LCD_IID + Desc_address_0 = 0x040, // LCD_DA0 + Source_address_0 = 0x044, // LCD_SA0 + Frame_id_0 = 0x048, // LCD_FID0 + Command_0 = 0x04c, // LCD_CMD0 + Counter_position_0 = 0x068, // LCD_CPOS0 + Foreground_size_0 = 0x06c, // LCD_DESSIZE0 + Desc_address_1 = 0x050, // LCD_DA1 + Source_address_1 = 0x054, // LCD_SA1 + Frame_id_1 = 0x058, // LCD_FID1 + Command_1 = 0x05c, // LCD_CMD1 + Counter_position_1 = 0x078, // LCD_CPOS1 + Foreground_size_1 = 0x07c, // LCD_DESSIZE1 + Rgb_control = 0x090, // LCD_RGBC (JZ4780) + Alpha_levels = 0x108, // LCD_ALPHA (JZ4780) + Priority_level = 0x2c0, // LCD_PCFG + + // OSD registers. + + Osd_config = 0x100, // LCD_OSDC + Osd_control = 0x104, // LCD_OSDCTRL + Osd_status = 0x108, // LCD_OSDS +}; + +// Lcd_config descriptions. + +enum Config_values : unsigned +{ + Config_stn_pins_mask = 0x3, + Config_mode_mask = 0xf, +}; + +// Field positions for registers employing two values, with the first typically +// being the start value and the second being an end value. + +enum Value_pair_bits : unsigned +{ + Value_first = 16, + Value_second = 0, +}; + +// Virtual area bits. + +enum Virtual_area_values : unsigned +{ + Virtual_area_horizontal_size = Value_first, // sum of display and blank regions (dot/pixel clock periods) + Virtual_area_vertical_size = Value_second, // sum of display and blank regions (line periods) +}; + +// Lcd_control descriptions. + +enum Control_bits : unsigned +{ + Control_pin_modify = 31, // PINMD (change pin usage from 15..0 to 17..10, 8..1) + Control_burst_length = 28, // BST (burst length selection) + Control_rgb_mode = 27, // RGB (RGB mode) + Control_out_underrun = 26, // OFUP (output FIFO underrun protection) + Control_frc_algorithm = 24, // FRC (STN FRC algorithm selection) + Control_palette_delay = 16, // PDD (load palette delay counter) + Control_dac_loopback_test = 14, // DACTE (DAC loopback test) + Control_frame_end_irq_enable = 13, // EOFM (end of frame interrupt enable) + Control_frame_start_irq_enable = 12, // SOFM (start of frame interrupt enable) + Control_out_underrun_irq_enable = 11, // OFUM (output FIFO underrun interrupt enable) + Control_in0_underrun_irq_enable = 10, // IFUM0 (input FIFO 0 underrun interrupt enable) + Control_in1_underrun_irq_enable = 9, // IFUM1 (input FIFO 1 underrun interrupt enable) + Control_disabled_irq_enable = 8, // LDDM (LCD disable done interrupt enable) + Control_quick_disabled_irq_enable = 7, // QDM (LCD quick disable done interrupt enable) + Control_endian_select = 6, // BEDN (endian selection) + Control_bit_order = 5, // PEDN (bit order in bytes) + Control_disable = 4, // DIS (disable controller) + Control_enable = 3, // ENA (enable controller) + Control_bpp = 0, // BPP (bits per pixel) +}; + +enum Burst_length_values : unsigned +{ + Burst_length_4 = 0, // 4 word + Burst_length_8 = 1, // 8 word + Burst_length_16 = 2, // 16 word + + // JZ4780 extensions. + + Burst_length_32 = 3, // 32 word + Burst_length_64 = 4, // 64 word + Burst_length_mask = 0x7, +}; + +enum Rgb_mode_values : unsigned +{ + Rgb_mode_565 = 0, + Rgb_mode_555 = 1, + Rgb_mode_mask = 0x1, +}; + +enum Frc_algorithm_values : unsigned +{ + Frc_greyscales_16 = 0, + Frc_greyscales_4 = 1, + Frc_greyscales_2 = 2, + Frc_greyscales_mask = 0x3, +}; + +enum Control_bpp_values : unsigned +{ + Control_bpp_1bpp = 0, + Control_bpp_2bpp = 1, + Control_bpp_4bpp = 2, + Control_bpp_8bpp = 3, + Control_bpp_15bpp = 4, + Control_bpp_16bpp = 4, + Control_bpp_18bpp = 5, + Control_bpp_24bpp = 5, + Control_bpp_24bpp_comp = 6, + Control_bpp_30bpp = 7, + Control_bpp_32bpp = 7, + Control_bpp_mask = 0x7, +}; + +// Command descriptions. + +enum Command_bits : unsigned +{ + Command_frame_start_irq = 31, // SOFINT (start of frame interrupt) + Command_frame_end_irq = 30, // EOFINT (end of frame interrupt) + Command_lcm_command = 29, // JZ4780: CMD (LCM command/data via DMA0) + Command_palette_buffer = 28, // PAL (descriptor references palette, not display data) + Command_frame_compressed = 27, // JZ4780: COMPEN (16/24bpp compression enabled) + Command_frame_enable = 26, // JZ4780: FRM_EN + Command_field_even = 25, // JZ4780: FIELD_SEL (interlace even field) + Command_16x16_block = 24, // JZ4780: 16x16BLOCK (fetch data by 16x16 block) + Command_buffer_length = 0, // LEN +}; + +enum Command_values : unsigned +{ + Command_buffer_length_mask = 0x00ffffff, +}; + +// Status descriptions. + +enum Status_bits : unsigned +{ + Status_frame_end_irq = 5, + Status_frame_start_irq = 4, + Status_out_underrun_irq = 3, + Status_in0_underrun_irq = 2, + Status_in1_underrun_irq = 1, + Status_disabled = 0, +}; + +// OSD configuration bits (JZ4780). + +enum Osd_config_bits : unsigned +{ + Osd_config_fg1_pixel_alpha_enable = 17, + Osd_config_fg1_frame_start_irq_enable = 15, + Osd_config_fg1_frame_end_irq_enable = 14, + Osd_config_fg0_frame_start_irq_enable = 11, + Osd_config_fg0_frame_end_irq_enable = 10, + Osd_config_fg1_enable = 4, + Osd_config_fg0_enable = 3, + Osd_config_alpha_enable = 2, + Osd_config_fg0_pixel_alpha_enable = 1, + Osd_config_enable = 0, +}; + +enum Osd_control_bits : unsigned +{ + Osd_control_ipu_clock_enable = 15, +}; + +// RGB control (JZ4780). + +enum Rgb_control_bits : unsigned +{ + Rgb_data_padded = 15, // RGBDM + Rgb_padding_mode = 14, // DMM + Rgb_422 = 8, // 422 + Rgb_format_enable = 7, // RGBFMT + Rgb_odd_line = 4, // OddRGB + Rgb_even_line = 0, // EvenRGB +}; + +enum Rgb_control_values : unsigned +{ + Rgb_padding_end = 0U << Rgb_padding_mode, + Rgb_padding_start = 1U << Rgb_padding_mode, + Rgb_odd_line_rgb = 0U << Rgb_odd_line, + Rgb_odd_line_rbg = 1U << Rgb_odd_line, + Rgb_odd_line_grb = 2U << Rgb_odd_line, + Rgb_odd_line_gbr = 3U << Rgb_odd_line, + Rgb_odd_line_brg = 4U << Rgb_odd_line, + Rgb_odd_line_bgr = 5U << Rgb_odd_line, + Rgb_even_line_rgb = 0U << Rgb_even_line, + Rgb_even_line_rbg = 1U << Rgb_even_line, + Rgb_even_line_grb = 2U << Rgb_even_line, + Rgb_even_line_gbr = 3U << Rgb_even_line, + Rgb_even_line_brg = 4U << Rgb_even_line, + Rgb_even_line_bgr = 5U << Rgb_even_line, +}; + +// Alpha levels (JZ4780). + +enum Alpha_levels_bits : unsigned +{ + Alpha_level_fg1 = 8, + Alpha_level_fg0 = 0, +}; + +enum Alpha_levels_values : unsigned +{ + Alpha_level_fg1_mask = 0x0000ff00, + Alpha_level_fg0_mask = 0x000000ff, +}; + +// Priority level. + +enum Priority_level_bits : unsigned +{ + Priority_mode = 31, + Priority_highest_burst = 28, + Priority_threshold2 = 18, + Priority_threshold1 = 9, + Priority_threshold0 = 0, +}; + +enum Priority_level_values : unsigned +{ + Priority_mode_dynamic = 0U << Priority_mode, + Priority_mode_arbiter = 1U << Priority_mode, +}; + +enum Priority_burst_values : unsigned +{ + Priority_burst_4 = 0, + Priority_burst_8 = 1, + Priority_burst_16 = 2, + Priority_burst_32 = 3, + Priority_burst_64 = 4, + Priority_burst_16_cont = 5, + Priority_burst_disable = 7, +}; + +// Position descriptor member. + +enum Position_bits : unsigned +{ + Position_bpp = 27, + Position_premultiply_lcd = 26, + Position_coefficient = 24, + Position_y_position = 12, + Position_x_position = 0, +}; + +enum Position_values : unsigned +{ + Position_bpp_15_16bpp = 4, + Position_bpp_18_24bpp = 5, + Position_bpp_30bpp = 7, +}; diff -r 8bb3e38c7439 -r 367867780278 pkg/devices/lib/lcd/include/lcd-jz4740.h --- a/pkg/devices/lib/lcd/include/lcd-jz4740.h Sat Jun 06 00:04:50 2020 +0200 +++ b/pkg/devices/lib/lcd/include/lcd-jz4740.h Sat Jun 06 01:22:18 2020 +0200 @@ -68,7 +68,7 @@ class Lcd_jz4740_chip : public Lcd_chip { -private: +protected: Hw::Register_block<32> _regs; Jz4740_lcd_panel *_panel; int _burst_size; @@ -95,14 +95,6 @@ uint32_t _status_irq(); - /* Priority level threshold value calculation. */ - - uint32_t _priority_transfer(); - - /* Position value calculation. */ - - uint32_t _position_bpp(); - /* Panel mode access. */ uint32_t _mode(); @@ -115,9 +107,9 @@ /* Descriptor initialisation. */ - void _set_descriptor(struct Jz4740_lcd_descriptor &desc, l4_addr_t source, - l4_size_t size, struct Jz4740_lcd_descriptor *next, - uint32_t flags = 0, bool frame_enable = true); + virtual void _set_descriptor(struct Jz4740_lcd_descriptor &desc, l4_addr_t source, + l4_size_t size, struct Jz4740_lcd_descriptor *next, + uint32_t flags = 0); public: Lcd_jz4740_chip(l4_addr_t addr, Jz4740_lcd_panel *panel); @@ -167,9 +159,9 @@ /* Configuration. */ - void config(struct Jz4740_lcd_descriptor *desc_vaddr, - struct Jz4740_lcd_descriptor *desc_paddr, - l4_addr_t fb_paddr); + virtual void config(struct Jz4740_lcd_descriptor *desc_vaddr, + struct Jz4740_lcd_descriptor *desc_paddr, + l4_addr_t fb_paddr); /* Interrupt configuration. */ diff -r 8bb3e38c7439 -r 367867780278 pkg/devices/lib/lcd/include/lcd-jz4780.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/devices/lib/lcd/include/lcd-jz4780.h Sat Jun 06 01:22:18 2020 +0200 @@ -0,0 +1,71 @@ +/* + * LCD peripheral support for the JZ4780 and related SoCs. + * + * Copyright (C) 2018, 2020 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#pragma once + +#include "lcd-jz4740.h" + + + +/* C++ language interface. */ + +#ifdef __cplusplus + +#include + +class Lcd_jz4780_chip : public Lcd_jz4740_chip +{ +protected: + /* Priority level threshold value calculation. */ + + uint32_t _priority_transfer(); + + /* Position value calculation. */ + + uint32_t _position_bpp(); + + /* Descriptor initialisation. */ + + void _set_descriptor(struct Jz4740_lcd_descriptor &desc, l4_addr_t source, + l4_size_t size, struct Jz4740_lcd_descriptor *next, + uint32_t flags = 0, bool frame_enable = true); + +public: + Lcd_jz4780_chip(l4_addr_t addr, Jz4740_lcd_panel *panel); + + /* Configuration. */ + + void config(struct Jz4740_lcd_descriptor *desc_vaddr, + struct Jz4740_lcd_descriptor *desc_paddr, + l4_addr_t fb_paddr); +}; + +#endif + + + +/* C language interface mainly provided by jz4740_lcd functions. */ + +EXTERN_C_BEGIN + +void *jz4780_lcd_init(l4_addr_t lcd_base, struct Jz4740_lcd_panel *panel); + +EXTERN_C_END diff -r 8bb3e38c7439 -r 367867780278 pkg/devices/lib/lcd/src/jz4740/Makefile --- a/pkg/devices/lib/lcd/src/jz4740/Makefile Sat Jun 06 00:04:50 2020 +0200 +++ b/pkg/devices/lib/lcd/src/jz4740/Makefile Sat Jun 06 01:22:18 2020 +0200 @@ -1,10 +1,10 @@ PKGDIR ?= ../../../.. L4DIR ?= $(PKGDIR)/../.. -TARGET = liblcd_jz4740.o.a liblcd_jz4740.o.so +TARGET = liblcd_jz4740.o.a PC_FILENAME := libdrivers-lcd-jz4740 -SRC_CC := lcd-jz4740.cc +SRC_CC := lcd-jz4740.cc lcd-jz4780.cc PRIVATE_INCDIR += $(PKGDIR)/lib/lcd/include diff -r 8bb3e38c7439 -r 367867780278 pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc --- a/pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc Sat Jun 06 00:04:50 2020 +0200 +++ b/pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc Sat Jun 06 01:22:18 2020 +0200 @@ -29,284 +29,10 @@ #include "lcd-jz4740.h" #include "lcd-jz4740-config.h" +#include "lcd-jz4740-regs.h" #include -enum Regs : unsigned -{ - Lcd_config = 0x000, // LCD_CFG - Lcd_vsync = 0x004, // LCD_VSYNC - Lcd_hsync = 0x008, // LCD_HSYNC - Virtual_area = 0x00c, // LCD_VAT - Display_hlimits = 0x010, // LCD_DAH - Display_vlimits = 0x014, // LCD_DAV - Lcd_ps = 0x018, // LCD_PS - Lcd_cls = 0x01c, // LCD_CLS - Lcd_spl = 0x020, // LCD_SPL - Lcd_rev = 0x024, // LCD_REV - Lcd_control = 0x030, // LCD_CTRL - Lcd_status = 0x034, // LCD_STATE - Lcd_irq_id = 0x038, // LCD_IID - Desc_address_0 = 0x040, // LCD_DA0 - Source_address_0 = 0x044, // LCD_SA0 - Frame_id_0 = 0x048, // LCD_FID0 - Command_0 = 0x04c, // LCD_CMD0 - Counter_position_0 = 0x068, // LCD_CPOS0 - Foreground_size_0 = 0x06c, // LCD_DESSIZE0 - Desc_address_1 = 0x050, // LCD_DA1 - Source_address_1 = 0x054, // LCD_SA1 - Frame_id_1 = 0x058, // LCD_FID1 - Command_1 = 0x05c, // LCD_CMD1 - Counter_position_1 = 0x078, // LCD_CPOS1 - Foreground_size_1 = 0x07c, // LCD_DESSIZE1 - Rgb_control = 0x090, // LCD_RGBC (JZ4780) - Alpha_levels = 0x108, // LCD_ALPHA (JZ4780) - Priority_level = 0x2c0, // LCD_PCFG - - // OSD registers. - - Osd_config = 0x100, // LCD_OSDC - Osd_control = 0x104, // LCD_OSDCTRL - Osd_status = 0x108, // LCD_OSDS -}; - -// Lcd_config descriptions. - -enum Config_values : unsigned -{ - Config_stn_pins_mask = 0x3, - Config_mode_mask = 0xf, -}; - -// Field positions for registers employing two values, with the first typically -// being the start value and the second being an end value. - -enum Value_pair_bits : unsigned -{ - Value_first = 16, - Value_second = 0, -}; - -// Virtual area bits. - -enum Virtual_area_values : unsigned -{ - Virtual_area_horizontal_size = Value_first, // sum of display and blank regions (dot/pixel clock periods) - Virtual_area_vertical_size = Value_second, // sum of display and blank regions (line periods) -}; - -// Lcd_control descriptions. - -enum Control_bits : unsigned -{ - Control_pin_modify = 31, // PINMD (change pin usage from 15..0 to 17..10, 8..1) - Control_burst_length = 28, // BST (burst length selection) - Control_rgb_mode = 27, // RGB (RGB mode) - Control_out_underrun = 26, // OFUP (output FIFO underrun protection) - Control_frc_algorithm = 24, // FRC (STN FRC algorithm selection) - Control_palette_delay = 16, // PDD (load palette delay counter) - Control_dac_loopback_test = 14, // DACTE (DAC loopback test) - Control_frame_end_irq_enable = 13, // EOFM (end of frame interrupt enable) - Control_frame_start_irq_enable = 12, // SOFM (start of frame interrupt enable) - Control_out_underrun_irq_enable = 11, // OFUM (output FIFO underrun interrupt enable) - Control_in0_underrun_irq_enable = 10, // IFUM0 (input FIFO 0 underrun interrupt enable) - Control_in1_underrun_irq_enable = 9, // IFUM1 (input FIFO 1 underrun interrupt enable) - Control_disabled_irq_enable = 8, // LDDM (LCD disable done interrupt enable) - Control_quick_disabled_irq_enable = 7, // QDM (LCD quick disable done interrupt enable) - Control_endian_select = 6, // BEDN (endian selection) - Control_bit_order = 5, // PEDN (bit order in bytes) - Control_disable = 4, // DIS (disable controller) - Control_enable = 3, // ENA (enable controller) - Control_bpp = 0, // BPP (bits per pixel) -}; - -enum Burst_length_values : unsigned -{ - Burst_length_4 = 0, // 4 word - Burst_length_8 = 1, // 8 word - Burst_length_16 = 2, // 16 word - - // JZ4780 extensions. - - Burst_length_32 = 3, // 32 word - Burst_length_64 = 4, // 64 word - Burst_length_mask = 0x7, -}; - -enum Rgb_mode_values : unsigned -{ - Rgb_mode_565 = 0, - Rgb_mode_555 = 1, - Rgb_mode_mask = 0x1, -}; - -enum Frc_algorithm_values : unsigned -{ - Frc_greyscales_16 = 0, - Frc_greyscales_4 = 1, - Frc_greyscales_2 = 2, - Frc_greyscales_mask = 0x3, -}; - -enum Control_bpp_values : unsigned -{ - Control_bpp_1bpp = 0, - Control_bpp_2bpp = 1, - Control_bpp_4bpp = 2, - Control_bpp_8bpp = 3, - Control_bpp_15bpp = 4, - Control_bpp_16bpp = 4, - Control_bpp_18bpp = 5, - Control_bpp_24bpp = 5, - Control_bpp_24bpp_comp = 6, - Control_bpp_30bpp = 7, - Control_bpp_32bpp = 7, - Control_bpp_mask = 0x7, -}; - -// Command descriptions. - -enum Command_bits : unsigned -{ - Command_frame_start_irq = 31, // SOFINT (start of frame interrupt) - Command_frame_end_irq = 30, // EOFINT (end of frame interrupt) - Command_lcm_command = 29, // JZ4780: CMD (LCM command/data via DMA0) - Command_palette_buffer = 28, // PAL (descriptor references palette, not display data) - Command_frame_compressed = 27, // JZ4780: COMPEN (16/24bpp compression enabled) - Command_frame_enable = 26, // JZ4780: FRM_EN - Command_field_even = 25, // JZ4780: FIELD_SEL (interlace even field) - Command_16x16_block = 24, // JZ4780: 16x16BLOCK (fetch data by 16x16 block) - Command_buffer_length = 0, // LEN -}; - -enum Command_values : unsigned -{ - Command_buffer_length_mask = 0x00ffffff, -}; - -// Status descriptions. - -enum Status_bits : unsigned -{ - Status_frame_end_irq = 5, - Status_frame_start_irq = 4, - Status_out_underrun_irq = 3, - Status_in0_underrun_irq = 2, - Status_in1_underrun_irq = 1, - Status_disabled = 0, -}; - -// OSD configuration bits (JZ4780). - -enum Osd_config_bits : unsigned -{ - Osd_config_fg1_pixel_alpha_enable = 17, - Osd_config_fg1_frame_start_irq_enable = 15, - Osd_config_fg1_frame_end_irq_enable = 14, - Osd_config_fg0_frame_start_irq_enable = 11, - Osd_config_fg0_frame_end_irq_enable = 10, - Osd_config_fg1_enable = 4, - Osd_config_fg0_enable = 3, - Osd_config_alpha_enable = 2, - Osd_config_fg0_pixel_alpha_enable = 1, - Osd_config_enable = 0, -}; - -enum Osd_control_bits : unsigned -{ - Osd_control_ipu_clock_enable = 15, -}; - -// RGB control (JZ4780). - -enum Rgb_control_bits : unsigned -{ - Rgb_data_padded = 15, // RGBDM - Rgb_padding_mode = 14, // DMM - Rgb_422 = 8, // 422 - Rgb_format_enable = 7, // RGBFMT - Rgb_odd_line = 4, // OddRGB - Rgb_even_line = 0, // EvenRGB -}; - -enum Rgb_control_values : unsigned -{ - Rgb_padding_end = 0U << Rgb_padding_mode, - Rgb_padding_start = 1U << Rgb_padding_mode, - Rgb_odd_line_rgb = 0U << Rgb_odd_line, - Rgb_odd_line_rbg = 1U << Rgb_odd_line, - Rgb_odd_line_grb = 2U << Rgb_odd_line, - Rgb_odd_line_gbr = 3U << Rgb_odd_line, - Rgb_odd_line_brg = 4U << Rgb_odd_line, - Rgb_odd_line_bgr = 5U << Rgb_odd_line, - Rgb_even_line_rgb = 0U << Rgb_even_line, - Rgb_even_line_rbg = 1U << Rgb_even_line, - Rgb_even_line_grb = 2U << Rgb_even_line, - Rgb_even_line_gbr = 3U << Rgb_even_line, - Rgb_even_line_brg = 4U << Rgb_even_line, - Rgb_even_line_bgr = 5U << Rgb_even_line, -}; - -// Alpha levels (JZ4780). - -enum Alpha_levels_bits : unsigned -{ - Alpha_level_fg1 = 8, - Alpha_level_fg0 = 0, -}; - -enum Alpha_levels_values : unsigned -{ - Alpha_level_fg1_mask = 0x0000ff00, - Alpha_level_fg0_mask = 0x000000ff, -}; - -// Priority level. - -enum Priority_level_bits : unsigned -{ - Priority_mode = 31, - Priority_highest_burst = 28, - Priority_threshold2 = 18, - Priority_threshold1 = 9, - Priority_threshold0 = 0, -}; - -enum Priority_level_values : unsigned -{ - Priority_mode_dynamic = 0U << Priority_mode, - Priority_mode_arbiter = 1U << Priority_mode, -}; - -enum Priority_burst_values : unsigned -{ - Priority_burst_4 = 0, - Priority_burst_8 = 1, - Priority_burst_16 = 2, - Priority_burst_32 = 3, - Priority_burst_64 = 4, - Priority_burst_16_cont = 5, - Priority_burst_disable = 7, -}; - -// Position descriptor member. - -enum Position_bits : unsigned -{ - Position_bpp = 27, - Position_premultiply_lcd = 26, - Position_coefficient = 24, - Position_y_position = 12, - Position_x_position = 0, -}; - -enum Position_values : unsigned -{ - Position_bpp_15_16bpp = 4, - Position_bpp_18_24bpp = 5, - Position_bpp_30bpp = 7, -}; - // Utility functions. @@ -348,8 +74,7 @@ : _panel(panel) { _regs = new Hw::Mmio_register_block<32>(addr); - _burst_size = 64; // 64-word burst size (JZ4780) - //_burst_size = 16; // 16-word burst size + _burst_size = 16; // 16-word burst size } struct Jz4740_lcd_panel * @@ -644,25 +369,6 @@ } } -// Return colour depth control value. -// JZ4780 position details only. - -uint32_t -Lcd_jz4740_chip::_position_bpp() -{ - uint32_t value; - - switch (_panel->bpp) - { - case 15: case 16: value = Position_bpp_15_16bpp; break; - case 18: case 24: value = Position_bpp_18_24bpp; break; - case 30: value = Position_bpp_30bpp; break; - default: value = 0; break; - } - - return value << Position_bpp; -} - // Return a panel-related control value. uint32_t @@ -742,28 +448,6 @@ ((_irq_conditions & Lcd_irq_frame_end) ? (1U << Status_frame_end_irq) : 0); } -uint32_t -Lcd_jz4740_chip::_priority_transfer() -{ - uint32_t length; - - switch (_burst_size) - { - case 4: length = Priority_burst_4; break; - case 8: length = Priority_burst_8; break; - case 32: length = Priority_burst_32; break; - case 64: length = Priority_burst_64; break; - case 16: - default: length = Priority_burst_16; break; - } - - return Priority_mode_arbiter | - (length << Priority_highest_burst) | - (511U << Priority_threshold2) | - (400U << Priority_threshold1) | - (256U << Priority_threshold0); -} - // STN panel-specific initialisation. void @@ -861,32 +545,17 @@ Lcd_jz4740_chip::_set_descriptor(struct Jz4740_lcd_descriptor &desc, l4_addr_t source, l4_size_t size, struct Jz4740_lcd_descriptor *next, - uint32_t flags, - bool frame_enable) + uint32_t flags) { // In the command, indicate the number of words from the source for transfer. desc.next = next; - desc.source = frame_enable ? source : 0; + desc.source = source; desc.identifier = source; desc.command = ((size / sizeof(uint32_t)) & Command_buffer_length_mask) | - (frame_enable ? (1U << Command_frame_enable) : 0) | flags; - - // Initialise "new" descriptor fields. - - desc.offset = 0; - desc.page_width = 0; - desc.command_position = (1U << Position_premultiply_lcd) | - ((frame_enable ? 1U : 3U) << Position_coefficient) | - _position_bpp(); - desc.fg_size = 0xff000000 | - ((_panel->height - 1) << 12) | - ((_panel->width - 1) << 0); } - - // Initialise the LCD controller with the memory, panel and framebuffer details. // Any palette must be initialised separately using get_palette and init_palette. @@ -895,13 +564,8 @@ struct Jz4740_lcd_descriptor *desc_paddr, l4_addr_t fb_paddr) { - // NOTE: Remarks in the Ingenic Linux 3.0.8 driver suggest that the JZ4775 and - // NOTE: JZ4780 do not support palettes. - int have_palette = (_panel->bpp <= 8); - bool _have_fg1 = true; // NOTE: To be formalised! - // Provide the first framebuffer descriptor in single and dual modes. // Flip back and forth between any palette and the framebuffer. @@ -913,12 +577,11 @@ // Provide the second framebuffer descriptor only in dual-panel mode. // Only employ this descriptor in the second DMA channel. - if ((get_panels() == 2) || _have_fg1) + if (get_panels() == 2) _set_descriptor(desc_vaddr[1], get_framebuffer(1, fb_paddr), get_aligned_size(), desc_paddr + 1, - _command_irq(), - false); + _command_irq()); // Initialise palette descriptor details for lower colour depths. @@ -941,7 +604,7 @@ // Provide a descriptor for the second DMA channel in dual-panel mode. - if ((get_panels() == 2) || _have_fg1) + if (get_panels() == 2) _regs[Desc_address_1] = (uint32_t) (desc_paddr + 1); // Initialise panel-related registers. @@ -949,19 +612,9 @@ _init_panel(); // Initialise the control and configuration registers. - // NOTE: JZ4780 does not support bpp setting here. _regs[Lcd_control] = _control_panel() | _control_bpp() | _control_transfer() | _control_irq(); _regs[Lcd_config] = _panel->config; - - // NOTE: JZ4780 only. - - _regs[Rgb_control] = (1U << Rgb_format_enable) | Rgb_odd_line_rgb | Rgb_even_line_rgb; - _regs[Priority_level] = _priority_transfer(); - _regs[Osd_config] = (1U << Osd_config_enable) | - (1U << Osd_config_alpha_enable); - _regs[Alpha_levels] = ((255U << Alpha_level_fg1) & Alpha_level_fg1_mask) | - ((255U << Alpha_level_fg0) & Alpha_level_fg0_mask); } // Set the interrupt for controller-related events. diff -r 8bb3e38c7439 -r 367867780278 pkg/devices/lib/lcd/src/jz4740/lcd-jz4780.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/devices/lib/lcd/src/jz4740/lcd-jz4780.cc Sat Jun 06 01:22:18 2020 +0200 @@ -0,0 +1,192 @@ +/* + * LCD peripheral support for the JZ4740 and related SoCs. + * + * Copyright (C) Xiangfu Liu + * Copyright (C) 2015, 2016, 2017, 2018, + * 2020 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include +#include + +#include "lcd-jz4780.h" +#include "lcd-jz4740-config.h" +#include "lcd-jz4740-regs.h" + +#include + + + +// JZ4780-specific methods. + +Lcd_jz4780_chip::Lcd_jz4780_chip(l4_addr_t addr, Jz4740_lcd_panel *panel) +: Lcd_jz4740_chip(addr, panel) +{ + _burst_size = 64; // 64-word burst size available in the JZ4780 +} + +// Return colour depth control value. +// JZ4780 position details only. + +uint32_t +Lcd_jz4780_chip::_position_bpp() +{ + uint32_t value; + + switch (_panel->bpp) + { + case 15: case 16: value = Position_bpp_15_16bpp; break; + case 18: case 24: value = Position_bpp_18_24bpp; break; + case 30: value = Position_bpp_30bpp; break; + default: value = 0; break; + } + + return value << Position_bpp; +} + +uint32_t +Lcd_jz4780_chip::_priority_transfer() +{ + uint32_t length; + + switch (_burst_size) + { + case 4: length = Priority_burst_4; break; + case 8: length = Priority_burst_8; break; + case 32: length = Priority_burst_32; break; + case 64: length = Priority_burst_64; break; + case 16: + default: length = Priority_burst_16; break; + } + + return Priority_mode_arbiter | + (length << Priority_highest_burst) | + (511U << Priority_threshold2) | + (400U << Priority_threshold1) | + (256U << Priority_threshold0); +} + +// Initialise a DMA descriptor for the JZ4780. The principal differences with +// earlier SoCs are the "new" descriptor fields which populate additional +// registers controlling OSD foreground planes, and the frame enable flag which +// allows the descriptors/planes to be disabled and left unused. + +void +Lcd_jz4780_chip::_set_descriptor(struct Jz4740_lcd_descriptor &desc, + l4_addr_t source, l4_size_t size, + struct Jz4740_lcd_descriptor *next, + uint32_t flags, + bool frame_enable) +{ + // In the command, indicate the number of words from the source for transfer. + + desc.next = next; + desc.source = frame_enable ? source : 0; + desc.identifier = source; + desc.command = ((size / sizeof(uint32_t)) & Command_buffer_length_mask) | + (frame_enable ? (1U << Command_frame_enable) : 0) | + flags; + + // Initialise "new" descriptor fields. + + desc.offset = 0; + desc.page_width = 0; + desc.command_position = (1U << Position_premultiply_lcd) | + ((frame_enable ? 1U : 3U) << Position_coefficient) | + _position_bpp(); + desc.fg_size = 0xff000000 | + ((_panel->height - 1) << 12) | + ((_panel->width - 1) << 0); +} + +// HDMI-compatible JZ4780 configuration. +// Remarks in the Ingenic Linux 3.0.8 driver suggest that the JZ4775 and JZ4780 +// do not support palettes. Here, multiple panels are also not supported. + +void +Lcd_jz4780_chip::config(struct Jz4740_lcd_descriptor *desc_vaddr, + struct Jz4740_lcd_descriptor *desc_paddr, + l4_addr_t fb_paddr) +{ + // Provide the first framebuffer descriptor in single and dual modes. + // Flip back and forth between any palette and the framebuffer. + + _set_descriptor(desc_vaddr[0], get_framebuffer(0, fb_paddr), + get_aligned_size(), + desc_paddr, + _command_irq()); + + // Provide the second framebuffer descriptor only in dual-panel mode. + // Only employ this descriptor in the second DMA channel. + + _set_descriptor(desc_vaddr[1], get_framebuffer(1, fb_paddr), + get_aligned_size(), + desc_paddr + 1, + _command_irq(), + false); + + // Flush cached structure data. + + l4_cache_clean_data((unsigned long) desc_vaddr, + (unsigned long) desc_vaddr + get_descriptors_size()); + + // Configure DMA by setting frame descriptor addresses. + + // Provide the palette descriptor address first, if employed. + + _regs[Desc_address_0] = (uint32_t) desc_paddr; + + // Provide a descriptor for the second DMA channel, providing foreground 1. + + _regs[Desc_address_1] = (uint32_t) (desc_paddr + 1); + + // Initialise panel-related registers. + + _init_panel(); + + // Initialise the control and configuration registers. + // JZ4780 does not support bpp setting here. Otherwise, this is the same as + // with earlier SoCs. + + _regs[Lcd_control] = _control_panel() | _control_transfer() | _control_irq(); + _regs[Lcd_config] = _panel->config; + + // JZ4780-specific configuration. + // The RGB control register usage may be superfluous. + + _regs[Rgb_control] = (1U << Rgb_format_enable) | Rgb_odd_line_rgb | Rgb_even_line_rgb; + _regs[Priority_level] = _priority_transfer(); + + // Employ whole image alpha levels by default. + + _regs[Osd_config] = (1U << Osd_config_enable) | + (1U << Osd_config_alpha_enable); + _regs[Alpha_levels] = ((255U << Alpha_level_fg1) & Alpha_level_fg1_mask) | + ((255U << Alpha_level_fg0) & Alpha_level_fg0_mask); +} + + + +// C language interface functions. + +void * +jz4780_lcd_init(l4_addr_t lcd_base, struct Jz4740_lcd_panel *panel) +{ + return (void *) new Lcd_jz4780_chip(lcd_base, panel); +} diff -r 8bb3e38c7439 -r 367867780278 pkg/landfall-examples/ci20_hdmi_i2c/ci20_hdmi_i2c.c --- a/pkg/landfall-examples/ci20_hdmi_i2c/ci20_hdmi_i2c.c Sat Jun 06 00:04:50 2020 +0200 +++ b/pkg/landfall-examples/ci20_hdmi_i2c/ci20_hdmi_i2c.c Sat Jun 06 01:22:18 2020 +0200 @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -330,7 +330,7 @@ printf("Set up LCD...\n"); - lcd = jz4740_lcd_init(lcd_base, &panel); + lcd = jz4780_lcd_init(lcd_base, &panel); /* Test initialisation with a frequency appropriate for the test panel. */