Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exynos-drm fixes #37

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions arch/arm/mach-exynos/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ config MACH_HKDK4412
select EXYNOS_DEV_DMA
select EXYNOS_DEV_DRM
select EXYNOS_DEV_SYSMMU
select EXYNOS4_SETUP_I2C2
select S3C_DEV_I2C2
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_USB_HSOTG
Expand Down
21 changes: 2 additions & 19 deletions arch/arm/mach-exynos/mach-hkdk4412.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,24 +158,6 @@ static struct i2c_board_info hkdk4412_i2c_devs1[] __initdata = {
#endif
};

/* I2C2 bus GPIO-Bitbanging */
#define GPIO_I2C2_SDA EXYNOS4_GPA0(6)
#define GPIO_I2C2_SCL EXYNOS4_GPA0(7)
static struct i2c_gpio_platform_data i2c2_gpio_platdata = {
.sda_pin = GPIO_I2C2_SDA,
.scl_pin = GPIO_I2C2_SCL,
.udelay = 5,
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.scl_is_output_only = 0
};

static struct platform_device gpio_device_i2c2 = {
.name = "i2c-gpio",
.id = 2, // adepter number
.dev.platform_data = &i2c2_gpio_platdata,
};

/* Odroid-O2 schematics show the DDC of the remote HDMI device connected to
* I2C2. HDMI specs state that DDC always sits at bus address 0x50. */
static struct i2c_board_info hkdk4412_i2c_devs2[] __initdata = {
Expand Down Expand Up @@ -485,7 +467,7 @@ static struct platform_device *hkdk4412_devices[] __initdata = {
&s3c_device_hsmmc2,
&s3c_device_i2c0,
&s3c_device_i2c1,
&gpio_device_i2c2,
&s3c_device_i2c2,
&s3c_device_i2c3,
#if defined(CONFIG_ODROID_U2)
&gpio_device_i2c4,
Expand Down Expand Up @@ -622,6 +604,7 @@ static void __init hkdk4412_machine_init(void)
i2c_register_board_info(1, hkdk4412_i2c_devs1,
ARRAY_SIZE(hkdk4412_i2c_devs1));

s3c_i2c2_set_platdata(NULL);
i2c_register_board_info(2, hkdk4412_i2c_devs2,
ARRAY_SIZE(hkdk4412_i2c_devs2));

Expand Down
1 change: 0 additions & 1 deletion drivers/cpufreq/exynos4x12-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,6 @@ static const unsigned int asv_voltage_4x12[CPUFREQ_LEVEL_END] = {
925000,
925000,
925000,
};
#endif
static void exynos4x12_set_clkdiv(unsigned int div_index)
{
Expand Down
16 changes: 16 additions & 0 deletions drivers/gpu/drm/exynos/exynos_drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ struct exynos_drm_crtc {
unsigned int pipe;
unsigned int dpms;
enum exynos_crtc_mode mode;
wait_queue_head_t pending_flip_queue;
atomic_t pending_flip;
};

static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
Expand All @@ -61,6 +63,13 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
return;
}

if (mode > DRM_MODE_DPMS_ON) {
/* wait for the completion of page flip. */
wait_event(exynos_crtc->pending_flip_queue,
atomic_read(&exynos_crtc->pending_flip) == 0);
drm_vblank_off(crtc->dev, exynos_crtc->pipe);
}

exynos_drm_fn_encoder(crtc, &mode, exynos_drm_encoder_crtc_dpms);
exynos_crtc->dpms = mode;
}
Expand Down Expand Up @@ -225,6 +234,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
spin_lock_irq(&dev->event_lock);
list_add_tail(&event->base.link,
&dev_priv->pageflip_event_list);
atomic_set(&exynos_crtc->pending_flip, 1);
spin_unlock_irq(&dev->event_lock);

crtc->fb = fb;
Expand Down Expand Up @@ -344,6 +354,8 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)

