Merge 53322c29af on remote branch

Change-Id: I75589ab7483782f28780a15427aa14242e029ff4
This commit is contained in:
Linux Build Service Account 2021-07-09 22:16:48 -07:00
commit c2542f71ed
16 changed files with 1777 additions and 27 deletions

View file

@ -59,3 +59,13 @@ LINUXINCLUDE += -include $(srctree)/techpack/display/config/monacodispconf.h
endif
obj-$(CONFIG_DRM_MSM) += msm/
ifeq ($(CONFIG_ARCH_SDXLEMUR), y)
include $(srctree)/techpack/display/config/sdxlemurdisp.conf
endif
ifeq ($(CONFIG_ARCH_SDXLEMUR), y)
LINUXINCLUDE += -include $(srctree)/techpack/display/config/sdxlemurdispconf.h
endif
obj-$(CONFIG_DRM_QPIC_DISPLAY) += tinydrm/

4
config/sdxlemurdisp.conf Normal file
View file

@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2021, The Linux Foundation. All rights reserved.
export CONFIG_DRM_QPIC_DISPLAY=y

View file

@ -0,0 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#define CONFIG_DRM_QPIC_DISPLAY 1

View file

@ -1668,6 +1668,11 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc,
return;
}
if (test_bit(SDE_CRTC_DIRTY_DIM_LAYERS, &sde_crtc->revalidate_mask)) {
set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, sde_crtc_state->dirty);
clear_bit(SDE_CRTC_DIRTY_DIM_LAYERS, &sde_crtc->revalidate_mask);
}
for (i = 0; i < sde_crtc->num_mixers; i++) {
if (!mixer[i].hw_lm) {
SDE_ERROR("invalid lm or ctl assigned to mixer\n");
@ -3977,6 +3982,7 @@ void sde_crtc_reset_sw_state(struct drm_crtc *crtc)
{
struct sde_crtc_state *cstate = to_sde_crtc_state(crtc->state);
struct drm_plane *plane;
struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
/* mark planes, mixers, and other blocks dirty for next update */
drm_atomic_crtc_for_each_plane(plane, crtc)
@ -3986,7 +3992,7 @@ void sde_crtc_reset_sw_state(struct drm_crtc *crtc)
sde_crtc_clear_cached_mixer_cfg(crtc);
/* mark other properties which need to be dirty for next update */
set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, cstate->dirty);
set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, &sde_crtc->revalidate_mask);
if (cstate->num_ds_enabled)
set_bit(SDE_CRTC_DIRTY_DEST_SCALER, cstate->dirty);
}

View file

