diff options
Diffstat (limited to 'drivers')
28 files changed, 520 insertions, 841 deletions
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index cdd6c46d6557..7a9f20a2fd30 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -881,6 +881,17 @@ static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { .atomic_disable = ast_crtc_helper_atomic_disable, }; +static void ast_crtc_reset(struct drm_crtc *crtc) +{ + struct ast_crtc_state *ast_state = + kzalloc(sizeof(*ast_state), GFP_KERNEL); + + if (crtc->state) + crtc->funcs->atomic_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &ast_state->base); +} + static void ast_crtc_destroy(struct drm_crtc *crtc) { drm_crtc_cleanup(crtc); @@ -919,7 +930,7 @@ static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc, } static const struct drm_crtc_funcs ast_crtc_funcs = { - .reset = drm_atomic_helper_crtc_reset, + .reset = ast_crtc_reset, .set_config = drm_crtc_helper_set_config, .gamma_set = drm_atomic_helper_legacy_gamma_set, .destroy = ast_crtc_destroy, diff --git a/drivers/gpu/drm/bridge/adv7511/Kconfig b/drivers/gpu/drm/bridge/adv7511/Kconfig index 47d4eb9e845d..f46a5e26b5dd 100644 --- a/drivers/gpu/drm/bridge/adv7511/Kconfig +++ b/drivers/gpu/drm/bridge/adv7511/Kconfig @@ -6,7 +6,7 @@ config DRM_I2C_ADV7511 select REGMAP_I2C select DRM_MIPI_DSI help - Support for the Analog Device ADV7511(W)/13/33/35 HDMI encoders. + Support for the Analog Devices ADV7511(W)/13/33/35 HDMI encoders. config DRM_I2C_ADV7511_AUDIO bool "ADV7511 HDMI Audio driver" diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c index a428185be2c1..f101dd2819b5 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c @@ -19,13 +19,15 @@ static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs, { switch (fs) { case 32000: - *n = 4096; + case 48000: + case 96000: + case 192000: + *n = fs * 128 / 1000; break; case 44100: - *n = 6272; - break; - case 48000: - *n = 6144; + case 88200: + case 176400: + *n = fs * 128 / 900; break; } @@ -119,6 +121,9 @@ int adv7511_hdmi_hw_params(struct device *dev, void *data, audio_source = ADV7511_AUDIO_SOURCE_I2S; i2s_format = ADV7511_I2S_FORMAT_LEFT_J; break; + case HDMI_SPDIF: + audio_source = ADV7511_AUDIO_SOURCE_SPDIF; + break; default: return -EINVAL; } @@ -175,11 +180,21 @@ static int audio_startup(struct device *dev, void *data) /* use Audio infoframe updated info */ regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(1), BIT(5), 0); + /* enable SPDIF receiver */ + if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, + BIT(7), BIT(7)); + return 0; } static void audio_shutdown(struct device *dev, void *data) { + struct adv7511 *adv7511 = dev_get_drvdata(dev); + + if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, + BIT(7), 0); } static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component, @@ -213,6 +228,7 @@ static const struct hdmi_codec_pdata codec_data = { .ops = &adv7511_codec_ops, .max_i2s_channels = 2, .i2s = 1, + .spdif = 1, }; int adv7511_audio_init(struct device *dev, struct adv7511 *adv7511) diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 9801c0333eca..cb2349ad338d 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -2,7 +2,7 @@ /* * drm kms/fb cma (contiguous memory allocator) helper functions * - * Copyright (C) 2012 Analog Device Inc. + * Copyright (C) 2012 Analog Devices Inc. * Author: Lars-Peter Clausen <lars@metafoo.de> * * Based on udl_fbdev.c diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index cac15294aef6..ccc2c71fa491 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -76,10 +76,8 @@ drm_gem_fb_init(struct drm_device *dev, fb->obj[i] = obj[i]; ret = drm_framebuffer_init(dev, fb, funcs); - if (ret) { + if (ret) drm_err(dev, "Failed to init framebuffer: %d\n", ret); - kfree(fb); - } return ret; } diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 13947ec06dbb..f41cbb753bb4 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -1272,37 +1272,8 @@ cdv_intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZ return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; } - -#if 0 -static char *voltage_names[] = { - "0.4V", "0.6V", "0.8V", "1.2V" -}; -static char *pre_emph_names[] = { - "0dB", "3.5dB", "6dB", "9.5dB" -}; -static char *link_train_names[] = { - "pattern 1", "pattern 2", "idle", "off" -}; -#endif - #define CDV_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_LEVEL_3 -/* -static uint8_t -cdv_intel_dp_pre_emphasis_max(uint8_t voltage_swing) -{ - switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { - case DP_TRAIN_VOLTAGE_SWING_400: - return DP_TRAIN_PRE_EMPHASIS_6; - case DP_TRAIN_VOLTAGE_SWING_600: - return DP_TRAIN_PRE_EMPHASIS_6; - case DP_TRAIN_VOLTAGE_SWING_800: - return DP_TRAIN_PRE_EMPHASIS_3_5; - case DP_TRAIN_VOLTAGE_SWING_1200: - default: - return DP_TRAIN_PRE_EMPHASIS_0; - } -} -*/ + static void cdv_intel_get_adjust_train(struct gma_encoder *encoder) { diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index 18de10e9ff9a..eaaf4efec217 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -74,89 +74,6 @@ static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev) return retval; } -#if 0 -/* - * Set LVDS backlight level by I2C command - */ -static int cdv_lvds_i2c_set_brightness(struct drm_device *dev, - unsigned int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus; - u8 out_buf[2]; - unsigned int blc_i2c_brightness; - - struct i2c_msg msgs[] = { - { - .addr = lvds_i2c_bus->slave_addr, - .flags = 0, - .len = 2, - .buf = out_buf, - } - }; - - blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level * - BRIGHTNESS_MASK / - BRIGHTNESS_MAX_LEVEL); - - if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) - blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness; - - out_buf[0] = dev_priv->lvds_bl->brightnesscmd; - out_buf[1] = (u8)blc_i2c_brightness; - - if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) - return 0; - - DRM_ERROR("I2C transfer error\n"); - return -1; -} - - -static int cdv_lvds_pwm_set_brightness(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - u32 max_pwm_blc; - u32 blc_pwm_duty_cycle; - - max_pwm_blc = cdv_intel_lvds_get_max_backlight(dev); - - /*BLC_PWM_CTL Should be initiated while backlight device init*/ - BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0); - - blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; - - if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) - blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle; - - blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; - REG_WRITE(BLC_PWM_CTL, - (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | - (blc_pwm_duty_cycle)); - - return 0; -} - -/* - * Set LVDS backlight level either by I2C or PWM - */ -void cdv_intel_lvds_set_brightness(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->lvds_bl) { - DRM_ERROR("NO LVDS Backlight Info\n"); - return; - } - - if (dev_priv->lvds_bl->type == BLC_I2C_TYPE) - cdv_lvds_i2c_set_brightness(dev, level); - else - cdv_lvds_pwm_set_brightness(dev, level); -} -#endif - /** * Sets the backlight level. * diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index 4fff110c4921..aae2d358364c 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -658,16 +658,6 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, dev_dbg(dev->dev, "pipe = 0x%x\n", pipe); -#if 0 - if (pipe == 1) { - if (!gma_power_begin(dev, true)) - return 0; - android_hdmi_crtc_mode_set(crtc, mode, adjusted_mode, - x, y, old_fb); - goto mrst_crtc_mode_set_exit; - } -#endif - ret = check_fb(crtc->primary->fb); if (ret) return ret; @@ -918,14 +908,6 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, } dpll = 0; -#if 0 /* FIXME revisit later */ - if (ksel == KSEL_CRYSTAL_19 || ksel == KSEL_BYPASS_19 || - ksel == KSEL_BYPASS_25) - dpll &= ~MDFLD_INPUT_REF_SEL; - else if (ksel == KSEL_BYPASS_83_100) - dpll |= MDFLD_INPUT_REF_SEL; -#endif /* FIXME revisit later */ - if (is_hdmi) dpll |= MDFLD_VCO_SEL; @@ -935,20 +917,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, /* compute bitmask from p1 value */ dpll |= (1 << (clock.p1 - 2)) << 17; -#if 0 /* 1080p30 & 720p */ - dpll = 0x00050000; - fp = 0x000001be; -#endif -#if 0 /* 480p */ - dpll = 0x02010000; - fp = 0x000000d2; -#endif } else { -#if 0 /*DBI_TPO_480x864*/ - dpll = 0x00020000; - fp = 0x00000156; -#endif /* DBI_TPO_480x864 */ /* get from spec. */ - dpll = 0x00800000; fp = 0x000000c1; } diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c index b25086f252ae..a097a59a9eae 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c @@ -663,11 +663,6 @@ failed_connector: kfree(gma_encoder); } -static const struct pci_device_id hdmi_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) }, - { 0 } -}; - void oaktrail_hdmi_setup(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 264d7ad004b4..68fb3d7c172b 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -864,36 +864,6 @@ static bool psb_intel_sdvo_set_avi_infoframe(struct psb_intel_sdvo *psb_intel_sd DRM_INFO("HDMI is not supported yet"); return false; -#if 0 - struct dip_infoframe avi_if = { - .type = DIP_TYPE_AVI, - .ver = DIP_VERSION_AVI, - .len = DIP_LEN_AVI, - }; - uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; - uint8_t set_buf_index[2] = { 1, 0 }; - uint64_t *data = (uint64_t *)&avi_if; - unsigned i; - - intel_dip_infoframe_csum(&avi_if); - - if (!psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2)) - return false; - - for (i = 0; i < sizeof(avi_if); i += 8) { - if (!psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_HBUF_DATA, - data, 8)) - return false; - data++; - } - - return psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_HBUF_TXRATE, - &tx_rate, 1); -#endif } static bool psb_intel_sdvo_set_tv_format(struct psb_intel_sdvo *psb_intel_sdvo) @@ -1227,75 +1197,6 @@ static bool psb_intel_sdvo_get_capabilities(struct psb_intel_sdvo *psb_intel_sdv return true; } -/* No use! */ -#if 0 -struct drm_connector* psb_intel_sdvo_find(struct drm_device *dev, int sdvoB) -{ - struct drm_connector *connector = NULL; - struct psb_intel_sdvo *iout = NULL; - struct psb_intel_sdvo *sdvo; - - /* find the sdvo connector */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - iout = to_psb_intel_sdvo(connector); - - if (iout->type != INTEL_OUTPUT_SDVO) - continue; - - sdvo = iout->dev_priv; - - if (sdvo->sdvo_reg == SDVOB && sdvoB) - return connector; - - if (sdvo->sdvo_reg == SDVOC && !sdvoB) - return connector; - - } - - return NULL; -} - -int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector) -{ - u8 response[2]; - u8 status; - struct psb_intel_sdvo *psb_intel_sdvo; - DRM_DEBUG_KMS("\n"); - - if (!connector) - return 0; - - psb_intel_sdvo = to_psb_intel_sdvo(connector); - - return psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, - &response, 2) && response[0]; -} - -void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on) -{ - u8 response[2]; - u8 status; - struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(connector); - - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); - psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); - - if (on) { - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); - status = psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); - - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); - } else { - response[0] = 0; - response[1] = 0; - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); - } - - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); - psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); -} -#endif - static bool psb_intel_sdvo_multifunc_encoder(struct psb_intel_sdvo *psb_intel_sdvo) { diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index b87d22eb6ae1..33463b79a37b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -769,7 +769,7 @@ static bool rockchip_mod_supported(struct drm_plane *plane, return true; if (!rockchip_afbc(modifier)) { - DRM_DEBUG_KMS("Unsupported format modifer 0x%llx\n", modifier); + DRM_DEBUG_KMS("Unsupported format modifier 0x%llx\n", modifier); return false; } diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index 7dfb50f65067..105fb9cdbb3b 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -5,12 +5,10 @@ #include <linux/clk.h> #include <linux/delay.h> -#include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> #include <linux/of_device.h> -#include <linux/of_gpio.h> #include <linux/pinctrl/pinconf-generic.h> #include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinmux.h> diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 804869799305..b25443255be6 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -9,7 +9,7 @@ #include <linux/host1x.h> #include <linux/iova.h> -#include <linux/of_gpio.h> +#include <linux/gpio/consumer.h> #include <drm/drm_atomic.h> #include <drm/drm_edid.h> diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index b8a328f53862..2b0666ac681b 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -4,7 +4,7 @@ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. * * Based on the KMS/FB CMA helpers - * Copyright (C) 2012 Analog Device Inc. + * Copyright (C) 2012 Analog Devices Inc. */ #include <linux/console.h> diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index c4c8348df090..d09a24931c87 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -7,7 +7,6 @@ #include <linux/clk.h> #include <linux/debugfs.h> #include <linux/delay.h> -#include <linux/gpio.h> #include <linux/hdmi.h> #include <linux/math64.h> #include <linux/module.h> diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 8495ea921b3c..7cbcf9617f5e 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -6,7 +6,6 @@ #include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/debugfs.h> -#include <linux/gpio.h> #include <linux/io.h> #include <linux/module.h> #include <linux/of_device.h> diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 91b0a719d221..fa88e8b9a83d 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -472,7 +472,7 @@ config FB_OF config FB_CONTROL bool "Apple \"control\" display support" - depends on (FB = y) && PPC_PMAC && PPC32 + depends on (FB = y) && ((PPC_PMAC && PPC32) || COMPILE_TEST) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/drivers/video/fbdev/arcfb.c b/drivers/video/fbdev/arcfb.c index 314ab82e01c0..6f7838979f0a 100644 --- a/drivers/video/fbdev/arcfb.c +++ b/drivers/video/fbdev/arcfb.c @@ -544,10 +544,6 @@ static int arcfb_probe(struct platform_device *dev) par->cslut[1] = 0x06; info->flags = FBINFO_FLAG_DEFAULT; spin_lock_init(&par->lock); - retval = register_framebuffer(info); - if (retval < 0) - goto err1; - platform_set_drvdata(dev, info); if (irq) { par->irq = irq; if (request_irq(par->irq, &arcfb_interrupt, IRQF_SHARED, @@ -558,6 +554,10 @@ static int arcfb_probe(struct platform_device *dev) goto err1; } } + retval = register_framebuffer(info); + if (retval < 0) + goto err1; + platform_set_drvdata(dev, info); fb_info(info, "Arc frame buffer device, using %dK of video memory\n", videomemorysize >> 10); @@ -593,6 +593,8 @@ static int arcfb_remove(struct platform_device *dev) if (info) { unregister_framebuffer(info); + if (irq) + free_irq(((struct arcfb_par *)(info->par))->irq, info); vfree((void __force *)info->screen_base); framebuffer_release(info); } diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c index d7e41c8dd533..d05d4195acad 100644 --- a/drivers/video/fbdev/aty/aty128fb.c +++ b/drivers/video/fbdev/aty/aty128fb.c @@ -334,20 +334,6 @@ static const struct aty128_meminfo sdr_128 = { .name = "128-bit SDR SGRAM (1:1)", }; -static const struct aty128_meminfo sdr_64 = { - .ML = 4, - .MB = 8, - .Trcd = 3, - .Trp = 3, - .Twr = 1, - .CL = 3, - .Tr2w = 1, - .LoopLatency = 17, - .DspOn = 46, - .Rloop = 17, - .name = "64-bit SDR SGRAM (1:1)", -}; - static const struct aty128_meminfo sdr_sgram = { .ML = 4, .MB = 4, diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c index 38b61cdb5ca4..52170ed20e74 100644 --- a/drivers/video/fbdev/controlfb.c +++ b/drivers/video/fbdev/controlfb.c @@ -31,7 +31,6 @@ * more details. */ -#include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/string.h> @@ -48,12 +47,37 @@ #include <linux/nvram.h> #include <linux/adb.h> #include <linux/cuda.h> +#ifdef CONFIG_PPC_PMAC #include <asm/prom.h> #include <asm/btext.h> +#endif #include "macmodes.h" #include "controlfb.h" +#ifndef CONFIG_PPC_PMAC +#define invalid_vram_cache(addr) +#undef in_8 +#undef out_8 +#undef in_le32 +#undef out_le32 +#define in_8(addr) 0 +#define out_8(addr, val) +#define in_le32(addr) 0 +#define out_le32(addr, val) +#define pgprot_cached_wthru(prot) (prot) +#else +static void invalid_vram_cache(void __force *addr) +{ + eieio(); + dcbf(addr); + mb(); + eieio(); + dcbf(addr); + mb(); +} +#endif + struct fb_par_control { int vmode, cmode; int xres, yres; @@ -117,38 +141,6 @@ struct fb_info_control { #define CNTRL_REG(INFO,REG) (&(((INFO)->control_regs->REG).r)) -/******************** Prototypes for exported functions ********************/ -/* - * struct fb_ops - */ -static int controlfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info); -static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp, struct fb_info *info); -static int controlfb_blank(int blank_mode, struct fb_info *info); -static int controlfb_mmap(struct fb_info *info, - struct vm_area_struct *vma); -static int controlfb_set_par (struct fb_info *info); -static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info); - -/******************** Prototypes for internal functions **********************/ - -static void set_control_clock(unsigned char *params); -static int init_control(struct fb_info_control *p); -static void control_set_hardware(struct fb_info_control *p, - struct fb_par_control *par); -static int control_of_init(struct device_node *dp); -static void find_vram_size(struct fb_info_control *p); -static int read_control_sense(struct fb_info_control *p); -static int calc_clock_params(unsigned long clk, unsigned char *param); -static int control_var_to_par(struct fb_var_screeninfo *var, - struct fb_par_control *par, const struct fb_info *fb_info); -static inline void control_par_to_var(struct fb_par_control *par, - struct fb_var_screeninfo *var); -static void control_init_info(struct fb_info *info, struct fb_info_control *p); -static void control_cleanup(void); - - /************************** Internal variables *******************************/ static struct fb_info_control *control_fb; @@ -157,189 +149,6 @@ static int default_vmode __initdata = VMODE_NVRAM; static int default_cmode __initdata = CMODE_NVRAM; -static const struct fb_ops controlfb_ops = { - .owner = THIS_MODULE, - .fb_check_var = controlfb_check_var, - .fb_set_par = controlfb_set_par, - .fb_setcolreg = controlfb_setcolreg, - .fb_pan_display = controlfb_pan_display, - .fb_blank = controlfb_blank, - .fb_mmap = controlfb_mmap, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -}; - - -/******************** The functions for controlfb_ops ********************/ - -#ifdef MODULE -MODULE_LICENSE("GPL"); - -int init_module(void) -{ - struct device_node *dp; - int ret = -ENXIO; - - dp = of_find_node_by_name(NULL, "control"); - if (dp && !control_of_init(dp)) - ret = 0; - of_node_put(dp); - - return ret; -} - -void cleanup_module(void) -{ - control_cleanup(); -} -#endif - -/* - * Checks a var structure - */ -static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct fb_par_control par; - int err; - - err = control_var_to_par(var, &par, info); - if (err) - return err; - control_par_to_var(&par, var); - - return 0; -} - -/* - * Applies current var to display - */ -static int controlfb_set_par (struct fb_info *info) -{ - struct fb_info_control *p = - container_of(info, struct fb_info_control, info); - struct fb_par_control par; - int err; - - if((err = control_var_to_par(&info->var, &par, info))) { - printk (KERN_ERR "controlfb_set_par: error calling" - " control_var_to_par: %d.\n", err); - return err; - } - - control_set_hardware(p, &par); - - info->fix.visual = (p->par.cmode == CMODE_8) ? - FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; - info->fix.line_length = p->par.pitch; - info->fix.xpanstep = 32 >> p->par.cmode; - info->fix.ypanstep = 1; - - return 0; -} - -/* - * Set screen start address according to var offset values - */ -static inline void set_screen_start(int xoffset, int yoffset, - struct fb_info_control *p) -{ - struct fb_par_control *par = &p->par; - - par->xoffset = xoffset; - par->yoffset = yoffset; - out_le32(CNTRL_REG(p,start_addr), - par->yoffset * par->pitch + (par->xoffset << par->cmode)); -} - - -static int controlfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - unsigned int xoffset, hstep; - struct fb_info_control *p = - container_of(info, struct fb_info_control, info); - struct fb_par_control *par = &p->par; - - /* - * make sure start addr will be 32-byte aligned - */ - hstep = 0x1f >> par->cmode; - xoffset = (var->xoffset + hstep) & ~hstep; - - if (xoffset+par->xres > par->vxres || - var->yoffset+par->yres > par->vyres) - return -EINVAL; - - set_screen_start(xoffset, var->yoffset, p); - - return 0; -} - - -/* - * Private mmap since we want to have a different caching on the framebuffer - * for controlfb. - * Note there's no locking in here; it's done in fb_mmap() in fbmem.c. - */ -static int controlfb_mmap(struct fb_info *info, - struct vm_area_struct *vma) -{ - unsigned long mmio_pgoff; - unsigned long start; - u32 len; - - start = info->fix.smem_start; - len = info->fix.smem_len; - mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; - if (vma->vm_pgoff >= mmio_pgoff) { - if (info->var.accel_flags) - return -EINVAL; - vma->vm_pgoff -= mmio_pgoff; - start = info->fix.mmio_start; - len = info->fix.mmio_len; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - } else { - /* framebuffer */ - vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot); - } - - return vm_iomap_memory(vma, start, len); -} - -static int controlfb_blank(int blank_mode, struct fb_info *info) -{ - struct fb_info_control *p = - container_of(info, struct fb_info_control, info); - unsigned ctrl; - - ctrl = le32_to_cpup(CNTRL_REG(p,ctrl)); - if (blank_mode > 0) - switch (blank_mode) { - case FB_BLANK_VSYNC_SUSPEND: - ctrl &= ~3; - break; - case FB_BLANK_HSYNC_SUSPEND: - ctrl &= ~0x30; - break; - case FB_BLANK_POWERDOWN: - ctrl &= ~0x33; - /* fall through */ - case FB_BLANK_NORMAL: - ctrl |= 0x400; - break; - default: - break; - } - else { - ctrl &= ~0x400; - ctrl |= 0x33; - } - out_le32(CNTRL_REG(p,ctrl), ctrl); - - return 0; -} - static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { @@ -396,75 +205,18 @@ static void set_control_clock(unsigned char *params) #endif } - /* - * finish off the driver initialization and register + * Set screen start address according to var offset values */ -static int __init init_control(struct fb_info_control *p) +static inline void set_screen_start(int xoffset, int yoffset, + struct fb_info_control *p) { - int full, sense, vmode, cmode, vyres; - struct fb_var_screeninfo var; - int rc; - - printk(KERN_INFO "controlfb: "); - - full = p->total_vram == 0x400000; - - /* Try to pick a video mode out of NVRAM if we have one. */ - cmode = default_cmode; - if (IS_REACHABLE(CONFIG_NVRAM) && cmode == CMODE_NVRAM) - cmode = nvram_read_byte(NV_CMODE); - if (cmode < CMODE_8 || cmode > CMODE_32) - cmode = CMODE_8; - - vmode = default_vmode; - if (IS_REACHABLE(CONFIG_NVRAM) && vmode == VMODE_NVRAM) - vmode = nvram_read_byte(NV_VMODE); - if (vmode < 1 || vmode > VMODE_MAX || - control_mac_modes[vmode - 1].m[full] < cmode) { - sense = read_control_sense(p); - printk(KERN_CONT "Monitor sense value = 0x%x, ", sense); - vmode = mac_map_monitor_sense(sense); - if (control_mac_modes[vmode - 1].m[full] < 0) - vmode = VMODE_640_480_60; - cmode = min(cmode, control_mac_modes[vmode - 1].m[full]); - } - - /* Initialize info structure */ - control_init_info(&p->info, p); - - /* Setup default var */ - if (mac_vmode_to_var(vmode, cmode, &var) < 0) { - /* This shouldn't happen! */ - printk("mac_vmode_to_var(%d, %d,) failed\n", vmode, cmode); -try_again: - vmode = VMODE_640_480_60; - cmode = CMODE_8; - if (mac_vmode_to_var(vmode, cmode, &var) < 0) { - printk(KERN_ERR "controlfb: mac_vmode_to_var() failed\n"); - return -ENXIO; - } - printk(KERN_INFO "controlfb: "); - } - printk("using video mode %d and color mode %d.\n", vmode, cmode); - - vyres = (p->total_vram - CTRLFB_OFF) / (var.xres << cmode); - if (vyres > var.yres) - var.yres_virtual = vyres; - - /* Apply default var */ - var.activate = FB_ACTIVATE_NOW; - rc = fb_set_var(&p->info, &var); - if (rc && (vmode != VMODE_640_480_60 || cmode != CMODE_8)) - goto try_again; - - /* Register with fbdev layer */ - if (register_framebuffer(&p->info) < 0) - return -ENXIO; - - fb_info(&p->info, "control display adapter\n"); + struct fb_par_control *par = &p->par; - return 0; + par->xoffset = xoffset; + par->yoffset = yoffset; + out_le32(CNTRL_REG(p,start_addr), + par->yoffset * par->pitch + (par->xoffset << par->cmode)); } #define RADACAL_WRITE(a,d) \ @@ -528,67 +280,6 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro #endif /* CONFIG_BOOTX_TEXT */ } - -/* - * Parse user specified options (`video=controlfb:') - */ -static void __init control_setup(char *options) -{ - char *this_opt; - - if (!options || !*options) - return; - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!strncmp(this_opt, "vmode:", 6)) { - int vmode = simple_strtoul(this_opt+6, NULL, 0); - if (vmode > 0 && vmode <= VMODE_MAX && - control_mac_modes[vmode - 1].m[1] >= 0) - default_vmode = vmode; - } else if (!strncmp(this_opt, "cmode:", 6)) { - int depth = simple_strtoul(this_opt+6, NULL, 0); - switch (depth) { - case CMODE_8: - case CMODE_16: - case CMODE_32: - default_cmode = depth; - break; - case 8: - default_cmode = CMODE_8; - break; - case 15: - case 16: - default_cmode = CMODE_16; - break; - case 24: - case 32: - default_cmode = CMODE_32; - break; - } - } - } -} - -static int __init control_init(void) -{ - struct device_node *dp; - char *option = NULL; - int ret = -ENXIO; - - if (fb_get_options("controlfb", &option)) - return -ENODEV; - control_setup(option); - - dp = of_find_node_by_name(NULL, "control"); - if (dp && !control_of_init(dp)) - ret = 0; - of_node_put(dp); - - return ret; -} - -module_init(control_init); - /* Work out which banks of VRAM we have installed. */ /* danj: I guess the card just ignores writes to nonexistant VRAM... */ @@ -605,12 +296,7 @@ static void __init find_vram_size(struct fb_info_control *p) out_8(&p->frame_buffer[0x600000], 0xb3); out_8(&p->frame_buffer[0x600001], 0x71); - asm volatile("eieio; dcbf 0,%0" : : "r" (&p->frame_buffer[0x600000]) - : "memory" ); - mb(); - asm volatile("eieio; dcbi 0,%0" : : "r" (&p->frame_buffer[0x600000]) - : "memory" ); - mb(); + invalid_vram_cache(&p->frame_buffer[0x600000]); bank2 = (in_8(&p->frame_buffer[0x600000]) == 0xb3) && (in_8(&p->frame_buffer[0x600001]) == 0x71); @@ -624,12 +310,7 @@ static void __init find_vram_size(struct fb_info_control *p) out_8(&p->frame_buffer[0], 0x5a); out_8(&p->frame_buffer[1], 0xc7); - asm volatile("eieio; dcbf 0,%0" : : "r" (&p->frame_buffer[0]) - : "memory" ); - mb(); - asm volatile("eieio; dcbi 0,%0" : : "r" (&p->frame_buffer[0]) - : "memory" ); - mb(); + invalid_vram_cache(&p->frame_buffer[0]); bank1 = (in_8(&p->frame_buffer[0]) == 0x5a) && (in_8(&p->frame_buffer[1]) == 0xc7); @@ -663,78 +344,6 @@ static void __init find_vram_size(struct fb_info_control *p) (bank1 + bank2) << 1, bank1 << 1, bank2 << 1); } - -/* - * find "control" and initialize - */ -static int __init control_of_init(struct device_node *dp) -{ - struct fb_info_control *p; - struct resource fb_res, reg_res; - - if (control_fb) { - printk(KERN_ERR "controlfb: only one control is supported\n"); - return -ENXIO; - } - - if (of_pci_address_to_resource(dp, 2, &fb_res) || - of_pci_address_to_resource(dp, 1, ®_res)) { - printk(KERN_ERR "can't get 2 addresses for control\n"); - return -ENXIO; - } - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (!p) - return -ENOMEM; - control_fb = p; /* save it for cleanups */ - - /* Map in frame buffer and registers */ - p->fb_orig_base = fb_res.start; - p->fb_orig_size = resource_size(&fb_res); - /* use the big-endian aperture (??) */ - p->frame_buffer_phys = fb_res.start + 0x800000; - p->control_regs_phys = reg_res.start; - p->control_regs_size = resource_size(®_res); - - if (!p->fb_orig_base || - !request_mem_region(p->fb_orig_base,p->fb_orig_size,"controlfb")) { - p->fb_orig_base = 0; - goto error_out; - } - /* map at most 8MB for the frame buffer */ - p->frame_buffer = ioremap_wt(p->frame_buffer_phys, 0x800000); - - if (!p->control_regs_phys || - !request_mem_region(p->control_regs_phys, p->control_regs_size, - "controlfb regs")) { - p->control_regs_phys = 0; - goto error_out; - } - p->control_regs = ioremap(p->control_regs_phys, p->control_regs_size); - - p->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */ - if (!request_mem_region(p->cmap_regs_phys, 0x1000, "controlfb cmap")) { - p->cmap_regs_phys = 0; - goto error_out; - } - p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000); - - if (!p->cmap_regs || !p->control_regs || !p->frame_buffer) - goto error_out; - - find_vram_size(p); - if (!p->total_vram) - goto error_out; - - if (init_control(p) < 0) - goto error_out; - - return 0; - -error_out: - control_cleanup(); - return -ENXIO; -} - /* * Get the monitor sense value. * Note that this can be called before calibrate_delay, @@ -1019,6 +628,150 @@ static void control_par_to_var(struct fb_par_control *par, struct fb_var_screeni var->pixclock >>= par->regvals.clock_params[2]; } +/******************** The functions for controlfb_ops ********************/ + +/* + * Checks a var structure + */ +static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct fb_par_control par; + int err; + + err = control_var_to_par(var, &par, info); + if (err) + return err; + control_par_to_var(&par, var); + + return 0; +} + +/* + * Applies current var to display + */ +static int controlfb_set_par (struct fb_info *info) +{ + struct fb_info_control *p = + container_of(info, struct fb_info_control, info); + struct fb_par_control par; + int err; + + if((err = control_var_to_par(&info->var, &par, info))) { + printk (KERN_ERR "controlfb_set_par: error calling" + " control_var_to_par: %d.\n", err); + return err; + } + + control_set_hardware(p, &par); + + info->fix.visual = (p->par.cmode == CMODE_8) ? + FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; + info->fix.line_length = p->par.pitch; + info->fix.xpanstep = 32 >> p->par.cmode; + info->fix.ypanstep = 1; + + return 0; +} + +static int controlfb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + unsigned int xoffset, hstep; + struct fb_info_control *p = + container_of(info, struct fb_info_control, info); + struct fb_par_control *par = &p->par; + + /* + * make sure start addr will be 32-byte aligned + */ + hstep = 0x1f >> par->cmode; + xoffset = (var->xoffset + hstep) & ~hstep; + + if (xoffset+par->xres > par->vxres || + var->yoffset+par->yres > par->vyres) + return -EINVAL; + + set_screen_start(xoffset, var->yoffset, p); + + return 0; +} + +static int controlfb_blank(int blank_mode, struct fb_info *info) +{ + struct fb_info_control __maybe_unused *p = + container_of(info, struct fb_info_control, info); + unsigned ctrl; + + ctrl = in_le32(CNTRL_REG(p, ctrl)); + if (blank_mode > 0) + switch (blank_mode) { + case FB_BLANK_VSYNC_SUSPEND: + ctrl &= ~3; + break; + case FB_BLANK_HSYNC_SUSPEND: + ctrl &= ~0x30; + break; + case FB_BLANK_POWERDOWN: + ctrl &= ~0x33; + /* fall through */ + case FB_BLANK_NORMAL: + ctrl |= 0x400; + break; + default: + break; + } + else { + ctrl &= ~0x400; + ctrl |= 0x33; + } + out_le32(CNTRL_REG(p,ctrl), ctrl); + + return 0; +} + +/* + * Private mmap since we want to have a different caching on the framebuffer + * for controlfb. + * Note there's no locking in here; it's done in fb_mmap() in fbmem.c. + */ +static int controlfb_mmap(struct fb_info *info, + struct vm_area_struct *vma) +{ + unsigned long mmio_pgoff; + unsigned long start; + u32 len; + + start = info->fix.smem_start; + len = info->fix.smem_len; + mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; + if (vma->vm_pgoff >= mmio_pgoff) { + if (info->var.accel_flags) + return -EINVAL; + vma->vm_pgoff -= mmio_pgoff; + start = info->fix.mmio_start; + len = info->fix.mmio_len; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + } else { + /* framebuffer */ + vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot); + } + + return vm_iomap_memory(vma, start, len); +} + +static const struct fb_ops controlfb_ops = { + .owner = THIS_MODULE, + .fb_check_var = controlfb_check_var, + .fb_set_par = controlfb_set_par, + .fb_setcolreg = controlfb_setcolreg, + .fb_pan_display = controlfb_pan_display, + .fb_blank = controlfb_blank, + .fb_mmap = controlfb_mmap, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + /* * Set misc info vars for this driver */ @@ -1045,6 +798,115 @@ static void __init control_init_info(struct fb_info *info, struct fb_info_contro info->fix.accel = FB_ACCEL_NONE; } +/* + * Parse user specified options (`video=controlfb:') + */ +static void __init control_setup(char *options) +{ + char *this_opt; + + if (!options || !*options) + return; + + while ((this_opt = strsep(&options, ",")) != NULL) { + if (!strncmp(this_opt, "vmode:", 6)) { + int vmode = simple_strtoul(this_opt+6, NULL, 0); + if (vmode > 0 && vmode <= VMODE_MAX && + control_mac_modes[vmode - 1].m[1] >= 0) + default_vmode = vmode; + } else if (!strncmp(this_opt, "cmode:", 6)) { + int depth = simple_strtoul(this_opt+6, NULL, 0); + switch (depth) { + case CMODE_8: + case CMODE_16: + case CMODE_32: + default_cmode = depth; + break; + case 8: + default_cmode = CMODE_8; + break; + case 15: + case 16: + default_cmode = CMODE_16; + break; + case 24: + case 32: + default_cmode = CMODE_32; + break; + } + } + } +} + +/* + * finish off the driver initialization and register + */ +static int __init init_control(struct fb_info_control *p) +{ + int full, sense, vmode, cmode, vyres; + struct fb_var_screeninfo var; + int rc; + + printk(KERN_INFO "controlfb: "); + + full = p->total_vram == 0x400000; + + /* Try to pick a video mode out of NVRAM if we have one. */ + cmode = default_cmode; + if (IS_REACHABLE(CONFIG_NVRAM) && cmode == CMODE_NVRAM) + cmode = nvram_read_byte(NV_CMODE); + if (cmode < CMODE_8 || cmode > CMODE_32) + cmode = CMODE_8; + + vmode = default_vmode; + if (IS_REACHABLE(CONFIG_NVRAM) && vmode == VMODE_NVRAM) + vmode = nvram_read_byte(NV_VMODE); + if (vmode < 1 || vmode > VMODE_MAX || + control_mac_modes[vmode - 1].m[full] < cmode) { + sense = read_control_sense(p); + printk(KERN_CONT "Monitor sense value = 0x%x, ", sense); + vmode = mac_map_monitor_sense(sense); + if (control_mac_modes[vmode - 1].m[full] < 0) + vmode = VMODE_640_480_60; + cmode = min(cmode, control_mac_modes[vmode - 1].m[full]); + } + + /* Initialize info structure */ + control_init_info(&p->info, p); + + /* Setup default var */ + if (mac_vmode_to_var(vmode, cmode, &var) < 0) { + /* This shouldn't happen! */ + printk("mac_vmode_to_var(%d, %d,) failed\n", vmode, cmode); +try_again: + vmode = VMODE_640_480_60; + cmode = CMODE_8; + if (mac_vmode_to_var(vmode, cmode, &var) < 0) { + printk(KERN_ERR "controlfb: mac_vmode_to_var() failed\n"); + return -ENXIO; + } + printk(KERN_INFO "controlfb: "); + } + printk("using video mode %d and color mode %d.\n", vmode, cmode); + + vyres = (p->total_vram - CTRLFB_OFF) / (var.xres << cmode); + if (vyres > var.yres) + var.yres_virtual = vyres; + + /* Apply default var */ + var.activate = FB_ACTIVATE_NOW; + rc = fb_set_var(&p->info, &var); + if (rc && (vmode != VMODE_640_480_60 || cmode != CMODE_8)) + goto try_again; + + /* Register with fbdev layer */ + if (register_framebuffer(&p->info) < 0) + return -ENXIO; + + fb_info(&p->info, "control display adapter\n"); + + return 0; +} static void control_cleanup(void) { @@ -1071,4 +933,93 @@ static void control_cleanup(void) kfree(p); } +/* + * find "control" and initialize + */ +static int __init control_of_init(struct device_node *dp) +{ + struct fb_info_control *p; + struct resource fb_res, reg_res; + + if (control_fb) { + printk(KERN_ERR "controlfb: only one control is supported\n"); + return -ENXIO; + } + + if (of_pci_address_to_resource(dp, 2, &fb_res) || + of_pci_address_to_resource(dp, 1, ®_res)) { + printk(KERN_ERR "can't get 2 addresses for control\n"); + return -ENXIO; + } + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + control_fb = p; /* save it for cleanups */ + + /* Map in frame buffer and registers */ + p->fb_orig_base = fb_res.start; + p->fb_orig_size = resource_size(&fb_res); + /* use the big-endian aperture (??) */ + p->frame_buffer_phys = fb_res.start + 0x800000; + p->control_regs_phys = reg_res.start; + p->control_regs_size = resource_size(®_res); + + if (!p->fb_orig_base || + !request_mem_region(p->fb_orig_base,p->fb_orig_size,"controlfb")) { + p->fb_orig_base = 0; + goto error_out; + } + /* map at most 8MB for the frame buffer */ + p->frame_buffer = ioremap_wt(p->frame_buffer_phys, 0x800000); + + if (!p->control_regs_phys || + !request_mem_region(p->control_regs_phys, p->control_regs_size, + "controlfb regs")) { + p->control_regs_phys = 0; + goto error_out; + } + p->control_regs = ioremap(p->control_regs_phys, p->control_regs_size); + + p->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */ + if (!request_mem_region(p->cmap_regs_phys, 0x1000, "controlfb cmap")) { + p->cmap_regs_phys = 0; + goto error_out; + } + p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000); + + if (!p->cmap_regs || !p->control_regs || !p->frame_buffer) + goto error_out; + + find_vram_size(p); + if (!p->total_vram) + goto error_out; + + if (init_control(p) < 0) + goto error_out; + + return 0; + +error_out: + control_cleanup(); + return -ENXIO; +} + +static int __init control_init(void) +{ + struct device_node *dp; + char *option = NULL; + int ret = -ENXIO; + + if (fb_get_options("controlfb", &option)) + return -ENODEV; + control_setup(option); + + dp = of_find_node_by_name(NULL, "control"); + if (dp && !control_of_init(dp)) + ret = 0; + of_node_put(dp); + + return ret; +} +device_initcall(control_init); diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index 370bf2553d43..884b16efa7e8 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -172,6 +172,7 @@ struct imxfb_info { int num_modes; struct regulator *lcd_pwr; + int lcd_pwr_enabled; }; static const struct platform_device_id imxfb_devtype[] = { @@ -801,16 +802,30 @@ static int imxfb_lcd_get_power(struct lcd_device *lcddev) return FB_BLANK_UNBLANK; } +static int imxfb_regulator_set(struct imxfb_info *fbi, int enable) +{ + int ret; + + if (enable == fbi->lcd_pwr_enabled) + return 0; + + if (enable) + ret = regulator_enable(fbi->lcd_pwr); + else + ret = regulator_disable(fbi->lcd_pwr); + + if (ret == 0) + fbi->lcd_pwr_enabled = enable; + + return ret; +} + static int imxfb_lcd_set_power(struct lcd_device *lcddev, int power) { struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev); - if (!IS_ERR(fbi->lcd_pwr)) { - if (power == FB_BLANK_UNBLANK) - return regulator_enable(fbi->lcd_pwr); - else - return regulator_disable(fbi->lcd_pwr); - } + if (!IS_ERR(fbi->lcd_pwr)) + return imxfb_regulator_set(fbi, power == FB_BLANK_UNBLANK); return 0; } diff --git a/drivers/video/fbdev/omap2/omapfb/dss/venc.c b/drivers/video/fbdev/omap2/omapfb/dss/venc.c index f81e2a46366d..d5404d56c922 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/venc.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/venc.c @@ -209,49 +209,6 @@ static const struct venc_config venc_config_ntsc_trm = { .gen_ctrl = 0x00F90000, }; -static const struct venc_config venc_config_pal_bdghi = { - .f_control = 0, - .vidout_ctrl = 0, - .sync_ctrl = 0, - .hfltr_ctrl = 0, - .x_color = 0, - .line21 = 0, - .ln_sel = 21, - .htrigger_vtrigger = 0, - .tvdetgp_int_start_stop_x = 0x00140001, - .tvdetgp_int_start_stop_y = 0x00010001, - .gen_ctrl = 0x00FB0000, - - .llen = 864-1, - .flens = 625-1, - .cc_carr_wss_carr = 0x2F7625ED, - .c_phase = 0xDF, - .gain_u = 0x111, - .gain_v = 0x181, - .gain_y = 0x140, - .black_level = 0x3e, - .blank_level = 0x3e, - .m_control = 0<<2 | 1<<1, - .bstamp_wss_data = 0x42, - .s_carr = 0x2a098acb, - .l21__wc_ctl = 0<<13 | 0x16<<8 | 0<<0, - .savid__eavid = 0x06A70108, - .flen__fal = 23<<16 | 624<<0, - .lal__phase_reset = 2<<17 | 310<<0, - .hs_int_start_stop_x = 0x00920358, - .hs_ext_start_stop_x = 0x000F035F, - .vs_int_start_x = 0x1a7<<16, - .vs_int_stop_x__vs_int_start_y = 0x000601A7, - .vs_int_stop_y__vs_ext_start_x = 0x01AF0036, - .vs_ext_stop_x__vs_ext_start_y = 0x27101af, - .vs_ext_stop_y = 0x05, - .avid_start_stop_x = 0x03530082, - .avid_start_stop_y = 0x0270002E, - .fid_int_start_x__fid_int_start_y = 0x0005008A, - .fid_int_offset_y__fid_ext_start_x = 0x002E0138, - .fid_ext_start_y__fid_ext_offset_y = 0x01380005, -}; - const struct omap_video_timings omap_dss_pal_timings = { .x_res = 720, .y_res = 574, diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c index eaea8c373753..4541afcf9386 100644 --- a/drivers/video/fbdev/s1d13xxxfb.c +++ b/drivers/video/fbdev/s1d13xxxfb.c @@ -721,9 +721,7 @@ static void s1d13xxxfb_fetch_hw_state(struct fb_info *info) xres, yres, xres_virtual, yres_virtual, is_color, is_dual, is_tft); } - -static int -s1d13xxxfb_remove(struct platform_device *pdev) +static void __s1d13xxxfb_remove(struct platform_device *pdev) { struct fb_info *info = platform_get_drvdata(pdev); struct s1d13xxxfb_par *par = NULL; @@ -749,6 +747,14 @@ s1d13xxxfb_remove(struct platform_device *pdev) resource_size(&pdev->resource[0])); release_mem_region(pdev->resource[1].start, resource_size(&pdev->resource[1])); +} + +static int s1d13xxxfb_remove(struct platform_device *pdev) +{ + struct fb_info *info = platform_get_drvdata(pdev); + + unregister_framebuffer(info); + __s1d13xxxfb_remove(pdev); return 0; } @@ -895,7 +901,7 @@ static int s1d13xxxfb_probe(struct platform_device *pdev) return 0; bail: - s1d13xxxfb_remove(pdev); + __s1d13xxxfb_remove(pdev); return ret; } diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index 2d285cc384cf..3e6e13f7a831 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -173,7 +173,7 @@ #include <linux/init.h> #include <linux/ioport.h> #include <linux/cpufreq.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/mutex.h> @@ -799,8 +799,8 @@ static void sa1100fb_enable_controller(struct sa1100fb_info *fbi) writel_relaxed(fbi->dbar2, fbi->base + DBAR2); writel_relaxed(fbi->reg_lccr0 | LCCR0_LEN, fbi->base + LCCR0); - if (machine_is_shannon()) - gpio_set_value(SHANNON_GPIO_DISP_EN, 1); + if (fbi->shannon_lcden) + gpiod_set_value(fbi->shannon_lcden, 1); dev_dbg(fbi->dev, "DBAR1: 0x%08x\n", readl_relaxed(fbi->base + DBAR1)); dev_dbg(fbi->dev, "DBAR2: 0x%08x\n", readl_relaxed(fbi->base + DBAR2)); @@ -817,8 +817,8 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) dev_dbg(fbi->dev, "Disabling LCD controller\n"); - if (machine_is_shannon()) - gpio_set_value(SHANNON_GPIO_DISP_EN, 0); + if (fbi->shannon_lcden) + gpiod_set_value(fbi->shannon_lcden, 0); set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&fbi->ctrlr_wait, &wait); @@ -1173,12 +1173,10 @@ static int sa1100fb_probe(struct platform_device *pdev) return ret; } - if (machine_is_shannon()) { - ret = devm_gpio_request_one(&pdev->dev, SHANNON_GPIO_DISP_EN, - GPIOF_OUT_INIT_LOW, "display enable"); - if (ret) - return ret; - } + fbi->shannon_lcden = gpiod_get_optional(&pdev->dev, "shannon-lcden", + GPIOD_OUT_LOW); + if (IS_ERR(fbi->shannon_lcden)) + return PTR_ERR(fbi->shannon_lcden); /* Initialize video memory */ ret = sa1100fb_map_video_memory(fbi); diff --git a/drivers/video/fbdev/sa1100fb.h b/drivers/video/fbdev/sa1100fb.h index d0aa33b0b88a..b4363444fa5d 100644 --- a/drivers/video/fbdev/sa1100fb.h +++ b/drivers/video/fbdev/sa1100fb.h @@ -10,6 +10,8 @@ * for more details. */ +struct gpio_desc; + #define LCCR0 0x0000 /* LCD Control Reg. 0 */ #define LCSR 0x0004 /* LCD Status Reg. */ #define DBAR1 0x0010 /* LCD DMA Base Address Reg. channel 1 */ @@ -33,6 +35,7 @@ struct sa1100fb_info { struct device *dev; const struct sa1100fb_rgb *rgb[NR_RGB]; void __iomem *base; + struct gpio_desc *shannon_lcden; /* * These are the addresses we mapped diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 12fa1050f3eb..8e06ba912d60 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -12,8 +12,7 @@ #include <linux/i2c.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_gpio.h> +#include <linux/property.h> #include <linux/pwm.h> #include <linux/uaccess.h> #include <linux/regulator/consumer.h> @@ -49,8 +48,6 @@ static u_int refreshrate = REFRESHRATE; module_param(refreshrate, uint, 0); -struct ssd1307fb_par; - struct ssd1307fb_deviceinfo { u32 default_vcomh; u32 default_dclk_div; @@ -80,7 +77,6 @@ struct ssd1307fb_par { u32 prechargep1; u32 prechargep2; struct pwm_device *pwm; - u32 pwm_period; struct gpio_desc *reset; struct regulator *vbat_reg; u32 vcomh; @@ -298,9 +294,9 @@ static void ssd1307fb_deferred_io(struct fb_info *info, static int ssd1307fb_init(struct ssd1307fb_par *par) { + struct pwm_state pwmstate; int ret; u32 precharge, dclk, com_invdir, compins; - struct pwm_args pargs; if (par->device_info->need_pwm) { par->pwm = pwm_get(&par->client->dev, NULL); @@ -309,21 +305,15 @@ static int ssd1307fb_init(struct ssd1307fb_par *par) return PTR_ERR(par->pwm); } - /* - * FIXME: pwm_apply_args() should be removed when switching to - * the atomic PWM API. - */ - pwm_apply_args(par->pwm); - - pwm_get_args(par->pwm, &pargs); + pwm_init_state(par->pwm, &pwmstate); + pwm_set_relative_duty_cycle(&pwmstate, 50, 100); + pwm_apply_state(par->pwm, &pwmstate); - par->pwm_period = pargs.period; /* Enable the PWM */ - pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period); pwm_enable(par->pwm); dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n", - par->pwm->pwm, par->pwm_period); + par->pwm->pwm, pwm_get_period(par->pwm)); } /* Set initial contrast */ @@ -586,25 +576,19 @@ static const struct of_device_id ssd1307fb_of_match[] = { }; MODULE_DEVICE_TABLE(of, ssd1307fb_of_match); -static int ssd1307fb_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ssd1307fb_probe(struct i2c_client *client) { + struct device *dev = &client->dev; struct backlight_device *bl; char bl_name[12]; struct fb_info *info; - struct device_node *node = client->dev.of_node; struct fb_deferred_io *ssd1307fb_defio; u32 vmem_size; struct ssd1307fb_par *par; void *vmem; int ret; - if (!node) { - dev_err(&client->dev, "No device tree data found!\n"); - return -EINVAL; - } - - info = framebuffer_alloc(sizeof(struct ssd1307fb_par), &client->dev); + info = framebuffer_alloc(sizeof(struct ssd1307fb_par), dev); if (!info) return -ENOMEM; @@ -612,67 +596,65 @@ static int ssd1307fb_probe(struct i2c_client *client, par->info = info; par->client = client; - par->device_info = of_device_get_match_data(&client->dev); + par->device_info = device_get_match_data(dev); - par->reset = devm_gpiod_get_optional(&client->dev, "reset", - GPIOD_OUT_LOW); + par->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(par->reset)) { - dev_err(&client->dev, "failed to get reset gpio: %ld\n", + dev_err(dev, "failed to get reset gpio: %ld\n", PTR_ERR(par->reset)); ret = PTR_ERR(par->reset); goto fb_alloc_error; } - par->vbat_reg = devm_regulator_get_optional(&client->dev, "vbat"); + par->vbat_reg = devm_regulator_get_optional(dev, "vbat"); if (IS_ERR(par->vbat_reg)) { ret = PTR_ERR(par->vbat_reg); if (ret == -ENODEV) { par->vbat_reg = NULL; } else { - dev_err(&client->dev, "failed to get VBAT regulator: %d\n", - ret); + dev_err(dev, "failed to get VBAT regulator: %d\n", ret); goto fb_alloc_error; } } - if (of_property_read_u32(node, "solomon,width", &par->width)) + if (device_property_read_u32(dev, "solomon,width", &par->width)) par->width = 96; - if (of_property_read_u32(node, "solomon,height", &par->height)) + if (device_property_read_u32(dev, "solomon,height", &par->height)) par->height = 16; - if (of_property_read_u32(node, "solomon,page-offset", &par->page_offset)) + if (device_property_read_u32(dev, "solomon,page-offset", &par->page_offset)) par->page_offset = 1; - if (of_property_read_u32(node, "solomon,com-offset", &par->com_offset)) + if (device_property_read_u32(dev, "solomon,com-offset", &par->com_offset)) par->com_offset = 0; - if (of_property_read_u32(node, "solomon,prechargep1", &par->prechargep1)) + if (device_property_read_u32(dev, "solomon,prechargep1", &par->prechargep1)) par->prechargep1 = 2; - if (of_property_read_u32(node, "solomon,prechargep2", &par->prechargep2)) + if (device_property_read_u32(dev, "solomon,prechargep2", &par->prechargep2)) par->prechargep2 = 2; - if (!of_property_read_u8_array(node, "solomon,lookup-table", - par->lookup_table, - ARRAY_SIZE(par->lookup_table))) + if (!device_property_read_u8_array(dev, "solomon,lookup-table", + par->lookup_table, + ARRAY_SIZE(par->lookup_table))) par->lookup_table_set = 1; - par->seg_remap = !of_property_read_bool(node, "solomon,segment-no-remap"); - par->com_seq = of_property_read_bool(node, "solomon,com-seq"); - par->com_lrremap = of_property_read_bool(node, "solomon,com-lrremap"); - par->com_invdir = of_property_read_bool(node, "solomon,com-invdir"); + par->seg_remap = !device_property_read_bool(dev, "solomon,segment-no-remap"); + par->com_seq = device_property_read_bool(dev, "solomon,com-seq"); + par->com_lrremap = device_property_read_bool(dev, "solomon,com-lrremap"); + par->com_invdir = device_property_read_bool(dev, "solomon,com-invdir"); par->area_color_enable = - of_property_read_bool(node, "solomon,area-color-enable"); - par->low_power = of_property_read_bool(node, "solomon,low-power"); + device_property_read_bool(dev, "solomon,area-color-enable"); + par->low_power = device_property_read_bool(dev, "solomon,low-power"); par->contrast = 127; par->vcomh = par->device_info->default_vcomh; /* Setup display timing */ - if (of_property_read_u32(node, "solomon,dclk-div", &par->dclk_div)) + if (device_property_read_u32(dev, "solomon,dclk-div", &par->dclk_div)) par->dclk_div = par->device_info->default_dclk_div; - if (of_property_read_u32(node, "solomon,dclk-frq", &par->dclk_frq)) + if (device_property_read_u32(dev, "solomon,dclk-frq", &par->dclk_frq)) par->dclk_frq = par->device_info->default_dclk_frq; vmem_size = DIV_ROUND_UP(par->width, 8) * par->height; @@ -680,15 +662,15 @@ static int ssd1307fb_probe(struct i2c_client *client, vmem = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(vmem_size)); if (!vmem) { - dev_err(&client->dev, "Couldn't allocate graphical memory.\n"); + dev_err(dev, "Couldn't allocate graphical memory.\n"); ret = -ENOMEM; goto fb_alloc_error; } - ssd1307fb_defio = devm_kzalloc(&client->dev, sizeof(*ssd1307fb_defio), + ssd1307fb_defio = devm_kzalloc(dev, sizeof(*ssd1307fb_defio), GFP_KERNEL); if (!ssd1307fb_defio) { - dev_err(&client->dev, "Couldn't allocate deferred io.\n"); + dev_err(dev, "Couldn't allocate deferred io.\n"); ret = -ENOMEM; goto fb_alloc_error; } @@ -726,8 +708,7 @@ static int ssd1307fb_probe(struct i2c_client *client, if (par->vbat_reg) { ret = regulator_enable(par->vbat_reg); if (ret) { - dev_err(&client->dev, "failed to enable VBAT: %d\n", - ret); + dev_err(dev, "failed to enable VBAT: %d\n", ret); goto reset_oled_error; } } @@ -738,17 +719,16 @@ static int ssd1307fb_probe(struct i2c_client *client, ret = register_framebuffer(info); if (ret) { - dev_err(&client->dev, "Couldn't register the framebuffer\n"); + dev_err(dev, "Couldn't register the framebuffer\n"); goto panel_init_error; } snprintf(bl_name, sizeof(bl_name), "ssd1307fb%d", info->node); - bl = backlight_device_register(bl_name, &client->dev, par, - &ssd1307fb_bl_ops, NULL); + bl = backlight_device_register(bl_name, dev, par, &ssd1307fb_bl_ops, + NULL); if (IS_ERR(bl)) { ret = PTR_ERR(bl); - dev_err(&client->dev, "unable to register backlight device: %d\n", - ret); + dev_err(dev, "unable to register backlight device: %d\n", ret); goto bl_init_error; } @@ -756,7 +736,7 @@ static int ssd1307fb_probe(struct i2c_client *client, bl->props.max_brightness = MAX_CONTRAST; info->bl_dev = bl; - dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size); + dev_info(dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size); return 0; @@ -810,7 +790,7 @@ static const struct i2c_device_id ssd1307fb_i2c_id[] = { MODULE_DEVICE_TABLE(i2c, ssd1307fb_i2c_id); static struct i2c_driver ssd1307fb_driver = { - .probe = ssd1307fb_probe, + .probe_new = ssd1307fb_probe, .remove = ssd1307fb_remove, .id_table = ssd1307fb_i2c_id, .driver = { diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c index a1fe24ea869b..df6de5a9dd4c 100644 --- a/drivers/video/fbdev/vesafb.c +++ b/drivers/video/fbdev/vesafb.c @@ -32,6 +32,7 @@ struct vesafb_par { u32 pseudo_palette[256]; int wc_cookie; + struct resource *region; }; static struct fb_var_screeninfo vesafb_defined = { @@ -411,7 +412,7 @@ static int vesafb_probe(struct platform_device *dev) /* request failure does not faze us, as vgacon probably has this * region already (FIXME) */ - request_region(0x3c0, 32, "vesafb"); + par->region = request_region(0x3c0, 32, "vesafb"); if (mtrr == 3) { unsigned int temp_size = size_total; @@ -439,7 +440,7 @@ static int vesafb_probe(struct platform_device *dev) "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n", vesafb_fix.smem_len, vesafb_fix.smem_start); err = -EIO; - goto err; + goto err_release_region; } printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, " @@ -458,19 +459,22 @@ static int vesafb_probe(struct platform_device *dev) if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { err = -ENOMEM; - goto err; + goto err_release_region; } if (register_framebuffer(info)<0) { err = -EINVAL; fb_dealloc_cmap(&info->cmap); - goto err; + goto err_release_region; } fb_info(info, "%s frame buffer device\n", info->fix.id); return 0; -err: +err_release_region: arch_phys_wc_del(par->wc_cookie); if (info->screen_base) iounmap(info->screen_base); + if (par->region) + release_region(0x3c0, 32); +err: framebuffer_release(info); release_mem_region(vesafb_fix.smem_start, size_total); return err; @@ -481,6 +485,8 @@ static int vesafb_remove(struct platform_device *pdev) struct fb_info *info = platform_get_drvdata(pdev); unregister_framebuffer(info); + if (((struct vesafb_par *)(info->par))->region) + release_region(0x3c0, 32); framebuffer_release(info); return 0; diff --git a/drivers/video/fbdev/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c index f744479dc7df..c61476247ba8 100644 --- a/drivers/video/fbdev/vt8500lcdfb.c +++ b/drivers/video/fbdev/vt8500lcdfb.c @@ -230,6 +230,7 @@ static int vt8500lcd_blank(int blank, struct fb_info *info) info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) for (i = 0; i < 256; i++) vt8500lcd_setcolreg(i, 0, 0, 0, 0, info); + fallthrough; case FB_BLANK_UNBLANK: if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR || info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) |