exynos_crtc->pipe = nr;
exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
init_waitqueue_head(&exynos_crtc->pending_flip_queue);
atomic_set(&exynos_crtc->pending_flip, 0);
exynos_crtc->plane = exynos_plane_init(dev, 1 << nr, true);
if (!exynos_crtc->plane) {
kfree(exynos_crtc);
Expand Down Expand Up @@ -399,6 +411,8 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc)
struct exynos_drm_private *dev_priv = dev->dev_private;
struct drm_pending_vblank_event *e, *t;
struct timeval now;
struct drm_crtc *drm_crtc = dev_priv->crtc[crtc];
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(drm_crtc);
unsigned long flags;

DRM_DEBUG_KMS("%s\n", __FILE__);
Expand All @@ -419,6 +433,8 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc)
list_move_tail(&e->base.link, &e->base.file_priv->event_list);
wake_up_interruptible(&e->base.file_priv->event_wait);
drm_vblank_put(dev, crtc);
atomic_set(&exynos_crtc->pending_flip, 0);
wake_up(&exynos_crtc->pending_flip_queue);
}

spin_unlock_irqrestore(&dev->event_lock, flags);
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/exynos/exynos_drm_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,8 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
args->pitch = args->width * ((args->bpp + 7) / 8);
args->size = args->pitch * args->height;

exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);
exynos_gem_obj = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG |
EXYNOS_BO_WC, args->size);
if (IS_ERR(exynos_gem_obj))
return PTR_ERR(exynos_gem_obj);

Expand Down
9 changes: 8 additions & 1 deletion drivers/gpu/drm/exynos/exynos_drm_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,17 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)

DRM_DEBUG_KMS("%s\n", __FILE__);

/* When powering up, we must first power up the HDMI component, as
* otherwise mixer register accesses will sometimes hang.
* When powering down, we do the opposite: mixer off, HDMI off. */

if (mode == DRM_MODE_DPMS_ON && hdmi_ops && hdmi_ops->dpms)
hdmi_ops->dpms(ctx->hdmi_ctx->ctx, mode);

if (mixer_ops && mixer_ops->dpms)
mixer_ops->dpms(ctx->mixer_ctx->ctx, mode);

if (hdmi_ops && hdmi_ops->dpms)
if (mode != DRM_MODE_DPMS_ON && hdmi_ops && hdmi_ops->dpms)
hdmi_ops->dpms(ctx->hdmi_ctx->ctx, mode);
}

Expand Down
39 changes: 32 additions & 7 deletions drivers/gpu/drm/exynos/exynos_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <linux/gpio.h>
#include <media/s5p_hdmi.h>

#define HOTPLUG_DEBOUNCE_MS 1100
#define MAX_WIDTH 1920
#define MAX_HEIGHT 1080
#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
Expand Down Expand Up @@ -165,6 +166,7 @@ struct hdmi_context {
void __iomem *regs;
void *parent_ctx;
int irq;
struct delayed_work hotplug_work;

struct i2c_client *ddc_port;
struct i2c_client *hdmiphy_port;
Expand Down Expand Up @@ -1755,6 +1757,14 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
{
struct hdmi_core_regs *core = &hdata->mode_conf.core;
struct hdmi_tg_regs *tg = &hdata->mode_conf.tg;
int hcorrect = 0;
int vcorrect = 0;

if ((m->vdisplay == 768 && m->hdisplay == 1024) || (m->vdisplay == 1024 && m->hdisplay == 1280)) {
pr_info("exynos-drm: Applying 257px timings hack\n");
hcorrect = 257;
vcorrect = 1;
}

hdata->mode_conf.cea_video_id = drm_match_cea_mode(m);

Expand Down Expand Up @@ -1812,8 +1822,8 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
hdmi_set_reg(core->v_sync_line_aft_1, 2, 0xffff);
hdmi_set_reg(core->v_sync_line_aft_pxl_2, 2, 0xffff);
hdmi_set_reg(core->v_sync_line_aft_pxl_1, 2, 0xffff);
hdmi_set_reg(tg->vact_st, 2, m->vtotal - m->vdisplay);
hdmi_set_reg(tg->vact_sz, 2, m->vdisplay);
hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) - vcorrect);
hdmi_set_reg(tg->vact_sz, 2, m->vdisplay + vcorrect);
hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
hdmi_set_reg(tg->vact_st3, 2, 0x47b); /* Reset value */
hdmi_set_reg(tg->vact_st4, 2, 0x6ae); /* Reset value */
Expand Down Expand Up @@ -1844,8 +1854,8 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
/* Timing generator registers */
hdmi_set_reg(tg->cmd, 1, 0x0);
hdmi_set_reg(tg->h_fsz, 2, m->htotal);
hdmi_set_reg(tg->hact_st, 2, m->htotal - m->hdisplay);
hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
hdmi_set_reg(tg->hact_st, 2, (m->htotal - m->hdisplay) - hcorrect);
hdmi_set_reg(tg->hact_sz, 2, m->hdisplay + hcorrect);
hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
hdmi_set_reg(tg->vsync, 2, 0x1);
hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
Expand Down Expand Up @@ -1943,6 +1953,8 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
hdmiphy_conf_reset(hdata);
hdmiphy_poweroff(hdata);

cancel_delayed_work(&hdata->hotplug_work);

clk_disable(res->sclk_hdmi);
clk_disable(res->hdmi);
clk_disable(res->hdmiphy);
Expand Down Expand Up @@ -1993,17 +2005,28 @@ static struct exynos_hdmi_ops hdmi_ops = {
.dpms = hdmi_dpms,
};

static irqreturn_t hdmi_irq_thread(int irq, void *arg)
static void hdmi_hotplug_work_func(struct work_struct *work)
{
struct exynos_drm_hdmi_context *ctx = arg;
struct hdmi_context *hdata = ctx->ctx;
struct hdmi_context *hdata = container_of(work, struct hdmi_context,
hotplug_work.work);
struct exynos_drm_hdmi_context *ctx =
(struct exynos_drm_hdmi_context *) hdata->parent_ctx;

mutex_lock(&hdata->hdmi_mutex);
hdata->hpd = gpio_get_value(hdata->hpd_gpio);
mutex_unlock(&hdata->hdmi_mutex);

if (ctx->drm_dev)
drm_helper_hpd_irq_event(ctx->drm_dev);
}

static irqreturn_t hdmi_irq_thread(int irq, void *arg)
{
struct exynos_drm_hdmi_context *ctx = arg;
struct hdmi_context *hdata = ctx->ctx;

mod_delayed_work(system_wq, &hdata->hotplug_work,
msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));

return IRQ_HANDLED;
}
Expand Down Expand Up @@ -2198,6 +2221,7 @@ static int hdmi_probe(struct platform_device *pdev)
}

mutex_init(&hdata->hdmi_mutex);
INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);

drm_hdmi_ctx->ctx = (void *)hdata;
hdata->parent_ctx = (void *)drm_hdmi_ctx;
Expand Down Expand Up @@ -2310,6 +2334,7 @@ static int hdmi_remove(struct platform_device *pdev)
pm_runtime_disable(dev);

free_irq(hdata->irq, hdata);
cancel_delayed_work_sync(&hdata->hotplug_work);


/* hdmiphy i2c driver */
Expand Down
8 changes: 4 additions & 4 deletions drivers/gpu/drm/exynos/exynos_mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,13 @@ static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
MXR_CFG_SCAN_PROGRASSIVE);

/* choosing between porper HD and SD mode */
if (height == 480)
if (height <= 480)
val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
else if (height == 576)
else if (height <= 576)
val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
else if (height == 720)
else if (height <= 720)
val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
else if (height == 1080)
else if (height <= 1080)
val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
else
val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
Expand Down
4 changes: 2 additions & 2 deletions drivers/media/platform/s5p-mfc/s5p_mfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,7 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = {
.buf_size = &buf_size_v5,
.buf_align = &mfc_buf_align_v5,
.mclk_name = "sclk_mfc",
.fw_name = "s5p-mfc.fw",
.fw_name = "s5p-mfc/s5p-mfc.fw",
};

struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
Expand All @@ -1320,7 +1320,7 @@ static struct s5p_mfc_variant mfc_drvdata_v6 = {
.buf_size = &buf_size_v6,
.buf_align = &mfc_buf_align_v6,
.mclk_name = "aclk_333",
.fw_name = "s5p-mfc-v6.fw",
.fw_name = "s5p-mfc/s5p-mfc-v6.fw",
};

static struct platform_device_id mfc_driver_ids[] = {
Expand Down