@ -254,6 +254,7 @@ struct sde_crtc_misr_info {
* @feature_list : list of color processing features supported on a crtc
* @active_list : list of color processing features are active
* @dirty_list : list of color processing features are dirty
* @revalidate_mask : stores dirty flags to revalidate after idlepc
* @ad_dirty : list containing ad properties that are dirty
* @ad_active : list containing ad properties that are active
* @crtc_lock : crtc lock around create, destroy and access.
@ -348,6 +349,7 @@ struct sde_crtc {
spinlock_t spin_lock;
spinlock_t fevent_spin_lock;
bool kickoff_in_progress;
unsigned long revalidate_mask;
/* for handling internal event thread */
struct sde_crtc_event event_cache[SDE_CRTC_MAX_EVENT_COUNT];

View file

@ -4740,6 +4740,19 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
sde_cfg->sui_block_xin_mask = 0x1;
sde_cfg->has_hdr = false;
sde_cfg->has_sui_blendstage = true;
} else if (IS_MONACO_TARGET(hw_rev)) {
sde_cfg->has_cwb_support = false;
sde_cfg->has_qsync = true;
sde_cfg->perf.min_prefill_lines = 24;
sde_cfg->vbif_qos_nlvl = 8;
sde_cfg->ts_prefill_rev = 2;
sde_cfg->ctl_rev = SDE_CTL_CFG_VERSION_1_0_0;
sde_cfg->delay_prg_fetch_start = true;
sde_cfg->sui_ns_allowed = true;
sde_cfg->sui_misr_supported = true;
sde_cfg->sui_block_xin_mask = 0x1;
sde_cfg->has_hdr = false;
sde_cfg->has_sui_blendstage = true;
} else if (IS_LAHAINA_TARGET(hw_rev)) {
sde_cfg->has_demura = true;
sde_cfg->demura_supported[SSPP_DMA1][0] = 0;

View file

@ -46,6 +46,7 @@
#define SDE_HW_VER_650 SDE_HW_VER(6, 5, 0) /* scuba */
#define SDE_HW_VER_660 SDE_HW_VER(6, 6, 0) /* holi */
#define SDE_HW_VER_670 SDE_HW_VER(6, 7, 0) /* shima */
#define SDE_HW_VER_680 SDE_HW_VER(6, 8, 0) /* monaco */
#define SDE_HW_VER_690 SDE_HW_VER(6, 9, 0) /* blair */
#define SDE_HW_VER_700 SDE_HW_VER(7, 0, 0) /* lahaina */
#define SDE_HW_VER_720 SDE_HW_VER(7, 2, 0) /* yupik */
@ -72,6 +73,7 @@
#define IS_SCUBA_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_650)
#define IS_HOLI_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_660)
#define IS_SHIMA_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_670)
#define IS_MONACO_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_680)
#define IS_BLAIR_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_690)
#define IS_LAHAINA_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_700)
#define IS_YUPIK_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_720)

View file

@ -529,7 +529,7 @@ void reg_dmav1_setup_dspp_vlutv18(struct sde_hw_dspp *ctx, void *cfg)
return;
}
data = kzalloc(VLUT_LEN, GFP_KERNEL);
data = kvzalloc(VLUT_LEN, GFP_KERNEL);
if (!data)
return;
@ -577,7 +577,7 @@ void reg_dmav1_setup_dspp_vlutv18(struct sde_hw_dspp *ctx, void *cfg)
}
exit:
kfree(data);
kvfree(data);
/* update flush bit */
if (!rc && ctl && ctl->ops.update_bitmask_dspp_pavlut) {
int dspp_idx;
@ -1198,7 +1198,7 @@ int reg_dmav1_setup_rc_datav1(struct sde_hw_dspp *ctx, void *cfg)
}
DRM_DEBUG_DRIVER("allocating %u bytes of memory for dma\n", buf_sz);
data = kzalloc(buf_sz, GFP_KERNEL);
data = kvzalloc(buf_sz, GFP_KERNEL);
if (!data) {
DRM_ERROR("memory allocation failed ret %d\n", rc);
return -ENOMEM;
@ -1235,7 +1235,7 @@ int reg_dmav1_setup_rc_datav1(struct sde_hw_dspp *ctx, void *cfg)
}
exit:
kfree(data);
kvfree(data);
return rc;
}
@ -1339,7 +1339,7 @@ void reg_dmav1_setup_dspp_pcc_common(struct sde_hw_dspp *ctx, void *cfg)
return;
}
data = kzalloc(PCC_LEN, GFP_KERNEL);
data = kvzalloc(PCC_LEN, GFP_KERNEL);
if (!data)
return;
@ -1410,7 +1410,7 @@ void reg_dmav1_setup_dspp_pcc_common(struct sde_hw_dspp *ctx, void *cfg)
DRM_ERROR("failed to kick off ret %d\n", rc);
exit:
kfree(data);
kvfree(data);
}
@ -2424,7 +2424,7 @@ static int reg_dmav1_setup_vig_igc_common(struct sde_hw_reg_dma_ops *dma_ops,
hw_cfg->len, sizeof(struct drm_msm_igc_lut));
}
data = kzalloc(VIG_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL);
data = kvzalloc(VIG_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL);
if (!data)
return -ENOMEM;
@ -2486,7 +2486,7 @@ static int reg_dmav1_setup_vig_igc_common(struct sde_hw_reg_dma_ops *dma_ops,
if (rc)
DRM_ERROR("setting opcode failed ret %d\n", rc);
exit:
kfree(data);
kvfree(data);
return rc;
}
@ -2693,7 +2693,7 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg,
return;
}
data = kzalloc(DMA_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL);
data = kvzalloc(DMA_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL);
if (!data) {
DRM_ERROR("failed to allocate memory for igc\n");
return;
@ -2755,7 +2755,7 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg,
if (rc)
DRM_ERROR("failed to kick off ret %d\n", rc);
igc_exit:
kfree(data);
kvfree(data);
}
static void dma_gcv5_off(struct sde_hw_pipe *ctx, void *cfg,
@ -4118,7 +4118,7 @@ void reg_dmav2_setup_dspp_igcv4(struct sde_hw_dspp *ctx, void *cfg)
if (len % transfer_size_bytes)
len = len + (transfer_size_bytes - len % transfer_size_bytes);
data = kzalloc(len, GFP_KERNEL);
data = kvzalloc(len, GFP_KERNEL);
if (!data)
return;
@ -4166,7 +4166,7 @@ void reg_dmav2_setup_dspp_igcv4(struct sde_hw_dspp *ctx, void *cfg)
_perform_sbdma_kickoff(ctx, hw_cfg, dma_ops, blk, IGC);
exit:
kfree(data);
kvfree(data);
}
static void dspp_3d_gamutv43_off(struct sde_hw_dspp *ctx, void *cfg)
@ -4286,7 +4286,7 @@ void reg_dmav2_setup_dspp_3d_gamutv43(struct sde_hw_dspp *ctx, void *cfg)
if (len % transfer_size_bytes)
len = len + (transfer_size_bytes - len % transfer_size_bytes);
data = kzalloc(len, GFP_KERNEL);
data = kvzalloc(len, GFP_KERNEL);
if (!data)
return;
@ -4362,7 +4362,7 @@ void reg_dmav2_setup_dspp_3d_gamutv43(struct sde_hw_dspp *ctx, void *cfg)
_perform_sbdma_kickoff(ctx, hw_cfg, dma_ops, blk, GAMUT);
exit:
kfree(data);
kvfree(data);
}
void reg_dmav2_setup_vig_gamutv61(struct sde_hw_pipe *ctx, void *cfg)
@ -4440,7 +4440,7 @@ void reg_dmav2_setup_vig_gamutv61(struct sde_hw_pipe *ctx, void *cfg)
if (len % transfer_size_bytes)
len = len + (transfer_size_bytes - len % transfer_size_bytes);
data = kzalloc(len, GFP_KERNEL);
data = kvzalloc(len, GFP_KERNEL);
if (!data)
return;
@ -4505,7 +4505,7 @@ void reg_dmav2_setup_vig_gamutv61(struct sde_hw_pipe *ctx, void *cfg)
DRM_ERROR("failed to kick off ret %d\n", rc);
exit:
kfree(data);
kvfree(data);
}
int reg_dmav1_setup_spr_cfg3_params(struct sde_hw_dspp *ctx,
@ -4957,7 +4957,7 @@ static int __reg_dmav1_setup_demurav1_cfg0(struct sde_hw_dspp *ctx,
return 0;
}
temp = kzalloc(sizeof(struct drm_msm_dem_cfg), GFP_KERNEL);
temp = kvzalloc(sizeof(struct drm_msm_dem_cfg), GFP_KERNEL);
if (!temp)
return -ENOMEM;
@ -5093,7 +5093,7 @@ static int __reg_dmav1_setup_demurav1_cfg0(struct sde_hw_dspp *ctx,
goto quit;
}
quit:
kfree(temp);
kvfree(temp);
return rc;
}
@ -5113,7 +5113,7 @@ static int __reg_dmav1_setup_demurav1_cfg1(struct sde_hw_dspp *ctx,
return 0;
}
len = ARRAY_SIZE(dcfg->cfg1_param0_c0);
cfg1_data = kcalloc(len, sizeof(u32), GFP_KERNEL);
cfg1_data = kvzalloc((len * sizeof(u32)), GFP_KERNEL);
if (!cfg1_data)
return -ENOMEM;
@ -5191,7 +5191,7 @@ static int __reg_dmav1_setup_demurav1_cfg1(struct sde_hw_dspp *ctx,
}
quit:
kfree(cfg1_data);
kvfree(cfg1_data);
return rc;
}

