Commit 86a7e122 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'exynos-drm-next' of...

Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

   Summary:
   - Consider fallback option to gem allocation fail
     . try to allocate physically non-contiguous memory
       if iommu is supported when physically contiguous memory allocation
       failed.
   - Add runtime pm support to g2d driver
   - Add device tree support
     . add device tree support to rotator driver, make fimd driver get
       signal polarities from device tree.
   - some fixups
     . correct pixel format setting to fimd driver, and consider pixel
       format checking to a particular window layer.
   - some cleanups
     . replace fb_videomode with videomode.
     . remove non-DT support

* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (21 commits)
  drm/exynos: Fix build error with exynos_drm_connector.c
  drm/exynos: Remove non-DT support in exynos_drm_fimd
  drm/exynos: Remove non-DT support in exynos_hdmi
  drm/exynos: Remove non-DT support in exynos_drm_g2d
  drm/exynos: Remove non-DT support in exynos_hdmiphy
  drm/exynos: Remove non-DT support in exynos_ddc
  drm/exynos: Make Exynos DRM drivers depend on OF
  drm/exynos: Consider fallback option to allocation fail
  drm/exynos: fimd: move platform data parsing to separate function
  drm/exynos: fimd: get signal polarities from device tree
  drm/exynos: fimd: replace struct fb_videomode with videomode
  drm/exynos: check a pixel format to a particular window layer
  drm/exynos: fix fimd pixel format setting
  drm/exynos: Add NULL pointer check
  drm/exynos: Remove redundant error messages
  drm/exynos: Add missing of.h header include
  drm/exynos: Remove redundant NULL check in exynos_drm_buf
  drm/exynos: add device tree support for rotator
  drm/exynos: Add missing includes
  drm/exynos: add runtime pm interfaces to g2d driver
  ...
