diff options
author | Dave Airlie <airlied@redhat.com> | 2017-01-23 01:15:44 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-01-23 01:15:44 +0100 |
commit | d64a1661c8f783214e1a4fd9d38c2919d5b8231d (patch) | |
tree | f69eff453dcd4a1e16bccd193835c8491ef5f38d | |
parent | Merge tag 'drm-misc-next-2017-01-09' of git://anongit.freedesktop.org/git/drm... (diff) | |
parent | drm/sti: sti_vtg: Handle return NULL error from devm_ioremap_nocache (diff) | |
download | linux-d64a1661c8f783214e1a4fd9d38c2919d5b8231d.tar.xz linux-d64a1661c8f783214e1a4fd9d38c2919d5b8231d.zip |
Merge tag 'sti-drm-next-2017-01-06' of https://github.com/vinceab/linux into drm-next
stih410 cleanup, create fbdev at binding, HQVDP fixes.
* tag 'sti-drm-next-2017-01-06' of https://github.com/vinceab/linux:
drm/sti: sti_vtg: Handle return NULL error from devm_ioremap_nocache
drm/sti: remove deprecated sti_vtac.c file
drm/sti: create fbdev at binding
drm/sti: update fps debugfs entries
drm/sti: do not post HQVDP command if no update
drm/sti: load XP70 firmware only once
drm/sti: allow audio playback on HDMI even if disabled.
-rw-r--r-- | drivers/gpu/drm/sti/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_drv.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_hdmi.c | 205 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_hqvdp.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_plane.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_plane.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_vtac.c | 223 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_vtg.c | 4 |
9 files changed, 154 insertions, 350 deletions
diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile index d20f7c0b4eac..c35db12435c3 100644 --- a/drivers/gpu/drm/sti/Makefile +++ b/drivers/gpu/drm/sti/Makefile @@ -13,7 +13,6 @@ sti-drm-y := \ sti_dvo.o \ sti_awg_utils.o \ sti_vtg.o \ - sti_vtac.o \ sti_hda.o \ sti_tvout.o \ sti_hqvdp.o \ diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index ff71e25ab5bf..278a63f10d9f 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c @@ -252,19 +252,7 @@ static void sti_output_poll_changed(struct drm_device *ddev) { struct sti_private *private = ddev->dev_private; - if (!ddev->mode_config.num_connector) - return; - - if (private->fbdev) { - drm_fbdev_cma_hotplug_event(private->fbdev); - return; - } - - private->fbdev = drm_fbdev_cma_init(ddev, 32, - ddev->mode_config.num_crtc, - ddev->mode_config.num_connector); - if (IS_ERR(private->fbdev)) - private->fbdev = NULL; + drm_fbdev_cma_hotplug_event(private->fbdev); } static const struct drm_mode_config_funcs sti_mode_config_funcs = { @@ -382,6 +370,8 @@ static void sti_cleanup(struct drm_device *ddev) static int sti_bind(struct device *dev) { struct drm_device *ddev; + struct sti_private *private; + struct drm_fbdev_cma *fbdev; int ret; ddev = drm_dev_alloc(&sti_driver, dev); @@ -404,6 +394,17 @@ static int sti_bind(struct device *dev) drm_mode_config_reset(ddev); + private = ddev->dev_private; + if (ddev->mode_config.num_connector) { + fbdev = drm_fbdev_cma_init(ddev, 32, ddev->mode_config.num_crtc, + ddev->mode_config.num_connector); + if (IS_ERR(fbdev)) { + DRM_DEBUG_DRIVER("Warning: fails to create fbdev\n"); + fbdev = NULL; + } + private->fbdev = fbdev; + } + return 0; err_register: @@ -476,7 +477,6 @@ static struct platform_driver sti_platform_driver = { static struct platform_driver * const drivers[] = { &sti_tvout_driver, - &sti_vtac_driver, &sti_hqvdp_driver, &sti_hdmi_driver, &sti_hda_driver, diff --git a/drivers/gpu/drm/sti/sti_drv.h b/drivers/gpu/drm/sti/sti_drv.h index 78ebe5e30f53..4c75845cc9ab 100644 --- a/drivers/gpu/drm/sti/sti_drv.h +++ b/drivers/gpu/drm/sti/sti_drv.h @@ -34,7 +34,6 @@ struct sti_private { }; extern struct platform_driver sti_tvout_driver; -extern struct platform_driver sti_vtac_driver; extern struct platform_driver sti_hqvdp_driver; extern struct platform_driver sti_hdmi_driver; extern struct platform_driver sti_hda_driver; diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index f0af1ae82ee9..5ef1d1fce6d1 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c @@ -788,6 +788,95 @@ static void sti_hdmi_disable(struct drm_bridge *bridge) hdmi->enabled = false; } +/** + * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent + * clocks. None-coherent clocks means that audio and TMDS clocks have not the + * same source (drifts between clocks). In this case assumption is that CTS is + * automatically calculated by hardware. + * + * @audio_fs: audio frame clock frequency in Hz + * + * Values computed are based on table described in HDMI specification 1.4b + * + * Returns n value. + */ +static int sti_hdmi_audio_get_non_coherent_n(unsigned int audio_fs) +{ + unsigned int n; + + switch (audio_fs) { + case 32000: + n = 4096; + break; + case 44100: + n = 6272; + break; + case 48000: + n = 6144; + break; + case 88200: + n = 6272 * 2; + break; + case 96000: + n = 6144 * 2; + break; + case 176400: + n = 6272 * 4; + break; + case 192000: + n = 6144 * 4; + break; + default: + /* Not pre-defined, recommended value: 128 * fs / 1000 */ + n = (audio_fs * 128) / 1000; + } + + return n; +} + +static int hdmi_audio_configure(struct sti_hdmi *hdmi) +{ + int audio_cfg, n; + struct hdmi_audio_params *params = &hdmi->audio; + struct hdmi_audio_infoframe *info = ¶ms->cea; + + DRM_DEBUG_DRIVER("\n"); + + if (!hdmi->enabled) + return 0; + + /* update N parameter */ + n = sti_hdmi_audio_get_non_coherent_n(params->sample_rate); + + DRM_DEBUG_DRIVER("Audio rate = %d Hz, TMDS clock = %d Hz, n = %d\n", + params->sample_rate, hdmi->mode.clock * 1000, n); + hdmi_write(hdmi, n, HDMI_AUDN); + + /* update HDMI registers according to configuration */ + audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID | + HDMI_AUD_CFG_ONE_BIT_INVALID; + + switch (info->channels) { + case 8: + audio_cfg |= HDMI_AUD_CFG_CH78_VALID; + case 6: + audio_cfg |= HDMI_AUD_CFG_CH56_VALID; + case 4: + audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH; + case 2: + audio_cfg |= HDMI_AUD_CFG_CH12_VALID; + break; + default: + DRM_ERROR("ERROR: Unsupported number of channels (%d)!\n", + info->channels); + return -EINVAL; + } + + hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG); + + return hdmi_audio_infoframe_config(hdmi); +} + static void sti_hdmi_pre_enable(struct drm_bridge *bridge) { struct sti_hdmi *hdmi = bridge->driver_private; @@ -826,9 +915,12 @@ static void sti_hdmi_pre_enable(struct drm_bridge *bridge) if (hdmi_avi_infoframe_config(hdmi)) DRM_ERROR("Unable to configure AVI infoframe\n"); - /* Program AUDIO infoframe */ - if (hdmi_audio_infoframe_config(hdmi)) - DRM_ERROR("Unable to configure AUDIO infoframe\n"); + if (hdmi->audio.enabled) { + if (hdmi_audio_configure(hdmi)) + DRM_ERROR("Unable to configure audio\n"); + } else { + hdmi_audio_infoframe_config(hdmi); + } /* Program VS infoframe */ if (hdmi_vendor_infoframe_config(hdmi)) @@ -1078,97 +1170,6 @@ static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev) return NULL; } -/** - * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent - * clocks. None-coherent clocks means that audio and TMDS clocks have not the - * same source (drifts between clocks). In this case assumption is that CTS is - * automatically calculated by hardware. - * - * @audio_fs: audio frame clock frequency in Hz - * - * Values computed are based on table described in HDMI specification 1.4b - * - * Returns n value. - */ -static int sti_hdmi_audio_get_non_coherent_n(unsigned int audio_fs) -{ - unsigned int n; - - switch (audio_fs) { - case 32000: - n = 4096; - break; - case 44100: - n = 6272; - break; - case 48000: - n = 6144; - break; - case 88200: - n = 6272 * 2; - break; - case 96000: - n = 6144 * 2; - break; - case 176400: - n = 6272 * 4; - break; - case 192000: - n = 6144 * 4; - break; - default: - /* Not pre-defined, recommended value: 128 * fs / 1000 */ - n = (audio_fs * 128) / 1000; - } - - return n; -} - -static int hdmi_audio_configure(struct sti_hdmi *hdmi, - struct hdmi_audio_params *params) -{ - int audio_cfg, n; - struct hdmi_audio_infoframe *info = ¶ms->cea; - - DRM_DEBUG_DRIVER("\n"); - - if (!hdmi->enabled) - return 0; - - /* update N parameter */ - n = sti_hdmi_audio_get_non_coherent_n(params->sample_rate); - - DRM_DEBUG_DRIVER("Audio rate = %d Hz, TMDS clock = %d Hz, n = %d\n", - params->sample_rate, hdmi->mode.clock * 1000, n); - hdmi_write(hdmi, n, HDMI_AUDN); - - /* update HDMI registers according to configuration */ - audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID | - HDMI_AUD_CFG_ONE_BIT_INVALID; - - switch (info->channels) { - case 8: - audio_cfg |= HDMI_AUD_CFG_CH78_VALID; - case 6: - audio_cfg |= HDMI_AUD_CFG_CH56_VALID; - case 4: - audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH; - case 2: - audio_cfg |= HDMI_AUD_CFG_CH12_VALID; - break; - default: - DRM_ERROR("ERROR: Unsupported number of channels (%d)!\n", - info->channels); - return -EINVAL; - } - - hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG); - - hdmi->audio = *params; - - return hdmi_audio_infoframe_config(hdmi); -} - static void hdmi_audio_shutdown(struct device *dev, void *data) { struct sti_hdmi *hdmi = dev_get_drvdata(dev); @@ -1192,17 +1193,9 @@ static int hdmi_audio_hw_params(struct device *dev, { struct sti_hdmi *hdmi = dev_get_drvdata(dev); int ret; - struct hdmi_audio_params audio = { - .sample_width = params->sample_width, - .sample_rate = params->sample_rate, - .cea = params->cea, - }; DRM_DEBUG_DRIVER("\n"); - if (!hdmi->enabled) - return 0; - if ((daifmt->fmt != HDMI_I2S) || daifmt->bit_clk_inv || daifmt->frame_clk_inv || daifmt->bit_clk_master || daifmt->frame_clk_master) { @@ -1213,9 +1206,13 @@ static int hdmi_audio_hw_params(struct device *dev, return -EINVAL; } - audio.enabled = true; + hdmi->audio.sample_width = params->sample_width; + hdmi->audio.sample_rate = params->sample_rate; + hdmi->audio.cea = params->cea; + + hdmi->audio.enabled = true; - ret = hdmi_audio_configure(hdmi, &audio); + ret = hdmi_audio_configure(hdmi); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c index becf10d255c4..4376fd8a8e52 100644 --- a/drivers/gpu/drm/sti/sti_hqvdp.c +++ b/drivers/gpu/drm/sti/sti_hqvdp.c @@ -332,6 +332,7 @@ struct sti_hqvdp_cmd { * @hqvdp_cmd_paddr: physical address of hqvdp_cmd * @vtg: vtg for main data path * @xp70_initialized: true if xp70 is already initialized + * @vtg_registered: true if registered to VTG */ struct sti_hqvdp { struct device *dev; @@ -347,6 +348,7 @@ struct sti_hqvdp { u32 hqvdp_cmd_paddr; struct sti_vtg *vtg; bool xp70_initialized; + bool vtg_registered; }; #define to_sti_hqvdp(x) container_of(x, struct sti_hqvdp, plane) @@ -771,7 +773,7 @@ static void sti_hqvdp_disable(struct sti_hqvdp *hqvdp) DRM_ERROR("XP70 could not revert to idle\n"); hqvdp->plane.status = STI_PLANE_DISABLED; - hqvdp->xp70_initialized = false; + hqvdp->vtg_registered = false; } /** @@ -1064,10 +1066,11 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane, return -EINVAL; } - if (!hqvdp->xp70_initialized) { + if (!hqvdp->xp70_initialized) /* Start HQVDP XP70 coprocessor */ sti_hqvdp_start_xp70(hqvdp); + if (!hqvdp->vtg_registered) { /* Prevent VTG shutdown */ if (clk_prepare_enable(hqvdp->clk_pix_main)) { DRM_ERROR("Failed to prepare/enable pix main clk\n"); @@ -1081,6 +1084,7 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane, DRM_ERROR("Cannot register VTG notifier\n"); return -EINVAL; } + hqvdp->vtg_registered = true; } DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s)\n", @@ -1113,6 +1117,21 @@ static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane, if (!crtc || !fb) return; + if ((oldstate->fb == state->fb) && + (oldstate->crtc_x == state->crtc_x) && + (oldstate->crtc_y == state->crtc_y) && + (oldstate->crtc_w == state->crtc_w) && + (oldstate->crtc_h == state->crtc_h) && + (oldstate->src_x == state->src_x) && + (oldstate->src_y == state->src_y) && + (oldstate->src_w == state->src_w) && + (oldstate->src_h == state->src_h)) { + /* No change since last update, do not post cmd */ + DRM_DEBUG_DRIVER("No change, not posting cmd\n"); + plane->status = STI_PLANE_UPDATED; + return; + } + mode = &crtc->mode; dst_x = state->crtc_x; dst_y = state->crtc_y; diff --git a/drivers/gpu/drm/sti/sti_plane.c b/drivers/gpu/drm/sti/sti_plane.c index ca4b3719a64a..699094c559b4 100644 --- a/drivers/gpu/drm/sti/sti_plane.c +++ b/drivers/gpu/drm/sti/sti_plane.c @@ -65,9 +65,18 @@ void sti_plane_update_fps(struct sti_plane *plane, fps->last_timestamp = now; fps->last_frame_counter = fps->curr_frame_counter; - fpks = (num_frames * 1000000) / ms_since_last; - snprintf(plane->fps_info.fps_str, FPS_LENGTH, "%-6s @ %d.%.3d fps", - sti_plane_to_str(plane), fpks / 1000, fpks % 1000); + + if (plane->drm_plane.fb) { + fpks = (num_frames * 1000000) / ms_since_last; + snprintf(plane->fps_info.fps_str, FPS_LENGTH, + "%-8s %4dx%-4d %.4s @ %3d.%-3.3d fps (%s)", + plane->drm_plane.name, + plane->drm_plane.fb->width, + plane->drm_plane.fb->height, + (char *)&plane->drm_plane.fb->pixel_format, + fpks / 1000, fpks % 1000, + sti_plane_to_str(plane)); + } if (fps->curr_field_counter) { /* Compute number of field updates */ @@ -75,7 +84,7 @@ void sti_plane_update_fps(struct sti_plane *plane, fps->last_field_counter = fps->curr_field_counter; fipks = (num_fields * 1000000) / ms_since_last; snprintf(plane->fps_info.fips_str, - FPS_LENGTH, " - %d.%.3d field/sec", + FPS_LENGTH, " - %3d.%-3.3d field/sec", fipks / 1000, fipks % 1000); } else { plane->fps_info.fips_str[0] = '\0'; diff --git a/drivers/gpu/drm/sti/sti_plane.h b/drivers/gpu/drm/sti/sti_plane.h index ce3e8d6c88bb..c36c13faaa18 100644 --- a/drivers/gpu/drm/sti/sti_plane.h +++ b/drivers/gpu/drm/sti/sti_plane.h @@ -48,7 +48,7 @@ enum sti_plane_status { STI_PLANE_DISABLED, }; -#define FPS_LENGTH 64 +#define FPS_LENGTH 128 struct sti_fps_info { bool output; unsigned int curr_frame_counter; diff --git a/drivers/gpu/drm/sti/sti_vtac.c b/drivers/gpu/drm/sti/sti_vtac.c deleted file mode 100644 index cf7fe8a1db42..000000000000 --- a/drivers/gpu/drm/sti/sti_vtac.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) STMicroelectronics SA 2014 - * Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics. - * License terms: GNU General Public License (GPL), version 2 - */ - -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/platform_device.h> - -#include <drm/drmP.h> - -#include "sti_drv.h" - -/* registers offset */ -#define VTAC_CONFIG 0x00 -#define VTAC_RX_FIFO_CONFIG 0x04 -#define VTAC_FIFO_CONFIG_VAL 0x04 - -#define VTAC_SYS_CFG8521 0x824 -#define VTAC_SYS_CFG8522 0x828 - -/* Number of phyts per pixel */ -#define VTAC_2_5_PPP 0x0005 -#define VTAC_3_PPP 0x0006 -#define VTAC_4_PPP 0x0008 -#define VTAC_5_PPP 0x000A -#define VTAC_6_PPP 0x000C -#define VTAC_13_PPP 0x001A -#define VTAC_14_PPP 0x001C -#define VTAC_15_PPP 0x001E -#define VTAC_16_PPP 0x0020 -#define VTAC_17_PPP 0x0022 -#define VTAC_18_PPP 0x0024 - -/* enable bits */ -#define VTAC_ENABLE 0x3003 - -#define VTAC_TX_PHY_ENABLE_CLK_PHY BIT(0) -#define VTAC_TX_PHY_ENABLE_CLK_DLL BIT(1) -#define VTAC_TX_PHY_PLL_NOT_OSC_MODE BIT(3) -#define VTAC_TX_PHY_RST_N_DLL_SWITCH BIT(4) -#define VTAC_TX_PHY_PROG_N3 BIT(9) - - -/** - * VTAC mode structure - * - * @vid_in_width: Video Data Resolution - * @phyts_width: Width of phyt buses(phyt low and phyt high). - * @phyts_per_pixel: Number of phyts sent per pixel - */ -struct sti_vtac_mode { - u32 vid_in_width; - u32 phyts_width; - u32 phyts_per_pixel; -}; - -static const struct sti_vtac_mode vtac_mode_main = { - .vid_in_width = 0x2, - .phyts_width = 0x2, - .phyts_per_pixel = VTAC_5_PPP, -}; -static const struct sti_vtac_mode vtac_mode_aux = { - .vid_in_width = 0x1, - .phyts_width = 0x0, - .phyts_per_pixel = VTAC_17_PPP, -}; - -/** - * VTAC structure - * - * @dev: pointer to device structure - * @regs: ioremapped registers for RX and TX devices - * @phy_regs: phy registers for TX device - * @clk: clock - * @mode: main or auxillary configuration mode - */ -struct sti_vtac { - struct device *dev; - void __iomem *regs; - void __iomem *phy_regs; - struct clk *clk; - const struct sti_vtac_mode *mode; -}; - -static void sti_vtac_rx_set_config(struct sti_vtac *vtac) -{ - u32 config; - - /* Enable VTAC clock */ - if (clk_prepare_enable(vtac->clk)) - DRM_ERROR("Failed to prepare/enable vtac_rx clock.\n"); - - writel(VTAC_FIFO_CONFIG_VAL, vtac->regs + VTAC_RX_FIFO_CONFIG); - - config = VTAC_ENABLE; - config |= vtac->mode->vid_in_width << 4; - config |= vtac->mode->phyts_width << 16; - config |= vtac->mode->phyts_per_pixel << 23; - writel(config, vtac->regs + VTAC_CONFIG); -} - -static void sti_vtac_tx_set_config(struct sti_vtac *vtac) -{ - u32 phy_config; - u32 config; - - /* Enable VTAC clock */ - if (clk_prepare_enable(vtac->clk)) - DRM_ERROR("Failed to prepare/enable vtac_tx clock.\n"); - - /* Configure vtac phy */ - phy_config = 0x00000000; - writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8522); - phy_config = VTAC_TX_PHY_ENABLE_CLK_PHY; - writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521); - phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521); - phy_config |= VTAC_TX_PHY_PROG_N3; - writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521); - phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521); - phy_config |= VTAC_TX_PHY_ENABLE_CLK_DLL; - writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521); - phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521); - phy_config |= VTAC_TX_PHY_RST_N_DLL_SWITCH; - writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521); - phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521); - phy_config |= VTAC_TX_PHY_PLL_NOT_OSC_MODE; - writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521); - - /* Configure vtac tx */ - config = VTAC_ENABLE; - config |= vtac->mode->vid_in_width << 4; - config |= vtac->mode->phyts_width << 16; - config |= vtac->mode->phyts_per_pixel << 23; - writel(config, vtac->regs + VTAC_CONFIG); -} - -static const struct of_device_id vtac_of_match[] = { - { - .compatible = "st,vtac-main", - .data = &vtac_mode_main, - }, { - .compatible = "st,vtac-aux", - .data = &vtac_mode_aux, - }, { - /* end node */ - } -}; -MODULE_DEVICE_TABLE(of, vtac_of_match); - -static int sti_vtac_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - const struct of_device_id *id; - struct sti_vtac *vtac; - struct resource *res; - - vtac = devm_kzalloc(dev, sizeof(*vtac), GFP_KERNEL); - if (!vtac) - return -ENOMEM; - - vtac->dev = dev; - - id = of_match_node(vtac_of_match, np); - if (!id) - return -ENOMEM; - - vtac->mode = id->data; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - DRM_ERROR("Invalid resource\n"); - return -ENOMEM; - } - vtac->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(vtac->regs)) - return PTR_ERR(vtac->regs); - - - vtac->clk = devm_clk_get(dev, "vtac"); - if (IS_ERR(vtac->clk)) { - DRM_ERROR("Cannot get vtac clock\n"); - return PTR_ERR(vtac->clk); - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (res) { - vtac->phy_regs = devm_ioremap_nocache(dev, res->start, - resource_size(res)); - sti_vtac_tx_set_config(vtac); - } else { - - sti_vtac_rx_set_config(vtac); - } - - platform_set_drvdata(pdev, vtac); - DRM_INFO("%s %s\n", __func__, dev_name(vtac->dev)); - - return 0; -} - -static int sti_vtac_remove(struct platform_device *pdev) -{ - return 0; -} - -struct platform_driver sti_vtac_driver = { - .driver = { - .name = "sti-vtac", - .owner = THIS_MODULE, - .of_match_table = vtac_of_match, - }, - .probe = sti_vtac_probe, - .remove = sti_vtac_remove, -}; - -MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>"); -MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/sti/sti_vtg.c b/drivers/gpu/drm/sti/sti_vtg.c index a8882bdd0f8b..c3d9c8ae14af 100644 --- a/drivers/gpu/drm/sti/sti_vtg.c +++ b/drivers/gpu/drm/sti/sti_vtg.c @@ -429,6 +429,10 @@ static int vtg_probe(struct platform_device *pdev) return -ENOMEM; } vtg->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!vtg->regs) { + DRM_ERROR("failed to remap I/O memory\n"); + return -ENOMEM; + } np = of_parse_phandle(pdev->dev.of_node, "st,slave", 0); if (np) { |