View file

@ -64,6 +64,7 @@ static u32 sde_hw_util_log_mask = SDE_DBG_MASK_NONE;
#define QSEED4_DEFAULT_PRELOAD_V 0x2
#define QSEED4_DEFAULT_PRELOAD_H 0x4
#define GET_REG_BLK_ID(c) (c->log_mask ? (ilog2(c->log_mask) + 1) : 0)
typedef void (*scaler_lut_type)(struct sde_hw_blk_reg_map *,
struct sde_hw_scaler3_cfg *, u32);
@ -76,10 +77,9 @@ void sde_reg_write(struct sde_hw_blk_reg_map *c,
if (c->log_mask & sde_hw_util_log_mask)
SDE_DEBUG_DRIVER("[%s:0x%X] <= 0x%X\n",
name, c->blk_off + reg_off, val);
SDE_EVT32_REGWRITE(c->blk_off, reg_off, val);
SDE_EVT32_REGWRITE(c->blk_off + reg_off, val, GET_REG_BLK_ID(c));
writel_relaxed(val, c->base_off + c->blk_off + reg_off);
SDE_REG_LOG(c->log_mask ? ilog2(c->log_mask)+1 : 0,
val, c->blk_off + reg_off);
SDE_REG_LOG(GET_REG_BLK_ID(c), val, c->blk_off + reg_off);
}
int sde_reg_read(struct sde_hw_blk_reg_map *c, u32 reg_off)