parents 3b28802e 6914262a
* Samsung Image Rotator
Required properties:
- compatible : value should be one of the following:
(a) "samsung,exynos4210-rotator" for Rotator IP in Exynos4210
(b) "samsung,exynos4212-rotator" for Rotator IP in Exynos4212/4412
(c) "samsung,exynos5250-rotator" for Rotator IP in Exynos5250
- reg : Physical base address of the IP registers and length of memory
mapped region.
- interrupts : Interrupt specifier for rotator interrupt, according to format
specific to interrupt parent.
- clocks : Clock specifier for rotator clock, according to generic clock
bindings. (See Documentation/devicetree/bindings/clock/exynos*.txt)
- clock-names : Names of clocks. For exynos rotator, it should be "rotator".
Example:
rotator@12810000 {
compatible = "samsung,exynos4210-rotator";
reg = <0x12810000 0x1000>;
interrupts = <0 83 0>;
clocks = <&clock 278>;
clock-names = "rotator";
};
config DRM_EXYNOS config DRM_EXYNOS
tristate "DRM Support for Samsung SoC EXYNOS Series" tristate "DRM Support for Samsung SoC EXYNOS Series"
depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM) depends on OF && DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM)
select DRM_KMS_HELPER select DRM_KMS_HELPER
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT select FB_CFB_IMAGEBLIT
select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
select VIDEOMODE_HELPERS
help help
Choose this option if you have a Samsung SoC EXYNOS chipset. Choose this option if you have a Samsung SoC EXYNOS chipset.
If M is selected the module will be called exynosdrm. If M is selected the module will be called exynosdrm.
...@@ -24,9 +25,8 @@ config DRM_EXYNOS_DMABUF ...@@ -24,9 +25,8 @@ config DRM_EXYNOS_DMABUF
config DRM_EXYNOS_FIMD config DRM_EXYNOS_FIMD
bool "Exynos DRM FIMD" bool "Exynos DRM FIMD"
depends on OF && DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM
select FB_MODE_HELPERS select FB_MODE_HELPERS
select VIDEOMODE_HELPERS
help help
Choose this option if you want to use Exynos FIMD for DRM. Choose this option if you want to use Exynos FIMD for DRM.
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/of.h>
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_hdmi.h" #include "exynos_hdmi.h"
...@@ -41,13 +41,6 @@ static int s5p_ddc_remove(struct i2c_client *client) ...@@ -41,13 +41,6 @@ static int s5p_ddc_remove(struct i2c_client *client)
return 0; return 0;
} }
static struct i2c_device_id ddc_idtable[] = {
{"s5p_ddc", 0},
{"exynos5-hdmiddc", 0},
{ },
};
#ifdef CONFIG_OF
static struct of_device_id hdmiddc_match_types[] = { static struct of_device_id hdmiddc_match_types[] = {
{ {
.compatible = "samsung,exynos5-hdmiddc", .compatible = "samsung,exynos5-hdmiddc",
...@@ -57,15 +50,13 @@ static struct of_device_id hdmiddc_match_types[] = { ...@@ -57,15 +50,13 @@ static struct of_device_id hdmiddc_match_types[] = {
/* end node */ /* end node */
} }
}; };
#endif
struct i2c_driver ddc_driver = { struct i2c_driver ddc_driver = {
.driver = { .driver = {
.name = "exynos-hdmiddc", .name = "exynos-hdmiddc",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(hdmiddc_match_types), .of_match_table = hdmiddc_match_types,
}, },
.id_table = ddc_idtable,
.probe = s5p_ddc_probe, .probe = s5p_ddc_probe,
.remove = s5p_ddc_remove, .remove = s5p_ddc_remove,
.command = NULL, .command = NULL,
......
...@@ -149,10 +149,8 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev, ...@@ -149,10 +149,8 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev,
DRM_DEBUG_KMS("desired size = 0x%x\n", size); DRM_DEBUG_KMS("desired size = 0x%x\n", size);
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
if (!buffer) { if (!buffer)
DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n");
return NULL; return NULL;
}
buffer->size = size; buffer->size = size;
return buffer; return buffer;
...@@ -161,11 +159,6 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev, ...@@ -161,11 +159,6 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev,
void exynos_drm_fini_buf(struct drm_device *dev, void exynos_drm_fini_buf(struct drm_device *dev,
struct exynos_drm_gem_buf *buffer) struct exynos_drm_gem_buf *buffer)
{ {
if (!buffer) {
DRM_DEBUG_KMS("buffer is null.\n");
return;
}
kfree(buffer); kfree(buffer);
buffer = NULL; buffer = NULL;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h" #include "exynos_drm_encoder.h"
#include "exynos_drm_connector.h"
#define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\ #define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\
drm_connector) drm_connector)
...@@ -28,35 +29,6 @@ struct exynos_drm_connector { ...@@ -28,35 +29,6 @@ struct exynos_drm_connector {
uint32_t dpms; uint32_t dpms;
}; };
/* convert exynos_video_timings to drm_display_mode */
static inline void
convert_to_display_mode(struct drm_display_mode *mode,
struct exynos_drm_panel_info *panel)
{
struct fb_videomode *timing = &panel->timing;
mode->clock = timing->pixclock / 1000;
mode->vrefresh = timing->refresh;
mode->hdisplay = timing->xres;
mode->hsync_start = mode->hdisplay + timing->right_margin;
mode->hsync_end = mode->hsync_start + timing->hsync_len;
mode->htotal = mode->hsync_end + timing->left_margin;
mode->vdisplay = timing->yres;
mode->vsync_start = mode->vdisplay + timing->lower_margin;
mode->vsync_end = mode->vsync_start + timing->vsync_len;
mode->vtotal = mode->vsync_end + timing->upper_margin;
mode->width_mm = panel->width_mm;
mode->height_mm = panel->height_mm;
if (timing->vmode & FB_VMODE_INTERLACED)
mode->flags |= DRM_MODE_FLAG_INTERLACE;
if (timing->vmode & FB_VMODE_DOUBLE)
mode->flags |= DRM_MODE_FLAG_DBLSCAN;
}
static int exynos_drm_connector_get_modes(struct drm_connector *connector) static int exynos_drm_connector_get_modes(struct drm_connector *connector)
{ {
struct exynos_drm_connector *exynos_connector = struct exynos_drm_connector *exynos_connector =
...@@ -111,7 +83,9 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) ...@@ -111,7 +83,9 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
return 0; return 0;
} }
convert_to_display_mode(mode, panel); drm_display_mode_from_videomode(&panel->vm, mode);
mode->width_mm = panel->width_mm;
mode->height_mm = panel->height_mm;
connector->display_info.width_mm = mode->width_mm; connector->display_info.width_mm = mode->width_mm;
connector->display_info.height_mm = mode->height_mm; connector->display_info.height_mm = mode->height_mm;
...@@ -278,10 +252,8 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, ...@@ -278,10 +252,8 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
int err; int err;
exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL); exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL);
if (!exynos_connector) { if (!exynos_connector)
DRM_ERROR("failed to allocate connector\n");
return NULL; return NULL;
}
connector = &exynos_connector->drm_connector; connector = &exynos_connector->drm_connector;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include "exynos_drm_crtc.h"
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h" #include "exynos_drm_encoder.h"
#include "exynos_drm_plane.h" #include "exynos_drm_plane.h"
...@@ -324,10 +325,8 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr) ...@@ -324,10 +325,8 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)
struct drm_crtc *crtc; struct drm_crtc *crtc;
exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL); exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
if (!exynos_crtc) { if (!exynos_crtc)
DRM_ERROR("failed to allocate exynos crtc\n");
return -ENOMEM; return -ENOMEM;
}
exynos_crtc->pipe = nr; exynos_crtc->pipe = nr;
exynos_crtc->dpms = DRM_MODE_DPMS_OFF; exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
#include "exynos_drm_dmabuf.h"
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_drm_gem.h" #include "exynos_drm_gem.h"
...@@ -230,7 +231,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, ...@@ -230,7 +231,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
if (!buffer) { if (!buffer) {
DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err_unmap_attach; goto err_unmap_attach;
} }
......
...@@ -47,10 +47,8 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) ...@@ -47,10 +47,8 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
int nr; int nr;
private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL); private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
if (!private) { if (!private)
DRM_ERROR("failed to allocate private\n");
return -ENOMEM; return -ENOMEM;
}
INIT_LIST_HEAD(&private->pageflip_event_list); INIT_LIST_HEAD(&private->pageflip_event_list);
dev->dev_private = (void *)private; dev->dev_private = (void *)private;
......
...@@ -324,10 +324,8 @@ exynos_drm_encoder_create(struct drm_device *dev, ...@@ -324,10 +324,8 @@ exynos_drm_encoder_create(struct drm_device *dev,
return NULL; return NULL;
exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL); exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL);
if (!exynos_encoder) { if (!exynos_encoder)
DRM_ERROR("failed to allocate encoder\n");
return NULL; return NULL;
}
exynos_encoder->dpms = DRM_MODE_DPMS_OFF; exynos_encoder->dpms = DRM_MODE_DPMS_OFF;
exynos_encoder->manager = manager; exynos_encoder->manager = manager;
......
...@@ -156,10 +156,8 @@ exynos_drm_framebuffer_init(struct drm_device *dev, ...@@ -156,10 +156,8 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
} }
exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL); exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
if (!exynos_fb) { if (!exynos_fb)
DRM_ERROR("failed to allocate exynos drm framebuffer\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd); drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
exynos_fb->exynos_gem_obj[0] = exynos_gem_obj; exynos_fb->exynos_gem_obj[0] = exynos_gem_obj;
...@@ -220,10 +218,8 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, ...@@ -220,10 +218,8 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
int i, ret; int i, ret;
exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL); exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
if (!exynos_fb) { if (!exynos_fb)
DRM_ERROR("failed to allocate exynos drm framebuffer\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
if (!obj) { if (!obj) {
......
...@@ -16,9 +16,11 @@ ...@@ -16,9 +16,11 @@
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_drm_fb.h" #include "exynos_drm_fb.h"
#include "exynos_drm_fbdev.h"
#include "exynos_drm_gem.h" #include "exynos_drm_gem.h"
#include "exynos_drm_iommu.h" #include "exynos_drm_iommu.h"
...@@ -165,8 +167,18 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, ...@@ -165,8 +167,18 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
size = mode_cmd.pitches[0] * mode_cmd.height; size = mode_cmd.pitches[0] * mode_cmd.height;
/* 0 means to allocate physically continuous memory */ exynos_gem_obj = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG, size);
exynos_gem_obj = exynos_drm_gem_create(dev, 0, size); /*
* If physically contiguous memory allocation fails and if IOMMU is
* supported then try to get buffer from non physically contiguous
* memory area.
*/
if (IS_ERR(exynos_gem_obj) && is_drm_iommu_supported(dev)) {
dev_warn(&pdev->dev, "contiguous FB allocation failed, falling back to non-contiguous\n");
exynos_gem_obj = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG,
size);
}
if (IS_ERR(exynos_gem_obj)) { if (IS_ERR(exynos_gem_obj)) {
ret = PTR_ERR(exynos_gem_obj); ret = PTR_ERR(exynos_gem_obj);
goto err_release_framebuffer; goto err_release_framebuffer;
...@@ -236,10 +248,8 @@ int exynos_drm_fbdev_init(struct drm_device *dev) ...@@ -236,10 +248,8 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
return 0; return 0;
fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
if (!fbdev) { if (!fbdev)
DRM_ERROR("failed to allocate drm fbdev.\n");
return -ENOMEM; return -ENOMEM;
}
private->fb_helper = helper = &fbdev->drm_fb_helper; private->fb_helper = helper = &fbdev->drm_fb_helper;
helper->funcs = &exynos_drm_fb_helper_funcs; helper->funcs = &exynos_drm_fb_helper_funcs;
......
...@@ -17,10 +17,12 @@ ...@@ -17,10 +17,12 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/of.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
#include "regs-fimc.h" #include "regs-fimc.h"
#include "exynos_drm_drv.h"
#include "exynos_drm_ipp.h" #include "exynos_drm_ipp.h"
#include "exynos_drm_fimc.h" #include "exynos_drm_fimc.h"
...@@ -1343,10 +1345,8 @@ static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv) ...@@ -1343,10 +1345,8 @@ static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
struct drm_exynos_ipp_prop_list *prop_list; struct drm_exynos_ipp_prop_list *prop_list;
prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL); prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
if (!prop_list) { if (!prop_list)
DRM_ERROR("failed to alloc property list.\n");
return -ENOMEM; return -ENOMEM;
}
prop_list->version = 1; prop_list->version = 1;
prop_list->writeback = 1; prop_list->writeback = 1;
......
This diff is collapsed.
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_drm_g2d.h"
#include "exynos_drm_gem.h" #include "exynos_drm_gem.h"
#include "exynos_drm_iommu.h" #include "exynos_drm_iommu.h"
...@@ -446,10 +447,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, ...@@ -446,10 +447,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
} }
g2d_userptr = kzalloc(sizeof(*g2d_userptr), GFP_KERNEL); g2d_userptr = kzalloc(sizeof(*g2d_userptr), GFP_KERNEL);
if (!g2d_userptr) { if (!g2d_userptr)
DRM_ERROR("failed to allocate g2d_userptr.\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
atomic_set(&g2d_userptr->refcount, 1); atomic_set(&g2d_userptr->refcount, 1);
...@@ -499,7 +498,6 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, ...@@ -499,7 +498,6 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
if (!sgt) { if (!sgt) {
DRM_ERROR("failed to allocate sg table.\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err_free_userptr; goto err_free_userptr;
} }
...@@ -808,17 +806,8 @@ static void g2d_dma_start(struct g2d_data *g2d, ...@@ -808,17 +806,8 @@ static void g2d_dma_start(struct g2d_data *g2d,
int ret; int ret;
ret = pm_runtime_get_sync(g2d->dev); ret = pm_runtime_get_sync(g2d->dev);
if (ret < 0) { if (ret < 0)
dev_warn(g2d->dev, "failed pm power on.\n");
return;
}
ret = clk_prepare_enable(g2d->gate_clk);
if (ret < 0) {
dev_warn(g2d->dev, "failed to enable clock.\n");
pm_runtime_put_sync(g2d->dev);
return; return;
}
writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR);
writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND);
...@@ -871,7 +860,6 @@ static void g2d_runqueue_worker(struct work_struct *work) ...@@ -871,7 +860,6 @@ static void g2d_runqueue_worker(struct work_struct *work)
runqueue_work); runqueue_work);
mutex_lock(&g2d->runqueue_mutex); mutex_lock(&g2d->runqueue_mutex);
clk_disable_unprepare(g2d->gate_clk);
pm_runtime_put_sync(g2d->dev); pm_runtime_put_sync(g2d->dev);
complete(&g2d->runqueue_node->complete); complete(&g2d->runqueue_node->complete);
...@@ -1096,8 +1084,6 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, ...@@ -1096,8 +1084,6 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
e = kzalloc(sizeof(*node->event), GFP_KERNEL); e = kzalloc(sizeof(*node->event), GFP_KERNEL);
if (!e) { if (!e) {
dev_err(dev, "failed to allocate event\n");
spin_lock_irqsave(&drm_dev->event_lock, flags); spin_lock_irqsave(&drm_dev->event_lock, flags);
file->event_space += sizeof(e->event); file->event_space += sizeof(e->event);
spin_unlock_irqrestore(&drm_dev->event_lock, flags); spin_unlock_irqrestore(&drm_dev->event_lock, flags);
...@@ -1327,10 +1313,8 @@ static int g2d_open(struct drm_device *drm_dev, struct device *dev, ...@@ -1327,10 +1313,8 @@ static int g2d_open(struct drm_device *drm_dev, struct device *dev,
struct exynos_drm_g2d_private *g2d_priv; struct exynos_drm_g2d_private *g2d_priv;
g2d_priv = kzalloc(sizeof(*g2d_priv), GFP_KERNEL); g2d_priv = kzalloc(sizeof(*g2d_priv), GFP_KERNEL);
if (!g2d_priv) { if (!g2d_priv)
dev_err(dev, "failed to allocate g2d private data\n");
return -ENOMEM; return -ENOMEM;
}
g2d_priv->dev = dev; g2d_priv->dev = dev;
file_priv->g2d_priv = g2d_priv; file_priv->g2d_priv = g2d_priv;
...@@ -1386,10 +1370,8 @@ static int g2d_probe(struct platform_device *pdev) ...@@ -1386,10 +1370,8 @@ static int g2d_probe(struct platform_device *pdev)
int ret; int ret;
g2d = devm_kzalloc(dev, sizeof(*g2d), GFP_KERNEL); g2d = devm_kzalloc(dev, sizeof(*g2d), GFP_KERNEL);
if (!g2d) { if (!g2d)
dev_err(dev, "failed to allocate driver data\n");
return -ENOMEM; return -ENOMEM;
}
g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",
sizeof(struct g2d_runqueue_node), 0, 0, NULL); sizeof(struct g2d_runqueue_node), 0, 0, NULL);
...@@ -1524,14 +1506,38 @@ static int g2d_resume(struct device *dev) ...@@ -1524,14 +1506,38 @@ static int g2d_resume(struct device *dev)
} }
#endif #endif
static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); #ifdef CONFIG_PM_RUNTIME
static int g2d_runtime_suspend(struct device *dev)
{
struct g2d_data *g2d = dev_get_drvdata(dev);
clk_disable_unprepare(g2d->gate_clk);
return 0;
}
static int g2d_runtime_resume(struct device *dev)
{
struct g2d_data *g2d = dev_get_drvdata(dev);
int ret;
ret = clk_prepare_enable(g2d->gate_clk);
if (ret < 0)
dev_warn(dev, "failed to enable clock.\n");
return ret;
}
#endif
static const struct dev_pm_ops g2d_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(g2d_suspend, g2d_resume)
SET_RUNTIME_PM_OPS(g2d_runtime_suspend, g2d_runtime_resume, NULL)
};
#ifdef CONFIG_OF
static const struct of_device_id exynos_g2d_match[] = { static const struct of_device_id exynos_g2d_match[] = {
{ .compatible = "samsung,exynos5250-g2d" }, { .compatible = "samsung,exynos5250-g2d" },
{}, {},
}; };
#endif
struct platform_driver g2d_driver = { struct platform_driver g2d_driver = {
.probe = g2d_probe, .probe = g2d_probe,
...@@ -1540,6 +1546,6 @@ struct platform_driver g2d_driver = { ...@@ -1540,6 +1546,6 @@ struct platform_driver g2d_driver = {
.name = "s5p-g2d", .name = "s5p-g2d",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &g2d_pm_ops, .pm = &g2d_pm_ops,
.of_match_table = of_match_ptr(exynos_g2d_match), .of_match_table = exynos_g2d_match,
}, },
}; };
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_drm_gem.h" #include "exynos_drm_gem.h"
#include "exynos_drm_buf.h" #include "exynos_drm_buf.h"
#include "exynos_drm_iommu.h"
static unsigned int convert_to_vm_err_msg(int msg) static unsigned int convert_to_vm_err_msg(int msg)
{ {
...@@ -191,10 +192,8 @@ struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev, ...@@ -191,10 +192,8 @@ struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
int ret; int ret;
exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL); exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL);
if (!exynos_gem_obj) { if (!exynos_gem_obj)
DRM_ERROR("failed to allocate exynos gem object\n");
return NULL; return NULL;
}
exynos_gem_obj->size = size; exynos_gem_obj->size = size;
obj = &exynos_gem_obj->base; obj = &exynos_gem_obj->base;
...@@ -668,6 +667,18 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, ...@@ -668,6 +667,18 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
exynos_gem_obj = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG | exynos_gem_obj = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG |
EXYNOS_BO_WC, args->size); EXYNOS_BO_WC, args->size);
/*
* If physically contiguous memory allocation fails and if IOMMU is
* supported then try to get buffer from non physically contiguous
* memory area.
*/
if (IS_ERR(exynos_gem_obj) && is_drm_iommu_supported(dev)) {
dev_warn(dev->dev, "contiguous FB allocation failed, falling back to non-contiguous\n");
exynos_gem_obj = exynos_drm_gem_create(dev,
EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC,
args->size);
}
if (IS_ERR(exynos_gem_obj)) if (IS_ERR(exynos_gem_obj))
return PTR_ERR(exynos_gem_obj); return PTR_ERR(exynos_gem_obj);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
#include "regs-gsc.h" #include "regs-gsc.h"
#include "exynos_drm_drv.h"
#include "exynos_drm_ipp.h" #include "exynos_drm_ipp.h"
#include "exynos_drm_gsc.h" #include "exynos_drm_gsc.h"
...@@ -1337,10 +1338,8 @@ static int gsc_init_prop_list(struct exynos_drm_ippdrv *ippdrv) ...@@ -1337,10 +1338,8 @@ static int gsc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
struct drm_exynos_ipp_prop_list *prop_list; struct drm_exynos_ipp_prop_list *prop_list;
prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL); prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
if (!prop_list) { if (!prop_list)
DRM_ERROR("failed to alloc property list.\n");
return -ENOMEM; return -ENOMEM;
}
prop_list->version = 1; prop_list->version = 1;
prop_list->writeback = 1; prop_list->writeback = 1;
......
...@@ -403,10 +403,8 @@ static int exynos_drm_hdmi_probe(struct platform_device *pdev) ...@@ -403,10 +403,8 @@ static int exynos_drm_hdmi_probe(struct platform_device *pdev)
struct drm_hdmi_context *ctx; struct drm_hdmi_context *ctx;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx) { if (!ctx)
DRM_LOG_KMS("failed to alloc common hdmi context.\n");
return -ENOMEM; return -ENOMEM;
}
subdrv = &ctx->subdrv; subdrv = &ctx->subdrv;
......
...@@ -47,10 +47,16 @@ int drm_create_iommu_mapping(struct drm_device *drm_dev) ...@@ -47,10 +47,16 @@ int drm_create_iommu_mapping(struct drm_device *drm_dev)
dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms),
GFP_KERNEL); GFP_KERNEL);
if (!dev->dma_parms)
goto error;
dma_set_max_seg_size(dev, 0xffffffffu); dma_set_max_seg_size(dev, 0xffffffffu);
dev->archdata.mapping = mapping; dev->archdata.mapping = mapping;
return 0; return 0;
error:
arm_iommu_release_mapping(mapping);
return -ENOMEM;
} }
/* /*
...@@ -91,6 +97,9 @@ int drm_iommu_attach_device(struct drm_device *drm_dev, ...@@ -91,6 +97,9 @@ int drm_iommu_attach_device(struct drm_device *drm_dev,
subdrv_dev->dma_parms = devm_kzalloc(subdrv_dev, subdrv_dev->dma_parms = devm_kzalloc(subdrv_dev,
sizeof(*subdrv_dev->dma_parms), sizeof(*subdrv_dev->dma_parms),
GFP_KERNEL); GFP_KERNEL);
if (!subdrv_dev->dma_parms)
return -ENOMEM;
dma_set_max_seg_size(subdrv_dev, 0xffffffffu); dma_set_max_seg_size(subdrv_dev, 0xffffffffu);
ret = arm_iommu_attach_device(subdrv_dev, dev->archdata.mapping); ret = arm_iommu_attach_device(subdrv_dev, dev->archdata.mapping);
......
...@@ -408,10 +408,8 @@ static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void) ...@@ -408,10 +408,8 @@ static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void)
struct drm_exynos_ipp_cmd_work *cmd_work; struct drm_exynos_ipp_cmd_work *cmd_work;
cmd_work = kzalloc(sizeof(*cmd_work), GFP_KERNEL); cmd_work = kzalloc(sizeof(*cmd_work), GFP_KERNEL);
if (!cmd_work) { if (!cmd_work)
DRM_ERROR("failed to alloc cmd_work.\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
INIT_WORK((struct work_struct *)cmd_work, ipp_sched_cmd); INIT_WORK((struct work_struct *)cmd_work, ipp_sched_cmd);
...@@ -423,10 +421,8 @@ static struct drm_exynos_ipp_event_work *ipp_create_event_work(void) ...@@ -423,10 +421,8 @@ static struct drm_exynos_ipp_event_work *ipp_create_event_work(void)
struct drm_exynos_ipp_event_work *event_work; struct drm_exynos_ipp_event_work *event_work;
event_work = kzalloc(sizeof(*event_work), GFP_KERNEL); event_work = kzalloc(sizeof(*event_work), GFP_KERNEL);
if (!event_work) { if (!event_work)
DRM_ERROR("failed to alloc event_work.\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
INIT_WORK((struct work_struct *)event_work, ipp_sched_event); INIT_WORK((struct work_struct *)event_work, ipp_sched_event);
...@@ -482,10 +478,8 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, ...@@ -482,10 +478,8 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
/* allocate command node */ /* allocate command node */
c_node = kzalloc(sizeof(*c_node), GFP_KERNEL); c_node = kzalloc(sizeof(*c_node), GFP_KERNEL);
if (!c_node) { if (!c_node)
DRM_ERROR("failed to allocate map node.\n");
return -ENOMEM; return -ENOMEM;
}
/* create property id */ /* create property id */
ret = ipp_create_id(&ctx->prop_idr, &ctx->prop_lock, c_node, ret = ipp_create_id(&ctx->prop_idr, &ctx->prop_lock, c_node,
...@@ -694,10 +688,8 @@ static struct drm_exynos_ipp_mem_node ...@@ -694,10 +688,8 @@ static struct drm_exynos_ipp_mem_node
mutex_lock(&c_node->mem_lock); mutex_lock(&c_node->mem_lock);
m_node = kzalloc(sizeof(*m_node), GFP_KERNEL); m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
if (!m_node) { if (!m_node)
DRM_ERROR("failed to allocate queue node.\n");
goto err_unlock; goto err_unlock;
}
/* clear base address for error handling */ /* clear base address for error handling */
memset(&buf_info, 0x0, sizeof(buf_info)); memset(&buf_info, 0x0, sizeof(buf_info));
...@@ -798,9 +790,7 @@ static int ipp_get_event(struct drm_device *drm_dev, ...@@ -798,9 +790,7 @@ static int ipp_get_event(struct drm_device *drm_dev,
DRM_DEBUG_KMS("ops_id[%d]buf_id[%d]\n", qbuf->ops_id, qbuf->buf_id); DRM_DEBUG_KMS("ops_id[%d]buf_id[%d]\n", qbuf->ops_id, qbuf->buf_id);
e = kzalloc(sizeof(*e), GFP_KERNEL); e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e) { if (!e) {
DRM_ERROR("failed to allocate event.\n");
spin_lock_irqsave(&drm_dev->event_lock, flags); spin_lock_irqsave(&drm_dev->event_lock, flags);
file->event_space += sizeof(e->event); file->event_space += sizeof(e->event);
spin_unlock_irqrestore(&drm_dev->event_lock, flags); spin_unlock_irqrestore(&drm_dev->event_lock, flags);
...@@ -1780,10 +1770,8 @@ static int ipp_subdrv_open(struct drm_device *drm_dev, struct device *dev, ...@@ -1780,10 +1770,8 @@ static int ipp_subdrv_open(struct drm_device *drm_dev, struct device *dev,
struct exynos_drm_ipp_private *priv; struct exynos_drm_ipp_private *priv;
priv = kzalloc(sizeof(*priv), GFP_KERNEL); priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) { if (!priv)
DRM_ERROR("failed to allocate priv.\n");
return -ENOMEM; return -ENOMEM;
}
priv->dev = dev; priv->dev = dev;
file_priv->ipp_priv = priv; file_priv->ipp_priv = priv;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "exynos_drm_encoder.h" #include "exynos_drm_encoder.h"
#include "exynos_drm_fb.h" #include "exynos_drm_fb.h"
#include "exynos_drm_gem.h" #include "exynos_drm_gem.h"
#include "exynos_drm_plane.h"
#define to_exynos_plane(x) container_of(x, struct exynos_plane, base) #define to_exynos_plane(x) container_of(x, struct exynos_plane, base)
...@@ -264,10 +265,8 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev, ...@@ -264,10 +265,8 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
int err; int err;
exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL); exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
if (!exynos_plane) { if (!exynos_plane)
DRM_ERROR("failed to allocate plane\n");
return NULL; return NULL;
}
err = drm_plane_init(dev, &exynos_plane->base, possible_crtcs, err = drm_plane_init(dev, &exynos_plane->base, possible_crtcs,
&exynos_plane_funcs, formats, ARRAY_SIZE(formats), &exynos_plane_funcs, formats, ARRAY_SIZE(formats),
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
#include "regs-rotator.h" #include "regs-rotator.h"
#include "exynos_drm.h" #include "exynos_drm.h"
#include "exynos_drm_drv.h"
#include "exynos_drm_ipp.h" #include "exynos_drm_ipp.h"
/* /*
...@@ -471,10 +472,8 @@ static int rotator_init_prop_list(struct exynos_drm_ippdrv *ippdrv) ...@@ -471,10 +472,8 @@ static int rotator_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
struct drm_exynos_ipp_prop_list *prop_list; struct drm_exynos_ipp_prop_list *prop_list;
prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL); prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
if (!prop_list) { if (!prop_list)
DRM_ERROR("failed to alloc property list.\n");
return -ENOMEM; return -ENOMEM;
}
prop_list->version = 1; prop_list->version = 1;
prop_list->flip = (1 << EXYNOS_DRM_FLIP_VERTICAL) | prop_list->flip = (1 << EXYNOS_DRM_FLIP_VERTICAL) |
...@@ -631,21 +630,96 @@ static int rotator_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) ...@@ -631,21 +630,96 @@ static int rotator_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
return 0; return 0;
} }
static struct rot_limit_table rot_limit_tbl_4210 = {
.ycbcr420_2p = {
.min_w = 32,
.min_h = 32,
.max_w = SZ_64K,
.max_h = SZ_64K,
.align = 3,
},
.rgb888 = {
.min_w = 8,
.min_h = 8,
.max_w = SZ_16K,
.max_h = SZ_16K,
.align = 2,
},
};
static struct rot_limit_table rot_limit_tbl_4x12 = {
.ycbcr420_2p = {
.min_w = 32,
.min_h = 32,
.max_w = SZ_32K,
.max_h = SZ_32K,
.align = 3,
},
.rgb888 = {
.min_w = 8,
.min_h = 8,
.max_w = SZ_8K,
.max_h = SZ_8K,
.align = 2,
},
};
static struct rot_limit_table rot_limit_tbl_5250 = {
.ycbcr420_2p = {
.min_w = 32,
.min_h = 32,
.max_w = SZ_32K,
.max_h = SZ_32K,
.align = 3,
},
.rgb888 = {
.min_w = 8,
.min_h = 8,
.max_w = SZ_8K,
.max_h = SZ_8K,
.align = 1,
},
};
static const struct of_device_id exynos_rotator_match[] = {
{
.compatible = "samsung,exynos4210-rotator",
.data = &rot_limit_tbl_4210,
},
{
.compatible = "samsung,exynos4212-rotator",
.data = &rot_limit_tbl_4x12,
},
{
.compatible = "samsung,exynos5250-rotator",
.data = &rot_limit_tbl_5250,
},
{},
};
static int rotator_probe(struct platform_device *pdev) static int rotator_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct rot_context *rot; struct rot_context *rot;
struct exynos_drm_ippdrv *ippdrv; struct exynos_drm_ippdrv *ippdrv;
const struct of_device_id *match;
int ret; int ret;
if (!dev->of_node) {
dev_err(dev, "cannot find of_node.\n");
return -ENODEV;
}
rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL); rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL);
if (!rot) { if (!rot)
dev_err(dev, "failed to allocate rot\n");
return -ENOMEM; return -ENOMEM;
}
rot->limit_tbl = (struct rot_limit_table *) match = of_match_node(exynos_rotator_match, dev->of_node);
platform_get_device_id(pdev)->driver_data; if (!match) {
dev_err(dev, "failed to match node\n");
return -ENODEV;
}
rot->limit_tbl = (struct rot_limit_table *)match->data;
rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rot->regs = devm_ioremap_resource(dev, rot->regs_res); rot->regs = devm_ioremap_resource(dev, rot->regs_res);
...@@ -717,31 +791,6 @@ static int rotator_remove(struct platform_device *pdev) ...@@ -717,31 +791,6 @@ static int rotator_remove(struct platform_device *pdev)
return 0; return 0;
} }
static struct rot_limit_table rot_limit_tbl = {
.ycbcr420_2p = {
.min_w = 32,
.min_h = 32,
.max_w = SZ_32K,
.max_h = SZ_32K,
.align = 3,
},
.rgb888 = {
.min_w = 8,
.min_h = 8,
.max_w = SZ_8K,
.max_h = SZ_8K,
.align = 2,
},
};
static struct platform_device_id rotator_driver_ids[] = {
{
.name = "exynos-rot",
.driver_data = (unsigned long)&rot_limit_tbl,
},
{},
};
static int rotator_clk_crtl(struct rot_context *rot, bool enable) static int rotator_clk_crtl(struct rot_context *rot, bool enable)
{ {
if (enable) { if (enable) {
...@@ -803,10 +852,10 @@ static const struct dev_pm_ops rotator_pm_ops = { ...@@ -803,10 +852,10 @@ static const struct dev_pm_ops rotator_pm_ops = {
struct platform_driver rotator_driver = { struct platform_driver rotator_driver = {
.probe = rotator_probe, .probe = rotator_probe,
.remove = rotator_remove, .remove = rotator_remove,
.id_table = rotator_driver_ids,
.driver = { .driver = {
.name = "exynos-rot", .name = "exynos-rot",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &rotator_pm_ops, .pm = &rotator_pm_ops,
.of_match_table = exynos_rotator_match,
}, },
}; };
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h" #include "exynos_drm_crtc.h"
#include "exynos_drm_encoder.h" #include "exynos_drm_encoder.h"
#include "exynos_drm_vidi.h"
/* vidi has totally three virtual windows. */ /* vidi has totally three virtual windows. */
#define WINDOWS_NR 3 #define WINDOWS_NR 3
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
...@@ -1824,10 +1825,8 @@ static int hdmi_resources_init(struct hdmi_context *hdata) ...@@ -1824,10 +1825,8 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) * res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
sizeof(res->regul_bulk[0]), GFP_KERNEL); sizeof(res->regul_bulk[0]), GFP_KERNEL);
if (!res->regul_bulk) { if (!res->regul_bulk)
DRM_ERROR("failed to get memory for regulators\n");
goto fail; goto fail;
}
for (i = 0; i < ARRAY_SIZE(supply); ++i) { for (i = 0; i < ARRAY_SIZE(supply); ++i) {
res->regul_bulk[i].supply = supply[i]; res->regul_bulk[i].supply = supply[i];
res->regul_bulk[i].consumer = NULL; res->regul_bulk[i].consumer = NULL;
...@@ -1859,7 +1858,6 @@ void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy) ...@@ -1859,7 +1858,6 @@ void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
hdmi_hdmiphy = hdmiphy; hdmi_hdmiphy = hdmiphy;
} }
#ifdef CONFIG_OF
static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
(struct device *dev) (struct device *dev)
{ {
...@@ -1868,10 +1866,8 @@ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata ...@@ -1868,10 +1866,8 @@ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
u32 value; u32 value;
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
if (!pd) { if (!pd)
DRM_ERROR("memory allocation for pdata failed\n");
goto err_data; goto err_data;
}
if (!of_find_property(np, "hpd-gpio", &value)) { if (!of_find_property(np, "hpd-gpio", &value)) {
DRM_ERROR("no hpd gpio property found\n"); DRM_ERROR("no hpd gpio property found\n");
...@@ -1885,33 +1881,7 @@ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata ...@@ -1885,33 +1881,7 @@ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
err_data: err_data:
return NULL; return NULL;
} }
#else
static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
(struct device *dev)
{
return NULL;
}
#endif
static struct platform_device_id hdmi_driver_types[] = {
{
.name = "s5pv210-hdmi",
.driver_data = HDMI_TYPE13,
}, {
.name = "exynos4-hdmi",
.driver_data = HDMI_TYPE13,
}, {
.name = "exynos4-hdmi14",
.driver_data = HDMI_TYPE14,
}, {
.name = "exynos5-hdmi",
.driver_data = HDMI_TYPE14,
}, {
/* end node */
}
};
#ifdef CONFIG_OF
static struct of_device_id hdmi_match_types[] = { static struct of_device_id hdmi_match_types[] = {
{ {
.compatible = "samsung,exynos5-hdmi", .compatible = "samsung,exynos5-hdmi",
...@@ -1923,7 +1893,6 @@ static struct of_device_id hdmi_match_types[] = { ...@@ -1923,7 +1893,6 @@ static struct of_device_id hdmi_match_types[] = {
/* end node */ /* end node */
} }
}; };
#endif
static int hdmi_probe(struct platform_device *pdev) static int hdmi_probe(struct platform_device *pdev)
{ {
...@@ -1932,36 +1901,23 @@ static int hdmi_probe(struct platform_device *pdev) ...@@ -1932,36 +1901,23 @@ static int hdmi_probe(struct platform_device *pdev)
struct hdmi_context *hdata; struct hdmi_context *hdata;
struct s5p_hdmi_platform_data *pdata; struct s5p_hdmi_platform_data *pdata;
struct resource *res; struct resource *res;
const struct of_device_id *match;
int ret; int ret;
if (dev->of_node) { if (!dev->of_node)
pdata = drm_hdmi_dt_parse_pdata(dev); return -ENODEV;
if (IS_ERR(pdata)) {
DRM_ERROR("failed to parse dt\n");
return PTR_ERR(pdata);
}
} else {
pdata = dev->platform_data;
}
if (!pdata) { pdata = drm_hdmi_dt_parse_pdata(dev);
DRM_ERROR("no platform data specified\n"); if (!pdata)
return -EINVAL; return -EINVAL;
}
drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx), drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx), GFP_KERNEL);
GFP_KERNEL); if (!drm_hdmi_ctx)
if (!drm_hdmi_ctx) {
DRM_ERROR("failed to allocate common hdmi context.\n");
return -ENOMEM; return -ENOMEM;
}
hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
GFP_KERNEL); if (!hdata)
if (!hdata) {
DRM_ERROR("out of memory\n");
return -ENOMEM; return -ENOMEM;
}
mutex_init(&hdata->hdmi_mutex); mutex_init(&hdata->hdmi_mutex);
...@@ -1970,23 +1926,15 @@ static int hdmi_probe(struct platform_device *pdev) ...@@ -1970,23 +1926,15 @@ static int hdmi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, drm_hdmi_ctx); platform_set_drvdata(pdev, drm_hdmi_ctx);
if (dev->of_node) { match = of_match_node(hdmi_match_types, dev->of_node);
const struct of_device_id *match; if (!match)
match = of_match_node(of_match_ptr(hdmi_match_types),
dev->of_node);
if (match == NULL)
return -ENODEV; return -ENODEV;
hdata->type = (enum hdmi_type)match->data; hdata->type = (enum hdmi_type)match->data;
} else {
hdata->type = (enum hdmi_type)platform_get_device_id
(pdev)->driver_data;
}
hdata->hpd_gpio = pdata->hpd_gpio; hdata->hpd_gpio = pdata->hpd_gpio;
hdata->dev = dev; hdata->dev = dev;
ret = hdmi_resources_init(hdata); ret = hdmi_resources_init(hdata);
if (ret) { if (ret) {
DRM_ERROR("hdmi_resources_init failed\n"); DRM_ERROR("hdmi_resources_init failed\n");
return -EINVAL; return -EINVAL;
...@@ -2141,11 +2089,10 @@ static const struct dev_pm_ops hdmi_pm_ops = { ...@@ -2141,11 +2089,10 @@ static const struct dev_pm_ops hdmi_pm_ops = {
struct platform_driver hdmi_driver = { struct platform_driver hdmi_driver = {
.probe = hdmi_probe, .probe = hdmi_probe,
.remove = hdmi_remove, .remove = hdmi_remove,
.id_table = hdmi_driver_types,
.driver = { .driver = {
.name = "exynos-hdmi", .name = "exynos-hdmi",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &hdmi_pm_ops, .pm = &hdmi_pm_ops,
.of_match_table = of_match_ptr(hdmi_match_types), .of_match_table = hdmi_match_types,
}, },
}; };
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/of.h>
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_hdmi.h" #include "exynos_hdmi.h"
...@@ -39,13 +40,6 @@ static int hdmiphy_remove(struct i2c_client *client) ...@@ -39,13 +40,6 @@ static int hdmiphy_remove(struct i2c_client *client)
return 0; return 0;
} }
static const struct i2c_device_id hdmiphy_id[] = {
{ "s5p_hdmiphy", 0 },
{ "exynos5-hdmiphy", 0 },
{ },
};
#ifdef CONFIG_OF
static struct of_device_id hdmiphy_match_types[] = { static struct of_device_id hdmiphy_match_types[] = {
{ {
.compatible = "samsung,exynos5-hdmiphy", .compatible = "samsung,exynos5-hdmiphy",
...@@ -57,15 +51,13 @@ static struct of_device_id hdmiphy_match_types[] = { ...@@ -57,15 +51,13 @@ static struct of_device_id hdmiphy_match_types[] = {
/* end node */ /* end node */
} }
}; };
#endif
struct i2c_driver hdmiphy_driver = { struct i2c_driver hdmiphy_driver = {
.driver = { .driver = {
.name = "exynos-hdmiphy", .name = "exynos-hdmiphy",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(hdmiphy_match_types), .of_match_table = hdmiphy_match_types,
}, },
.id_table = hdmiphy_id,
.probe = hdmiphy_probe, .probe = hdmiphy_probe,
.remove = hdmiphy_remove, .remove = hdmiphy_remove,
.command = NULL, .command = NULL,
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/of.h>
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
...@@ -1185,16 +1186,12 @@ static int mixer_probe(struct platform_device *pdev) ...@@ -1185,16 +1186,12 @@ static int mixer_probe(struct platform_device *pdev)
drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx), drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx),
GFP_KERNEL); GFP_KERNEL);
if (!drm_hdmi_ctx) { if (!drm_hdmi_ctx)
DRM_ERROR("failed to allocate common hdmi context.\n");
return -ENOMEM; return -ENOMEM;
}
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx) { if (!ctx)
DRM_ERROR("failed to alloc mixer context.\n");
return -ENOMEM; return -ENOMEM;
}
mutex_init(&ctx->mixer_mutex); mutex_init(&ctx->mixer_mutex);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#define _EXYNOS_DRM_H_ #define _EXYNOS_DRM_H_
#include <uapi/drm/exynos_drm.h> #include <uapi/drm/exynos_drm.h>
#include <video/videomode.h>
/** /**
* A structure for lcd panel information. * A structure for lcd panel information.
...@@ -24,7 +25,7 @@ ...@@ -24,7 +25,7 @@
* @height_mm: physical size of lcd height. * @height_mm: physical size of lcd height.
*/ */
struct exynos_drm_panel_info { struct exynos_drm_panel_info {
struct fb_videomode timing; struct videomode vm;
u32 width_mm; u32 width_mm;
u32 height_mm; u32 height_mm;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment