适配新七寸屏
This commit is contained in:
+3
-3
@@ -8,7 +8,7 @@
|
||||
//#include "lcd/lcd_g40396_truly_mipi_fhd.dtsi"
|
||||
//#include "lcd/lcd_nt36672e_truly_mipi_fhd_nodsc.dtsi"
|
||||
#include "lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi"
|
||||
#include "lcd/lcd_ili9881c_truly_mipi_wxga.dtsi"
|
||||
#include "lcd/lcd_jd9365_mipi_wxga.dtsi"
|
||||
#include "tp/ums9620-tp.dtsi"
|
||||
#include <dt-bindings/mfd/sprd,ump9620-regs.h>
|
||||
#include <dt-bindings/mfd/sprd,ump9620-mask.h>
|
||||
@@ -594,7 +594,7 @@
|
||||
sprd,backlight = <&pwm_backlight>;
|
||||
avdd-gpio = <&ap_gpio 153 GPIO_ACTIVE_HIGH>;
|
||||
avee-gpio = <&ap_gpio 178 GPIO_ACTIVE_HIGH>;
|
||||
iovdd-gpio = <&ap_gpio 187 GPIO_ACTIVE_HIGH>;
|
||||
/* GPIO187 is kept high by the shared hdmi_5v_en gpio-hog above. */
|
||||
reset-gpio = <&ap_gpio 152 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
@@ -604,7 +604,7 @@
|
||||
};
|
||||
|
||||
|
||||
&lcd_ili9881c_truly_mipi_wxga {
|
||||
&lcd_jd9365_mipi_wxga {
|
||||
sprd,sr-width = <800>;
|
||||
sprd,sr-height = <1280>;
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
sprd,dsi-lane-number = <4>;
|
||||
sprd,dsi-color-format = "rgb888";
|
||||
|
||||
/* Vendor PLL_CLOCK: 407 Mbps per lane. */
|
||||
/* Last visually verified clean U-Boot configuration. */
|
||||
sprd,phy-bit-clock = <407000>;
|
||||
sprd,phy-escape-clock = <20000>;
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
sprd,reset-on-sequence = <1 5>, <0 10>, <1 120>;
|
||||
sprd,reset-off-sequence = <0 20>;
|
||||
|
||||
sprd,use-dcs-write;
|
||||
/* Vendor table entries are 0x23 generic short writes. */
|
||||
sprd,initial-command = [
|
||||
23 00 00 02 E0 00
|
||||
23 00 00 02 E1 93
|
||||
@@ -241,13 +241,14 @@
|
||||
|
||||
display-timings {
|
||||
timing0 {
|
||||
clock-frequency = <67750800>;
|
||||
clock-frequency = <64000000>;
|
||||
hactive = <800>;
|
||||
vactive = <1280>;
|
||||
hback-porch = <20>;
|
||||
hfront-porch = <20>;
|
||||
vback-porch = <8>;
|
||||
vfront-porch = <17>;
|
||||
/* Keep the U-Boot-only timing that produced a clean logo. */
|
||||
vback-porch = <24>;
|
||||
vfront-porch = <1>;
|
||||
hsync-len = <20>;
|
||||
vsync-len = <8>;
|
||||
};
|
||||
|
||||
@@ -18,6 +18,23 @@
|
||||
#include "mipi_dsi_api.h"
|
||||
#include "mipi_dsi_hal.h"
|
||||
|
||||
static bool use_jd9365_rounded_timing(struct sprd_dsi *dsi)
|
||||
{
|
||||
return dsi->panel && dsi->panel->lcd_name &&
|
||||
!strcmp(dsi->panel->lcd_name, "lcd_jd9365_mipi_wxga");
|
||||
}
|
||||
|
||||
static u16 calc_dpi_byte_cycles(struct sprd_dsi *dsi,
|
||||
struct dpi_video_param *param, u32 pixels)
|
||||
{
|
||||
if (use_jd9365_rounded_timing(dsi))
|
||||
return DIV_ROUND_CLOSEST_ULL((u64)pixels * param->byte_clk,
|
||||
param->pixel_clk);
|
||||
|
||||
/* Preserve the vendor calculation for every other panel. */
|
||||
return pixels * (param->byte_clk * 1000 / param->pixel_clk) / 1000;
|
||||
}
|
||||
|
||||
static u16 calc_bytes_per_pixel_x100(int coding)
|
||||
{
|
||||
u16 bpp_x100;
|
||||
@@ -207,6 +224,7 @@ int mipi_dsi_dpi_video(struct sprd_dsi *dsi, struct dpi_video_param *param)
|
||||
u32 chunk_overhead = 0;
|
||||
const u8 pkt_header = 6;
|
||||
u32 div = 0;
|
||||
u16 hline_time;
|
||||
|
||||
video_size = round_video_size(param->coding, param->hact);
|
||||
bpp_x100 = calc_bytes_per_pixel_x100(param->coding);
|
||||
@@ -215,15 +233,18 @@ int mipi_dsi_dpi_video(struct sprd_dsi *dsi, struct dpi_video_param *param)
|
||||
return -1;
|
||||
|
||||
ratio_x1000 = param->byte_clk * 1000 / param->pixel_clk;
|
||||
hline_time = calc_dpi_byte_cycles(dsi, param, param->hline);
|
||||
|
||||
dsi_hal_power_en(dsi, 0);
|
||||
dsi_hal_dpi_frame_ack_en(dsi, param->frame_ack_en);
|
||||
dsi_hal_dpi_color_coding(dsi, param->coding);
|
||||
dsi_hal_dpi_video_burst_mode(dsi, param->burst_mode);
|
||||
dsi_hal_dpi_sig_delay(dsi, 95 * param->hline * ratio_x1000 / 100000);
|
||||
dsi_hal_dpi_hline_time(dsi, param->hline * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_hsync_time(dsi, param->hsync * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_hbp_time(dsi, param->hbp * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_sig_delay(dsi, 95 * hline_time / 100);
|
||||
dsi_hal_dpi_hline_time(dsi, hline_time);
|
||||
dsi_hal_dpi_hsync_time(dsi,
|
||||
calc_dpi_byte_cycles(dsi, param, param->hsync));
|
||||
dsi_hal_dpi_hbp_time(dsi,
|
||||
calc_dpi_byte_cycles(dsi, param, param->hbp));
|
||||
dsi_hal_dpi_vact(dsi, param->vact);
|
||||
dsi_hal_dpi_vfp(dsi, param->vfp);
|
||||
dsi_hal_dpi_vbp(dsi, param->vbp);
|
||||
@@ -360,15 +381,17 @@ int mipi_dsi_edpi_video(struct sprd_dsi *dsi, struct edpi_video_param *param)
|
||||
|
||||
int mipi_dsi_htime_update(struct sprd_dsi *dsi, struct dpi_video_param *param)
|
||||
{
|
||||
u32 ratio_x1000 = 0;
|
||||
u16 hline_time;
|
||||
|
||||
ratio_x1000 = param->byte_clk * 1000 / param->pixel_clk;
|
||||
hline_time = calc_dpi_byte_cycles(dsi, param, param->hline);
|
||||
|
||||
dsi_hal_power_en(dsi, 0);
|
||||
dsi_hal_dpi_sig_delay(dsi, 95 * param->hline * ratio_x1000 / 100000);
|
||||
dsi_hal_dpi_hline_time(dsi, param->hline * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_hsync_time(dsi, param->hsync * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_hbp_time(dsi, param->hbp * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_sig_delay(dsi, 95 * hline_time / 100);
|
||||
dsi_hal_dpi_hline_time(dsi, hline_time);
|
||||
dsi_hal_dpi_hsync_time(dsi,
|
||||
calc_dpi_byte_cycles(dsi, param, param->hsync));
|
||||
dsi_hal_dpi_hbp_time(dsi,
|
||||
calc_dpi_byte_cycles(dsi, param, param->hbp));
|
||||
dsi_hal_power_en(dsi, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
+16
-4
@@ -10,6 +10,7 @@
|
||||
__overlay__ {
|
||||
lcds {
|
||||
lcd_jd9365_mipi_wxga: lcd_jd9365_mipi_wxga {
|
||||
/* Match the U-Boot handoff and the stable Unisoc burst path. */
|
||||
sprd,dsi-work-mode = <1>;
|
||||
sprd,dsi-lane-number = <4>;
|
||||
sprd,dsi-color-format = "rgb888";
|
||||
@@ -26,7 +27,13 @@
|
||||
sprd,reset-on-sequence = <1 5>, <0 10>, <1 120>;
|
||||
sprd,reset-off-sequence = <0 20>;
|
||||
|
||||
sprd,use-dcs-write;
|
||||
/*
|
||||
* The vendor register table uses packet type 0x23
|
||||
* (generic short write, two parameters). Do not set
|
||||
* sprd,use-dcs-write here: that makes the panel driver
|
||||
* recode every entry as a DCS packet and the JD9365
|
||||
* vendor-page registers are then not programmed.
|
||||
*/
|
||||
sprd,initial-command = [
|
||||
23 00 00 02 E0 00
|
||||
23 00 00 02 E1 93
|
||||
@@ -241,13 +248,18 @@
|
||||
native-mode = <&jd9365_timing0>;
|
||||
|
||||
jd9365_timing0: timing0 {
|
||||
clock-frequency = <67750800>;
|
||||
clock-frequency = <64000000>;
|
||||
hactive = <800>;
|
||||
vactive = <1280>;
|
||||
hback-porch = <20>;
|
||||
hfront-porch = <20>;
|
||||
vback-porch = <8>;
|
||||
vfront-porch = <17>;
|
||||
/*
|
||||
* DPU r6p0 requires vsync + vback-porch >= 32.
|
||||
* Keep the 25-line total blanking unchanged while
|
||||
* matching the visually clean U-Boot handoff.
|
||||
*/
|
||||
vback-porch = <24>;
|
||||
vfront-porch = <1>;
|
||||
hsync-len = <20>;
|
||||
vsync-len = <8>;
|
||||
};
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
//#include "lcd/lcd_g40396_truly_mipi_fhd.dtsi"
|
||||
//#include "lcd/lcd_nt36672e_truly_mipi_fhd_nodsc.dtsi"
|
||||
#include "lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi"
|
||||
#include "lcd/lcd_ili9881c_truly_mipi_wxga.dtsi"
|
||||
#include "lcd/lcd_jd9365_mipi_wxga.dtsi"
|
||||
#include "tp/ums9620-tp.dtsi"
|
||||
#include <dt-bindings/mfd/sprd,ump9620-regs.h>
|
||||
#include <dt-bindings/mfd/sprd,ump9620-mask.h>
|
||||
@@ -594,7 +594,7 @@
|
||||
sprd,backlight = <&pwm_backlight>;
|
||||
avdd-gpio = <&ap_gpio 153 GPIO_ACTIVE_HIGH>;
|
||||
avee-gpio = <&ap_gpio 178 GPIO_ACTIVE_HIGH>;
|
||||
iovdd-gpio = <&ap_gpio 187 GPIO_ACTIVE_HIGH>;
|
||||
/* GPIO187 is kept high by the shared hdmi_5v_en gpio-hog above. */
|
||||
reset-gpio = <&ap_gpio 152 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
@@ -604,7 +604,7 @@
|
||||
};
|
||||
|
||||
|
||||
&lcd_ili9881c_truly_mipi_wxga {
|
||||
&lcd_jd9365_mipi_wxga {
|
||||
sprd,sr-width = <800>;
|
||||
sprd,sr-height = <1280>;
|
||||
};
|
||||
|
||||
+49
-10
@@ -7,6 +7,39 @@
|
||||
|
||||
#include "sprd_dsi_hal.h"
|
||||
|
||||
static bool use_jd9365_rounded_timing(struct dsi_context *ctx)
|
||||
{
|
||||
return ctx->lcd_name &&
|
||||
!strcmp(ctx->lcd_name, "lcd_jd9365_mipi_wxga");
|
||||
}
|
||||
|
||||
static u16 calc_dpi_byte_cycles(struct dsi_context *ctx,
|
||||
struct videomode *vm, u32 pixels)
|
||||
{
|
||||
u32 pixel_clk = vm->pixelclock / 1000;
|
||||
u32 ratio_x1000;
|
||||
|
||||
if (use_jd9365_rounded_timing(ctx))
|
||||
return DIV_ROUND_CLOSEST_ULL((u64)pixels * ctx->byte_clk,
|
||||
pixel_clk);
|
||||
|
||||
/* Preserve the original calculation for every other DSI panel. */
|
||||
ratio_x1000 = ctx->byte_clk * 1000 / pixel_clk;
|
||||
return pixels * ratio_x1000 / 1000;
|
||||
}
|
||||
|
||||
static u16 calc_dpi_sig_delay(struct dsi_context *ctx,
|
||||
struct videomode *vm, u32 pixels)
|
||||
{
|
||||
u32 ratio_x1000;
|
||||
|
||||
if (use_jd9365_rounded_timing(ctx))
|
||||
return 95 * calc_dpi_byte_cycles(ctx, vm, pixels) / 100;
|
||||
|
||||
ratio_x1000 = ctx->byte_clk * 1000 / (vm->pixelclock / 1000);
|
||||
return 95 * pixels * ratio_x1000 / 100000;
|
||||
}
|
||||
|
||||
static int dsi_wait_tx_payload_fifo_empty(struct sprd_dsi *dsi)
|
||||
{
|
||||
int timeout;
|
||||
@@ -219,8 +252,8 @@ void sprd_dsi_fini(struct sprd_dsi *dsi)
|
||||
int sprd_dsi_vrr_timing(struct sprd_dsi *dsi)
|
||||
{
|
||||
u16 Bpp_x100;
|
||||
u32 ratio_x1000;
|
||||
u16 hline;
|
||||
u16 hline_time;
|
||||
u8 coding;
|
||||
struct dsi_context *ctx = &dsi->ctx;
|
||||
struct videomode *vm = &dsi->ctx.vm;
|
||||
@@ -232,13 +265,15 @@ int sprd_dsi_vrr_timing(struct sprd_dsi *dsi)
|
||||
|
||||
coding = fmt_to_coding(ctx->format);
|
||||
Bpp_x100 = calc_bytes_per_pixel_x100(coding);
|
||||
ratio_x1000 = ctx->byte_clk * 1000 / (vm->pixelclock / 1000);
|
||||
hline = vm->hactive + vm->hsync_len + vm->hfront_porch +
|
||||
vm->hback_porch;
|
||||
dsi_hal_dpi_sig_delay(dsi, 95 * hline * ratio_x1000 / 100000);
|
||||
dsi_hal_dpi_hline_time(dsi, hline * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_hsync_time(dsi, vm->hsync_len * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_hbp_time(dsi, vm->hback_porch * ratio_x1000 / 1000);
|
||||
hline_time = calc_dpi_byte_cycles(ctx, vm, hline);
|
||||
dsi_hal_dpi_sig_delay(dsi, calc_dpi_sig_delay(ctx, vm, hline));
|
||||
dsi_hal_dpi_hline_time(dsi, hline_time);
|
||||
dsi_hal_dpi_hsync_time(dsi,
|
||||
calc_dpi_byte_cycles(ctx, vm, vm->hsync_len));
|
||||
dsi_hal_dpi_hbp_time(dsi,
|
||||
calc_dpi_byte_cycles(ctx, vm, vm->hback_porch));
|
||||
dsi_hal_dpi_vact(dsi, vm->vactive);
|
||||
dsi_hal_dpi_vfp(dsi, vm->vfront_porch);
|
||||
dsi_hal_dpi_vbp(dsi, vm->vback_porch);
|
||||
@@ -274,6 +309,7 @@ int sprd_dsi_dpi_video(struct sprd_dsi *dsi)
|
||||
u8 coding;
|
||||
int div;
|
||||
u16 hline;
|
||||
u16 hline_time;
|
||||
struct dsi_context *ctx = &dsi->ctx;
|
||||
struct videomode *vm = &dsi->ctx.vm;
|
||||
|
||||
@@ -284,15 +320,18 @@ int sprd_dsi_dpi_video(struct sprd_dsi *dsi)
|
||||
ratio_x1000 = ctx->byte_clk * 1000 / (vm->pixelclock / 1000);
|
||||
hline = vm->hactive + vm->hsync_len + vm->hfront_porch +
|
||||
vm->hback_porch;
|
||||
hline_time = calc_dpi_byte_cycles(ctx, vm, hline);
|
||||
|
||||
dsi_hal_power_en(dsi, 0);
|
||||
dsi_hal_dpi_frame_ack_en(dsi, ctx->frame_ack_en);
|
||||
dsi_hal_dpi_color_coding(dsi, coding);
|
||||
dsi_hal_dpi_video_burst_mode(dsi, ctx->burst_mode);
|
||||
dsi_hal_dpi_sig_delay(dsi, 95 * hline * ratio_x1000 / 100000);
|
||||
dsi_hal_dpi_hline_time(dsi, hline * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_hsync_time(dsi, vm->hsync_len * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_hbp_time(dsi, vm->hback_porch * ratio_x1000 / 1000);
|
||||
dsi_hal_dpi_sig_delay(dsi, calc_dpi_sig_delay(ctx, vm, hline));
|
||||
dsi_hal_dpi_hline_time(dsi, hline_time);
|
||||
dsi_hal_dpi_hsync_time(dsi,
|
||||
calc_dpi_byte_cycles(ctx, vm, vm->hsync_len));
|
||||
dsi_hal_dpi_hbp_time(dsi,
|
||||
calc_dpi_byte_cycles(ctx, vm, vm->hback_porch));
|
||||
dsi_hal_dpi_vact(dsi, vm->vactive);
|
||||
dsi_hal_dpi_vfp(dsi, vm->vfront_porch);
|
||||
dsi_hal_dpi_vbp(dsi, vm->vback_porch);
|
||||
|
||||
-68
@@ -8,19 +8,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include "sprd_dpu.h"
|
||||
|
||||
/* DPU_VSP clock-controller (ums9620 dpu_vsp_clk) register block @ 0x30110000. */
|
||||
#define DPU_VSP_CLK_BASE 0x30110000UL
|
||||
#define DPU_VSP_CLK_SIZE 0x3000
|
||||
/* dispc0_dpi pixel-clock divider: offset 0x78, bits[3:0] (value 3 = div-by-4). */
|
||||
#define REG_DISPC0_DPI_DIV 0x78
|
||||
#define REG_DISPC0_DPI_DIV_MASK 0xf
|
||||
static void __iomem *dpu_vsp_clk_base;
|
||||
|
||||
static struct clk *clk_dpuvsp_eb;
|
||||
static struct clk *clk_dpuvsp_disp_eb;
|
||||
static struct clk *clk_master_div6_eb;
|
||||
@@ -163,20 +153,6 @@ static int dpu_clk_parse_dt(struct dpu_context *ctx,
|
||||
clk_ctx->clk_dpu_dpi = NULL;
|
||||
}
|
||||
|
||||
/* Map the DPU_VSP clock-controller MMIO so the DPI-divider workaround
|
||||
* can write register 0x30110078 directly. pr_err on failure - the ioremap
|
||||
* must succeed or the workaround cannot fire at all.
|
||||
*/
|
||||
if (!dpu_vsp_clk_base) {
|
||||
dpu_vsp_clk_base = ioremap_nocache(DPU_VSP_CLK_BASE,
|
||||
DPU_VSP_CLK_SIZE);
|
||||
if (!dpu_vsp_clk_base)
|
||||
pr_err("ioremap dpu_vsp_clk (0x%lx) failed\n",
|
||||
DPU_VSP_CLK_BASE);
|
||||
else
|
||||
pr_info("dpu_vsp_clk base mapped for dpi-div workaround\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -211,40 +187,6 @@ static struct clk *div_to_clk(struct dpu_clk_context *clk_ctx, u32 clk_div)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Most direct path to force the dispc0_dpi pixel-clock divider to 3
|
||||
* (divide-by-4): write bits[3:0] of register 0x30110078 (= DPU_VSP clock
|
||||
* controller base 0x30110000 + offset 0x78). This bypasses the CCF and writes
|
||||
* the MMIO register directly; the value is read back to confirm it latched.
|
||||
* Returns the final divider value (should be 3 on success) or a negative errno.
|
||||
*/
|
||||
static int dpu_force_dpi_div3(void)
|
||||
{
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
|
||||
if (!dpu_vsp_clk_base) {
|
||||
pr_err("force dpi div=3: clk mmio not mapped\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
reg = dpu_vsp_clk_base + REG_DISPC0_DPI_DIV;
|
||||
|
||||
val = readl_relaxed(reg);
|
||||
val = (val & ~REG_DISPC0_DPI_DIV_MASK) | 3;
|
||||
writel_relaxed(val, reg);
|
||||
|
||||
/* read-back flush, then re-read to confirm */
|
||||
val = readl_relaxed(reg);
|
||||
if ((val & REG_DISPC0_DPI_DIV_MASK) != 3) {
|
||||
pr_err("force dpi div=3 (0x30110078) failed, readback=0x%x\n", val);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pr_info("force dpi div=3 (0x30110078) ok, reg=0x%x\n", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dpu_clk_init(struct dpu_context *ctx)
|
||||
{
|
||||
int ret;
|
||||
@@ -287,16 +229,6 @@ static int dpu_clk_init(struct dpu_context *ctx)
|
||||
if (ret)
|
||||
pr_err("dpu update dpi clk rate failed\n");
|
||||
|
||||
/* Workaround: on resume (suspend->on), the DPI pixel-clock divider
|
||||
* at 0x30110078 (dispc0_dpi div, bits[3:0]) is not re-applied and
|
||||
* the panel lights up black. Force divider value 3 (div-by-4) by
|
||||
* writing the MMIO register directly (most-direct path). Only acted
|
||||
* upon when flagged from the resume path.
|
||||
*/
|
||||
if (ctx->dpi_div_force3) {
|
||||
ctx->dpi_div_force3 = false;
|
||||
dpu_force_dpi_div3();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -378,18 +378,6 @@ static void sprd_dpu_enable(struct sprd_dpu *dpu)
|
||||
|
||||
void sprd_dpu_resume(struct sprd_dpu *dpu)
|
||||
{
|
||||
struct dpu_context *ctx = &dpu->ctx;
|
||||
u32 mipi_port = 0;
|
||||
/* Flag the DPI-divider workaround: force value 3 at 0x30110078 on the
|
||||
* next dpu_clk_init() to avoid black screen on wake.
|
||||
*/
|
||||
if (dpu->dsi && dpu->dsi->panel) {
|
||||
struct sprd_panel *panel = (struct sprd_panel *)container_of(dpu->dsi->panel, struct sprd_panel, base);
|
||||
mipi_port = panel->info.mipi_port;
|
||||
}
|
||||
if(mipi_port == 1){
|
||||
ctx->dpi_div_force3 = true;
|
||||
}
|
||||
sprd_dpu_enable(dpu);
|
||||
enable_irq(dpu->ctx.irq);
|
||||
sprd_iommu_restore(&dpu->dev);
|
||||
|
||||
@@ -220,12 +220,6 @@ struct dpu_context {
|
||||
/* spi frame refresh parameters */
|
||||
unsigned int flag_mask_refresh;
|
||||
|
||||
/* DPI pixel-clock divider force workaround.
|
||||
* Set true from the resume path so dpu_clk_init() re-applies divider
|
||||
* value 3 to register 0x30110078 (dispc0_dpi div, bits[3:0]) which is
|
||||
* lost/missing on resume and causes a black screen on wake.
|
||||
*/
|
||||
bool dpi_div_force3;
|
||||
};
|
||||
|
||||
struct sprd_dpu_ops {
|
||||
|
||||
@@ -278,7 +278,15 @@ static int sprd_panel_get_modes(struct drm_panel *p)
|
||||
/* parse and create sr mode config */
|
||||
of_property_read_u32(panel->info.of_node, "sprd,sr-width", &sr_width);
|
||||
of_property_read_u32(panel->info.of_node, "sprd,sr-height", &sr_height);
|
||||
if (sr_width && sr_height) {
|
||||
/*
|
||||
* Do not advertise an SR mode when it is identical to the native
|
||||
* panel mode. drm_display_mode_from_videomode() would otherwise
|
||||
* create a duplicate with a synthetic pixel clock and zero porches,
|
||||
* which userspace may select instead of the valid native timing.
|
||||
*/
|
||||
if (sr_width && sr_height &&
|
||||
(sr_width != panel->info.mode.hdisplay ||
|
||||
sr_height != panel->info.mode.vdisplay)) {
|
||||
for (i = 0; i < panel->info.num_buildin_modes; i++) {
|
||||
struct videomode vm = {};
|
||||
vm.hactive = sr_width;
|
||||
@@ -488,27 +496,35 @@ static int sprd_panel_gpio_request(struct device *dev,
|
||||
{
|
||||
panel->info.iovdd_gpio = devm_gpiod_get_optional(dev,
|
||||
"iovdd", GPIOD_ASIS);
|
||||
if (IS_ERR_OR_NULL(panel->info.iovdd_gpio))
|
||||
if (IS_ERR(panel->info.iovdd_gpio)) {
|
||||
DRM_WARN("can't get panel iovdd gpio: %ld\n",
|
||||
PTR_ERR(panel->info.iovdd_gpio));
|
||||
panel->info.iovdd_gpio = NULL;
|
||||
}
|
||||
|
||||
panel->info.avdd_gpio = devm_gpiod_get_optional(dev,
|
||||
"avdd", GPIOD_ASIS);
|
||||
if (IS_ERR_OR_NULL(panel->info.avdd_gpio))
|
||||
if (IS_ERR(panel->info.avdd_gpio)) {
|
||||
DRM_WARN("can't get panel avdd gpio: %ld\n",
|
||||
PTR_ERR(panel->info.avdd_gpio));
|
||||
panel->info.avdd_gpio = NULL;
|
||||
}
|
||||
|
||||
panel->info.avee_gpio = devm_gpiod_get_optional(dev,
|
||||
"avee", GPIOD_ASIS);
|
||||
if (IS_ERR_OR_NULL(panel->info.avee_gpio))
|
||||
if (IS_ERR(panel->info.avee_gpio)) {
|
||||
DRM_WARN("can't get panel avee gpio: %ld\n",
|
||||
PTR_ERR(panel->info.avee_gpio));
|
||||
panel->info.avee_gpio = NULL;
|
||||
}
|
||||
|
||||
panel->info.reset_gpio = devm_gpiod_get_optional(dev,
|
||||
"reset", GPIOD_ASIS);
|
||||
if (IS_ERR_OR_NULL(panel->info.reset_gpio))
|
||||
if (IS_ERR(panel->info.reset_gpio)) {
|
||||
DRM_WARN("can't get panel reset gpio: %ld\n",
|
||||
PTR_ERR(panel->info.reset_gpio));
|
||||
panel->info.reset_gpio = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user