View file

@ -2453,11 +2453,14 @@ int sde_rm_reserve(
* Poll for rsvp_nxt clear, allow the check_only commit if rsvp_nxt
* gets cleared and bailout if it does not get cleared before timeout.
*/
if (test_only && rsvp_cur && rsvp_nxt) {
if (test_only && rsvp_nxt) {
rsvp_nxt = _sde_rm_poll_get_rsvp_nxt_locked(rm, enc);
if (rsvp_nxt) {
SDE_ERROR("poll timeout cur %d nxt %d enc %d\n",
rsvp_cur->seq, rsvp_nxt->seq, enc->base.id);
(rsvp_cur) ? rsvp_cur->seq : -1,
rsvp_nxt->seq, enc->base.id);
SDE_EVT32(enc->base.id, (rsvp_cur) ? rsvp_cur->seq : -1,
rsvp_nxt->seq, SDE_EVTLOG_ERROR);
ret = -EINVAL;
goto end;
}

View file

@ -36,7 +36,8 @@ void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 debug)
DEV_DBG("[%08x] => %08x [%08x]\n",
(u32)(unsigned long)(io->base + offset),
value, in_val);
SDE_EVT32_REGWRITE(io->base, offset, value, in_val);
SDE_EVT32_REGWRITE(io->base + offset, value,
SDE_REG_LOG_RSCC, in_val);
}
SDE_REG_LOG(SDE_REG_LOG_RSCC, value, offset);
} /* dss_reg_w */

5
tinydrm/Makefile Normal file
View file

@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_DRM_QPIC_DISPLAY) += qpic_display.o \
qpic_panel_ili9341.o \

1386
tinydrm/qpic_display.c Normal file

File diff suppressed because it is too large Load diff

137
tinydrm/qpic_display.h Normal file
View file

@ -0,0 +1,137 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2014-2015, 2021, The Linux Foundation. All rights reserved.
*/
#ifndef __QPIC_DISPLAY_H__
#define __QPIC_DISPLAY_H__
#include <linux/clk.h>
#include <linux/msm-sps.h>
#include <linux/interrupt.h>
#include <linux/interconnect.h>
#include <linux/regulator/consumer.h>
#include <linux/pinctrl/consumer.h>
#include <drm/drm_drv.h>
#include <drm/drm_connector.h>
#include <drm/drm_simple_kms_helper.h>
#define QPIC_REG_QPIC_LCDC_CTRL 0x22000
#define QPIC_REG_LCDC_VERSION 0x22004
#define QPIC_REG_QPIC_LCDC_IRQ_EN 0x22008
#define QPIC_REG_QPIC_LCDC_IRQ_STTS 0x2200C
#define QPIC_REG_QPIC_LCDC_IRQ_CLR 0x22010
#define QPIC_REG_QPIC_LCDC_STTS 0x22014
#define QPIC_REG_QPIC_LCDC_CMD_DATA_CYCLE_CNT 0x22018
#define QPIC_REG_QPIC_LCDC_CFG0 0x22020
#define QPIC_REG_QPIC_LCDC_CFG1 0x22024
#define QPIC_REG_QPIC_LCDC_CFG2 0x22028
#define QPIC_REG_QPIC_LCDC_RESET 0x2202C
#define QPIC_REG_QPIC_LCDC_FIFO_SOF 0x22100
#define QPIC_REG_LCD_DEVICE_CMD0 0x23000
#define QPIC_REG_QPIC_LCDC_FIFO_DATA_PORT0 0x22140
#define QPIC_REG_QPIC_LCDC_FIFO_EOF 0x22180
#define QPIC_OUTP(qpic_display, off, data) \
writel_relaxed((data), (qpic_display)->qpic_base + (off))
#define QPIC_OUTPW(qpic_display, off, data) \
writew_relaxed((data), (qpic_display)->qpic_base + (off))
#define QPIC_INP(qpic_display, off) \
readl_relaxed((qpic_display)->qpic_base + (off))
#define QPIC_MAX_VSYNC_WAIT_TIME_IN_MS 500
#define QPIC_MAX_CMD_BUF_SIZE_IN_BYTES 512
#define QPIC_PINCTRL_STATE_DEFAULT "qpic_display_default"
#define QPIC_PINCTRL_STATE_SLEEP "qpic_display_sleep"
/* Structure that defines an SPS end point for a BAM pipe. */
struct qpic_sps_endpt {
struct sps_pipe *handle;
struct sps_connect config;
struct sps_register_event bam_event;
struct completion completion;
};
struct qpic_panel_config {
u32 xres;
u32 yres;
u32 bpp;
u32 type;
};
struct qpic_pinctrl_res {
struct pinctrl *pinctrl;
struct pinctrl_state *gpio_state_active;
struct pinctrl_state *gpio_state_suspend;
};
struct qpic_panel_io_desc {
int rst_gpio;
int cs_gpio;
int ad8_gpio;
int te_gpio;
int bl_gpio;
struct regulator *vdd_vreg;
struct regulator *avdd_vreg;
struct qpic_pinctrl_res pin_res;
};
struct bus_scaling_data {
u64 ab;
u64 ib;
};
struct msm_bus_path {
unsigned int num_paths;
struct bus_scaling_data *vec;
};
struct qpic_display_bus_scale_pdata {
const char *name;
unsigned int num_usecase;
struct msm_bus_path *usecase;
struct icc_path *data_bus_hdl;
u32 curr_vote;
};
struct qpic_display_data {
u32 rev;
struct platform_device *pdev;
struct drm_device drm_dev;
struct drm_simple_display_pipe pipe;
struct drm_connector conn;
struct drm_display_mode drm_mode;
bool pipe_enabled;
size_t qpic_reg_size;
u32 qpic_phys;
char __iomem *qpic_base;
u32 irq_id;
bool irq_ena;
u32 res_init;
void *cmd_buf_virt;
phys_addr_t cmd_buf_phys;
struct qpic_sps_endpt qpic_endpt;
u32 sps_init;
u32 irq_requested;
struct qpic_display_bus_scale_pdata *data_bus_pdata;
struct completion fifo_eof_comp;
bool is_qpic_on;
struct clk *qpic_clk;
struct clk *qpic_a_clk;
int (*qpic_transfer)(struct qpic_display_data *qpic_display,
u32 cmd, u8 *param, u32 len);
bool is_panel_on;
struct qpic_panel_config *panel_config;
struct qpic_panel_io_desc panel_io;
int (*panel_on)(struct qpic_display_data *qpic_display);
void (*panel_off)(struct qpic_display_data *qpic_display);
};
int get_ili_qvga_panel_config(struct qpic_display_data *qpic_display);
#endif

View file

