Skip to content
This repository has been archived by the owner on Oct 5, 2018. It is now read-only.

Commit

Permalink
Merge pull request #8 from ldts/hikey
Browse files Browse the repository at this point in the history
gpu/drm: hisilicon patchset addressing display issues
  • Loading branch information
fboudra committed Mar 6, 2015
2 parents 8bc8cde + f7754a0 commit 7bfade6
Show file tree
Hide file tree
Showing 11 changed files with 1,094 additions and 99 deletions.
38 changes: 3 additions & 35 deletions arch/arm64/boot/dts/hi6220.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -675,45 +675,15 @@
pinctrl-1 = <&I2C2_SCL_pmx_idle &I2C2_SDA_pmx_idle &I2C2_SCL_cfg_idle &I2C2_SDA_cfg_idle>;
status = "ok";

/*
adv7533: adv7533@39 {
compatible = "adi,adv7511";
compatible = "adi,adv7533";
reg = <0x39>;
interrupt-parent = <&gpio1>;
interrupts = <1 2>;

gpio_pd = <&gpio0 4 0>;
pd-gpio = <&gpio0 4 0>;
adi,input-depth = <8>;
adi,input-colorspace = "rgb";
adi,input-clock = "1x";
adi,input-style = <1>;
adi,input-justification = "evenly";
};
*/

packet: adv7533@70 {
compatible = "adv7533,packet";
reg = <0x38>;
};
main: adv7533@7a {
compatible = "adv7533,main";
reg = <0x39>;
has-regulator;
hdmi_vdd-supply = <&ldo15>;
hdmi_v1p2-supply = <&ldo22>;
gpio_int = <&gpio1 1 0>;
gpio_pd = <&gpio0 4 0>;
gpio_dsi_sel = <&gpio0 1 0>;
};
cec_dsi: adv7533@78 {
compatible = "adv7533,cec_dsi";
reg = <0x3c>;
};
edid: adv7533@7e {
compatible = "adv7533,edid";
reg = <0x3f>;
};

};

display-subsystem {
Expand Down Expand Up @@ -752,10 +722,8 @@
reg = <0x0 0xf4107800 0x0 0x100>;
clocks = <&clock_media HI6220_DSI_PCLK>;
clock-names = "pclk_dsi";
dsi_bit_clk_rate = <640>;
vc = <0>;
//encoder-slave = <&adv7533>;

encoder-slave = <&adv7533>;
};
};

Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/configs/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,9 @@ CONFIG_REGULATOR_HI6220=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
CONFIG_VIDEO_ADV7533=y
CONFIG_DRM=y
CONFIG_DRM_HISI=y
CONFIG_DRM_I2C_ADV7533=y
CONFIG_FB_ARMCLCD=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
Expand Down
43 changes: 30 additions & 13 deletions drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1125,9 +1125,9 @@ EXPORT_SYMBOL(drm_edid_is_valid);
* Return: 0 on success or -1 on failure.
*/
static int
drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
int block, int len)
drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
{
struct i2c_adapter *adapter = data;
unsigned char start = block * EDID_LENGTH;
unsigned char segment = block >> 1;
unsigned char xfers = segment ? 3 : 2;
Expand Down Expand Up @@ -1184,8 +1184,26 @@ static bool drm_edid_is_zero(u8 *in_edid, int length)
return true;
}

static u8 *
drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
/**
* drm_do_get_edid - get EDID data using a custom EDID block read function
* @connector: connector we're probing
* @get_edid_block: EDID block read function
* @data: private data passed to the block read function
*
* When the I2C adapter connected to the DDC bus is hidden behind a device that
* exposes a different interface to read EDID blocks this function can be used
* to get EDID data using a custom block read function.
*
* As in the general case the DDC bus is accessible by the kernel at the I2C
* level, drivers must make all reasonable efforts to expose it as an I2C
* adapter and use drm_get_edid() instead of abusing this function.
*
* Return: Pointer to valid EDID or NULL if we couldn't find any.
*/
struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
size_t len),
void *data)
{
int i, j = 0, valid_extensions = 0;
u8 *block, *new;
Expand All @@ -1196,7 +1214,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)