@ -0,0 +1,91 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2014-2015, 2021, The Linux Foundation. All rights reserved.
*/
#ifndef __QPIC_DISPLAY_PANEL_H__
#define __QPIC_DISPLAY_PANEL_H__
#include <linux/delay.h>
/**
* Macros for coding MIPI commands
*/
#define INV_SIZE 0xFFFF
/* Size of argument to MIPI command is variable */
#define OP_SIZE_PAIR(op, size) ((op<<16) | size)
/* MIPI {command, argument size} tuple */
#define LCDC_EXTRACT_OP_SIZE(op_identifier) ((op_identifier&0xFFFF))
/* extract size from command identifier */
#define LCDC_EXTRACT_OP_CMD(op_identifier) (((op_identifier>>16)&0xFFFF))
/* extract command id from command identifier */
/* MIPI standard efinitions */
#define LCDC_ADDRESS_MODE_ORDER_BOTTOM_TO_TOP 0x80
#define LCDC_ADDRESS_MODE_ORDER_RIGHT_TO_LEFT 0x40
#define LCDC_ADDRESS_MODE_ORDER_REVERSE 0x20
#define LCDC_ADDRESS_MODE_ORDER_REFRESH_BOTTOM_TO_TOP 0x10
#define LCDC_ADDRESS_MODE_ORDER_BGER_RGB 0x08
#define LCDC_ADDRESS_MODE_ORDER_REFERESH_RIGHT_TO_LEFT 0x04
#define LCDC_ADDRESS_MODE_FLIP_HORIZONTAL 0x02
#define LCDC_ADDRESS_MODE_FLIP_VERTICAL 0x01
#define LCDC_PIXEL_FORMAT_3_BITS_PER_PIXEL 0x1
#define LCDC_PIXEL_FORMAT_8_BITS_PER_PIXEL 0x2
#define LCDC_PIXEL_FORMAT_12_BITS_PER_PIXEL 0x3
#define LCDC_PIXEL_FORMAT_16_BITS_PER_PIXEL 0x5
#define LCDC_PIXEL_FORMAT_18_BITS_PER_PIXEL 0x6
#define LCDC_PIXEL_FORMAT_24_BITS_PER_PIXEL 0x7
#define LCDC_CREATE_PIXEL_FORMAT(dpi_format, dbi_format) \
(dpi_format | (dpi_format<<4))
#define POWER_MODE_IDLE_ON 0x40
#define POWER_MODE_PARTIAL_ON 0x20
#define POWER_MODE_SLEEP_ON 0x10
#define POWER_MODE_NORMAL_ON 0x08
#define POWER_MODE_DISPLAY_ON 0x04
#define LCDC_DISPLAY_MODE_SCROLLING_ON 0x80
#define LCDC_DISPLAY_MODE_INVERSION_ON 0x20
#define LCDC_DISPLAY_MODE_GAMMA_MASK 0x07
/**
* LDCc MIPI Type B supported commands
*/
#define OP_ENTER_IDLE_MODE 0x39
#define OP_ENTER_INVERT_MODE 0x21
#define OP_ENTER_NORMAL_MODE 0x13
#define OP_ENTER_PARTIAL_MODE 0x12
#define OP_ENTER_SLEEP_MODE 0x10
#define OP_EXIT_INVERT_MODE 0x20
#define OP_EXIT_SLEEP_MODE 0x11
#define OP_EXIT_IDLE_MODE 0x38
#define OP_GET_ADDRESS_MODE 0x0B /* size 1 */
#define OP_GET_BLUE_CHANNEL 0x08 /* size 1 */
#define OP_GET_DIAGNOSTIC 0x0F /* size 2 */
#define OP_GET_DISPLAY_MODE 0x0D /* size 1 */
#define OP_GET_GREEN_CHANNEL 0x07 /* size 1 */
#define OP_GET_PIXEL_FORMAT 0x0C /* size 1 */
#define OP_GET_POWER_MODE 0x0A /* size 1 */
#define OP_GET_RED_CHANNEL 0x06 /* size 1 */
#define OP_GET_SCANLINE 0x45 /* size 1 */
#define OP_GET_SIGNAL_MODE 0x0E /* size 1 */
#define OP_NOP 0x00
#define OP_READ_DDB_CONTINUE 0xA8 /* size not fixed */
#define OP_READ_DDB_START 0xA1 /* size not fixed */
#define OP_READ_MEMORY_CONTINUE 0x3E /* size not fixed */
#define OP_READ_MEMORY_START 0x2E /* size not fixed */
#define OP_SET_ADDRESS_MODE 0x36 /* size 1 */
#define OP_SET_COLUMN_ADDRESS 0x2A /* size 4 */
#define OP_SET_DISPLAY_OFF 0x28
#define OP_SET_DISPLAY_ON 0x29
#define OP_SET_GAMMA_CURVE 0x26 /* size 1 */
#define OP_SET_PAGE_ADDRESS 0x2B /* size 4 */
#define OP_SET_PARTIAL_COLUMNS 0x31 /* size 4 */
#define OP_SET_PARTIAL_ROWS 0x30 /* size 4 */
#define OP_SET_PIXEL_FORMAT 0x3A /* size 1 */
#define OP_SOFT_RESET 0x01
#define OP_WRITE_MEMORY_CONTINUE 0x3C /* size not fixed */
#define OP_WRITE_MEMORY_START 0x2C /* size not fixed */
#endif

View file

@ -0,0 +1,84 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2013-2015, 2021, The Linux Foundation. All rights reserved.
*/
#include "qpic_display.h"
#include "qpic_display_panel.h"
/**
* ILI9341 commands
*/
#define OP_ILI9341_INTERFACE_CONTROL 0xf6
#define OP_ILI9341_TEARING_EFFECT_LINE_ON 0x35
static int ili9341_on(struct qpic_display_data *qpic_display)
{
u8 param[4];
qpic_display->qpic_transfer(qpic_display, OP_SOFT_RESET, NULL, 0);
/* wait for 120 ms after reset as panel spec suggests */
msleep(120);
qpic_display->qpic_transfer(qpic_display, OP_SET_DISPLAY_OFF, NULL, 0);
/* wait for 20 ms after disply off */
msleep(20);
/* set memory access control */
param[0] = 0x48;
qpic_display->qpic_transfer(qpic_display, OP_SET_ADDRESS_MODE, param, 1);
/* wait for 20 ms after command sent as panel spec suggests */
msleep(20);
param[0] = 0x66;
qpic_display->qpic_transfer(qpic_display, OP_SET_PIXEL_FORMAT, param, 1);
/* wait for 20 ms after command sent as panel spec suggests */
msleep(20);
/* set interface */
param[0] = 1;
param[1] = 0;
param[2] = 0;
qpic_display->qpic_transfer(qpic_display, OP_ILI9341_INTERFACE_CONTROL, param, 3);
/* wait for 20 ms after command sent */
msleep(20);
/* exit sleep mode */
qpic_display->qpic_transfer(qpic_display, OP_EXIT_SLEEP_MODE, NULL, 0);
/* wait for 20 ms after command sent as panel spec suggests */
msleep(20);
/* normal mode */
qpic_display->qpic_transfer(qpic_display, OP_ENTER_NORMAL_MODE, NULL, 0);
/* wait for 20 ms after command sent as panel spec suggests */
msleep(20);
/* display on */
qpic_display->qpic_transfer(qpic_display, OP_SET_DISPLAY_ON, NULL, 0);
/* wait for 20 ms after command sent as panel spec suggests */
msleep(20);
param[0] = 0;
qpic_display->qpic_transfer(qpic_display, OP_ILI9341_TEARING_EFFECT_LINE_ON, param, 1);
return 0;
}
static void ili9341_off(struct qpic_display_data *qpic_display)
{
qpic_display->qpic_transfer(qpic_display, OP_SET_DISPLAY_OFF, NULL, 0);
/* wait for 20 ms after display off */
msleep(20);
}
static struct qpic_panel_config ili_qvga_panel = {
.xres = 320,
.yres = 480,
.bpp = 16,
};
int get_ili_qvga_panel_config(struct qpic_display_data *qpic_display)
{
qpic_display->panel_config = &ili_qvga_panel;
qpic_display->panel_on = ili9341_on;
qpic_display->panel_off = ili9341_off;
}