/* base block fetch */
for (i = 0; i < 4; i++) {
if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH))
if (get_edid_block(data, block, 0, EDID_LENGTH))
goto out;
if (drm_edid_block_valid(block, 0, print_bad_edid))
break;
Expand All @@ -1210,7 +1228,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)

/* if there's no extensions, we're done */
if (block[0x7e] == 0)
return block;
return (struct edid *)block;

new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
if (!new)
Expand All @@ -1219,7 +1237,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)

for (j = 1; j <= block[0x7e]; j++) {
for (i = 0; i < 4; i++) {
if (drm_do_probe_ddc_edid(adapter,
if (get_edid_block(data,
block + (valid_extensions + 1) * EDID_LENGTH,
j, EDID_LENGTH))
goto out;
Expand Down Expand Up @@ -1247,7 +1265,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
block = new;
}

return block;
return (struct edid *)block;

carp:
if (print_bad_edid) {
Expand All @@ -1260,6 +1278,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
kfree(block);
return NULL;
}
EXPORT_SYMBOL_GPL(drm_do_get_edid);

/**
* drm_probe_ddc() - probe DDC presence
Expand Down Expand Up @@ -1289,12 +1308,10 @@ EXPORT_SYMBOL(drm_probe_ddc);
struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter)
{
struct edid *edid = NULL;

if (drm_probe_ddc(adapter))
edid = (struct edid *)drm_do_get_edid(connector, adapter);
if (!drm_probe_ddc(adapter))
return NULL;

return edid;
return drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
}
EXPORT_SYMBOL(drm_get_edid);

Expand Down
75 changes: 40 additions & 35 deletions drivers/gpu/drm/hisilicon/hisi_drm_ade.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ struct hisi_drm_ade_crtc {
u32 ade_core_rate;
u32 media_noc_rate;
u32 x , y;
bool first_time;

struct drm_device *drm_dev;
struct drm_crtc crtc;
Expand Down Expand Up @@ -340,35 +341,50 @@ static int hisi_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
stride, (u32)obj->paddr, display_addr,
fb->width, fb_hight);

/* TOP */
writel(0, (ade_base + ADE_WDMA2_SRC_CFG_REG));
writel(0, (ade_base + ADE_SCL3_MUX_CFG_REG));
writel(0, (ade_base + ADE_SCL1_MUX_CFG_REG));
writel(0, (ade_base + ADE_ROT_SRC_CFG_REG));
writel(0, (ade_base + ADE_SCL2_SRC_CFG_REG));
writel(0, (ade_base + ADE_SEC_OVLY_SRC_CFG_REG));
writel(0, (ade_base + ADE_WDMA3_SRC_CFG_REG));
writel(0, (ade_base + ADE_OVLY1_TRANS_CFG_REG));
writel(0, (ade_base + ADE_CTRAN5_TRANS_CFG_REG));
writel(0, (ade_base + ADE_OVLY_CTL_REG));

writel(0, (ade_base + ADE_SOFT_RST_SEL0_REG));
writel(0, (ade_base + ADE_SOFT_RST_SEL1_REG));
set_TOP_SOFT_RST_SEL0_disp_rdma(ade_base, 1);
set_TOP_SOFT_RST_SEL0_ctran5(ade_base, 1);
set_TOP_SOFT_RST_SEL0_ctran6(ade_base, 1);

writel(0, (ade_base + ADE_RELOAD_DIS0_REG));
writel(0, (ade_base + ADE_RELOAD_DIS1_REG));

writel(TOP_DISP_CH_SRC_RDMA, (ade_base + ADE_DISP_SRC_CFG_REG));
if (crtc_ade->first_time) {
crtc_ade->first_time = false;
/* TOP */
writel(0, (ade_base + ADE_WDMA2_SRC_CFG_REG));
writel(0, (ade_base + ADE_SCL3_MUX_CFG_REG));
writel(0, (ade_base + ADE_SCL1_MUX_CFG_REG));
writel(0, (ade_base + ADE_ROT_SRC_CFG_REG));
writel(0, (ade_base + ADE_SCL2_SRC_CFG_REG));
writel(0, (ade_base + ADE_SEC_OVLY_SRC_CFG_REG));
writel(0, (ade_base + ADE_WDMA3_SRC_CFG_REG));
writel(0, (ade_base + ADE_OVLY1_TRANS_CFG_REG));
writel(0, (ade_base + ADE_CTRAN5_TRANS_CFG_REG));
writel(0, (ade_base + ADE_OVLY_CTL_REG));

writel(0, (ade_base + ADE_SOFT_RST_SEL0_REG));
writel(0, (ade_base + ADE_SOFT_RST_SEL1_REG));
set_TOP_SOFT_RST_SEL0_disp_rdma(ade_base, 1);
set_TOP_SOFT_RST_SEL0_ctran5(ade_base, 1);
set_TOP_SOFT_RST_SEL0_ctran6(ade_base, 1);

writel(0, (ade_base + ADE_RELOAD_DIS0_REG));
writel(0, (ade_base + ADE_RELOAD_DIS1_REG));

writel(TOP_DISP_CH_SRC_RDMA, (ade_base + ADE_DISP_SRC_CFG_REG));

/* ctran5 */
writel(1, (ade_base + ADE_CTRAN5_DIS_REG));
writel(fb->width * fb_hight - 1,
(ade_base + ADE_CTRAN5_IMAGE_SIZE_REG));
writel(1, (ade_base + ADE_CTRAN5_CFG_OK_REG));

/* ctran6 */
writel(1, (ade_base + ADE_CTRAN6_DIS_REG));
writel(fb->width * fb_hight - 1,
(ade_base + ADE_CTRAN6_IMAGE_SIZE_REG));
writel(1, (ade_base + ADE_CTRAN6_CFG_OK_REG));
}

/* DISP DMA */
if (16 == fb->bits_per_pixel)
writel((ADE_RGB_565 << 16) & 0x1f0000,
(ade_base + RD_CH_DISP_CTRL_REG));
else if (32 == fb->bits_per_pixel)
writel((ADE_ARGB_8888 << 16) & 0x1f0000,
writel((ADE_ABGR_8888 << 16) & 0x1f0000,
(ade_base + RD_CH_DISP_CTRL_REG));

writel(display_addr, (ade_base + RD_CH_DISP_ADDR_REG));
Expand All @@ -377,18 +393,6 @@ static int hisi_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
writel(fb_hight * stride, (ade_base + RD_CH_DISP_SPACE_REG));
writel(1, (ade_base + RD_CH_DISP_EN_REG));

/* ctran5 */
writel(1, (ade_base + ADE_CTRAN5_DIS_REG));
writel(fb->width * fb_hight - 1,
(ade_base + ADE_CTRAN5_IMAGE_SIZE_REG));
writel(1, (ade_base + ADE_CTRAN5_CFG_OK_REG));

/* ctran6 */
writel(1, (ade_base + ADE_CTRAN6_DIS_REG));
writel(fb->width * fb_hight - 1,
(ade_base + ADE_CTRAN6_IMAGE_SIZE_REG));
writel(1, (ade_base + ADE_CTRAN6_CFG_OK_REG));

writel(1, (ade_base + ADE_EN_REG));
set_TOP_CTL_frm_end_start(ade_base, 1);
set_LDI_CTRL_ldi_en(ade_base, ADE_ENABLE);
Expand Down Expand Up @@ -442,6 +446,7 @@ static int hisi_drm_crtc_create(struct hisi_drm_ade_crtc *crtc_ade)
int ret;

crtc_ade->dpms = DRM_MODE_DPMS_OFF;
crtc_ade->first_time = true;

ret = drm_crtc_init(crtc_ade->drm_dev, crtc, &crtc_funcs);
if (ret < 0)
Expand Down
Loading

0 comments on commit 7bfade6

Please sign in to comment.