diff options
Diffstat (limited to 'drivers/video')
57 files changed, 440 insertions, 6281 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 936ba1e4d35e..4c33e971c0f0 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -90,13 +90,6 @@ config LCD_PLATFORM This driver provides a platform-device registered LCD power control interface. -config LCD_TOSA - tristate "Sharp SL-6000 LCD Driver" - depends on I2C && SPI && MACH_TOSA - help - If you have an Sharp SL-6000 Zaurus say Y to enable a driver - for its LCD. - config LCD_HP700 tristate "HP Jornada 700 series LCD Driver" depends on SA1100_JORNADA720_SSP && !PREEMPTION @@ -190,6 +183,14 @@ config BACKLIGHT_KTD253 which is a 1-wire GPIO-controlled backlight found in some mobile phones. +config BACKLIGHT_KTZ8866 + tristate "Backlight Driver for Kinetic KTZ8866" + depends on I2C + select REGMAP_I2C + help + Say Y to enable the backlight driver for the Kinetic KTZ8866 + found in Xiaomi Mi Pad 5 series. + config BACKLIGHT_LM3533 tristate "Backlight Driver for LM3533" depends on MFD_LM3533 @@ -288,13 +289,6 @@ config BACKLIGHT_APPLE If you have an Intel-based Apple say Y to enable a driver for its backlight. -config BACKLIGHT_TOSA - tristate "Sharp SL-6000 Backlight Driver" - depends on I2C && MACH_TOSA && LCD_TOSA - help - If you have an Sharp SL-6000 Zaurus say Y to enable a driver - for its backlight - config BACKLIGHT_QCOM_WLED tristate "Qualcomm PMIC WLED Driver" select REGMAP diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index e815f3f1deff..f72e1c3c59e9 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o obj-$(CONFIG_LCD_OTM3225A) += otm3225a.o obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o obj-$(CONFIG_LCD_TDO24M) += tdo24m.o -obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o @@ -36,6 +35,7 @@ obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o obj-$(CONFIG_BACKLIGHT_IPAQ_MICRO) += ipaq_micro_bl.o obj-$(CONFIG_BACKLIGHT_KTD253) += ktd253-backlight.o +obj-$(CONFIG_BACKLIGHT_KTZ8866) += ktz8866.o obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o obj-$(CONFIG_BACKLIGHT_LM3630A) += lm3630a_bl.o obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o @@ -53,7 +53,6 @@ obj-$(CONFIG_BACKLIGHT_QCOM_WLED) += qcom-wled.o obj-$(CONFIG_BACKLIGHT_RT4831) += rt4831-backlight.o obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o obj-$(CONFIG_BACKLIGHT_SKY81452) += sky81452-backlight.o -obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o obj-$(CONFIG_BACKLIGHT_ARCXCNN) += arcxcnn_bl.o diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c index a7af9adafad6..1cbb303e9c88 100644 --- a/drivers/video/backlight/aat2870_bl.c +++ b/drivers/video/backlight/aat2870_bl.c @@ -59,7 +59,7 @@ static int aat2870_bl_update_status(struct backlight_device *bd) struct aat2870_bl_driver_data *aat2870_bl = bl_get_data(bd); struct aat2870_data *aat2870 = dev_get_drvdata(aat2870_bl->pdev->dev.parent); - int brightness = bd->props.brightness; + int brightness = backlight_get_brightness(bd); int ret; if ((brightness < 0) || (bd->props.max_brightness < brightness)) { @@ -70,11 +70,6 @@ static int aat2870_bl_update_status(struct backlight_device *bd) dev_dbg(&bd->dev, "brightness=%d, power=%d, state=%d\n", bd->props.brightness, bd->props.power, bd->props.state); - if ((bd->props.power != FB_BLANK_UNBLANK) || - (bd->props.state & BL_CORE_FBBLANK) || - (bd->props.state & BL_CORE_SUSPENDED)) - brightness = 0; - ret = aat2870->write(aat2870, AAT2870_BLM, (u8)aat2870_brightness(aat2870_bl, brightness)); if (ret < 0) diff --git a/drivers/video/backlight/arcxcnn_bl.c b/drivers/video/backlight/arcxcnn_bl.c index 555b036643fb..e610d7a1d13d 100644 --- a/drivers/video/backlight/arcxcnn_bl.c +++ b/drivers/video/backlight/arcxcnn_bl.c @@ -130,12 +130,9 @@ static int arcxcnn_set_brightness(struct arcxcnn *lp, u32 brightness) static int arcxcnn_bl_update_status(struct backlight_device *bl) { struct arcxcnn *lp = bl_get_data(bl); - u32 brightness = bl->props.brightness; + u32 brightness = backlight_get_brightness(bl); int ret; - if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) - brightness = 0; - ret = arcxcnn_set_brightness(lp, brightness); if (ret) return ret; diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index b788ff3d0f45..6eea72aa8dbf 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -501,7 +501,7 @@ EXPORT_SYMBOL(backlight_device_get_by_type); * * This function looks up a backlight device by its name. It obtains a reference * on the backlight device and it is the caller's responsibility to drop the - * reference by calling backlight_put(). + * reference by calling put_device(). * * Returns: * A pointer to the backlight device if found, otherwise NULL. diff --git a/drivers/video/backlight/ipaq_micro_bl.c b/drivers/video/backlight/ipaq_micro_bl.c index 85b16cc82878..f595b8c8cbb2 100644 --- a/drivers/video/backlight/ipaq_micro_bl.c +++ b/drivers/video/backlight/ipaq_micro_bl.c @@ -16,17 +16,12 @@ static int micro_bl_update_status(struct backlight_device *bd) { struct ipaq_micro *micro = dev_get_drvdata(&bd->dev); - int intensity = bd->props.brightness; + int intensity = backlight_get_brightness(bd); struct ipaq_micro_msg msg = { .id = MSG_BACKLIGHT, .tx_len = 3, }; - if (bd->props.power != FB_BLANK_UNBLANK) - intensity = 0; - if (bd->props.state & (BL_CORE_FBBLANK | BL_CORE_SUSPENDED)) - intensity = 0; - /* * Message format: * Byte 0: backlight instance (usually 1) diff --git a/drivers/video/backlight/ktd253-backlight.c b/drivers/video/backlight/ktd253-backlight.c index 37aa5a669530..d7d43454f64a 100644 --- a/drivers/video/backlight/ktd253-backlight.c +++ b/drivers/video/backlight/ktd253-backlight.c @@ -173,12 +173,9 @@ static int ktd253_backlight_probe(struct platform_device *pdev) } ktd253->gpiod = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(ktd253->gpiod)) { - ret = PTR_ERR(ktd253->gpiod); - if (ret != -EPROBE_DEFER) - dev_err(dev, "gpio line missing or invalid.\n"); - return ret; - } + if (IS_ERR(ktd253->gpiod)) + return dev_err_probe(dev, PTR_ERR(ktd253->gpiod), + "gpio line missing or invalid.\n"); gpiod_set_consumer_name(ktd253->gpiod, dev_name(dev)); /* Bring backlight to a known off state */ msleep(KTD253_T_OFF_MS); diff --git a/drivers/video/backlight/ktz8866.c b/drivers/video/backlight/ktz8866.c new file mode 100644 index 000000000000..d38c13ad39c7 --- /dev/null +++ b/drivers/video/backlight/ktz8866.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Backlight driver for the Kinetic KTZ8866 + * + * Copyright (C) 2022, 2023 Jianhua Lu <lujianhua000@gmail.com> + */ + +#include <linux/backlight.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regmap.h> + +#define DEFAULT_BRIGHTNESS 1500 +#define MAX_BRIGHTNESS 2047 +#define REG_MAX 0x15 + +/* reg */ +#define DEVICE_ID 0x01 +#define BL_CFG1 0x02 +#define BL_CFG2 0x03 +#define BL_BRT_LSB 0x04 +#define BL_BRT_MSB 0x05 +#define BL_EN 0x08 +#define LCD_BIAS_CFG1 0x09 +#define LCD_BIAS_CFG2 0x0A +#define LCD_BIAS_CFG3 0x0B +#define LCD_BOOST_CFG 0x0C +#define OUTP_CFG 0x0D +#define OUTN_CFG 0x0E +#define FLAG 0x0F +#define BL_OPTION1 0x10 +#define BL_OPTION2 0x11 +#define PWM2DIG_LSBs 0x12 +#define PWM2DIG_MSBs 0x13 +#define BL_DIMMING 0x14 +#define PWM_RAMP_TIME 0x15 + +/* definition */ +#define BL_EN_BIT BIT(6) +#define LCD_BIAS_EN 0x9F +#define PWM_HYST 0x5 + +struct ktz8866 { + struct i2c_client *client; + struct regmap *regmap; + bool led_on; + struct gpio_desc *enable_gpio; +}; + +static const struct regmap_config ktz8866_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = REG_MAX, +}; + +static int ktz8866_write(struct ktz8866 *ktz, unsigned int reg, + unsigned int val) +{ + return regmap_write(ktz->regmap, reg, val); +} + +static int ktz8866_update_bits(struct ktz8866 *ktz, unsigned int reg, + unsigned int mask, unsigned int val) +{ + return regmap_update_bits(ktz->regmap, reg, mask, val); +} + +static int ktz8866_backlight_update_status(struct backlight_device *backlight_dev) +{ + struct ktz8866 *ktz = bl_get_data(backlight_dev); + unsigned int brightness = backlight_get_brightness(backlight_dev); + + if (!ktz->led_on && brightness > 0) { + ktz8866_update_bits(ktz, BL_EN, BL_EN_BIT, BL_EN_BIT); + ktz->led_on = true; + } else if (brightness == 0) { + ktz8866_update_bits(ktz, BL_EN, BL_EN_BIT, 0); + ktz->led_on = false; + } + + /* Set brightness */ + ktz8866_write(ktz, BL_BRT_LSB, brightness & 0x7); + ktz8866_write(ktz, BL_BRT_MSB, (brightness >> 3) & 0xFF); + + return 0; +} + +static const struct backlight_ops ktz8866_backlight_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = ktz8866_backlight_update_status, +}; + +static void ktz8866_init(struct ktz8866 *ktz) +{ + unsigned int val = 0; + + if (of_property_read_u32(ktz->client->dev.of_node, "current-num-sinks", &val)) + ktz8866_write(ktz, BL_EN, BIT(val) - 1); + else + /* Enable all 6 current sinks if the number of current sinks isn't specified. */ + ktz8866_write(ktz, BL_EN, BIT(6) - 1); + + if (of_property_read_u32(ktz->client->dev.of_node, "kinetic,current-ramp-delay-ms", &val)) { + if (val <= 128) + ktz8866_write(ktz, BL_CFG2, BIT(7) | (ilog2(val) << 3) | PWM_HYST); + else + ktz8866_write(ktz, BL_CFG2, BIT(7) | ((5 + val / 64) << 3) | PWM_HYST); + } + + if (of_property_read_u32(ktz->client->dev.of_node, "kinetic,led-enable-ramp-delay-ms", &val)) { + if (val == 0) + ktz8866_write(ktz, BL_DIMMING, 0); + else { + unsigned int ramp_off_time = ilog2(val) + 1; + unsigned int ramp_on_time = ramp_off_time << 4; + ktz8866_write(ktz, BL_DIMMING, ramp_on_time | ramp_off_time); + } + } + + if (of_property_read_bool(ktz->client->dev.of_node, "kinetic,enable-lcd-bias")) + ktz8866_write(ktz, LCD_BIAS_CFG1, LCD_BIAS_EN); +} + +static int ktz8866_probe(struct i2c_client *client) +{ + struct backlight_device *backlight_dev; + struct backlight_properties props; + struct ktz8866 *ktz; + int ret = 0; + + ktz = devm_kzalloc(&client->dev, sizeof(*ktz), GFP_KERNEL); + if (!ktz) + return -ENOMEM; + + ktz->client = client; + ktz->regmap = devm_regmap_init_i2c(client, &ktz8866_regmap_config); + if (IS_ERR(ktz->regmap)) + return dev_err_probe(&client->dev, PTR_ERR(ktz->regmap), "failed to init regmap\n"); + + ret = devm_regulator_get_enable(&client->dev, "vddpos"); + if (ret) + return dev_err_probe(&client->dev, ret, "get regulator vddpos failed\n"); + ret = devm_regulator_get_enable(&client->dev, "vddneg"); + if (ret) + return dev_err_probe(&client->dev, ret, "get regulator vddneg failed\n"); + + ktz->enable_gpio = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(ktz->enable_gpio)) + return PTR_ERR(ktz->enable_gpio); + + memset(&props, 0, sizeof(props)); + props.type = BACKLIGHT_RAW; + props.max_brightness = MAX_BRIGHTNESS; + props.brightness = DEFAULT_BRIGHTNESS; + props.scale = BACKLIGHT_SCALE_LINEAR; + + backlight_dev = devm_backlight_device_register(&client->dev, "ktz8866-backlight", + &client->dev, ktz, &ktz8866_backlight_ops, &props); + if (IS_ERR(backlight_dev)) + return dev_err_probe(&client->dev, PTR_ERR(backlight_dev), + "failed to register backlight device\n"); + + ktz8866_init(ktz); + + i2c_set_clientdata(client, backlight_dev); + backlight_update_status(backlight_dev); + + return 0; +} + +static void ktz8866_remove(struct i2c_client *client) +{ + struct backlight_device *backlight_dev = i2c_get_clientdata(client); + backlight_dev->props.brightness = 0; + backlight_update_status(backlight_dev); +} + +static const struct i2c_device_id ktz8866_ids[] = { + { "ktz8866", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, ktz8866_ids); + +static const struct of_device_id ktz8866_match_table[] = { + { + .compatible = "kinetic,ktz8866", + }, + {}, +}; + +static struct i2c_driver ktz8866_driver = { + .driver = { + .name = "ktz8866", + .of_match_table = ktz8866_match_table, + }, + .probe_new = ktz8866_probe, + .remove = ktz8866_remove, + .id_table = ktz8866_ids, +}; + +module_i2c_driver(ktz8866_driver); + +MODULE_DESCRIPTION("Kinetic KTZ8866 Backlight Driver"); +MODULE_AUTHOR("Jianhua Lu <lujianhua000@gmail.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index 0468ea82159f..346d3e29a843 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -95,8 +95,6 @@ void locomolcd_power(int on) /* read comadj */ if (comadj == -1 && machine_is_collie()) comadj = 128; - if (comadj == -1 && machine_is_poodle()) - comadj = 118; if (on) locomolcd_on(comadj); @@ -181,14 +179,6 @@ static int locomolcd_probe(struct locomo_dev *ldev) locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0); - /* - * the poodle_lcd_power function is called for the first time - * from fs_initcall, which is before locomo is activated. - * We need to recall poodle_lcd_power here - */ - if (machine_is_poodle()) - locomolcd_power(1); - local_irq_restore(flags); memset(&props, 0, sizeof(struct backlight_properties)); diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index c0523a0269ee..fb388148d98f 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -28,7 +28,6 @@ struct pwm_bl_data { struct regulator *power_supply; struct gpio_desc *enable_gpio; unsigned int scale; - bool legacy; unsigned int post_pwm_on_delay; unsigned int pwm_off_delay; int (*notify)(struct device *, @@ -41,19 +40,16 @@ struct pwm_bl_data { static void pwm_backlight_power_on(struct pwm_bl_data *pb) { - struct pwm_state state; int err; - pwm_get_state(pb->pwm, &state); if (pb->enabled) return; - err = regulator_enable(pb->power_supply); - if (err < 0) - dev_err(pb->dev, "failed to enable power supply\n"); - - state.enabled = true; - pwm_apply_state(pb->pwm, &state); + if (pb->power_supply) { + err = regulator_enable(pb->power_supply); + if (err < 0) + dev_err(pb->dev, "failed to enable power supply\n"); + } if (pb->post_pwm_on_delay) msleep(pb->post_pwm_on_delay); @@ -66,9 +62,6 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb) static void pwm_backlight_power_off(struct pwm_bl_data *pb) { - struct pwm_state state; - - pwm_get_state(pb->pwm, &state); if (!pb->enabled) return; @@ -78,28 +71,22 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb) if (pb->pwm_off_delay) msleep(pb->pwm_off_delay); - state.enabled = false; - state.duty_cycle = 0; - pwm_apply_state(pb->pwm, &state); - - regulator_disable(pb->power_supply); + if (pb->power_supply) + regulator_disable(pb->power_supply); pb->enabled = false; } -static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness) +static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness, struct pwm_state *state) { unsigned int lth = pb->lth_brightness; - struct pwm_state state; u64 duty_cycle; - pwm_get_state(pb->pwm, &state); - if (pb->levels) duty_cycle = pb->levels[brightness]; else duty_cycle = brightness; - duty_cycle *= state.period - lth; + duty_cycle *= state->period - lth; do_div(duty_cycle, pb->scale); return duty_cycle + lth; @@ -116,11 +103,26 @@ static int pwm_backlight_update_status(struct backlight_device *bl) if (brightness > 0) { pwm_get_state(pb->pwm, &state); - state.duty_cycle = compute_duty_cycle(pb, brightness); + state.duty_cycle = compute_duty_cycle(pb, brightness, &state); + state.enabled = true; pwm_apply_state(pb->pwm, &state); + pwm_backlight_power_on(pb); } else { pwm_backlight_power_off(pb); + + pwm_get_state(pb->pwm, &state); + state.duty_cycle = 0; + /* + * We cannot assume a disabled PWM to drive its output to the + * inactive state. If we have an enable GPIO and/or a regulator + * we assume that this isn't relevant and we can disable the PWM + * to save power. If however there is neither an enable GPIO nor + * a regulator keep the PWM on be sure to get a constant + * inactive output. + */ + state.enabled = !pb->power_supply && !pb->enable_gpio; + pwm_apply_state(pb->pwm, &state); } if (pb->notify_after) @@ -417,7 +419,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb) if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0) active = false; - if (!regulator_is_enabled(pb->power_supply)) + if (pb->power_supply && !regulator_is_enabled(pb->power_supply)) active = false; if (!pwm_is_enabled(pb->pwm)) @@ -455,7 +457,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) struct platform_pwm_backlight_data defdata; struct backlight_properties props; struct backlight_device *bl; - struct device_node *node = pdev->dev.of_node; struct pwm_bl_data *pb; struct pwm_state state; unsigned int i; @@ -499,19 +500,16 @@ static int pwm_backlight_probe(struct platform_device *pdev) goto err_alloc; } - pb->power_supply = devm_regulator_get(&pdev->dev, "power"); + pb->power_supply = devm_regulator_get_optional(&pdev->dev, "power"); if (IS_ERR(pb->power_supply)) { ret = PTR_ERR(pb->power_supply); - goto err_alloc; + if (ret == -ENODEV) + pb->power_supply = NULL; + else + goto err_alloc; } pb->pwm = devm_pwm_get(&pdev->dev, NULL); - if (IS_ERR(pb->pwm) && PTR_ERR(pb->pwm) != -EPROBE_DEFER && !node) { - dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); - pb->legacy = true; - pb->pwm = pwm_request(data->pwm_id, "pwm-backlight"); - } - if (IS_ERR(pb->pwm)) { ret = PTR_ERR(pb->pwm); if (ret != -EPROBE_DEFER) @@ -604,8 +602,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); ret = PTR_ERR(bl); - if (pb->legacy) - pwm_free(pb->pwm); goto err_alloc; } @@ -639,8 +635,6 @@ static int pwm_backlight_remove(struct platform_device *pdev) if (pb->exit) pb->exit(&pdev->dev); - if (pb->legacy) - pwm_free(pb->pwm); return 0; } diff --git a/drivers/video/backlight/sky81452-backlight.c b/drivers/video/backlight/sky81452-backlight.c index c95e0de7f4e7..0172438c38ce 100644 --- a/drivers/video/backlight/sky81452-backlight.c +++ b/drivers/video/backlight/sky81452-backlight.c @@ -41,7 +41,7 @@ #define SKY81452_MAX_BRIGHTNESS (SKY81452_CS + 1) /** - * struct sky81452_platform_data + * struct sky81452_bl_platform_data - backlight platform data * @name: backlight driver name. * If it is not defined, default name is lcd-backlight. * @gpiod_enable:GPIO descriptor which control EN pin diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c deleted file mode 100644 index 77b71f6c19b5..000000000000 --- a/drivers/video/backlight/tosa_bl.c +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * LCD / Backlight control code for Sharp SL-6000x (tosa) - * - * Copyright (c) 2005 Dirk Opfer - * Copyright (c) 2007,2008 Dmitry Baryshkov - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/spi/spi.h> -#include <linux/i2c.h> -#include <linux/gpio/consumer.h> -#include <linux/fb.h> -#include <linux/backlight.h> -#include <linux/slab.h> - -#include <asm/mach/sharpsl_param.h> - -#include "tosa_bl.h" - -#define COMADJ_DEFAULT 97 - -#define DAC_CH1 0 -#define DAC_CH2 1 - -struct tosa_bl_data { - struct i2c_client *i2c; - struct backlight_device *bl; - struct gpio_desc *gpio; - - int comadj; -}; - -static void tosa_bl_set_backlight(struct tosa_bl_data *data, int brightness) -{ - struct spi_device *spi = dev_get_platdata(&data->i2c->dev); - - i2c_smbus_write_byte_data(data->i2c, DAC_CH1, data->comadj); - - /* SetBacklightDuty */ - i2c_smbus_write_byte_data(data->i2c, DAC_CH2, (u8)(brightness & 0xff)); - - /* SetBacklightVR */ - gpiod_set_value(data->gpio, brightness & 0x100); - - tosa_bl_enable(spi, brightness); -} - -static int tosa_bl_update_status(struct backlight_device *dev) -{ - struct backlight_properties *props = &dev->props; - struct tosa_bl_data *data = bl_get_data(dev); - int power = max(props->power, props->fb_blank); - int brightness = props->brightness; - - if (power) - brightness = 0; - - tosa_bl_set_backlight(data, brightness); - - return 0; -} - -static int tosa_bl_get_brightness(struct backlight_device *dev) -{ - struct backlight_properties *props = &dev->props; - - return props->brightness; -} - -static const struct backlight_ops bl_ops = { - .get_brightness = tosa_bl_get_brightness, - .update_status = tosa_bl_update_status, -}; - -static int tosa_bl_probe(struct i2c_client *client) -{ - struct backlight_properties props; - struct tosa_bl_data *data; - int ret = 0; - - data = devm_kzalloc(&client->dev, sizeof(struct tosa_bl_data), - GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj; - data->gpio = devm_gpiod_get(&client->dev, "backlight", GPIOD_OUT_LOW); - ret = PTR_ERR_OR_ZERO(data->gpio); - if (ret) { - dev_dbg(&data->bl->dev, "Unable to request gpio!\n"); - return ret; - } - - i2c_set_clientdata(client, data); - data->i2c = client; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_RAW; - props.max_brightness = 512 - 1; - data->bl = devm_backlight_device_register(&client->dev, "tosa-bl", - &client->dev, data, &bl_ops, - &props); - if (IS_ERR(data->bl)) { - ret = PTR_ERR(data->bl); - goto err_reg; - } - - data->bl->props.brightness = 69; - data->bl->props.power = FB_BLANK_UNBLANK; - - backlight_update_status(data->bl); - - return 0; - -err_reg: - data->bl = NULL; - return ret; -} - -static void tosa_bl_remove(struct i2c_client *client) -{ - struct tosa_bl_data *data = i2c_get_clientdata(client); - - data->bl = NULL; -} - -#ifdef CONFIG_PM_SLEEP -static int tosa_bl_suspend(struct device *dev) -{ - struct tosa_bl_data *data = dev_get_drvdata(dev); - - tosa_bl_set_backlight(data, 0); - - return 0; -} - -static int tosa_bl_resume(struct device *dev) -{ - struct tosa_bl_data *data = dev_get_drvdata(dev); - - backlight_update_status(data->bl); - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(tosa_bl_pm_ops, tosa_bl_suspend, tosa_bl_resume); - -static const struct i2c_device_id tosa_bl_id[] = { - { "tosa-bl", 0 }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, tosa_bl_id); - -static struct i2c_driver tosa_bl_driver = { - .driver = { - .name = "tosa-bl", - .pm = &tosa_bl_pm_ops, - }, - .probe_new = tosa_bl_probe, - .remove = tosa_bl_remove, - .id_table = tosa_bl_id, -}; - -module_i2c_driver(tosa_bl_driver); - -MODULE_AUTHOR("Dmitry Baryshkov"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); - diff --git a/drivers/video/backlight/tosa_bl.h b/drivers/video/backlight/tosa_bl.h deleted file mode 100644 index 589e17e6fdb2..000000000000 --- a/drivers/video/backlight/tosa_bl.h +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef _TOSA_BL_H -#define _TOSA_BL_H - -struct spi_device; -extern int tosa_bl_enable(struct spi_device *spi, int enable); - -#endif diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c deleted file mode 100644 index 23d6c6bf0f54..000000000000 --- a/drivers/video/backlight/tosa_lcd.c +++ /dev/null @@ -1,284 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * LCD / Backlight control code for Sharp SL-6000x (tosa) - * - * Copyright (c) 2005 Dirk Opfer - * Copyright (c) 2007,2008 Dmitry Baryshkov - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/spi/spi.h> -#include <linux/i2c.h> -#include <linux/slab.h> -#include <linux/gpio/consumer.h> -#include <linux/delay.h> -#include <linux/lcd.h> -#include <linux/fb.h> - -#include <asm/mach/sharpsl_param.h> - -#include "tosa_bl.h" - -#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) - -#define TG_REG0_VQV 0x0001 -#define TG_REG0_COLOR 0x0002 -#define TG_REG0_UD 0x0004 -#define TG_REG0_LR 0x0008 - -/* - * Timing Generator - */ -#define TG_PNLCTL 0x00 -#define TG_TPOSCTL 0x01 -#define TG_DUTYCTL 0x02 -#define TG_GPOSR 0x03 -#define TG_GPODR1 0x04 -#define TG_GPODR2 0x05 -#define TG_PINICTL 0x06 -#define TG_HPOSCTL 0x07 - - -#define DAC_BASE 0x4e - -struct tosa_lcd_data { - struct spi_device *spi; - struct lcd_device *lcd; - struct i2c_client *i2c; - struct gpio_desc *gpiod_tg; - - int lcd_power; - bool is_vga; -}; - -static int tosa_tg_send(struct spi_device *spi, int adrs, uint8_t data) -{ - u8 buf[1]; - struct spi_message msg; - struct spi_transfer xfer = { - .len = 1, - .cs_change = 0, - .tx_buf = buf, - }; - - buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f); - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - - return spi_sync(spi, &msg); -} - -int tosa_bl_enable(struct spi_device *spi, int enable) -{ - /* bl_enable GP04=1 otherwise GP04=0*/ - return tosa_tg_send(spi, TG_GPODR2, enable ? 0x01 : 0x00); -} -EXPORT_SYMBOL(tosa_bl_enable); - -static void tosa_lcd_tg_init(struct tosa_lcd_data *data) -{ - /* TG on */ - gpiod_set_value(data->gpiod_tg, 0); - - mdelay(60); - - /* delayed 0clk TCTL signal for VGA */ - tosa_tg_send(data->spi, TG_TPOSCTL, 0x00); - /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */ - tosa_tg_send(data->spi, TG_GPOSR, 0x02); -} - -static void tosa_lcd_tg_on(struct tosa_lcd_data *data) -{ - struct spi_device *spi = data->spi; - int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR; - - if (data->is_vga) - value |= TG_REG0_VQV; - - tosa_tg_send(spi, TG_PNLCTL, value); - - /* TG LCD pannel power up */ - tosa_tg_send(spi, TG_PINICTL, 0x4); - mdelay(50); - - /* TG LCD GVSS */ - tosa_tg_send(spi, TG_PINICTL, 0x0); - - if (IS_ERR_OR_NULL(data->i2c)) { - /* - * after the pannel is powered up the first time, - * we can access the i2c bus so probe for the DAC - */ - struct i2c_adapter *adap = i2c_get_adapter(0); - struct i2c_board_info info = { - .dev_name = "tosa-bl", - .type = "tosa-bl", - .addr = DAC_BASE, - .platform_data = data->spi, - }; - data->i2c = i2c_new_client_device(adap, &info); - } -} - -static void tosa_lcd_tg_off(struct tosa_lcd_data *data) -{ - struct spi_device *spi = data->spi; - - /* TG LCD VHSA off */ - tosa_tg_send(spi, TG_PINICTL, 0x4); - mdelay(50); - - /* TG LCD signal off */ - tosa_tg_send(spi, TG_PINICTL, 0x6); - mdelay(50); - - /* TG Off */ - gpiod_set_value(data->gpiod_tg, 1); - mdelay(100); -} - -int tosa_lcd_set_power(struct lcd_device *lcd, int power) -{ - struct tosa_lcd_data *data = lcd_get_data(lcd); - - if (POWER_IS_ON(power) && !POWER_IS_ON(data->lcd_power)) - tosa_lcd_tg_on(data); - - if (!POWER_IS_ON(power) && POWER_IS_ON(data->lcd_power)) - tosa_lcd_tg_off(data); - - data->lcd_power = power; - return 0; -} - -static int tosa_lcd_get_power(struct lcd_device *lcd) -{ - struct tosa_lcd_data *data = lcd_get_data(lcd); - - return data->lcd_power; -} - -static int tosa_lcd_set_mode(struct lcd_device *lcd, struct fb_videomode *mode) -{ - struct tosa_lcd_data *data = lcd_get_data(lcd); - - if (mode->xres == 320 || mode->yres == 320) - data->is_vga = false; - else - data->is_vga = true; - - if (POWER_IS_ON(data->lcd_power)) - tosa_lcd_tg_on(data); - - return 0; -} - -static struct lcd_ops tosa_lcd_ops = { - .set_power = tosa_lcd_set_power, - .get_power = tosa_lcd_get_power, - .set_mode = tosa_lcd_set_mode, -}; - -static int tosa_lcd_probe(struct spi_device *spi) -{ - int ret; - struct tosa_lcd_data *data; - - data = devm_kzalloc(&spi->dev, sizeof(struct tosa_lcd_data), - GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->is_vga = true; /* default to VGA mode */ - - /* - * bits_per_word cannot be configured in platform data - */ - spi->bits_per_word = 8; - - ret = spi_setup(spi); - if (ret < 0) - return ret; - - data->spi = spi; - spi_set_drvdata(spi, data); - - data->gpiod_tg = devm_gpiod_get(&spi->dev, "tg #pwr", GPIOD_OUT_LOW); - if (IS_ERR(data->gpiod_tg)) - return PTR_ERR(data->gpiod_tg); - - mdelay(60); - - tosa_lcd_tg_init(data); - - tosa_lcd_tg_on(data); - - data->lcd = devm_lcd_device_register(&spi->dev, "tosa-lcd", &spi->dev, - data, &tosa_lcd_ops); - - if (IS_ERR(data->lcd)) { - ret = PTR_ERR(data->lcd); - data->lcd = NULL; - goto err_register; - } - - return 0; - -err_register: - tosa_lcd_tg_off(data); - return ret; -} - -static void tosa_lcd_remove(struct spi_device *spi) -{ - struct tosa_lcd_data *data = spi_get_drvdata(spi); - - i2c_unregister_device(data->i2c); - - tosa_lcd_tg_off(data); -} - -#ifdef CONFIG_PM_SLEEP -static int tosa_lcd_suspend(struct device *dev) -{ - struct tosa_lcd_data *data = dev_get_drvdata(dev); - - tosa_lcd_tg_off(data); - - return 0; -} - -static int tosa_lcd_resume(struct device *dev) -{ - struct tosa_lcd_data *data = dev_get_drvdata(dev); - - tosa_lcd_tg_init(data); - if (POWER_IS_ON(data->lcd_power)) - tosa_lcd_tg_on(data); - else - tosa_lcd_tg_off(data); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(tosa_lcd_pm_ops, tosa_lcd_suspend, tosa_lcd_resume); - -static struct spi_driver tosa_lcd_driver = { - .driver = { - .name = "tosa-lcd", - .pm = &tosa_lcd_pm_ops, - }, - .probe = tosa_lcd_probe, - .remove = tosa_lcd_remove, -}; - -module_spi_driver(tosa_lcd_driver); - -MODULE_AUTHOR("Dmitry Baryshkov"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); -MODULE_ALIAS("spi:tosa-lcd"); diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index b2bed599e6c6..ff3646c30d0d 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1841,23 +1841,6 @@ config FB_FSL_DIU help Framebuffer driver for the Freescale SoC DIU -config FB_W100 - tristate "W100 frame buffer support" - depends on FB && HAS_IOMEM && (ARCH_PXA || COMPILE_TEST) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. - It can also drive the w3220 chip found on iPAQ hx4700. - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called w100fb. If you want to compile it as a module, - say M here and read <file:Documentation/kbuild/modules.rst>. - - If unsure, say N. - config FB_SH_MOBILE_LCDC tristate "SuperH Mobile LCDC framebuffer support" depends on FB && HAVE_CLK && HAS_IOMEM @@ -1871,44 +1854,20 @@ config FB_SH_MOBILE_LCDC help Frame buffer driver for the on-chip SH-Mobile LCD controller. -config FB_TMIO - tristate "Toshiba Mobile IO FrameBuffer support" - depends on FB && (MFD_TMIO || COMPILE_TEST) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Frame buffer driver for the Toshiba Mobile IO integrated as found - on the Sharp SL-6000 series - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called tmiofb. If you want to compile it as a module, - say M here and read <file:Documentation/kbuild/modules.rst>. - - If unsure, say N. - -config FB_TMIO_ACCELL - bool "tmiofb acceleration" - depends on FB_TMIO - default y - config FB_S3C tristate "Samsung S3C framebuffer support" depends on FB && HAVE_CLK && HAS_IOMEM - depends on (CPU_S3C2416 || ARCH_S3C64XX) || COMPILE_TEST + depends on ARCH_S3C64XX || COMPILE_TEST select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT help Frame buffer driver for the built-in FB controller in the Samsung - SoC line from the S3C2443 onwards, including the S3C2416, S3C2450, - and the S3C64XX series such as the S3C6400 and S3C6410. + SoC line such as the S3C6400 and S3C6410. These chips all have the same basic framebuffer design with the - actual capabilities depending on the chip. For instance the S3C6400 - and S3C6410 support 4 hardware windows whereas the S3C24XX series - currently only have two. + actual capabilities depending on the chip. The S3C6400 + and S3C6410 support 4 hardware windows. Currently the support is only for the S3C6400 and S3C6410 SoCs. @@ -1918,29 +1877,6 @@ config FB_S3C_DEBUG_REGWRITE help Show all register writes via pr_debug() -config FB_S3C2410 - tristate "S3C2410 LCD framebuffer support" - depends on FB && ARCH_S3C24XX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Frame buffer driver for the built-in LCD controller in the Samsung - S3C2410 processor. - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called s3c2410fb. If you want to compile it as a module, - say M here and read <file:Documentation/kbuild/modules.rst>. - - If unsure, say N. -config FB_S3C2410_DEBUG - bool "S3C2410 lcd debug messages" - depends on FB_S3C2410 - help - Turn on debugging messages. Note that you can set/unset at run time - through sysfs - config FB_SM501 tristate "Silicon Motion SM501 framebuffer support" depends on FB && MFD_SM501 diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 7795c4126706..e6b0ae094b8b 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -84,8 +84,6 @@ obj-$(CONFIG_FB_PXA) += pxafb.o obj-$(CONFIG_FB_PXA168) += pxa168fb.o obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o obj-$(CONFIG_MMP_DISP) += mmp/ -obj-$(CONFIG_FB_W100) += w100fb.o -obj-$(CONFIG_FB_TMIO) += tmiofb.o obj-$(CONFIG_FB_AU1100) += au1100fb.o obj-$(CONFIG_FB_AU1200) += au1200fb.o obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o @@ -100,7 +98,6 @@ obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o obj-$(CONFIG_FB_SH7760) += sh7760fb.o obj-$(CONFIG_FB_IMX) += imxfb.o obj-$(CONFIG_FB_S3C) += s3c-fb.o -obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 1fc8de4ecbeb..8187a7c4f910 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -49,7 +49,6 @@ struct atmel_lcdfb_info { struct clk *lcdc_clk; struct backlight_device *backlight; - u8 bl_power; u8 saved_lcdcon; u32 pseudo_palette[16]; @@ -109,22 +108,7 @@ static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8 static int atmel_bl_update_status(struct backlight_device *bl) { struct atmel_lcdfb_info *sinfo = bl_get_data(bl); - int power = sinfo->bl_power; - int brightness = bl->props.brightness; - - /* REVISIT there may be a meaningful difference between - * fb_blank and power ... there seem to be some cases - * this doesn't handle correctly. - */ - if (bl->props.fb_blank != sinfo->bl_power) - power = bl->props.fb_blank; - else if (bl->props.power != sinfo->bl_power) - power = bl->props.power; - - if (brightness < 0 && power == FB_BLANK_UNBLANK) - brightness = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); - else if (power != FB_BLANK_UNBLANK) - brightness = 0; + int brightness = backlight_get_brightness(bl); lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, brightness); if (contrast_ctr & ATMEL_LCDC_POL_POSITIVE) @@ -133,8 +117,6 @@ static int atmel_bl_update_status(struct backlight_device *bl) else lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); - bl->props.fb_blank = bl->props.power = sinfo->bl_power = power; - return 0; } @@ -155,8 +137,6 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo) struct backlight_properties props; struct backlight_device *bl; - sinfo->bl_power = FB_BLANK_UNBLANK; - if (sinfo->backlight) return; diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c index dd31b9d7d337..36a9ac05a340 100644 --- a/drivers/video/fbdev/aty/aty128fb.c +++ b/drivers/video/fbdev/aty/aty128fb.c @@ -1766,12 +1766,10 @@ static int aty128_bl_update_status(struct backlight_device *bd) unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); int level; - if (bd->props.power != FB_BLANK_UNBLANK || - bd->props.fb_blank != FB_BLANK_UNBLANK || - !par->lcd_on) + if (!par->lcd_on) level = 0; else - level = bd->props.brightness; + level = backlight_get_brightness(bd); reg |= LVDS_BL_MOD_EN | LVDS_BLON; if (level > 0) { diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index d59215a4992e..b02e4e645035 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -2219,13 +2219,7 @@ static int aty_bl_update_status(struct backlight_device *bd) { struct atyfb_par *par = bl_get_data(bd); unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); - int level; - - if (bd->props.power != FB_BLANK_UNBLANK || - bd->props.fb_blank != FB_BLANK_UNBLANK) - level = 0; - else - level = bd->props.brightness; + int level = backlight_get_brightness(bd); reg |= (BLMOD_EN | BIASMOD_EN); if (level > 0) { diff --git a/drivers/video/fbdev/aty/radeon_backlight.c b/drivers/video/fbdev/aty/radeon_backlight.c index d2c1263ad260..427adc838f77 100644 --- a/drivers/video/fbdev/aty/radeon_backlight.c +++ b/drivers/video/fbdev/aty/radeon_backlight.c @@ -57,11 +57,7 @@ static int radeon_bl_update_status(struct backlight_device *bd) * backlight. This provides some greater power saving and the display * is useless without backlight anyway. */ - if (bd->props.power != FB_BLANK_UNBLANK || - bd->props.fb_blank != FB_BLANK_UNBLANK) - level = 0; - else - level = bd->props.brightness; + level = backlight_get_brightness(bd); del_timer_sync(&rinfo->lvds_timer); radeon_engine_idle(); diff --git a/drivers/video/fbdev/clps711x-fb.c b/drivers/video/fbdev/clps711x-fb.c index a1061c2f1640..45c75ff01eca 100644 --- a/drivers/video/fbdev/clps711x-fb.c +++ b/drivers/video/fbdev/clps711x-fb.c @@ -251,16 +251,8 @@ static int clps711x_fb_probe(struct platform_device *pdev) goto out_fb_release; } - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_fb_release; - } - cfb->buffsize = resource_size(res); info->fix.smem_start = res->start; - info->apertures->ranges[0].base = info->fix.smem_start; - info->apertures->ranges[0].size = cfb->buffsize; cfb->clk = devm_clk_get(dev, NULL); if (IS_ERR(cfb->clk)) { @@ -345,7 +337,7 @@ static int clps711x_fb_probe(struct platform_device *pdev) &clps711x_lcd_ops); if (!IS_ERR(lcd)) return 0; - + ret = PTR_ERR(lcd); unregister_framebuffer(info); diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index dc310c7b5769..aa5f059d0222 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -157,10 +157,6 @@ static vm_fault_t fb_deferred_io_track_page(struct fb_info *info, unsigned long /* protect against the workqueue changing the page list */ mutex_lock(&fbdefio->lock); - /* first write in this cycle, notify the driver */ - if (fbdefio->first_io && list_empty(&fbdefio->pagereflist)) - fbdefio->first_io(info); - pageref = fb_deferred_io_pageref_get(info, offset, page); if (WARN_ON_ONCE(!pageref)) { ret = VM_FAULT_OOM; @@ -313,7 +309,7 @@ void fb_deferred_io_open(struct fb_info *info, } EXPORT_SYMBOL_GPL(fb_deferred_io_open); -void fb_deferred_io_cleanup(struct fb_info *info) +void fb_deferred_io_release(struct fb_info *info) { struct fb_deferred_io *fbdefio = info->fbdefio; struct page *page; @@ -327,6 +323,14 @@ void fb_deferred_io_cleanup(struct fb_info *info) page = fb_deferred_io_page(info, i); page->mapping = NULL; } +} +EXPORT_SYMBOL_GPL(fb_deferred_io_release); + +void fb_deferred_io_cleanup(struct fb_info *info) +{ + struct fb_deferred_io *fbdefio = info->fbdefio; + + fb_deferred_io_release(info); kvfree(info->pagerefs); mutex_destroy(&fbdefio->lock); diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 14a7d404062c..94d4ed0331c9 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -26,7 +26,7 @@ * * Hardware cursor support added by Emmanuel Marty (core@ggi-project.org) * Smart redraw scrolling, arbitrary font width support, 512char font support - * and software scrollback added by + * and software scrollback added by * Jakub Jelinek (jj@ultra.linux.cz) * * Random hacking by Martin Mares <mj@ucw.cz> @@ -127,7 +127,7 @@ static int logo_shown = FBCON_LOGO_CANSHOW; /* console mappings */ static unsigned int first_fb_vc; static unsigned int last_fb_vc = MAX_NR_CONSOLES - 1; -static int fbcon_is_default = 1; +static int fbcon_is_default = 1; static int primary_device = -1; static int fbcon_has_console_bind; @@ -415,12 +415,12 @@ static int __init fb_console_setup(char *this_opt) strscpy(fontname, options + 5, sizeof(fontname)); continue; } - + if (!strncmp(options, "scrollback:", 11)) { pr_warn("Ignoring scrollback size option\n"); continue; } - + if (!strncmp(options, "map:", 4)) { options += 4; if (*options) { @@ -446,7 +446,7 @@ static int __init fb_console_setup(char *this_opt) last_fb_vc = simple_strtoul(options, &options, 10) - 1; if (last_fb_vc < first_fb_vc || last_fb_vc >= MAX_NR_CONSOLES) last_fb_vc = MAX_NR_CONSOLES - 1; - fbcon_is_default = 0; + fbcon_is_default = 0; continue; } @@ -940,7 +940,7 @@ static const char *fbcon_startup(void) info = fbcon_registered_fb[info_idx]; if (!info) return NULL; - + if (fbcon_open(info)) return NULL; @@ -958,7 +958,7 @@ static const char *fbcon_startup(void) set_blitting_type(vc, info); /* Setup default font */ - if (!p->fontdata && !vc->vc_font.data) { + if (!p->fontdata) { if (!fontname[0] || !(font = find_font(fontname))) font = get_default_font(info->var.xres, info->var.yres, @@ -968,8 +968,6 @@ static const char *fbcon_startup(void) vc->vc_font.height = font->height; vc->vc_font.data = (void *)(p->fontdata = font->data); vc->vc_font.charcount = font->charcount; - } else { - p->fontdata = vc->vc_font.data; } cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); @@ -1135,9 +1133,9 @@ static void fbcon_init(struct vc_data *vc, int init) ops->p = &fb_display[fg_console]; } -static void fbcon_free_font(struct fbcon_display *p, bool freefont) +static void fbcon_free_font(struct fbcon_display *p) { - if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) + if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); p->fontdata = NULL; p->userfont = 0; @@ -1172,8 +1170,8 @@ static void fbcon_deinit(struct vc_data *vc) struct fb_info *info; struct fbcon_ops *ops; int idx; - bool free_font = true; + fbcon_free_font(p); idx = con2fb_map[vc->vc_num]; if (idx == -1) @@ -1184,8 +1182,6 @@ static void fbcon_deinit(struct vc_data *vc) if (!info) goto finished; - if (info->flags & FBINFO_MISC_FIRMWARE) - free_font = false; ops = info->fbcon_par; if (!ops) @@ -1197,9 +1193,8 @@ static void fbcon_deinit(struct vc_data *vc) ops->initialized = false; finished: - fbcon_free_font(p, free_font); - if (free_font) - vc->vc_font.data = NULL; + fbcon_free_font(p); + vc->vc_font.data = NULL; if (vc->vc_hi_font_mask && vc->vc_screenbuf) set_vc_hi_font(vc, false); @@ -1999,7 +1994,7 @@ static void updatescrollmode(struct fbcon_display *p, #define PITCH(w) (((w) + 7) >> 3) #define CALC_FONTSZ(h, p, c) ((h) * (p) * (c)) /* size = height * pitch * charcount */ -static int fbcon_resize(struct vc_data *vc, unsigned int width, +static int fbcon_resize(struct vc_data *vc, unsigned int width, unsigned int height, unsigned int user) { struct fb_info *info = fbcon_info_from_console(vc->vc_num); @@ -2174,7 +2169,7 @@ static int fbcon_switch(struct vc_data *vc) ops->update_start(info); } - fbcon_set_palette(vc, color_table); + fbcon_set_palette(vc, color_table); fbcon_clear_margins(vc, 0); if (logo_shown == FBCON_LOGO_DRAW) { @@ -2343,7 +2338,7 @@ static void set_vc_hi_font(struct vc_data *vc, bool set) vc->vc_complement_mask >>= 1; vc->vc_s_complement_mask >>= 1; } - + /* ++Edmund: reorder the attribute bits */ if (vc->vc_can_do_color) { unsigned short *cp = @@ -2366,7 +2361,7 @@ static void set_vc_hi_font(struct vc_data *vc, bool set) vc->vc_complement_mask <<= 1; vc->vc_s_complement_mask <<= 1; } - + /* ++Edmund: reorder the attribute bits */ { unsigned short *cp = @@ -2495,9 +2490,12 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres)) return -EINVAL; + if (font->width > 32 || font->height > 32) + return -EINVAL; + /* Make sure drawing engine can handle the font */ - if (!(info->pixmap.blit_x & (1 << (font->width - 1))) || - !(info->pixmap.blit_y & (1 << (font->height - 1)))) + if (!(info->pixmap.blit_x & BIT(font->width - 1)) || + !(info->pixmap.blit_y & BIT(font->height - 1))) return -EINVAL; /* Make sure driver can handle the font length */ @@ -2528,7 +2526,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, /* Check if the same font is on some other console already */ for (i = first_fb_vc; i <= last_fb_vc; i++) { struct vc_data *tmp = vc_cons[i].d; - + if (fb_display[i].userfont && fb_display[i].fontdata && FNTSUM(fb_display[i].fontdata) == csum && @@ -3436,5 +3434,5 @@ void __exit fb_console_exit(void) do_unregister_con_driver(&fb_con); console_unlock(); -} +} #endif diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 3a6c8458eb8d..875541ff185b 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -13,7 +13,6 @@ #include <linux/module.h> -#include <linux/aperture.h> #include <linux/compat.h> #include <linux/types.h> #include <linux/errno.h> @@ -1454,6 +1453,10 @@ __releases(&info->lock) struct fb_info * const info = file->private_data; lock_fb_info(info); +#if IS_ENABLED(CONFIG_FB_DEFERRED_IO) + if (info->fbdefio) + fb_deferred_io_release(info); +#endif if (info->fbops->fb_release) info->fbops->fb_release(info,1); module_put(info->fbops->owner); @@ -1653,32 +1656,6 @@ static void do_unregister_framebuffer(struct fb_info *fb_info) put_fb_info(fb_info); } -static int fb_aperture_acquire_for_platform_device(struct fb_info *fb_info) -{ - struct apertures_struct *ap = fb_info->apertures; - struct device *dev = fb_info->device; - struct platform_device *pdev; - unsigned int i; - int ret; - - if (!ap) - return 0; - - if (!dev_is_platform(dev)) - return 0; - - pdev = to_platform_device(dev); - - for (ret = 0, i = 0; i < ap->count; ++i) { - ret = devm_aperture_acquire_for_platform_device(pdev, ap->ranges[i].base, - ap->ranges[i].size); - if (ret) - break; - } - - return ret; -} - /** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure @@ -1693,12 +1670,6 @@ register_framebuffer(struct fb_info *fb_info) { int ret; - if (fb_info->flags & FBINFO_MISC_FIRMWARE) { - ret = fb_aperture_acquire_for_platform_device(fb_info); - if (ret) - return ret; - } - mutex_lock(®istration_lock); ret = do_register_framebuffer(fb_info); mutex_unlock(®istration_lock); diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c index b0e690f41025..79e5bfbdd34c 100644 --- a/drivers/video/fbdev/core/fbmon.c +++ b/drivers/video/fbdev/core/fbmon.c @@ -1050,7 +1050,7 @@ static u32 fb_get_vblank(u32 hfreq) } /** - * fb_get_hblank_by_freq - get horizontal blank time given hfreq + * fb_get_hblank_by_hfreq - get horizontal blank time given hfreq * @hfreq: horizontal freq * @xres: horizontal resolution in pixels * diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c index 4d7f63892dcc..0c33c4adcd79 100644 --- a/drivers/video/fbdev/core/fbsysfs.c +++ b/drivers/video/fbdev/core/fbsysfs.c @@ -88,7 +88,6 @@ void framebuffer_release(struct fb_info *info) mutex_destroy(&info->bl_curve_mutex); #endif - kfree(info->apertures); kfree(info); } EXPORT_SYMBOL(framebuffer_release); diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index 16c1aaae9afa..a5779fb453a2 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -7,6 +7,7 @@ * */ +#include <linux/aperture.h> #include <linux/kernel.h> #include <linux/efi.h> #include <linux/efi-bgrt.h> @@ -49,6 +50,12 @@ static u64 mem_flags = EFI_MEMORY_WC | EFI_MEMORY_UC; static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */ +struct efifb_par { + u32 pseudo_palette[16]; + resource_size_t base; + resource_size_t size; +}; + static struct fb_var_screeninfo efifb_defined = { .activate = FB_ACTIVATE_NOW, .height = -1, @@ -249,6 +256,8 @@ static inline void efifb_show_boot_graphics(struct fb_info *info) {} */ static void efifb_destroy(struct fb_info *info) { + struct efifb_par *par = info->par; + if (efifb_pci_dev) pm_runtime_put(&efifb_pci_dev->dev); @@ -260,8 +269,7 @@ static void efifb_destroy(struct fb_info *info) } if (request_mem_succeeded) - release_mem_region(info->apertures->ranges[0].base, - info->apertures->ranges[0].size); + release_mem_region(par->base, par->size); fb_dealloc_cmap(&info->cmap); framebuffer_release(info); @@ -351,6 +359,7 @@ static u64 bar_offset; static int efifb_probe(struct platform_device *dev) { struct fb_info *info; + struct efifb_par *par; int err, orientation; unsigned int size_vmode; unsigned int size_remap; @@ -447,22 +456,17 @@ static int efifb_probe(struct platform_device *dev) efifb_fix.smem_start); } - info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); + info = framebuffer_alloc(sizeof(*par), &dev->dev); if (!info) { err = -ENOMEM; goto err_release_mem; } platform_set_drvdata(dev, info); - info->pseudo_palette = info->par; - info->par = NULL; + par = info->par; + info->pseudo_palette = par->pseudo_palette; - info->apertures = alloc_apertures(1); - if (!info->apertures) { - err = -ENOMEM; - goto err_release_fb; - } - info->apertures->ranges[0].base = efifb_fix.smem_start; - info->apertures->ranges[0].size = size_remap; + par->base = efifb_fix.smem_start; + par->size = size_remap; if (efi_enabled(EFI_MEMMAP) && !efi_mem_desc_lookup(efifb_fix.smem_start, &md)) { @@ -551,7 +555,7 @@ static int efifb_probe(struct platform_device *dev) info->fbops = &efifb_ops; info->var = efifb_defined; info->fix = efifb_fix; - info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE; + info->flags = FBINFO_FLAG_DEFAULT; orientation = drm_get_panel_orientation_quirk(efifb_defined.xres, efifb_defined.yres); @@ -584,6 +588,11 @@ static int efifb_probe(struct platform_device *dev) if (efifb_pci_dev) WARN_ON(pm_runtime_get_sync(&efifb_pci_dev->dev) < 0); + err = devm_aperture_acquire_for_platform_device(dev, par->base, par->size); + if (err) { + pr_err("efifb: cannot acquire aperture\n"); + goto err_put_rpm_ref; + } err = register_framebuffer(info); if (err < 0) { pr_err("efifb: cannot register framebuffer\n"); diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index fdbf02b42723..ec3f6cf05f8c 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -994,13 +994,10 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) struct pci_dev *pdev = NULL; void __iomem *fb_virt; int gen2vm = efi_enabled(EFI_BOOT); + resource_size_t base, size; phys_addr_t paddr; int ret; - info->apertures = alloc_apertures(1); - if (!info->apertures) - return -ENOMEM; - if (!gen2vm) { pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, PCI_DEVICE_ID_HYPERV_VIDEO, NULL); @@ -1009,8 +1006,8 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) return -ENODEV; } - info->apertures->ranges[0].base = pci_resource_start(pdev, 0); - info->apertures->ranges[0].size = pci_resource_len(pdev, 0); + base = pci_resource_start(pdev, 0); + size = pci_resource_len(pdev, 0); /* * For Gen 1 VM, we can directly use the contiguous memory @@ -1033,8 +1030,8 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) } pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n"); } else { - info->apertures->ranges[0].base = screen_info.lfb_base; - info->apertures->ranges[0].size = screen_info.lfb_size; + base = screen_info.lfb_base; + size = screen_info.lfb_size; } /* @@ -1076,9 +1073,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) info->screen_size = dio_fb_size; getmem_done: - aperture_remove_conflicting_devices(info->apertures->ranges[0].base, - info->apertures->ranges[0].size, - false, KBUILD_MODNAME); + aperture_remove_conflicting_devices(base, size, false, KBUILD_MODNAME); if (gen2vm) { /* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */ @@ -1239,8 +1234,7 @@ error1: return ret; } - -static int hvfb_remove(struct hv_device *hdev) +static void hvfb_remove(struct hv_device *hdev) { struct fb_info *info = hv_get_drvdata(hdev); struct hvfb_par *par = info->par; @@ -1261,8 +1255,6 @@ static int hvfb_remove(struct hv_device *hdev) hvfb_putmem(hdev, info); framebuffer_release(info); - - return 0; } static int hvfb_suspend(struct hv_device *hdev) diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c index b945b68984b9..76771e126d0a 100644 --- a/drivers/video/fbdev/mx3fb.c +++ b/drivers/video/fbdev/mx3fb.c @@ -283,12 +283,7 @@ static int mx3fb_bl_get_brightness(struct backlight_device *bl) static int mx3fb_bl_update_status(struct backlight_device *bl) { struct mx3fb_data *fbd = bl_get_data(bl); - int brightness = bl->props.brightness; - - if (bl->props.power != FB_BLANK_UNBLANK) - brightness = 0; - if (bl->props.fb_blank != FB_BLANK_UNBLANK) - brightness = 0; + int brightness = backlight_get_brightness(bl); fbd->backlight_level = (fbd->backlight_level & ~0xFF) | brightness; diff --git a/drivers/video/fbdev/nvidia/nv_backlight.c b/drivers/video/fbdev/nvidia/nv_backlight.c index 2ce53529f636..503a7a683855 100644 --- a/drivers/video/fbdev/nvidia/nv_backlight.c +++ b/drivers/video/fbdev/nvidia/nv_backlight.c @@ -49,17 +49,11 @@ static int nvidia_bl_update_status(struct backlight_device *bd) { struct nvidia_par *par = bl_get_data(bd); u32 tmp_pcrt, tmp_pmc, fpcontrol; - int level; + int level = backlight_get_brightness(bd); if (!par->FlatPanel) return 0; - if (bd->props.power != FB_BLANK_UNBLANK || - bd->props.fb_blank != FB_BLANK_UNBLANK) - level = 0; - else - level = bd->props.brightness; - tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF; tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC; fpcontrol = NV_RD32(par->PRAMDAC, 0x0848) & 0xCFFFFFCC; diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c index 1960916098d4..e60a276b4855 100644 --- a/drivers/video/fbdev/nvidia/nvidia.c +++ b/drivers/video/fbdev/nvidia/nvidia.c @@ -1197,17 +1197,17 @@ static int nvidia_set_fbinfo(struct fb_info *info) return nvidiafb_check_var(&info->var, info); } -static u32 nvidia_get_chipset(struct fb_info *info) +static u32 nvidia_get_chipset(struct pci_dev *pci_dev, + volatile u32 __iomem *REGS) { - struct nvidia_par *par = info->par; - u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device; + u32 id = (pci_dev->vendor << 16) | pci_dev->device; printk(KERN_INFO PFX "Device ID: %x \n", id); if ((id & 0xfff0) == 0x00f0 || (id & 0xfff0) == 0x02e0) { /* pci-e */ - id = NV_RD32(par->REGS, 0x1800); + id = NV_RD32(REGS, 0x1800); if ((id & 0x0000ffff) == 0x000010DE) id = 0x10DE0000 | (id >> 16); @@ -1220,12 +1220,11 @@ static u32 nvidia_get_chipset(struct fb_info *info) return id; } -static u32 nvidia_get_arch(struct fb_info *info) +static u32 nvidia_get_arch(u32 Chipset) { - struct nvidia_par *par = info->par; u32 arch = 0; - switch (par->Chipset & 0x0ff0) { + switch (Chipset & 0x0ff0) { case 0x0100: /* GeForce 256 */ case 0x0110: /* GeForce2 MX */ case 0x0150: /* GeForce2 */ @@ -1278,16 +1277,44 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent) struct fb_info *info; unsigned short cmd; int ret; + volatile u32 __iomem *REGS; + int Chipset; + u32 Architecture; NVTRACE_ENTER(); assert(pd != NULL); + if (pci_enable_device(pd)) { + printk(KERN_ERR PFX "cannot enable PCI device\n"); + return -ENODEV; + } + + /* enable IO and mem if not already done */ + pci_read_config_word(pd, PCI_COMMAND, &cmd); + cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY); + pci_write_config_word(pd, PCI_COMMAND, cmd); + + nvidiafb_fix.mmio_start = pci_resource_start(pd, 0); + nvidiafb_fix.mmio_len = pci_resource_len(pd, 0); + + REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len); + if (!REGS) { + printk(KERN_ERR PFX "cannot ioremap MMIO base\n"); + return -ENODEV; + } + + Chipset = nvidia_get_chipset(pd, REGS); + Architecture = nvidia_get_arch(Chipset); + if (Architecture == 0) { + printk(KERN_ERR PFX "unknown NV_ARCH\n"); + goto err_out; + } + ret = aperture_remove_conflicting_pci_devices(pd, "nvidiafb"); if (ret) - return ret; + goto err_out; info = framebuffer_alloc(sizeof(struct nvidia_par), &pd->dev); - if (!info) goto err_out; @@ -1298,11 +1325,6 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent) if (info->pixmap.addr == NULL) goto err_out_kfree; - if (pci_enable_device(pd)) { - printk(KERN_ERR PFX "cannot enable PCI device\n"); - goto err_out_enable; - } - if (pci_request_regions(pd, "nvidiafb")) { printk(KERN_ERR PFX "cannot request PCI regions\n"); goto err_out_enable; @@ -1318,34 +1340,17 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent) par->paneltweak = paneltweak; par->reverse_i2c = reverse_i2c; - /* enable IO and mem if not already done */ - pci_read_config_word(pd, PCI_COMMAND, &cmd); - cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY); - pci_write_config_word(pd, PCI_COMMAND, cmd); - - nvidiafb_fix.mmio_start = pci_resource_start(pd, 0); nvidiafb_fix.smem_start = pci_resource_start(pd, 1); - nvidiafb_fix.mmio_len = pci_resource_len(pd, 0); - - par->REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len); - if (!par->REGS) { - printk(KERN_ERR PFX "cannot ioremap MMIO base\n"); - goto err_out_free_base0; - } + par->REGS = REGS; - par->Chipset = nvidia_get_chipset(info); - par->Architecture = nvidia_get_arch(info); - - if (par->Architecture == 0) { - printk(KERN_ERR PFX "unknown NV_ARCH\n"); - goto err_out_arch; - } + par->Chipset = Chipset; + par->Architecture = Architecture; sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); if (NVCommonSetup(info)) - goto err_out_arch; + goto err_out_free_base0; par->FbAddress = nvidiafb_fix.smem_start; par->FbMapSize = par->RamAmountKBytes * 1024; @@ -1401,7 +1406,6 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent) goto err_out_iounmap_fb; } - printk(KERN_INFO PFX "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n", info->fix.id, @@ -1415,15 +1419,14 @@ err_out_iounmap_fb: err_out_free_base1: fb_destroy_modedb(info->monspecs.modedb); nvidia_delete_i2c_busses(par); -err_out_arch: - iounmap(par->REGS); - err_out_free_base0: +err_out_free_base0: pci_release_regions(pd); err_out_enable: kfree(info->pixmap.addr); err_out_kfree: framebuffer_release(info); err_out: + iounmap(REGS); return -ENODEV; } diff --git a/drivers/video/fbdev/offb.c b/drivers/video/fbdev/offb.c index 91001990e351..f7ad6bc9d02d 100644 --- a/drivers/video/fbdev/offb.c +++ b/drivers/video/fbdev/offb.c @@ -12,6 +12,7 @@ * more details. */ +#include <linux/aperture.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -53,10 +54,11 @@ struct offb_par { volatile void __iomem *cmap_data; int cmap_type; int blanked; + u32 pseudo_palette[16]; + resource_size_t base; + resource_size_t size; }; -struct offb_par default_par; - #ifdef CONFIG_PPC32 extern boot_infos_t *boot_infos; #endif @@ -280,9 +282,11 @@ static int offb_set_par(struct fb_info *info) static void offb_destroy(struct fb_info *info) { + struct offb_par *par = info->par; + if (info->screen_base) iounmap(info->screen_base); - release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); + release_mem_region(par->base, par->size); fb_dealloc_cmap(&info->cmap); framebuffer_release(info); } @@ -393,11 +397,11 @@ static void offb_init_fb(struct platform_device *parent, const char *name, int foreign_endian, struct device_node *dp) { unsigned long res_size = pitch * height; - struct offb_par *par = &default_par; unsigned long res_start = address; struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; struct fb_info *info; + struct offb_par *par; if (!request_mem_region(res_start, res_size, "offb")) return; @@ -411,17 +415,15 @@ static void offb_init_fb(struct platform_device *parent, const char *name, return; } - info = framebuffer_alloc(sizeof(u32) * 16, &parent->dev); - + info = framebuffer_alloc(sizeof(*par), &parent->dev); if (!info) { release_mem_region(res_start, res_size); return; } platform_set_drvdata(parent, info); - + par = info->par; fix = &info->fix; var = &info->var; - info->par = par; if (name) { strcpy(fix->id, "OFfb "); @@ -506,20 +508,18 @@ static void offb_init_fb(struct platform_device *parent, const char *name, var->sync = 0; var->vmode = FB_VMODE_NONINTERLACED; - /* set offb aperture size for generic probing */ - info->apertures = alloc_apertures(1); - if (!info->apertures) - goto out_aper; - info->apertures->ranges[0].base = address; - info->apertures->ranges[0].size = fix->smem_len; + par->base = address; + par->size = fix->smem_len; info->fbops = &offb_ops; info->screen_base = ioremap(address, fix->smem_len); - info->pseudo_palette = (void *) (info + 1); - info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE | foreign_endian; + info->pseudo_palette = par->pseudo_palette; + info->flags = FBINFO_DEFAULT | foreign_endian; fb_alloc_cmap(&info->cmap, 256, 0); + if (devm_aperture_acquire_for_platform_device(parent, par->base, par->size) < 0) + goto out_err; if (register_framebuffer(info) < 0) goto out_err; @@ -529,7 +529,6 @@ static void offb_init_fb(struct platform_device *parent, const char *name, out_err: fb_dealloc_cmap(&info->cmap); iounmap(info->screen_base); -out_aper: iounmap(par->cmap_adr); par->cmap_adr = NULL; framebuffer_release(info); diff --git a/drivers/video/fbdev/omap/Kconfig b/drivers/video/fbdev/omap/Kconfig index b1786cf1b486..a6548283451f 100644 --- a/drivers/video/fbdev/omap/Kconfig +++ b/drivers/video/fbdev/omap/Kconfig @@ -40,15 +40,6 @@ config FB_OMAP_LCD_MIPID the Mobile Industry Processor Interface DBI-C/DCS specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3) -config FB_OMAP_LCD_H3 - bool "TPS65010 LCD controller on OMAP-H3" - depends on MACH_OMAP_H3 || COMPILE_TEST - depends on TPS65010=y - default y - help - Say Y here if you want to have support for the LCD on the - H3 board. - config FB_OMAP_DMA_TUNE bool "Set DMA SDRAM access priority high" depends on FB_OMAP diff --git a/drivers/video/fbdev/omap/Makefile b/drivers/video/fbdev/omap/Makefile index b88e02f5cb1f..504edb9c09dd 100644 --- a/drivers/video/fbdev/omap/Makefile +++ b/drivers/video/fbdev/omap/Makefile @@ -17,16 +17,10 @@ objs-y$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o lcds-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o -lcds-y$(CONFIG_FB_OMAP_LCD_H3) += lcd_h3.o lcds-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o -lcds-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o -lcds-y$(CONFIG_MACH_OMAP_PALMZ71) += lcd_palmz71.o -lcds-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o -lcds-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o lcds-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o lcds-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o -lcds-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o omapfb-objs := $(objs-yy) diff --git a/drivers/video/fbdev/omap/lcd_h3.c b/drivers/video/fbdev/omap/lcd_h3.c deleted file mode 100644 index 1766dff767bb..000000000000 --- a/drivers/video/fbdev/omap/lcd_h3.c +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * LCD panel support for the TI OMAP H3 board - * - * Copyright (C) 2004 Nokia Corporation - * Author: Imre Deak <imre.deak@nokia.com> - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/mfd/tps65010.h> -#include <linux/gpio.h> - -#include "omapfb.h" - -#define MODULE_NAME "omapfb-lcd_h3" - -static int h3_panel_enable(struct lcd_panel *panel) -{ - int r = 0; - - /* GPIO1 and GPIO2 of TPS65010 send LCD_ENBKL and LCD_ENVDD signals */ - r = tps65010_set_gpio_out_value(GPIO1, HIGH); - if (!r) - r = tps65010_set_gpio_out_value(GPIO2, HIGH); - if (r) - pr_err(MODULE_NAME ": Unable to turn on LCD panel\n"); - - return r; -} - -static void h3_panel_disable(struct lcd_panel *panel) -{ - int r = 0; - - /* GPIO1 and GPIO2 of TPS65010 send LCD_ENBKL and LCD_ENVDD signals */ - r = tps65010_set_gpio_out_value(GPIO1, LOW); - if (!r) - tps65010_set_gpio_out_value(GPIO2, LOW); - if (r) - pr_err(MODULE_NAME ": Unable to turn off LCD panel\n"); -} - -static struct lcd_panel h3_panel = { - .name = "h3", - .config = OMAP_LCDC_PANEL_TFT, - - .data_lines = 16, - .bpp = 16, - .x_res = 240, - .y_res = 320, - .pixel_clock = 12000, - .hsw = 12, - .hfp = 14, - .hbp = 72 - 12, - .vsw = 1, - .vfp = 1, - .vbp = 0, - .pcd = 0, - - .enable = h3_panel_enable, - .disable = h3_panel_disable, -}; - -static int h3_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&h3_panel); - return 0; -} - -static struct platform_driver h3_panel_driver = { - .probe = h3_panel_probe, - .driver = { - .name = "lcd_h3", - }, -}; - -module_platform_driver(h3_panel_driver); - -MODULE_AUTHOR("Imre Deak"); -MODULE_DESCRIPTION("LCD panel support for the TI OMAP H3 board"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/omap/lcd_htcherald.c b/drivers/video/fbdev/omap/lcd_htcherald.c deleted file mode 100644 index d1c615c516dd..000000000000 --- a/drivers/video/fbdev/omap/lcd_htcherald.c +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * File: drivers/video/omap/lcd-htcherald.c - * - * LCD panel support for the HTC Herald - * - * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com> - * Copyright (C) 2009 Wing Linux - * - * Based on the lcd_htcwizard.c file from the linwizard project: - * Copyright (C) linwizard.sourceforge.net - * Author: Angelo Arrifano <miknix@gmail.com> - * Based on lcd_h4 by Imre Deak <imre.deak@nokia.com> - */ - -#include <linux/module.h> -#include <linux/platform_device.h> - -#include "omapfb.h" - -/* Found on WIZ200 (miknix) and some HERA110 models (darkstar62) */ -static struct lcd_panel htcherald_panel_1 = { - .name = "lcd_herald", - .config = OMAP_LCDC_PANEL_TFT | - OMAP_LCDC_INV_HSYNC | - OMAP_LCDC_INV_VSYNC | - OMAP_LCDC_INV_PIX_CLOCK, - .bpp = 16, - .data_lines = 16, - .x_res = 240, - .y_res = 320, - .pixel_clock = 6093, - .pcd = 0, /* 15 */ - .hsw = 10, - .hfp = 10, - .hbp = 20, - .vsw = 3, - .vfp = 2, - .vbp = 2, -}; - -static int htcherald_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&htcherald_panel_1); - return 0; -} - -static struct platform_driver htcherald_panel_driver = { - .probe = htcherald_panel_probe, - .driver = { - .name = "lcd_htcherald", - }, -}; - -module_platform_driver(htcherald_panel_driver); - -MODULE_AUTHOR("Cory Maccarrone"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("LCD panel support for the HTC Herald"); diff --git a/drivers/video/fbdev/omap/lcd_inn1510.c b/drivers/video/fbdev/omap/lcd_inn1510.c deleted file mode 100644 index bb915637e9b6..000000000000 --- a/drivers/video/fbdev/omap/lcd_inn1510.c +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * LCD panel support for the TI OMAP1510 Innovator board - * - * Copyright (C) 2004 Nokia Corporation - * Author: Imre Deak <imre.deak@nokia.com> - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/io.h> - -#include <linux/soc/ti/omap1-soc.h> - -#include "omapfb.h" - -static void __iomem *omap1510_fpga_lcd_panel_control; - -static int innovator1510_panel_enable(struct lcd_panel *panel) -{ - __raw_writeb(0x7, omap1510_fpga_lcd_panel_control); - return 0; -} - -static void innovator1510_panel_disable(struct lcd_panel *panel) -{ - __raw_writeb(0x0, omap1510_fpga_lcd_panel_control); -} - -static struct lcd_panel innovator1510_panel = { - .name = "inn1510", - .config = OMAP_LCDC_PANEL_TFT, - - .bpp = 16, - .data_lines = 16, - .x_res = 240, - .y_res = 320, - .pixel_clock = 12500, - .hsw = 40, - .hfp = 40, - .hbp = 72, - .vsw = 1, - .vfp = 1, - .vbp = 0, - .pcd = 12, - - .enable = innovator1510_panel_enable, - .disable = innovator1510_panel_disable, -}; - -static int innovator1510_panel_probe(struct platform_device *pdev) -{ - omap1510_fpga_lcd_panel_control = (void __iomem *)pdev->dev.platform_data; - omapfb_register_panel(&innovator1510_panel); - return 0; -} - -static struct platform_driver innovator1510_panel_driver = { - .probe = innovator1510_panel_probe, - .driver = { - .name = "lcd_inn1510", - }, -}; - -module_platform_driver(innovator1510_panel_driver); - -MODULE_AUTHOR("Imre Deak"); -MODULE_DESCRIPTION("LCD panel support for the TI OMAP1510 Innovator board"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/omap/lcd_inn1610.c b/drivers/video/fbdev/omap/lcd_inn1610.c deleted file mode 100644 index 901b28f35fab..000000000000 --- a/drivers/video/fbdev/omap/lcd_inn1610.c +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * LCD panel support for the TI OMAP1610 Innovator board - * - * Copyright (C) 2004 Nokia Corporation - * Author: Imre Deak <imre.deak@nokia.com> - */ - -#include <linux/module.h> -#include <linux/platform_device.h> - -#include <linux/gpio.h> -#include "omapfb.h" - -#define MODULE_NAME "omapfb-lcd_h3" - -static int innovator1610_panel_init(struct lcd_panel *panel, - struct omapfb_device *fbdev) -{ - int r = 0; - - /* configure GPIO(14, 15) as outputs */ - if (gpio_request_one(14, GPIOF_OUT_INIT_LOW, "lcd_en0")) { - pr_err(MODULE_NAME ": can't request GPIO 14\n"); - r = -1; - goto exit; - } - if (gpio_request_one(15, GPIOF_OUT_INIT_LOW, "lcd_en1")) { - pr_err(MODULE_NAME ": can't request GPIO 15\n"); - gpio_free(14); - r = -1; - goto exit; - } -exit: - return r; -} - -static void innovator1610_panel_cleanup(struct lcd_panel *panel) -{ - gpio_free(15); - gpio_free(14); -} - -static int innovator1610_panel_enable(struct lcd_panel *panel) -{ - /* set GPIO14 and GPIO15 high */ - gpio_set_value(14, 1); - gpio_set_value(15, 1); - return 0; -} - -static void innovator1610_panel_disable(struct lcd_panel *panel) -{ - /* set GPIO13, GPIO14 and GPIO15 low */ - gpio_set_value(14, 0); - gpio_set_value(15, 0); -} - -static struct lcd_panel innovator1610_panel = { - .name = "inn1610", - .config = OMAP_LCDC_PANEL_TFT, - - .bpp = 16, - .data_lines = 16, - .x_res = 320, - .y_res = 240, - .pixel_clock = 12500, - .hsw = 40, - .hfp = 40, - .hbp = 72, - .vsw = 1, - .vfp = 1, - .vbp = 0, - .pcd = 12, - - .init = innovator1610_panel_init, - .cleanup = innovator1610_panel_cleanup, - .enable = innovator1610_panel_enable, - .disable = innovator1610_panel_disable, -}; - -static int innovator1610_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&innovator1610_panel); - return 0; -} - -static struct platform_driver innovator1610_panel_driver = { - .probe = innovator1610_panel_probe, - .driver = { - .name = "lcd_inn1610", - }, -}; - -module_platform_driver(innovator1610_panel_driver); - -MODULE_AUTHOR("Imre Deak"); -MODULE_DESCRIPTION("LCD panel support for the TI OMAP1610 Innovator board"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/omap/lcd_palmtt.c b/drivers/video/fbdev/omap/lcd_palmtt.c deleted file mode 100644 index 703af0bc5c92..000000000000 --- a/drivers/video/fbdev/omap/lcd_palmtt.c +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * LCD panel support for Palm Tungsten|T - * Current version : Marek Vasut <marek.vasut@gmail.com> - * - * Modified from lcd_inn1510.c - */ - -/* -GPIO11 - backlight -GPIO12 - screen blanking -GPIO13 - screen blanking -*/ - -#include <linux/platform_device.h> -#include <linux/module.h> -#include <linux/io.h> -#include <linux/gpio.h> - -#include "omapfb.h" - -static unsigned long palmtt_panel_get_caps(struct lcd_panel *panel) -{ - return OMAPFB_CAPS_SET_BACKLIGHT; -} - -static struct lcd_panel palmtt_panel = { - .name = "palmtt", - .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | - OMAP_LCDC_INV_HSYNC | OMAP_LCDC_HSVS_RISING_EDGE | - OMAP_LCDC_HSVS_OPPOSITE, - .bpp = 16, - .data_lines = 16, - .x_res = 320, - .y_res = 320, - .pixel_clock = 10000, - .hsw = 4, - .hfp = 8, - .hbp = 28, - .vsw = 1, - .vfp = 8, - .vbp = 7, - .pcd = 0, - - .get_caps = palmtt_panel_get_caps, -}; - -static int palmtt_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&palmtt_panel); - return 0; -} - -static struct platform_driver palmtt_panel_driver = { - .probe = palmtt_panel_probe, - .driver = { - .name = "lcd_palmtt", - }, -}; - -module_platform_driver(palmtt_panel_driver); - -MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); -MODULE_DESCRIPTION("LCD panel support for Palm Tungsten|T"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/omap/lcd_palmz71.c b/drivers/video/fbdev/omap/lcd_palmz71.c deleted file mode 100644 index a955c908ab14..000000000000 --- a/drivers/video/fbdev/omap/lcd_palmz71.c +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * LCD panel support for the Palm Zire71 - * - * Original version : Romain Goyet - * Current version : Laurent Gonzalez - * Modified for zire71 : Marek Vasut - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/io.h> - -#include "omapfb.h" - -static unsigned long palmz71_panel_get_caps(struct lcd_panel *panel) -{ - return OMAPFB_CAPS_SET_BACKLIGHT; -} - -static struct lcd_panel palmz71_panel = { - .name = "palmz71", - .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | - OMAP_LCDC_INV_HSYNC | OMAP_LCDC_HSVS_RISING_EDGE | - OMAP_LCDC_HSVS_OPPOSITE, - .data_lines = 16, - .bpp = 16, - .pixel_clock = 24000, - .x_res = 320, - .y_res = 320, - .hsw = 4, - .hfp = 8, - .hbp = 28, - .vsw = 1, - .vfp = 8, - .vbp = 7, - .pcd = 0, - - .get_caps = palmz71_panel_get_caps, -}; - -static int palmz71_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&palmz71_panel); - return 0; -} - -static struct platform_driver palmz71_panel_driver = { - .probe = palmz71_panel_probe, - .driver = { - .name = "lcd_palmz71", - }, -}; - -module_platform_driver(palmz71_panel_driver); - -MODULE_AUTHOR("Romain Goyet, Laurent Gonzalez, Marek Vasut"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("LCD panel support for the Palm Zire71"); diff --git a/drivers/video/fbdev/omap/lcdc.c b/drivers/video/fbdev/omap/lcdc.c index e7ce783e5215..abb8b11464e8 100644 --- a/drivers/video/fbdev/omap/lcdc.c +++ b/drivers/video/fbdev/omap/lcdc.c @@ -706,8 +706,6 @@ static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode, if (machine_is_ams_delta()) rate /= 4; - if (machine_is_omap_h3()) - rate /= 3; r = clk_set_rate(lcdc.lcd_ck, rate); if (r) { dev_err(fbdev->dev, "failed to adjust LCD rate\n"); diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c index 4fc4b26a8d30..ba94a0a7bd4f 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c +++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c @@ -331,13 +331,7 @@ static int dsicm_bl_update_status(struct backlight_device *dev) struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev); struct omap_dss_device *in = ddata->in; int r; - int level; - - if (dev->props.fb_blank == FB_BLANK_UNBLANK && - dev->props.power == FB_BLANK_UNBLANK) - level = dev->props.brightness; - else - level = 0; + int level = backlight_get_brightness(dev); dev_dbg(&ddata->pdev->dev, "update brightness to %d\n", level); diff --git a/drivers/video/fbdev/omap2/omapfb/dss/display-sysfs.c b/drivers/video/fbdev/omap2/omapfb/dss/display-sysfs.c index bc5a44c2a144..ae937854403b 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/display-sysfs.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/display-sysfs.c @@ -10,6 +10,7 @@ #define DSS_SUBSYS_NAME "DISPLAY" #include <linux/kernel.h> +#include <linux/kstrtox.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/sysfs.h> @@ -36,7 +37,7 @@ static ssize_t display_enabled_store(struct omap_dss_device *dssdev, int r; bool enable; - r = strtobool(buf, &enable); + r = kstrtobool(buf, &enable); if (r) return r; @@ -73,7 +74,7 @@ static ssize_t display_tear_store(struct omap_dss_device *dssdev, if (!dssdev->driver->enable_te || !dssdev->driver->get_te) return -ENOENT; - r = strtobool(buf, &te); + r = kstrtobool(buf, &te); if (r) return r; @@ -183,7 +184,7 @@ static ssize_t display_mirror_store(struct omap_dss_device *dssdev, if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) return -ENOENT; - r = strtobool(buf, &mirror); + r = kstrtobool(buf, &mirror); if (r) return r; diff --git a/drivers/video/fbdev/omap2/omapfb/dss/manager-sysfs.c b/drivers/video/fbdev/omap2/omapfb/dss/manager-sysfs.c index ba21c4a2633d..1b644be5fe2e 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/manager-sysfs.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/manager-sysfs.c @@ -10,6 +10,7 @@ #define DSS_SUBSYS_NAME "MANAGER" #include <linux/kernel.h> +#include <linux/kstrtox.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -246,7 +247,7 @@ static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr, bool enable; int r; - r = strtobool(buf, &enable); + r = kstrtobool(buf, &enable); if (r) return r; @@ -290,7 +291,7 @@ static ssize_t manager_alpha_blending_enabled_store( if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) return -ENODEV; - r = strtobool(buf, &enable); + r = kstrtobool(buf, &enable); if (r) return r; @@ -329,7 +330,7 @@ static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr, if (!dss_has_feature(FEAT_CPR)) return -ENODEV; - r = strtobool(buf, &enable); + r = kstrtobool(buf, &enable); if (r) return r; diff --git a/drivers/video/fbdev/omap2/omapfb/dss/overlay-sysfs.c b/drivers/video/fbdev/omap2/omapfb/dss/overlay-sysfs.c index 601c0beb6de9..1da4fb1c77b4 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/overlay-sysfs.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/overlay-sysfs.c @@ -13,6 +13,7 @@ #include <linux/err.h> #include <linux/sysfs.h> #include <linux/kobject.h> +#include <linux/kstrtox.h> #include <linux/platform_device.h> #include <video/omapfb_dss.h> @@ -210,7 +211,7 @@ static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, int r; bool enable; - r = strtobool(buf, &enable); + r = kstrtobool(buf, &enable); if (r) return r; diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c index 06dc41aa0354..831b2c2fbdf9 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c @@ -15,6 +15,7 @@ #include <linux/uaccess.h> #include <linux/platform_device.h> #include <linux/kernel.h> +#include <linux/kstrtox.h> #include <linux/mm.h> #include <linux/omapfb.h> @@ -96,7 +97,7 @@ static ssize_t store_mirror(struct device *dev, int r; struct fb_var_screeninfo new_var; - r = strtobool(buf, &mirror); + r = kstrtobool(buf, &mirror); if (r) return r; diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index 644278146d3b..41edc6e79460 100644 --- a/drivers/video/fbdev/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -293,13 +293,7 @@ static int riva_bl_update_status(struct backlight_device *bd) { struct riva_par *par = bl_get_data(bd); U032 tmp_pcrt, tmp_pmc; - int level; - - if (bd->props.power != FB_BLANK_UNBLANK || - bd->props.fb_blank != FB_BLANK_UNBLANK) - level = 0; - else - level = bd->props.brightness; + int level = backlight_get_brightness(bd); tmp_pmc = NV_RD32(par->riva.PMC, 0x10F0) & 0x0000FFFF; tmp_pcrt = NV_RD32(par->riva.PCRTC0, 0x081C) & 0xFFFFFFFC; diff --git a/drivers/video/fbdev/s3c2410fb-regs-lcd.h b/drivers/video/fbdev/s3c2410fb-regs-lcd.h deleted file mode 100644 index 1e46f7a788e5..000000000000 --- a/drivers/video/fbdev/s3c2410fb-regs-lcd.h +++ /dev/null @@ -1,143 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - */ - -#ifndef ___ASM_ARCH_REGS_LCD_H -#define ___ASM_ARCH_REGS_LCD_H - -/* - * a couple of values are used as platform data in - * include/linux/platform_data/fb-s3c2410.h and not - * duplicated here. - */ -#include <linux/platform_data/fb-s3c2410.h> - -#define S3C2410_LCDREG(x) (x) - -/* LCD control registers */ -#define S3C2410_LCDCON1 S3C2410_LCDREG(0x00) -#define S3C2410_LCDCON2 S3C2410_LCDREG(0x04) -#define S3C2410_LCDCON3 S3C2410_LCDREG(0x08) -#define S3C2410_LCDCON4 S3C2410_LCDREG(0x0C) -#define S3C2410_LCDCON5 S3C2410_LCDREG(0x10) - -#define S3C2410_LCDCON1_CLKVAL(x) ((x) << 8) -#define S3C2410_LCDCON1_MMODE (1<<7) -#define S3C2410_LCDCON1_DSCAN4 (0<<5) -#define S3C2410_LCDCON1_STN4 (1<<5) -#define S3C2410_LCDCON1_STN8 (2<<5) -#define S3C2410_LCDCON1_TFT (3<<5) - -#define S3C2410_LCDCON1_STN1BPP (0<<1) -#define S3C2410_LCDCON1_STN2GREY (1<<1) -#define S3C2410_LCDCON1_STN4GREY (2<<1) -#define S3C2410_LCDCON1_STN8BPP (3<<1) -#define S3C2410_LCDCON1_STN12BPP (4<<1) - -#define S3C2410_LCDCON1_ENVID (1) - -#define S3C2410_LCDCON1_MODEMASK 0x1E - -#define S3C2410_LCDCON2_VBPD(x) ((x) << 24) -#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14) -#define S3C2410_LCDCON2_VFPD(x) ((x) << 6) -#define S3C2410_LCDCON2_VSPW(x) ((x) << 0) - -#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF) -#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >> 6) & 0xFF) -#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >> 0) & 0x3F) - -#define S3C2410_LCDCON3_HBPD(x) ((x) << 19) -#define S3C2410_LCDCON3_WDLY(x) ((x) << 19) -#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8) -#define S3C2410_LCDCON3_HFPD(x) ((x) << 0) -#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0) - -#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F) -#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >> 0) & 0xFF) - -/* LDCCON4 changes for STN mode on the S3C2412 */ - -#define S3C2410_LCDCON4_MVAL(x) ((x) << 8) -#define S3C2410_LCDCON4_HSPW(x) ((x) << 0) -#define S3C2410_LCDCON4_WLH(x) ((x) << 0) - -#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >> 0) & 0xFF) - -/* framebuffer start addressed */ -#define S3C2410_LCDSADDR1 S3C2410_LCDREG(0x14) -#define S3C2410_LCDSADDR2 S3C2410_LCDREG(0x18) -#define S3C2410_LCDSADDR3 S3C2410_LCDREG(0x1C) - -#define S3C2410_LCDBANK(x) ((x) << 21) -#define S3C2410_LCDBASEU(x) (x) - -#define S3C2410_OFFSIZE(x) ((x) << 11) -#define S3C2410_PAGEWIDTH(x) (x) - -/* colour lookup and miscellaneous controls */ - -#define S3C2410_REDLUT S3C2410_LCDREG(0x20) -#define S3C2410_GREENLUT S3C2410_LCDREG(0x24) -#define S3C2410_BLUELUT S3C2410_LCDREG(0x28) - -#define S3C2410_DITHMODE S3C2410_LCDREG(0x4C) -#define S3C2410_TPAL S3C2410_LCDREG(0x50) - -#define S3C2410_TPAL_EN (1<<24) - -/* interrupt info */ -#define S3C2410_LCDINTPND S3C2410_LCDREG(0x54) -#define S3C2410_LCDSRCPND S3C2410_LCDREG(0x58) -#define S3C2410_LCDINTMSK S3C2410_LCDREG(0x5C) -#define S3C2410_LCDINT_FIWSEL (1<<2) -#define S3C2410_LCDINT_FRSYNC (1<<1) -#define S3C2410_LCDINT_FICNT (1<<0) - -/* s3c2442 extra stn registers */ - -#define S3C2442_REDLUT S3C2410_LCDREG(0x20) -#define S3C2442_GREENLUT S3C2410_LCDREG(0x24) -#define S3C2442_BLUELUT S3C2410_LCDREG(0x28) -#define S3C2442_DITHMODE S3C2410_LCDREG(0x20) - -#define S3C2410_LPCSEL S3C2410_LCDREG(0x60) - -#define S3C2410_TFTPAL(x) S3C2410_LCDREG((0x400 + (x)*4)) - -/* S3C2412 registers */ - -#define S3C2412_TPAL S3C2410_LCDREG(0x20) - -#define S3C2412_LCDINTPND S3C2410_LCDREG(0x24) -#define S3C2412_LCDSRCPND S3C2410_LCDREG(0x28) -#define S3C2412_LCDINTMSK S3C2410_LCDREG(0x2C) - -#define S3C2412_TCONSEL S3C2410_LCDREG(0x30) - -#define S3C2412_LCDCON6 S3C2410_LCDREG(0x34) -#define S3C2412_LCDCON7 S3C2410_LCDREG(0x38) -#define S3C2412_LCDCON8 S3C2410_LCDREG(0x3C) -#define S3C2412_LCDCON9 S3C2410_LCDREG(0x40) - -#define S3C2412_REDLUT(x) S3C2410_LCDREG(0x44 + ((x)*4)) -#define S3C2412_GREENLUT(x) S3C2410_LCDREG(0x60 + ((x)*4)) -#define S3C2412_BLUELUT(x) S3C2410_LCDREG(0x98 + ((x)*4)) - -#define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4)) - -/* general registers */ - -/* base of the LCD registers, where INTPND, INTSRC and then INTMSK - * are available. */ - -#define S3C2410_LCDINTBASE S3C2410_LCDREG(0x54) -#define S3C2412_LCDINTBASE S3C2410_LCDREG(0x24) - -#define S3C24XX_LCDINTPND (0x00) -#define S3C24XX_LCDSRCPND (0x04) -#define S3C24XX_LCDINTMSK (0x08) - -#endif /* ___ASM_ARCH_REGS_LCD_H */ diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c deleted file mode 100644 index d8ae5258de46..000000000000 --- a/drivers/video/fbdev/s3c2410fb.c +++ /dev/null @@ -1,1142 +0,0 @@ -/* linux/drivers/video/s3c2410fb.c - * Copyright (c) 2004,2005 Arnaud Patard - * Copyright (c) 2004-2008 Ben Dooks - * - * S3C2410 LCD Framebuffer Driver - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - * - * Driver based on skeletonfb.c, sa1100fb.c and others. -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/err.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/cpufreq.h> -#include <linux/io.h> -#include <linux/platform_data/fb-s3c2410.h> - -#include <asm/div64.h> - -#include <asm/mach/map.h> - -#ifdef CONFIG_PM -#include <linux/pm.h> -#endif - -#include "s3c2410fb.h" -#include "s3c2410fb-regs-lcd.h" - -/* Debugging stuff */ -static int debug = IS_BUILTIN(CONFIG_FB_S3C2410_DEBUG); - -#define dprintk(msg...) \ -do { \ - if (debug) \ - pr_debug(msg); \ -} while (0) - -/* useful functions */ - -static int is_s3c2412(struct s3c2410fb_info *fbi) -{ - return (fbi->drv_type == DRV_S3C2412); -} - -/* s3c2410fb_set_lcdaddr - * - * initialise lcd controller address pointers - */ -static void s3c2410fb_set_lcdaddr(struct fb_info *info) -{ - unsigned long saddr1, saddr2, saddr3; - struct s3c2410fb_info *fbi = info->par; - void __iomem *regs = fbi->io; - - saddr1 = info->fix.smem_start >> 1; - saddr2 = info->fix.smem_start; - saddr2 += info->fix.line_length * info->var.yres; - saddr2 >>= 1; - - saddr3 = S3C2410_OFFSIZE(0) | - S3C2410_PAGEWIDTH((info->fix.line_length / 2) & 0x3ff); - - dprintk("LCDSADDR1 = 0x%08lx\n", saddr1); - dprintk("LCDSADDR2 = 0x%08lx\n", saddr2); - dprintk("LCDSADDR3 = 0x%08lx\n", saddr3); - - writel(saddr1, regs + S3C2410_LCDSADDR1); - writel(saddr2, regs + S3C2410_LCDSADDR2); - writel(saddr3, regs + S3C2410_LCDSADDR3); -} - -/* s3c2410fb_calc_pixclk() - * - * calculate divisor for clk->pixclk - */ -static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, - unsigned long pixclk) -{ - unsigned long clk = fbi->clk_rate; - unsigned long long div; - - /* pixclk is in picoseconds, our clock is in Hz - * - * Hz -> picoseconds is / 10^-12 - */ - - div = (unsigned long long)clk * pixclk; - div >>= 12; /* div / 2^12 */ - do_div(div, 625 * 625UL * 625); /* div / 5^12 */ - - dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div); - return div; -} - -/* - * s3c2410fb_check_var(): - * Get the video params out of 'var'. If a value doesn't fit, round it up, - * if it's too big, return -EINVAL. - * - */ -static int s3c2410fb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - struct s3c2410fb_info *fbi = info->par; - struct s3c2410fb_mach_info *mach_info = dev_get_platdata(fbi->dev); - struct s3c2410fb_display *display = NULL; - struct s3c2410fb_display *default_display = mach_info->displays + - mach_info->default_display; - int type = default_display->type; - unsigned i; - - dprintk("check_var(var=%p, info=%p)\n", var, info); - - /* validate x/y resolution */ - /* choose default mode if possible */ - if (var->yres == default_display->yres && - var->xres == default_display->xres && - var->bits_per_pixel == default_display->bpp) - display = default_display; - else - for (i = 0; i < mach_info->num_displays; i++) - if (type == mach_info->displays[i].type && - var->yres == mach_info->displays[i].yres && - var->xres == mach_info->displays[i].xres && - var->bits_per_pixel == mach_info->displays[i].bpp) { - display = mach_info->displays + i; - break; - } - - if (!display) { - dprintk("wrong resolution or depth %dx%d at %d bpp\n", - var->xres, var->yres, var->bits_per_pixel); - return -EINVAL; - } - - /* it is always the size as the display */ - var->xres_virtual = display->xres; - var->yres_virtual = display->yres; - var->height = display->height; - var->width = display->width; - - /* copy lcd settings */ - var->pixclock = display->pixclock; - var->left_margin = display->left_margin; - var->right_margin = display->right_margin; - var->upper_margin = display->upper_margin; - var->lower_margin = display->lower_margin; - var->vsync_len = display->vsync_len; - var->hsync_len = display->hsync_len; - - fbi->regs.lcdcon5 = display->lcdcon5; - /* set display type */ - fbi->regs.lcdcon1 = display->type; - - var->transp.offset = 0; - var->transp.length = 0; - /* set r/g/b positions */ - switch (var->bits_per_pixel) { - case 1: - case 2: - case 4: - var->red.offset = 0; - var->red.length = var->bits_per_pixel; - var->green = var->red; - var->blue = var->red; - break; - case 8: - if (display->type != S3C2410_LCDCON1_TFT) { - /* 8 bpp 332 */ - var->red.length = 3; - var->red.offset = 5; - var->green.length = 3; - var->green.offset = 2; - var->blue.length = 2; - var->blue.offset = 0; - } else { - var->red.offset = 0; - var->red.length = 8; - var->green = var->red; - var->blue = var->red; - } - break; - case 12: - /* 12 bpp 444 */ - var->red.length = 4; - var->red.offset = 8; - var->green.length = 4; - var->green.offset = 4; - var->blue.length = 4; - var->blue.offset = 0; - break; - - default: - case 16: - if (display->lcdcon5 & S3C2410_LCDCON5_FRM565) { - /* 16 bpp, 565 format */ - var->red.offset = 11; - var->green.offset = 5; - var->blue.offset = 0; - var->red.length = 5; - var->green.length = 6; - var->blue.length = 5; - } else { - /* 16 bpp, 5551 format */ - var->red.offset = 11; - var->green.offset = 6; - var->blue.offset = 1; - var->red.length = 5; - var->green.length = 5; - var->blue.length = 5; - } - break; - case 32: - /* 24 bpp 888 and 8 dummy */ - var->red.length = 8; - var->red.offset = 16; - var->green.length = 8; - var->green.offset = 8; - var->blue.length = 8; - var->blue.offset = 0; - break; - } - return 0; -} - -/* s3c2410fb_calculate_stn_lcd_regs - * - * calculate register values from var settings - */ -static void s3c2410fb_calculate_stn_lcd_regs(const struct fb_info *info, - struct s3c2410fb_hw *regs) -{ - const struct s3c2410fb_info *fbi = info->par; - const struct fb_var_screeninfo *var = &info->var; - int type = regs->lcdcon1 & ~S3C2410_LCDCON1_TFT; - int hs = var->xres >> 2; - unsigned wdly = (var->left_margin >> 4) - 1; - unsigned wlh = (var->hsync_len >> 4) - 1; - - if (type != S3C2410_LCDCON1_STN4) - hs >>= 1; - - switch (var->bits_per_pixel) { - case 1: - regs->lcdcon1 |= S3C2410_LCDCON1_STN1BPP; - break; - case 2: - regs->lcdcon1 |= S3C2410_LCDCON1_STN2GREY; - break; - case 4: - regs->lcdcon1 |= S3C2410_LCDCON1_STN4GREY; - break; - case 8: - regs->lcdcon1 |= S3C2410_LCDCON1_STN8BPP; - hs *= 3; - break; - case 12: - regs->lcdcon1 |= S3C2410_LCDCON1_STN12BPP; - hs *= 3; - break; - - default: - /* invalid pixel depth */ - dev_err(fbi->dev, "invalid bpp %d\n", - var->bits_per_pixel); - } - /* update X/Y info */ - dprintk("setting horz: lft=%d, rt=%d, sync=%d\n", - var->left_margin, var->right_margin, var->hsync_len); - - regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1); - - if (wdly > 3) - wdly = 3; - - if (wlh > 3) - wlh = 3; - - regs->lcdcon3 = S3C2410_LCDCON3_WDLY(wdly) | - S3C2410_LCDCON3_LINEBLANK(var->right_margin / 8) | - S3C2410_LCDCON3_HOZVAL(hs - 1); - - regs->lcdcon4 = S3C2410_LCDCON4_WLH(wlh); -} - -/* s3c2410fb_calculate_tft_lcd_regs - * - * calculate register values from var settings - */ -static void s3c2410fb_calculate_tft_lcd_regs(const struct fb_info *info, - struct s3c2410fb_hw *regs) -{ - const struct s3c2410fb_info *fbi = info->par; - const struct fb_var_screeninfo *var = &info->var; - - switch (var->bits_per_pixel) { - case 1: - regs->lcdcon1 |= S3C2410_LCDCON1_TFT1BPP; - break; - case 2: - regs->lcdcon1 |= S3C2410_LCDCON1_TFT2BPP; - break; - case 4: - regs->lcdcon1 |= S3C2410_LCDCON1_TFT4BPP; - break; - case 8: - regs->lcdcon1 |= S3C2410_LCDCON1_TFT8BPP; - regs->lcdcon5 |= S3C2410_LCDCON5_BSWP | - S3C2410_LCDCON5_FRM565; - regs->lcdcon5 &= ~S3C2410_LCDCON5_HWSWP; - break; - case 16: - regs->lcdcon1 |= S3C2410_LCDCON1_TFT16BPP; - regs->lcdcon5 &= ~S3C2410_LCDCON5_BSWP; - regs->lcdcon5 |= S3C2410_LCDCON5_HWSWP; - break; - case 32: - regs->lcdcon1 |= S3C2410_LCDCON1_TFT24BPP; - regs->lcdcon5 &= ~(S3C2410_LCDCON5_BSWP | - S3C2410_LCDCON5_HWSWP | - S3C2410_LCDCON5_BPP24BL); - break; - default: - /* invalid pixel depth */ - dev_err(fbi->dev, "invalid bpp %d\n", - var->bits_per_pixel); - } - /* update X/Y info */ - dprintk("setting vert: up=%d, low=%d, sync=%d\n", - var->upper_margin, var->lower_margin, var->vsync_len); - - dprintk("setting horz: lft=%d, rt=%d, sync=%d\n", - var->left_margin, var->right_margin, var->hsync_len); - - regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1) | - S3C2410_LCDCON2_VBPD(var->upper_margin - 1) | - S3C2410_LCDCON2_VFPD(var->lower_margin - 1) | - S3C2410_LCDCON2_VSPW(var->vsync_len - 1); - - regs->lcdcon3 = S3C2410_LCDCON3_HBPD(var->right_margin - 1) | - S3C2410_LCDCON3_HFPD(var->left_margin - 1) | - S3C2410_LCDCON3_HOZVAL(var->xres - 1); - - regs->lcdcon4 = S3C2410_LCDCON4_HSPW(var->hsync_len - 1); -} - -/* s3c2410fb_activate_var - * - * activate (set) the controller from the given framebuffer - * information - */ -static void s3c2410fb_activate_var(struct fb_info *info) -{ - struct s3c2410fb_info *fbi = info->par; - void __iomem *regs = fbi->io; - int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT; - struct fb_var_screeninfo *var = &info->var; - int clkdiv; - - clkdiv = DIV_ROUND_UP(s3c2410fb_calc_pixclk(fbi, var->pixclock), 2); - - dprintk("%s: var->xres = %d\n", __func__, var->xres); - dprintk("%s: var->yres = %d\n", __func__, var->yres); - dprintk("%s: var->bpp = %d\n", __func__, var->bits_per_pixel); - - if (type == S3C2410_LCDCON1_TFT) { - s3c2410fb_calculate_tft_lcd_regs(info, &fbi->regs); - --clkdiv; - if (clkdiv < 0) - clkdiv = 0; - } else { - s3c2410fb_calculate_stn_lcd_regs(info, &fbi->regs); - if (clkdiv < 2) - clkdiv = 2; - } - - fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv); - - /* write new registers */ - - dprintk("new register set:\n"); - dprintk("lcdcon[1] = 0x%08lx\n", fbi->regs.lcdcon1); - dprintk("lcdcon[2] = 0x%08lx\n", fbi->regs.lcdcon2); - dprintk("lcdcon[3] = 0x%08lx\n", fbi->regs.lcdcon3); - dprintk("lcdcon[4] = 0x%08lx\n", fbi->regs.lcdcon4); - dprintk("lcdcon[5] = 0x%08lx\n", fbi->regs.lcdcon5); - - writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID, - regs + S3C2410_LCDCON1); - writel(fbi->regs.lcdcon2, regs + S3C2410_LCDCON2); - writel(fbi->regs.lcdcon3, regs + S3C2410_LCDCON3); - writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4); - writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5); - - /* set lcd address pointers */ - s3c2410fb_set_lcdaddr(info); - - fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID, - writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1); -} - -/* - * s3c2410fb_set_par - Alters the hardware state. - * @info: frame buffer structure that represents a single frame buffer - * - */ -static int s3c2410fb_set_par(struct fb_info *info) -{ - struct fb_var_screeninfo *var = &info->var; - - switch (var->bits_per_pixel) { - case 32: - case 16: - case 12: - info->fix.visual = FB_VISUAL_TRUECOLOR; - break; - case 1: - info->fix.visual = FB_VISUAL_MONO01; - break; - default: - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - break; - } - - info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; - - /* activate this new configuration */ - - s3c2410fb_activate_var(info); - return 0; -} - -static void schedule_palette_update(struct s3c2410fb_info *fbi, - unsigned int regno, unsigned int val) -{ - unsigned long flags; - unsigned long irqen; - void __iomem *irq_base = fbi->irq_base; - - local_irq_save(flags); - - fbi->palette_buffer[regno] = val; - - if (!fbi->palette_ready) { - fbi->palette_ready = 1; - - /* enable IRQ */ - irqen = readl(irq_base + S3C24XX_LCDINTMSK); - irqen &= ~S3C2410_LCDINT_FRSYNC; - writel(irqen, irq_base + S3C24XX_LCDINTMSK); - } - - local_irq_restore(flags); -} - -/* from pxafb.c */ -static inline unsigned int chan_to_field(unsigned int chan, - struct fb_bitfield *bf) -{ - chan &= 0xffff; - chan >>= 16 - bf->length; - return chan << bf->offset; -} - -static int s3c2410fb_setcolreg(unsigned regno, - unsigned red, unsigned green, unsigned blue, - unsigned transp, struct fb_info *info) -{ - struct s3c2410fb_info *fbi = info->par; - void __iomem *regs = fbi->io; - unsigned int val; - - /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n", - regno, red, green, blue); */ - - switch (info->fix.visual) { - case FB_VISUAL_TRUECOLOR: - /* true-colour, use pseudo-palette */ - - if (regno < 16) { - u32 *pal = info->pseudo_palette; - - val = chan_to_field(red, &info->var.red); - val |= chan_to_field(green, &info->var.green); - val |= chan_to_field(blue, &info->var.blue); - - pal[regno] = val; - } - break; - - case FB_VISUAL_PSEUDOCOLOR: - if (regno < 256) { - /* currently assume RGB 5-6-5 mode */ - - val = (red >> 0) & 0xf800; - val |= (green >> 5) & 0x07e0; - val |= (blue >> 11) & 0x001f; - - writel(val, regs + S3C2410_TFTPAL(regno)); - schedule_palette_update(fbi, regno, val); - } - - break; - - default: - return 1; /* unknown type */ - } - - return 0; -} - -/* s3c2410fb_lcd_enable - * - * shutdown the lcd controller - */ -static void s3c2410fb_lcd_enable(struct s3c2410fb_info *fbi, int enable) -{ - unsigned long flags; - - local_irq_save(flags); - - if (enable) - fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID; - else - fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; - - writel(fbi->regs.lcdcon1, fbi->io + S3C2410_LCDCON1); - - local_irq_restore(flags); -} - - -/* - * s3c2410fb_blank - * @blank_mode: the blank mode we want. - * @info: frame buffer structure that represents a single frame buffer - * - * Blank the screen if blank_mode != 0, else unblank. Return 0 if - * blanking succeeded, != 0 if un-/blanking failed due to e.g. a - * video mode which doesn't support it. Implements VESA suspend - * and powerdown modes on hardware that supports disabling hsync/vsync: - * - * Returns negative errno on error, or zero on success. - * - */ -static int s3c2410fb_blank(int blank_mode, struct fb_info *info) -{ - struct s3c2410fb_info *fbi = info->par; - void __iomem *tpal_reg = fbi->io; - - dprintk("blank(mode=%d, info=%p)\n", blank_mode, info); - - tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL; - - if (blank_mode == FB_BLANK_POWERDOWN) - s3c2410fb_lcd_enable(fbi, 0); - else - s3c2410fb_lcd_enable(fbi, 1); - - if (blank_mode == FB_BLANK_UNBLANK) - writel(0x0, tpal_reg); - else { - dprintk("setting TPAL to output 0x000000\n"); - writel(S3C2410_TPAL_EN, tpal_reg); - } - - return 0; -} - -static int s3c2410fb_debug_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off"); -} - -static int s3c2410fb_debug_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - if (len < 1) - return -EINVAL; - - if (strncasecmp(buf, "on", 2) == 0 || - strncasecmp(buf, "1", 1) == 0) { - debug = 1; - dev_dbg(dev, "s3c2410fb: Debug On"); - } else if (strncasecmp(buf, "off", 3) == 0 || - strncasecmp(buf, "0", 1) == 0) { - debug = 0; - dev_dbg(dev, "s3c2410fb: Debug Off"); - } else { - return -EINVAL; - } - - return len; -} - -static DEVICE_ATTR(debug, 0664, s3c2410fb_debug_show, s3c2410fb_debug_store); - -static const struct fb_ops s3c2410fb_ops = { - .owner = THIS_MODULE, - .fb_check_var = s3c2410fb_check_var, - .fb_set_par = s3c2410fb_set_par, - .fb_blank = s3c2410fb_blank, - .fb_setcolreg = s3c2410fb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -}; - -/* - * s3c2410fb_map_video_memory(): - * Allocates the DRAM memory for the frame buffer. This buffer is - * remapped into a non-cached, non-buffered, memory region to - * allow palette and pixel writes to occur without flushing the - * cache. Once this area is remapped, all virtual memory - * access to the video memory should occur at the new region. - */ -static int s3c2410fb_map_video_memory(struct fb_info *info) -{ - struct s3c2410fb_info *fbi = info->par; - dma_addr_t map_dma; - unsigned map_size = PAGE_ALIGN(info->fix.smem_len); - - dprintk("map_video_memory(fbi=%p) map_size %u\n", fbi, map_size); - - info->screen_base = dma_alloc_wc(fbi->dev, map_size, &map_dma, - GFP_KERNEL); - - if (info->screen_base) { - /* prevent initial garbage on screen */ - dprintk("map_video_memory: clear %p:%08x\n", - info->screen_base, map_size); - memset(info->screen_base, 0x00, map_size); - - info->fix.smem_start = map_dma; - - dprintk("map_video_memory: dma=%08lx cpu=%p size=%08x\n", - info->fix.smem_start, info->screen_base, map_size); - } - - return info->screen_base ? 0 : -ENOMEM; -} - -static inline void s3c2410fb_unmap_video_memory(struct fb_info *info) -{ - struct s3c2410fb_info *fbi = info->par; - - dma_free_wc(fbi->dev, PAGE_ALIGN(info->fix.smem_len), - info->screen_base, info->fix.smem_start); -} - -static inline void modify_gpio(void __iomem *reg, - unsigned long set, unsigned long mask) -{ - unsigned long tmp; - - if (!reg) - return; - - tmp = readl(reg) & ~mask; - writel(tmp | set, reg); -} - -/* - * s3c2410fb_init_registers - Initialise all LCD-related registers - */ -static int s3c2410fb_init_registers(struct fb_info *info) -{ - struct s3c2410fb_info *fbi = info->par; - struct s3c2410fb_mach_info *mach_info = dev_get_platdata(fbi->dev); - unsigned long flags; - void __iomem *regs = fbi->io; - void __iomem *tpal; - void __iomem *lpcsel; - - if (is_s3c2412(fbi)) { - tpal = regs + S3C2412_TPAL; - lpcsel = regs + S3C2412_TCONSEL; - } else { - tpal = regs + S3C2410_TPAL; - lpcsel = regs + S3C2410_LPCSEL; - } - - /* Initialise LCD with values from haret */ - - local_irq_save(flags); - - /* modify the gpio(s) with interrupts set (bjd) */ - - modify_gpio(mach_info->gpcup_reg, mach_info->gpcup, mach_info->gpcup_mask); - modify_gpio(mach_info->gpccon_reg, mach_info->gpccon, mach_info->gpccon_mask); - modify_gpio(mach_info->gpdup_reg, mach_info->gpdup, mach_info->gpdup_mask); - modify_gpio(mach_info->gpdcon_reg, mach_info->gpdcon, mach_info->gpdcon_mask); - - local_irq_restore(flags); - - dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); - writel(mach_info->lpcsel, lpcsel); - - dprintk("replacing TPAL %08x\n", readl(tpal)); - - /* ensure temporary palette disabled */ - writel(0x00, tpal); - - return 0; -} - -static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi) -{ - unsigned int i; - void __iomem *regs = fbi->io; - - fbi->palette_ready = 0; - - for (i = 0; i < 256; i++) { - unsigned long ent = fbi->palette_buffer[i]; - if (ent == PALETTE_BUFF_CLEAR) - continue; - - writel(ent, regs + S3C2410_TFTPAL(i)); - - /* it seems the only way to know exactly - * if the palette wrote ok, is to check - * to see if the value verifies ok - */ - - if (readw(regs + S3C2410_TFTPAL(i)) == ent) - fbi->palette_buffer[i] = PALETTE_BUFF_CLEAR; - else - fbi->palette_ready = 1; /* retry */ - } -} - -static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) -{ - struct s3c2410fb_info *fbi = dev_id; - void __iomem *irq_base = fbi->irq_base; - unsigned long lcdirq = readl(irq_base + S3C24XX_LCDINTPND); - - if (lcdirq & S3C2410_LCDINT_FRSYNC) { - if (fbi->palette_ready) - s3c2410fb_write_palette(fbi); - - writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDINTPND); - writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDSRCPND); - } - - return IRQ_HANDLED; -} - -#ifdef CONFIG_ARM_S3C24XX_CPUFREQ - -static int s3c2410fb_cpufreq_transition(struct notifier_block *nb, - unsigned long val, void *data) -{ - struct s3c2410fb_info *info; - struct fb_info *fbinfo; - long delta_f; - - info = container_of(nb, struct s3c2410fb_info, freq_transition); - fbinfo = dev_get_drvdata(info->dev); - - /* work out change, <0 for speed-up */ - delta_f = info->clk_rate - clk_get_rate(info->clk); - - if ((val == CPUFREQ_POSTCHANGE && delta_f > 0) || - (val == CPUFREQ_PRECHANGE && delta_f < 0)) { - info->clk_rate = clk_get_rate(info->clk); - s3c2410fb_activate_var(fbinfo); - } - - return 0; -} - -static inline int s3c2410fb_cpufreq_register(struct s3c2410fb_info *info) -{ - info->freq_transition.notifier_call = s3c2410fb_cpufreq_transition; - - return cpufreq_register_notifier(&info->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -} - -static inline void s3c2410fb_cpufreq_deregister(struct s3c2410fb_info *info) -{ - cpufreq_unregister_notifier(&info->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -} - -#else -static inline int s3c2410fb_cpufreq_register(struct s3c2410fb_info *info) -{ - return 0; -} - -static inline void s3c2410fb_cpufreq_deregister(struct s3c2410fb_info *info) -{ -} -#endif - - -static const char driver_name[] = "s3c2410fb"; - -static int s3c24xxfb_probe(struct platform_device *pdev, - enum s3c_drv_type drv_type) -{ - struct s3c2410fb_info *info; - struct s3c2410fb_display *display; - struct fb_info *fbinfo; - struct s3c2410fb_mach_info *mach_info; - struct resource *res; - int ret; - int irq; - int i; - int size; - u32 lcdcon1; - - mach_info = dev_get_platdata(&pdev->dev); - if (mach_info == NULL) { - dev_err(&pdev->dev, - "no platform data for lcd, cannot attach\n"); - return -EINVAL; - } - - if (mach_info->default_display >= mach_info->num_displays) { - dev_err(&pdev->dev, "default is %d but only %d displays\n", - mach_info->default_display, mach_info->num_displays); - return -EINVAL; - } - - display = mach_info->displays + mach_info->default_display; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no irq for device\n"); - return -ENOENT; - } - - fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev); - if (!fbinfo) - return -ENOMEM; - - platform_set_drvdata(pdev, fbinfo); - - info = fbinfo->par; - info->dev = &pdev->dev; - info->drv_type = drv_type; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "failed to get memory registers\n"); - ret = -ENXIO; - goto dealloc_fb; - } - - size = resource_size(res); - info->mem = request_mem_region(res->start, size, pdev->name); - if (info->mem == NULL) { - dev_err(&pdev->dev, "failed to get memory region\n"); - ret = -ENOENT; - goto dealloc_fb; - } - - info->io = ioremap(res->start, size); - if (info->io == NULL) { - dev_err(&pdev->dev, "ioremap() of registers failed\n"); - ret = -ENXIO; - goto release_mem; - } - - if (drv_type == DRV_S3C2412) - info->irq_base = info->io + S3C2412_LCDINTBASE; - else - info->irq_base = info->io + S3C2410_LCDINTBASE; - - dprintk("devinit\n"); - - strcpy(fbinfo->fix.id, driver_name); - - /* Stop the video */ - lcdcon1 = readl(info->io + S3C2410_LCDCON1); - writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1); - - fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; - fbinfo->fix.type_aux = 0; - fbinfo->fix.xpanstep = 0; - fbinfo->fix.ypanstep = 0; - fbinfo->fix.ywrapstep = 0; - fbinfo->fix.accel = FB_ACCEL_NONE; - - fbinfo->var.nonstd = 0; - fbinfo->var.activate = FB_ACTIVATE_NOW; - fbinfo->var.accel_flags = 0; - fbinfo->var.vmode = FB_VMODE_NONINTERLACED; - - fbinfo->fbops = &s3c2410fb_ops; - fbinfo->flags = FBINFO_FLAG_DEFAULT; - fbinfo->pseudo_palette = &info->pseudo_pal; - - for (i = 0; i < 256; i++) - info->palette_buffer[i] = PALETTE_BUFF_CLEAR; - - ret = request_irq(irq, s3c2410fb_irq, 0, pdev->name, info); - if (ret) { - dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret); - ret = -EBUSY; - goto release_regs; - } - - info->clk = clk_get(NULL, "lcd"); - if (IS_ERR(info->clk)) { - dev_err(&pdev->dev, "failed to get lcd clock source\n"); - ret = PTR_ERR(info->clk); - goto release_irq; - } - - clk_prepare_enable(info->clk); - dprintk("got and enabled clock\n"); - - usleep_range(1000, 1100); - - info->clk_rate = clk_get_rate(info->clk); - - /* find maximum required memory size for display */ - for (i = 0; i < mach_info->num_displays; i++) { - unsigned long smem_len = mach_info->displays[i].xres; - - smem_len *= mach_info->displays[i].yres; - smem_len *= mach_info->displays[i].bpp; - smem_len >>= 3; - if (fbinfo->fix.smem_len < smem_len) - fbinfo->fix.smem_len = smem_len; - } - - /* Initialize video memory */ - ret = s3c2410fb_map_video_memory(fbinfo); - if (ret) { - dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret); - ret = -ENOMEM; - goto release_clock; - } - - dprintk("got video memory\n"); - - fbinfo->var.xres = display->xres; - fbinfo->var.yres = display->yres; - fbinfo->var.bits_per_pixel = display->bpp; - - s3c2410fb_init_registers(fbinfo); - - s3c2410fb_check_var(&fbinfo->var, fbinfo); - - ret = s3c2410fb_cpufreq_register(info); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register cpufreq\n"); - goto free_video_memory; - } - - ret = register_framebuffer(fbinfo); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register framebuffer device: %d\n", - ret); - goto free_cpufreq; - } - - /* create device files */ - ret = device_create_file(&pdev->dev, &dev_attr_debug); - if (ret) - dev_err(&pdev->dev, "failed to add debug attribute\n"); - - dev_info(&pdev->dev, "fb%d: %s frame buffer device\n", - fbinfo->node, fbinfo->fix.id); - - return 0; - - free_cpufreq: - s3c2410fb_cpufreq_deregister(info); -free_video_memory: - s3c2410fb_unmap_video_memory(fbinfo); -release_clock: - clk_disable_unprepare(info->clk); - clk_put(info->clk); -release_irq: - free_irq(irq, info); -release_regs: - iounmap(info->io); -release_mem: - release_mem_region(res->start, size); -dealloc_fb: - framebuffer_release(fbinfo); - return ret; -} - -static int s3c2410fb_probe(struct platform_device *pdev) -{ - return s3c24xxfb_probe(pdev, DRV_S3C2410); -} - -static int s3c2412fb_probe(struct platform_device *pdev) -{ - return s3c24xxfb_probe(pdev, DRV_S3C2412); -} - - -/* - * Cleanup - */ -static int s3c2410fb_remove(struct platform_device *pdev) -{ - struct fb_info *fbinfo = platform_get_drvdata(pdev); - struct s3c2410fb_info *info = fbinfo->par; - int irq; - - unregister_framebuffer(fbinfo); - s3c2410fb_cpufreq_deregister(info); - - s3c2410fb_lcd_enable(info, 0); - usleep_range(1000, 1100); - - s3c2410fb_unmap_video_memory(fbinfo); - - if (info->clk) { - clk_disable_unprepare(info->clk); - clk_put(info->clk); - info->clk = NULL; - } - - irq = platform_get_irq(pdev, 0); - free_irq(irq, info); - - iounmap(info->io); - - release_mem_region(info->mem->start, resource_size(info->mem)); - - framebuffer_release(fbinfo); - - return 0; -} - -#ifdef CONFIG_PM - -/* suspend and resume support for the lcd controller */ -static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) -{ - struct fb_info *fbinfo = platform_get_drvdata(dev); - struct s3c2410fb_info *info = fbinfo->par; - - s3c2410fb_lcd_enable(info, 0); - - /* sleep before disabling the clock, we need to ensure - * the LCD DMA engine is not going to get back on the bus - * before the clock goes off again (bjd) */ - - usleep_range(1000, 1100); - clk_disable_unprepare(info->clk); - - return 0; -} - -static int s3c2410fb_resume(struct platform_device *dev) -{ - struct fb_info *fbinfo = platform_get_drvdata(dev); - struct s3c2410fb_info *info = fbinfo->par; - - clk_prepare_enable(info->clk); - usleep_range(1000, 1100); - - s3c2410fb_init_registers(fbinfo); - - /* re-activate our display after resume */ - s3c2410fb_activate_var(fbinfo); - s3c2410fb_blank(FB_BLANK_UNBLANK, fbinfo); - - return 0; -} - -#else -#define s3c2410fb_suspend NULL -#define s3c2410fb_resume NULL -#endif - -static struct platform_driver s3c2410fb_driver = { - .probe = s3c2410fb_probe, - .remove = s3c2410fb_remove, - .suspend = s3c2410fb_suspend, - .resume = s3c2410fb_resume, - .driver = { - .name = "s3c2410-lcd", - }, -}; - -static struct platform_driver s3c2412fb_driver = { - .probe = s3c2412fb_probe, - .remove = s3c2410fb_remove, - .suspend = s3c2410fb_suspend, - .resume = s3c2410fb_resume, - .driver = { - .name = "s3c2412-lcd", - }, -}; - -int __init s3c2410fb_init(void) -{ - int ret = platform_driver_register(&s3c2410fb_driver); - - if (ret == 0) - ret = platform_driver_register(&s3c2412fb_driver); - - return ret; -} - -static void __exit s3c2410fb_cleanup(void) -{ - platform_driver_unregister(&s3c2410fb_driver); - platform_driver_unregister(&s3c2412fb_driver); -} - -module_init(s3c2410fb_init); -module_exit(s3c2410fb_cleanup); - -MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); -MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>"); -MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c2410-lcd"); -MODULE_ALIAS("platform:s3c2412-lcd"); diff --git a/drivers/video/fbdev/s3c2410fb.h b/drivers/video/fbdev/s3c2410fb.h deleted file mode 100644 index cdd11e2f8859..000000000000 --- a/drivers/video/fbdev/s3c2410fb.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/drivers/video/s3c2410fb.h - * Copyright (c) 2004 Arnaud Patard - * - * S3C2410 LCD Framebuffer Driver - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - * -*/ - -#ifndef __S3C2410FB_H -#define __S3C2410FB_H - -enum s3c_drv_type { - DRV_S3C2410, - DRV_S3C2412, -}; - -struct s3c2410fb_info { - struct device *dev; - struct clk *clk; - - struct resource *mem; - void __iomem *io; - void __iomem *irq_base; - - enum s3c_drv_type drv_type; - struct s3c2410fb_hw regs; - - unsigned long clk_rate; - unsigned int palette_ready; - -#ifdef CONFIG_ARM_S3C24XX_CPUFREQ - struct notifier_block freq_transition; -#endif - - /* keep these registers in case we need to re-write palette */ - u32 palette_buffer[256]; - u32 pseudo_pal[16]; -}; - -#define PALETTE_BUFF_CLEAR (0x80000000) /* entry is clear/invalid */ - -int s3c2410fb_init(void); - -#endif diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index 017c8efe8267..b1b8ccdbac4a 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -184,7 +184,6 @@ #include <mach/hardware.h> #include <asm/mach-types.h> -#include <mach/shannon.h> /* * Complain if VAR is out of range. diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index e770b4a356b5..10d71879d340 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -12,6 +12,7 @@ * Copyright (C) 1996 Paul Mackerras */ +#include <linux/aperture.h> #include <linux/errno.h> #include <linux/fb.h> #include <linux/io.h> @@ -68,6 +69,8 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, struct simplefb_par { u32 palette[PSEUDO_PALETTE_SIZE]; + resource_size_t base; + resource_size_t size; struct resource *mem; #if defined CONFIG_OF && defined CONFIG_COMMON_CLK bool clks_enabled; @@ -472,16 +475,11 @@ static int simplefb_probe(struct platform_device *pdev) info->var.blue = params.format->blue; info->var.transp = params.format->transp; - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto error_fb_release; - } - info->apertures->ranges[0].base = info->fix.smem_start; - info->apertures->ranges[0].size = info->fix.smem_len; + par->base = info->fix.smem_start; + par->size = info->fix.smem_len; info->fbops = &simplefb_ops; - info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE; + info->flags = FBINFO_DEFAULT; info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len); if (!info->screen_base) { @@ -511,6 +509,11 @@ static int simplefb_probe(struct platform_device *pdev) if (mem != res) par->mem = mem; /* release in clean-up handler */ + ret = devm_aperture_acquire_for_platform_device(pdev, par->base, par->size); + if (ret) { + dev_err(&pdev->dev, "Unable to acquire aperture: %d\n", ret); + goto error_regulators; + } ret = register_framebuffer(info); if (ret < 0) { dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); diff --git a/drivers/video/fbdev/tmiofb.c b/drivers/video/fbdev/tmiofb.c deleted file mode 100644 index 50111966c981..000000000000 --- a/drivers/video/fbdev/tmiofb.c +++ /dev/null @@ -1,1040 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller - * - * Copyright(C) 2005-2006 Chris Humbert - * Copyright(C) 2005 Dirk Opfer - * Copytight(C) 2007,2008 Dmitry Baryshkov - * - * Based on: - * drivers/video/w100fb.c - * code written by Sharp/Lineo for 2.4 kernels - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/fb.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -/* Why should fb driver call console functions? because console_lock() */ -#include <linux/console.h> -#include <linux/mfd/core.h> -#include <linux/mfd/tmio.h> -#include <linux/uaccess.h> - -/* - * accelerator commands - */ -#define TMIOFB_ACC_CSADR(x) (0x00000000 | ((x) & 0x001ffffe)) -#define TMIOFB_ACC_CHPIX(x) (0x01000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_CVPIX(x) (0x02000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_PSADR(x) (0x03000000 | ((x) & 0x00fffffe)) -#define TMIOFB_ACC_PHPIX(x) (0x04000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_PVPIX(x) (0x05000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_PHOFS(x) (0x06000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_PVOFS(x) (0x07000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_POADR(x) (0x08000000 | ((x) & 0x00fffffe)) -#define TMIOFB_ACC_RSTR(x) (0x09000000 | ((x) & 0x000000ff)) -#define TMIOFB_ACC_TCLOR(x) (0x0A000000 | ((x) & 0x0000ffff)) -#define TMIOFB_ACC_FILL(x) (0x0B000000 | ((x) & 0x0000ffff)) -#define TMIOFB_ACC_DSADR(x) (0x0C000000 | ((x) & 0x00fffffe)) -#define TMIOFB_ACC_SSADR(x) (0x0D000000 | ((x) & 0x00fffffe)) -#define TMIOFB_ACC_DHPIX(x) (0x0E000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_DVPIX(x) (0x0F000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_SHPIX(x) (0x10000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_SVPIX(x) (0x11000000 | ((x) & 0x000003ff)) -#define TMIOFB_ACC_LBINI(x) (0x12000000 | ((x) & 0x0000ffff)) -#define TMIOFB_ACC_LBK2(x) (0x13000000 | ((x) & 0x0000ffff)) -#define TMIOFB_ACC_SHBINI(x) (0x14000000 | ((x) & 0x0000ffff)) -#define TMIOFB_ACC_SHBK2(x) (0x15000000 | ((x) & 0x0000ffff)) -#define TMIOFB_ACC_SVBINI(x) (0x16000000 | ((x) & 0x0000ffff)) -#define TMIOFB_ACC_SVBK2(x) (0x17000000 | ((x) & 0x0000ffff)) - -#define TMIOFB_ACC_CMGO 0x20000000 -#define TMIOFB_ACC_CMGO_CEND 0x00000001 -#define TMIOFB_ACC_CMGO_INT 0x00000002 -#define TMIOFB_ACC_CMGO_CMOD 0x00000010 -#define TMIOFB_ACC_CMGO_CDVRV 0x00000020 -#define TMIOFB_ACC_CMGO_CDHRV 0x00000040 -#define TMIOFB_ACC_CMGO_RUND 0x00008000 -#define TMIOFB_ACC_SCGO 0x21000000 -#define TMIOFB_ACC_SCGO_CEND 0x00000001 -#define TMIOFB_ACC_SCGO_INT 0x00000002 -#define TMIOFB_ACC_SCGO_ROP3 0x00000004 -#define TMIOFB_ACC_SCGO_TRNS 0x00000008 -#define TMIOFB_ACC_SCGO_DVRV 0x00000010 -#define TMIOFB_ACC_SCGO_DHRV 0x00000020 -#define TMIOFB_ACC_SCGO_SVRV 0x00000040 -#define TMIOFB_ACC_SCGO_SHRV 0x00000080 -#define TMIOFB_ACC_SCGO_DSTXY 0x00008000 -#define TMIOFB_ACC_SBGO 0x22000000 -#define TMIOFB_ACC_SBGO_CEND 0x00000001 -#define TMIOFB_ACC_SBGO_INT 0x00000002 -#define TMIOFB_ACC_SBGO_DVRV 0x00000010 -#define TMIOFB_ACC_SBGO_DHRV 0x00000020 -#define TMIOFB_ACC_SBGO_SVRV 0x00000040 -#define TMIOFB_ACC_SBGO_SHRV 0x00000080 -#define TMIOFB_ACC_SBGO_SBMD 0x00000100 -#define TMIOFB_ACC_FLGO 0x23000000 -#define TMIOFB_ACC_FLGO_CEND 0x00000001 -#define TMIOFB_ACC_FLGO_INT 0x00000002 -#define TMIOFB_ACC_FLGO_ROP3 0x00000004 -#define TMIOFB_ACC_LDGO 0x24000000 -#define TMIOFB_ACC_LDGO_CEND 0x00000001 -#define TMIOFB_ACC_LDGO_INT 0x00000002 -#define TMIOFB_ACC_LDGO_ROP3 0x00000004 -#define TMIOFB_ACC_LDGO_ENDPX 0x00000008 -#define TMIOFB_ACC_LDGO_LVRV 0x00000010 -#define TMIOFB_ACC_LDGO_LHRV 0x00000020 -#define TMIOFB_ACC_LDGO_LDMOD 0x00000040 - -/* a FIFO is always allocated, even if acceleration is not used */ -#define TMIOFB_FIFO_SIZE 512 - -/* - * LCD Host Controller Configuration Register - * - * This iomem area supports only 16-bit IO. - */ -#define CCR_CMD 0x04 /* Command */ -#define CCR_REVID 0x08 /* Revision ID */ -#define CCR_BASEL 0x10 /* LCD Control Reg Base Addr Low */ -#define CCR_BASEH 0x12 /* LCD Control Reg Base Addr High */ -#define CCR_UGCC 0x40 /* Unified Gated Clock Control */ -#define CCR_GCC 0x42 /* Gated Clock Control */ -#define CCR_USC 0x50 /* Unified Software Clear */ -#define CCR_VRAMRTC 0x60 /* VRAM Timing Control */ - /* 0x61 VRAM Refresh Control */ -#define CCR_VRAMSAC 0x62 /* VRAM Access Control */ - /* 0x63 VRAM Status */ -#define CCR_VRAMBC 0x64 /* VRAM Block Control */ - -/* - * LCD Control Register - * - * This iomem area supports only 16-bit IO. - */ -#define LCR_UIS 0x000 /* Unified Interrupt Status */ -#define LCR_VHPN 0x008 /* VRAM Horizontal Pixel Number */ -#define LCR_CFSAL 0x00a /* Command FIFO Start Address Low */ -#define LCR_CFSAH 0x00c /* Command FIFO Start Address High */ -#define LCR_CFS 0x00e /* Command FIFO Size */ -#define LCR_CFWS 0x010 /* Command FIFO Writeable Size */ -#define LCR_BBIE 0x012 /* BitBLT Interrupt Enable */ -#define LCR_BBISC 0x014 /* BitBLT Interrupt Status and Clear */ -#define LCR_CCS 0x016 /* Command Count Status */ -#define LCR_BBES 0x018 /* BitBLT Execution Status */ -#define LCR_CMDL 0x01c /* Command Low */ -#define LCR_CMDH 0x01e /* Command High */ -#define LCR_CFC 0x022 /* Command FIFO Clear */ -#define LCR_CCIFC 0x024 /* CMOS Camera IF Control */ -#define LCR_HWT 0x026 /* Hardware Test */ -#define LCR_LCDCCRC 0x100 /* LCDC Clock and Reset Control */ -#define LCR_LCDCC 0x102 /* LCDC Control */ -#define LCR_LCDCOPC 0x104 /* LCDC Output Pin Control */ -#define LCR_LCDIS 0x108 /* LCD Interrupt Status */ -#define LCR_LCDIM 0x10a /* LCD Interrupt Mask */ -#define LCR_LCDIE 0x10c /* LCD Interrupt Enable */ -#define LCR_GDSAL 0x122 /* Graphics Display Start Address Low */ -#define LCR_GDSAH 0x124 /* Graphics Display Start Address High */ -#define LCR_VHPCL 0x12a /* VRAM Horizontal Pixel Count Low */ -#define LCR_VHPCH 0x12c /* VRAM Horizontal Pixel Count High */ -#define LCR_GM 0x12e /* Graphic Mode(VRAM access enable) */ -#define LCR_HT 0x140 /* Horizontal Total */ -#define LCR_HDS 0x142 /* Horizontal Display Start */ -#define LCR_HSS 0x144 /* H-Sync Start */ -#define LCR_HSE 0x146 /* H-Sync End */ -#define LCR_HNP 0x14c /* Horizontal Number of Pixels */ -#define LCR_VT 0x150 /* Vertical Total */ -#define LCR_VDS 0x152 /* Vertical Display Start */ -#define LCR_VSS 0x154 /* V-Sync Start */ -#define LCR_VSE 0x156 /* V-Sync End */ -#define LCR_CDLN 0x160 /* Current Display Line Number */ -#define LCR_ILN 0x162 /* Interrupt Line Number */ -#define LCR_SP 0x164 /* Sync Polarity */ -#define LCR_MISC 0x166 /* MISC(RGB565 mode) */ -#define LCR_VIHSS 0x16a /* Video Interface H-Sync Start */ -#define LCR_VIVS 0x16c /* Video Interface Vertical Start */ -#define LCR_VIVE 0x16e /* Video Interface Vertical End */ -#define LCR_VIVSS 0x170 /* Video Interface V-Sync Start */ -#define LCR_VCCIS 0x17e /* Video / CMOS Camera Interface Select */ -#define LCR_VIDWSAL 0x180 /* VI Data Write Start Address Low */ -#define LCR_VIDWSAH 0x182 /* VI Data Write Start Address High */ -#define LCR_VIDRSAL 0x184 /* VI Data Read Start Address Low */ -#define LCR_VIDRSAH 0x186 /* VI Data Read Start Address High */ -#define LCR_VIPDDST 0x188 /* VI Picture Data Display Start Timing */ -#define LCR_VIPDDET 0x186 /* VI Picture Data Display End Timing */ -#define LCR_VIE 0x18c /* Video Interface Enable */ -#define LCR_VCS 0x18e /* Video/Camera Select */ -#define LCR_VPHWC 0x194 /* Video Picture Horizontal Wait Count */ -#define LCR_VPHS 0x196 /* Video Picture Horizontal Size */ -#define LCR_VPVWC 0x198 /* Video Picture Vertical Wait Count */ -#define LCR_VPVS 0x19a /* Video Picture Vertical Size */ -#define LCR_PLHPIX 0x1a0 /* PLHPIX */ -#define LCR_XS 0x1a2 /* XStart */ -#define LCR_XCKHW 0x1a4 /* XCK High Width */ -#define LCR_STHS 0x1a8 /* STH Start */ -#define LCR_VT2 0x1aa /* Vertical Total */ -#define LCR_YCKSW 0x1ac /* YCK Start Wait */ -#define LCR_YSTS 0x1ae /* YST Start */ -#define LCR_PPOLS 0x1b0 /* #PPOL Start */ -#define LCR_PRECW 0x1b2 /* PREC Width */ -#define LCR_VCLKHW 0x1b4 /* VCLK High Width */ -#define LCR_OC 0x1b6 /* Output Control */ - -static char *mode_option; - -struct tmiofb_par { - u32 pseudo_palette[16]; - -#ifdef CONFIG_FB_TMIO_ACCELL - wait_queue_head_t wait_acc; - bool use_polling; -#endif - - void __iomem *ccr; - void __iomem *lcr; -}; - -/*--------------------------------------------------------------------------*/ - -/* - * reasons for an interrupt: - * uis bbisc lcdis - * 0100 0001 accelerator command completed - * 2000 0001 vsync start - * 2000 0002 display start - * 2000 0004 line number match(0x1ff mask???) - */ -static irqreturn_t tmiofb_irq(int irq, void *__info) -{ - struct fb_info *info = __info; - struct tmiofb_par *par = info->par; - unsigned int bbisc = tmio_ioread16(par->lcr + LCR_BBISC); - - - tmio_iowrite16(bbisc, par->lcr + LCR_BBISC); - -#ifdef CONFIG_FB_TMIO_ACCELL - /* - * We were in polling mode and now we got correct irq. - * Switch back to IRQ-based sync of command FIFO - */ - if (unlikely(par->use_polling && irq != -1)) { - printk(KERN_INFO "tmiofb: switching to waitq\n"); - par->use_polling = false; - } - - if (bbisc & 1) - wake_up(&par->wait_acc); -#endif - - return IRQ_HANDLED; -} - - -/*--------------------------------------------------------------------------*/ - - -/* - * Turns off the LCD controller and LCD host controller. - */ -static int tmiofb_hw_stop(struct platform_device *dev) -{ - struct tmio_fb_data *data = dev_get_platdata(&dev->dev); - struct fb_info *info = platform_get_drvdata(dev); - struct tmiofb_par *par = info->par; - - tmio_iowrite16(0, par->ccr + CCR_UGCC); - tmio_iowrite16(0, par->lcr + LCR_GM); - data->lcd_set_power(dev, 0); - tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC); - - return 0; -} - -/* - * Initializes the LCD host controller. - */ -static int tmiofb_hw_init(struct platform_device *dev) -{ - const struct mfd_cell *cell = mfd_get_cell(dev); - struct fb_info *info = platform_get_drvdata(dev); - struct tmiofb_par *par = info->par; - const struct resource *nlcr = &cell->resources[0]; - const struct resource *vram = &cell->resources[2]; - unsigned long base; - - if (nlcr == NULL || vram == NULL) - return -EINVAL; - - base = nlcr->start; - - tmio_iowrite16(0x003a, par->ccr + CCR_UGCC); - tmio_iowrite16(0x003a, par->ccr + CCR_GCC); - tmio_iowrite16(0x3f00, par->ccr + CCR_USC); - - msleep(2); /* wait for device to settle */ - - tmio_iowrite16(0x0000, par->ccr + CCR_USC); - tmio_iowrite16(base >> 16, par->ccr + CCR_BASEH); - tmio_iowrite16(base, par->ccr + CCR_BASEL); - tmio_iowrite16(0x0002, par->ccr + CCR_CMD); /* base address enable */ - tmio_iowrite16(0x40a8, par->ccr + CCR_VRAMRTC); /* VRAMRC, VRAMTC */ - tmio_iowrite16(0x0018, par->ccr + CCR_VRAMSAC); /* VRAMSTS, VRAMAC */ - tmio_iowrite16(0x0002, par->ccr + CCR_VRAMBC); - msleep(2); /* wait for device to settle */ - tmio_iowrite16(0x000b, par->ccr + CCR_VRAMBC); - - base = vram->start + info->screen_size; - tmio_iowrite16(base >> 16, par->lcr + LCR_CFSAH); - tmio_iowrite16(base, par->lcr + LCR_CFSAL); - tmio_iowrite16(TMIOFB_FIFO_SIZE - 1, par->lcr + LCR_CFS); - tmio_iowrite16(1, par->lcr + LCR_CFC); - tmio_iowrite16(1, par->lcr + LCR_BBIE); - tmio_iowrite16(0, par->lcr + LCR_CFWS); - - return 0; -} - -/* - * Sets the LCD controller's output resolution and pixel clock - */ -static void tmiofb_hw_mode(struct platform_device *dev) -{ - struct tmio_fb_data *data = dev_get_platdata(&dev->dev); - struct fb_info *info = platform_get_drvdata(dev); - struct fb_videomode *mode = info->mode; - struct tmiofb_par *par = info->par; - unsigned int i; - - tmio_iowrite16(0, par->lcr + LCR_GM); - data->lcd_set_power(dev, 0); - tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC); - data->lcd_mode(dev, mode); - data->lcd_set_power(dev, 1); - - tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPN); - tmio_iowrite16(0, par->lcr + LCR_GDSAH); - tmio_iowrite16(0, par->lcr + LCR_GDSAL); - tmio_iowrite16(info->fix.line_length >> 16, par->lcr + LCR_VHPCH); - tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPCL); - tmio_iowrite16(i = 0, par->lcr + LCR_HSS); - tmio_iowrite16(i += mode->hsync_len, par->lcr + LCR_HSE); - tmio_iowrite16(i += mode->left_margin, par->lcr + LCR_HDS); - tmio_iowrite16(i += mode->xres + mode->right_margin, par->lcr + LCR_HT); - tmio_iowrite16(mode->xres, par->lcr + LCR_HNP); - tmio_iowrite16(i = 0, par->lcr + LCR_VSS); - tmio_iowrite16(i += mode->vsync_len, par->lcr + LCR_VSE); - tmio_iowrite16(i += mode->upper_margin, par->lcr + LCR_VDS); - tmio_iowrite16(i += mode->yres, par->lcr + LCR_ILN); - tmio_iowrite16(i += mode->lower_margin, par->lcr + LCR_VT); - tmio_iowrite16(3, par->lcr + LCR_MISC); /* RGB565 mode */ - tmio_iowrite16(1, par->lcr + LCR_GM); /* VRAM enable */ - tmio_iowrite16(0x4007, par->lcr + LCR_LCDCC); - tmio_iowrite16(3, par->lcr + LCR_SP); /* sync polarity */ - - tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC); - msleep(5); /* wait for device to settle */ - tmio_iowrite16(0x0014, par->lcr + LCR_LCDCCRC); /* STOP_CKP */ - msleep(5); /* wait for device to settle */ - tmio_iowrite16(0x0015, par->lcr + LCR_LCDCCRC); /* STOP_CKP|SOFT_RESET*/ - tmio_iowrite16(0xfffa, par->lcr + LCR_VCS); -} - -/*--------------------------------------------------------------------------*/ - -#ifdef CONFIG_FB_TMIO_ACCELL -static int __must_check -tmiofb_acc_wait(struct fb_info *info, unsigned int ccs) -{ - struct tmiofb_par *par = info->par; - /* - * This code can be called with interrupts disabled. - * So instead of relaying on irq to trigger the event, - * poll the state till the necessary command is executed. - */ - if (irqs_disabled() || par->use_polling) { - int i = 0; - while (tmio_ioread16(par->lcr + LCR_CCS) > ccs) { - udelay(1); - i++; - if (i > 10000) { - pr_err("tmiofb: timeout waiting for %d\n", - ccs); - return -ETIMEDOUT; - } - tmiofb_irq(-1, info); - } - } else { - if (!wait_event_interruptible_timeout(par->wait_acc, - tmio_ioread16(par->lcr + LCR_CCS) <= ccs, - 1000)) { - pr_err("tmiofb: timeout waiting for %d\n", ccs); - return -ETIMEDOUT; - } - } - - return 0; -} - -/* - * Writes an accelerator command to the accelerator's FIFO. - */ -static int -tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count) -{ - struct tmiofb_par *par = info->par; - int ret; - - ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count); - if (ret) - return ret; - - for (; count; count--, cmd++) { - tmio_iowrite16(*cmd >> 16, par->lcr + LCR_CMDH); - tmio_iowrite16(*cmd, par->lcr + LCR_CMDL); - } - - return ret; -} - -/* - * Wait for the accelerator to finish its operations before writing - * to the framebuffer for consistent display output. - */ -static int tmiofb_sync(struct fb_info *fbi) -{ - struct tmiofb_par *par = fbi->par; - - int ret; - int i = 0; - - ret = tmiofb_acc_wait(fbi, 0); - - while (tmio_ioread16(par->lcr + LCR_BBES) & 2) { /* blit active */ - udelay(1); - i++ ; - if (i > 10000) { - printk(KERN_ERR "timeout waiting for blit to end!\n"); - return -ETIMEDOUT; - } - } - - return ret; -} - -static void -tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect) -{ - const u32 cmd[] = { - TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2), - TMIOFB_ACC_DHPIX(rect->width - 1), - TMIOFB_ACC_DVPIX(rect->height - 1), - TMIOFB_ACC_FILL(rect->color), - TMIOFB_ACC_FLGO, - }; - - if (fbi->state != FBINFO_STATE_RUNNING || - fbi->flags & FBINFO_HWACCEL_DISABLED) { - cfb_fillrect(fbi, rect); - return; - } - - tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd)); -} - -static void -tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area) -{ - const u32 cmd[] = { - TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2), - TMIOFB_ACC_DHPIX(area->width - 1), - TMIOFB_ACC_DVPIX(area->height - 1), - TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2), - TMIOFB_ACC_SCGO, - }; - - if (fbi->state != FBINFO_STATE_RUNNING || - fbi->flags & FBINFO_HWACCEL_DISABLED) { - cfb_copyarea(fbi, area); - return; - } - - tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd)); -} -#endif - -static void tmiofb_clearscreen(struct fb_info *info) -{ - const struct fb_fillrect rect = { - .dx = 0, - .dy = 0, - .width = info->mode->xres, - .height = info->mode->yres, - .color = 0, - .rop = ROP_COPY, - }; - - info->fbops->fb_fillrect(info, &rect); -} - -static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank) -{ - struct tmiofb_par *par = fbi->par; - struct fb_videomode *mode = fbi->mode; - unsigned int vcount = tmio_ioread16(par->lcr + LCR_CDLN); - unsigned int vds = mode->vsync_len + mode->upper_margin; - - vblank->vcount = vcount; - vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT - | FB_VBLANK_HAVE_VSYNC; - - if (vcount < mode->vsync_len) - vblank->flags |= FB_VBLANK_VSYNCING; - - if (vcount < vds || vcount > vds + mode->yres) - vblank->flags |= FB_VBLANK_VBLANKING; - - return 0; -} - - -static int tmiofb_ioctl(struct fb_info *fbi, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case FBIOGET_VBLANK: { - struct fb_vblank vblank = {0}; - void __user *argp = (void __user *) arg; - - tmiofb_vblank(fbi, &vblank); - if (copy_to_user(argp, &vblank, sizeof vblank)) - return -EFAULT; - return 0; - } - -#ifdef CONFIG_FB_TMIO_ACCELL - case FBIO_TMIO_ACC_SYNC: - tmiofb_sync(fbi); - return 0; - - case FBIO_TMIO_ACC_WRITE: { - u32 __user *argp = (void __user *) arg; - u32 len; - u32 acc[16]; - - if (get_user(len, argp)) - return -EFAULT; - if (len > ARRAY_SIZE(acc)) - return -EINVAL; - if (copy_from_user(acc, argp + 1, sizeof(u32) * len)) - return -EFAULT; - - return tmiofb_acc_write(fbi, acc, len); - } -#endif - } - - return -ENOTTY; -} - -/*--------------------------------------------------------------------------*/ - -/* Select the smallest mode that allows the desired resolution to be - * displayed. If desired, the x and y parameters can be rounded up to - * match the selected mode. - */ -static struct fb_videomode * -tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) -{ - struct tmio_fb_data *data = dev_get_platdata(info->device); - struct fb_videomode *best = NULL; - int i; - - for (i = 0; i < data->num_modes; i++) { - struct fb_videomode *mode = data->modes + i; - - if (mode->xres >= var->xres && mode->yres >= var->yres - && (!best || (mode->xres < best->xres - && mode->yres < best->yres))) - best = mode; - } - - return best; -} - -static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - - struct fb_videomode *mode; - struct tmio_fb_data *data = dev_get_platdata(info->device); - - mode = tmiofb_find_mode(info, var); - if (!mode || var->bits_per_pixel > 16) - return -EINVAL; - - fb_videomode_to_var(var, mode); - - var->xres_virtual = mode->xres; - var->yres_virtual = info->screen_size / (mode->xres * 2); - - if (var->yres_virtual < var->yres) - return -EINVAL; - - var->xoffset = 0; - var->yoffset = 0; - var->bits_per_pixel = 16; - var->grayscale = 0; - var->red.offset = 11; - var->red.length = 5; - var->green.offset = 5; - var->green.length = 6; - var->blue.offset = 0; - var->blue.length = 5; - var->transp.offset = 0; - var->transp.length = 0; - var->nonstd = 0; - var->height = data->height; /* mm */ - var->width = data->width; /* mm */ - var->rotate = 0; - return 0; -} - -static int tmiofb_set_par(struct fb_info *info) -{ - struct fb_var_screeninfo *var = &info->var; - struct fb_videomode *mode; - - mode = tmiofb_find_mode(info, var); - if (!mode) - return -EINVAL; - - info->mode = mode; - info->fix.line_length = info->mode->xres * - var->bits_per_pixel / 8; - - tmiofb_hw_mode(to_platform_device(info->device)); - tmiofb_clearscreen(info); - return 0; -} - -static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) -{ - struct tmiofb_par *par = info->par; - - if (regno < ARRAY_SIZE(par->pseudo_palette)) { - par->pseudo_palette[regno] = - ((red & 0xf800)) | - ((green & 0xfc00) >> 5) | - ((blue & 0xf800) >> 11); - return 0; - } - - return -EINVAL; -} - -static int tmiofb_blank(int blank, struct fb_info *info) -{ - /* - * everything is done in lcd/bl drivers. - * this is purely to make sysfs happy and work. - */ - return 0; -} - -static const struct fb_ops tmiofb_ops = { - .owner = THIS_MODULE, - - .fb_ioctl = tmiofb_ioctl, - .fb_check_var = tmiofb_check_var, - .fb_set_par = tmiofb_set_par, - .fb_setcolreg = tmiofb_setcolreg, - .fb_blank = tmiofb_blank, - .fb_imageblit = cfb_imageblit, -#ifdef CONFIG_FB_TMIO_ACCELL - .fb_sync = tmiofb_sync, - .fb_fillrect = tmiofb_fillrect, - .fb_copyarea = tmiofb_copyarea, -#else - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, -#endif -}; - -/*--------------------------------------------------------------------------*/ - -static int tmiofb_probe(struct platform_device *dev) -{ - const struct mfd_cell *cell = mfd_get_cell(dev); - struct tmio_fb_data *data = dev_get_platdata(&dev->dev); - struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1); - struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0); - struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2); - int irq = platform_get_irq(dev, 0); - struct fb_info *info; - struct tmiofb_par *par; - int retval; - - /* - * This is the only way ATM to disable the fb - */ - if (data == NULL) { - dev_err(&dev->dev, "NULL platform data!\n"); - return -EINVAL; - } - if (ccr == NULL || lcr == NULL || vram == NULL || irq < 0) { - dev_err(&dev->dev, "missing resources\n"); - return -EINVAL; - } - - info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev); - - if (!info) - return -ENOMEM; - - par = info->par; - -#ifdef CONFIG_FB_TMIO_ACCELL - init_waitqueue_head(&par->wait_acc); - - par->use_polling = true; - - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA - | FBINFO_HWACCEL_FILLRECT; -#else - info->flags = FBINFO_DEFAULT; -#endif - - info->fbops = &tmiofb_ops; - - strcpy(info->fix.id, "tmio-fb"); - info->fix.smem_start = vram->start; - info->fix.smem_len = resource_size(vram); - info->fix.type = FB_TYPE_PACKED_PIXELS; - info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.mmio_start = lcr->start; - info->fix.mmio_len = resource_size(lcr); - info->fix.accel = FB_ACCEL_NONE; - info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE); - info->pseudo_palette = par->pseudo_palette; - - par->ccr = ioremap(ccr->start, resource_size(ccr)); - if (!par->ccr) { - retval = -ENOMEM; - goto err_ioremap_ccr; - } - - par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len); - if (!par->lcr) { - retval = -ENOMEM; - goto err_ioremap_lcr; - } - - info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); - if (!info->screen_base) { - retval = -ENOMEM; - goto err_ioremap_vram; - } - - retval = request_irq(irq, &tmiofb_irq, 0, - dev_name(&dev->dev), info); - - if (retval) - goto err_request_irq; - - platform_set_drvdata(dev, info); - - retval = fb_find_mode(&info->var, info, mode_option, - data->modes, data->num_modes, - data->modes, 16); - if (!retval) { - retval = -EINVAL; - goto err_find_mode; - } - - if (cell->enable) { - retval = cell->enable(dev); - if (retval) - goto err_enable; - } - - retval = tmiofb_hw_init(dev); - if (retval) - goto err_hw_init; - - fb_videomode_to_modelist(data->modes, data->num_modes, - &info->modelist); - - retval = register_framebuffer(info); - if (retval < 0) - goto err_register_framebuffer; - - fb_info(info, "%s frame buffer device\n", info->fix.id); - - return 0; - -err_register_framebuffer: -/*err_set_par:*/ - tmiofb_hw_stop(dev); -err_hw_init: - if (cell->disable) - cell->disable(dev); -err_enable: -err_find_mode: - free_irq(irq, info); -err_request_irq: - iounmap(info->screen_base); -err_ioremap_vram: - iounmap(par->lcr); -err_ioremap_lcr: - iounmap(par->ccr); -err_ioremap_ccr: - framebuffer_release(info); - return retval; -} - -static int tmiofb_remove(struct platform_device *dev) -{ - const struct mfd_cell *cell = mfd_get_cell(dev); - struct fb_info *info = platform_get_drvdata(dev); - int irq = platform_get_irq(dev, 0); - struct tmiofb_par *par; - - if (info) { - par = info->par; - unregister_framebuffer(info); - - tmiofb_hw_stop(dev); - - if (cell->disable) - cell->disable(dev); - - free_irq(irq, info); - - iounmap(info->screen_base); - iounmap(par->lcr); - iounmap(par->ccr); - - framebuffer_release(info); - } - - return 0; -} - -#ifdef DEBUG -static void tmiofb_dump_regs(struct platform_device *dev) -{ - struct fb_info *info = platform_get_drvdata(dev); - struct tmiofb_par *par = info->par; - - printk(KERN_DEBUG "lhccr:\n"); -#define CCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\ - tmio_ioread16(par->ccr + CCR_ ## n)); - CCR_PR(CMD); - CCR_PR(REVID); - CCR_PR(BASEL); - CCR_PR(BASEH); - CCR_PR(UGCC); - CCR_PR(GCC); - CCR_PR(USC); - CCR_PR(VRAMRTC); - CCR_PR(VRAMSAC); - CCR_PR(VRAMBC); -#undef CCR_PR - - printk(KERN_DEBUG "lcr: \n"); -#define LCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\ - tmio_ioread16(par->lcr + LCR_ ## n)); - LCR_PR(UIS); - LCR_PR(VHPN); - LCR_PR(CFSAL); - LCR_PR(CFSAH); - LCR_PR(CFS); - LCR_PR(CFWS); - LCR_PR(BBIE); - LCR_PR(BBISC); - LCR_PR(CCS); - LCR_PR(BBES); - LCR_PR(CMDL); - LCR_PR(CMDH); - LCR_PR(CFC); - LCR_PR(CCIFC); - LCR_PR(HWT); - LCR_PR(LCDCCRC); - LCR_PR(LCDCC); - LCR_PR(LCDCOPC); - LCR_PR(LCDIS); - LCR_PR(LCDIM); - LCR_PR(LCDIE); - LCR_PR(GDSAL); - LCR_PR(GDSAH); - LCR_PR(VHPCL); - LCR_PR(VHPCH); - LCR_PR(GM); - LCR_PR(HT); - LCR_PR(HDS); - LCR_PR(HSS); - LCR_PR(HSE); - LCR_PR(HNP); - LCR_PR(VT); - LCR_PR(VDS); - LCR_PR(VSS); - LCR_PR(VSE); - LCR_PR(CDLN); - LCR_PR(ILN); - LCR_PR(SP); - LCR_PR(MISC); - LCR_PR(VIHSS); - LCR_PR(VIVS); - LCR_PR(VIVE); - LCR_PR(VIVSS); - LCR_PR(VCCIS); - LCR_PR(VIDWSAL); - LCR_PR(VIDWSAH); - LCR_PR(VIDRSAL); - LCR_PR(VIDRSAH); - LCR_PR(VIPDDST); - LCR_PR(VIPDDET); - LCR_PR(VIE); - LCR_PR(VCS); - LCR_PR(VPHWC); - LCR_PR(VPHS); - LCR_PR(VPVWC); - LCR_PR(VPVS); - LCR_PR(PLHPIX); - LCR_PR(XS); - LCR_PR(XCKHW); - LCR_PR(STHS); - LCR_PR(VT2); - LCR_PR(YCKSW); - LCR_PR(YSTS); - LCR_PR(PPOLS); - LCR_PR(PRECW); - LCR_PR(VCLKHW); - LCR_PR(OC); -#undef LCR_PR -} -#endif - -#ifdef CONFIG_PM -static int tmiofb_suspend(struct platform_device *dev, pm_message_t state) -{ - struct fb_info *info = platform_get_drvdata(dev); -#ifdef CONFIG_FB_TMIO_ACCELL - struct tmiofb_par *par = info->par; -#endif - const struct mfd_cell *cell = mfd_get_cell(dev); - int retval = 0; - - console_lock(); - - fb_set_suspend(info, 1); - - if (info->fbops->fb_sync) - info->fbops->fb_sync(info); - - -#ifdef CONFIG_FB_TMIO_ACCELL - /* - * The fb should be usable even if interrupts are disabled (and they are - * during suspend/resume). Switch temporary to forced polling. - */ - printk(KERN_INFO "tmiofb: switching to polling\n"); - par->use_polling = true; -#endif - tmiofb_hw_stop(dev); - - if (cell->suspend) - retval = cell->suspend(dev); - - console_unlock(); - - return retval; -} - -static int tmiofb_resume(struct platform_device *dev) -{ - struct fb_info *info = platform_get_drvdata(dev); - const struct mfd_cell *cell = mfd_get_cell(dev); - int retval = 0; - - console_lock(); - - if (cell->resume) { - retval = cell->resume(dev); - if (retval) - goto out; - } - - tmiofb_irq(-1, info); - - tmiofb_hw_init(dev); - - tmiofb_hw_mode(dev); - - fb_set_suspend(info, 0); -out: - console_unlock(); - return retval; -} -#else -#define tmiofb_suspend NULL -#define tmiofb_resume NULL -#endif - -static struct platform_driver tmiofb_driver = { - .driver.name = "tmio-fb", - .driver.owner = THIS_MODULE, - .probe = tmiofb_probe, - .remove = tmiofb_remove, - .suspend = tmiofb_suspend, - .resume = tmiofb_resume, -}; - -/*--------------------------------------------------------------------------*/ - -#ifndef MODULE -static void __init tmiofb_setup(char *options) -{ - char *this_opt; - - if (!options || !*options) - return; - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) - continue; - /* - * FIXME - */ - } -} -#endif - -static int __init tmiofb_init(void) -{ -#ifndef MODULE - char *option = NULL; - - if (fb_get_options("tmiofb", &option)) - return -ENODEV; - tmiofb_setup(option); -#endif - return platform_driver_register(&tmiofb_driver); -} - -static void __exit tmiofb_cleanup(void) -{ - platform_driver_unregister(&tmiofb_driver); -} - -module_init(tmiofb_init); -module_exit(tmiofb_cleanup); - -MODULE_DESCRIPTION("TMIO framebuffer driver"); -MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c index 929d4775cb4b..3f8bdfcf51f0 100644 --- a/drivers/video/fbdev/vesafb.c +++ b/drivers/video/fbdev/vesafb.c @@ -9,6 +9,7 @@ * */ +#include <linux/aperture.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -31,6 +32,8 @@ struct vesafb_par { u32 pseudo_palette[256]; + resource_size_t base; + resource_size_t size; int wc_cookie; struct resource *region; }; @@ -140,7 +143,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, * (according to the entries in the `var' structure). Return * != 0 for invalid regno. */ - + if (regno >= info->cmap.len) return 1; @@ -191,7 +194,7 @@ static void vesafb_destroy(struct fb_info *info) arch_phys_wc_del(par->wc_cookie); if (info->screen_base) iounmap(info->screen_base); - release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); + release_mem_region(par->base, par->size); framebuffer_release(info); } @@ -209,13 +212,13 @@ static struct fb_ops vesafb_ops = { static int vesafb_setup(char *options) { char *this_opt; - + if (!options || !*options) return 0; - + while ((this_opt = strsep(&options, ",")) != NULL) { if (!*this_opt) continue; - + if (! strcmp(this_opt, "inverse")) inverse=1; else if (! strcmp(this_opt, "redraw")) @@ -316,14 +319,8 @@ static int vesafb_probe(struct platform_device *dev) par = info->par; info->pseudo_palette = par->pseudo_palette; - /* set vesafb aperture size for generic probing */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - err = -ENOMEM; - goto err; - } - info->apertures->ranges[0].base = screen_info.lfb_base; - info->apertures->ranges[0].size = size_total; + par->base = screen_info.lfb_base; + par->size = size_total; printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); @@ -381,7 +378,7 @@ static int vesafb_probe(struct platform_device *dev) vesafb_defined.pixclock = 10000000 / vesafb_defined.xres * 1000 / vesafb_defined.yres; vesafb_defined.left_margin = (vesafb_defined.xres / 8) & 0xf8; vesafb_defined.hsync_len = (vesafb_defined.xres / 8) & 0xf8; - + vesafb_defined.red.offset = screen_info.red_pos; vesafb_defined.red.length = screen_info.red_size; vesafb_defined.green.offset = screen_info.green_pos; @@ -460,27 +457,29 @@ static int vesafb_probe(struct platform_device *dev) info->fbops = &vesafb_ops; info->var = vesafb_defined; info->fix = vesafb_fix; - info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE | - (ypan ? FBINFO_HWACCEL_YPAN : 0); + info->flags = FBINFO_FLAG_DEFAULT | (ypan ? FBINFO_HWACCEL_YPAN : 0); if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { err = -ENOMEM; goto err_release_region; } + err = devm_aperture_acquire_for_platform_device(dev, par->base, par->size); + if (err) + goto err_fb_dealloc_cmap; if (register_framebuffer(info)<0) { err = -EINVAL; - fb_dealloc_cmap(&info->cmap); - goto err_release_region; + goto err_fb_dealloc_cmap; } fb_info(info, "%s frame buffer device\n", info->fix.id); return 0; +err_fb_dealloc_cmap: + fb_dealloc_cmap(&info->cmap); 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; diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c index af47f8217095..1a8ffdb2be26 100644 --- a/drivers/video/fbdev/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -10,6 +10,7 @@ * archive for more details. */ +#include <linux/aperture.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -1324,11 +1325,6 @@ static int vga16fb_probe(struct platform_device *dev) ret = -ENOMEM; goto err_fb_alloc; } - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto err_ioremap; - } /* XXX share VGA_FB_PHYS_BASE and I/O region with vgacon and others */ info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS_BASE, 0); @@ -1363,8 +1359,7 @@ static int vga16fb_probe(struct platform_device *dev) info->fix = vga16fb_fix; /* supports rectangles with widths of multiples of 8 */ info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31; - info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE | - FBINFO_HWACCEL_YPAN; + info->flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_YPAN; i = (info->var.bits_per_pixel == 8) ? 256 : 16; ret = fb_alloc_cmap(&info->cmap, i, 0); @@ -1382,9 +1377,9 @@ static int vga16fb_probe(struct platform_device *dev) vga16fb_update_fix(info); - info->apertures->ranges[0].base = VGA_FB_PHYS_BASE; - info->apertures->ranges[0].size = VGA_FB_PHYS_SIZE; - + ret = devm_aperture_acquire_for_platform_device(dev, VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); + if (ret) + goto err_check_var; if (register_framebuffer(info) < 0) { printk(KERN_ERR "vga16fb: unable to register framebuffer\n"); ret = -EINVAL; diff --git a/drivers/video/fbdev/w100fb.c b/drivers/video/fbdev/w100fb.c deleted file mode 100644 index 4e641a780726..000000000000 --- a/drivers/video/fbdev/w100fb.c +++ /dev/null @@ -1,1644 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/drivers/video/w100fb.c - * - * Frame Buffer Device for ATI Imageon w100 (Wallaby) - * - * Copyright (C) 2002, ATI Corp. - * Copyright (C) 2004-2006 Richard Purdie - * Copyright (c) 2005 Ian Molton - * Copyright (c) 2006 Alberto Mardegan - * - * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net> - * - * Generic platform support by Ian Molton <spyro@f2s.com> - * and Richard Purdie <rpurdie@rpsys.net> - * - * w32xx support by Ian Molton - * - * Hardware acceleration support by Alberto Mardegan - * <mardy@users.sourceforge.net> - */ - -#include <linux/delay.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/vmalloc.h> -#include <linux/module.h> -#include <asm/io.h> -#include <linux/uaccess.h> -#include <video/w100fb.h> -#include "w100fb.h" - -/* - * Prototypes - */ -static void w100_suspend(u32 mode); -static void w100_vsync(void); -static void w100_hw_init(struct w100fb_par*); -static void w100_pwm_setup(struct w100fb_par*); -static void w100_init_clocks(struct w100fb_par*); -static void w100_setup_memory(struct w100fb_par*); -static void w100_init_lcd(struct w100fb_par*); -static void w100_set_dispregs(struct w100fb_par*); -static void w100_update_enable(void); -static void w100_update_disable(void); -static void calc_hsync(struct w100fb_par *par); -static void w100_init_graphic_engine(struct w100fb_par *par); -struct w100_pll_info *w100_get_xtal_table(unsigned int freq); - -/* Pseudo palette size */ -#define MAX_PALETTES 16 - -#define W100_SUSPEND_EXTMEM 0 -#define W100_SUSPEND_ALL 1 - -#define BITS_PER_PIXEL 16 - -/* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */ -static void __iomem *remapped_base; -static void __iomem *remapped_regs; -static void __iomem *remapped_fbuf; - -#define REMAPPED_FB_LEN 0x15ffff - -/* This is the offset in the w100's address space we map the current - framebuffer memory to. We use the position of external memory as - we can remap internal memory to there if external isn't present. */ -#define W100_FB_BASE MEM_EXT_BASE_VALUE - - -/* - * Sysfs functions - */ -static ssize_t flip_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct w100fb_par *par=info->par; - - return sprintf(buf, "%d\n",par->flip); -} - -static ssize_t flip_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int flip; - struct fb_info *info = dev_get_drvdata(dev); - struct w100fb_par *par=info->par; - - flip = simple_strtoul(buf, NULL, 10); - - if (flip > 0) - par->flip = 1; - else - par->flip = 0; - - w100_update_disable(); - w100_set_dispregs(par); - w100_update_enable(); - - calc_hsync(par); - - return count; -} - -static DEVICE_ATTR_RW(flip); - -static ssize_t w100fb_reg_read(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned long regs, param; - regs = simple_strtoul(buf, NULL, 16); - param = readl(remapped_regs + regs); - printk("Read Register 0x%08lX: 0x%08lX\n", regs, param); - return count; -} - -static DEVICE_ATTR(reg_read, 0200, NULL, w100fb_reg_read); - -static ssize_t w100fb_reg_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned long regs, param; - sscanf(buf, "%lx %lx", ®s, ¶m); - - if (regs <= 0x2000) { - printk("Write Register 0x%08lX: 0x%08lX\n", regs, param); - writel(param, remapped_regs + regs); - } - - return count; -} - -static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write); - - -static ssize_t fastpllclk_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct w100fb_par *par=info->par; - - return sprintf(buf, "%d\n",par->fastpll_mode); -} - -static ssize_t fastpllclk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct w100fb_par *par=info->par; - - if (simple_strtoul(buf, NULL, 10) > 0) { - par->fastpll_mode=1; - printk("w100fb: Using fast system clock (if possible)\n"); - } else { - par->fastpll_mode=0; - printk("w100fb: Using normal system clock\n"); - } - - w100_init_clocks(par); - calc_hsync(par); - - return count; -} - -static DEVICE_ATTR_RW(fastpllclk); - -static struct attribute *w100fb_attrs[] = { - &dev_attr_fastpllclk.attr, - &dev_attr_reg_read.attr, - &dev_attr_reg_write.attr, - &dev_attr_flip.attr, - NULL, -}; -ATTRIBUTE_GROUPS(w100fb); - -/* - * Some touchscreens need hsync information from the video driver to - * function correctly. We export it here. - */ -unsigned long w100fb_get_hsynclen(struct device *dev) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct w100fb_par *par=info->par; - - /* If display is blanked/suspended, hsync isn't active */ - if (par->blanked) - return 0; - else - return par->hsync_len; -} -EXPORT_SYMBOL(w100fb_get_hsynclen); - -static void w100fb_clear_screen(struct w100fb_par *par) -{ - memset_io(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), 0, (par->xres * par->yres * BITS_PER_PIXEL/8)); -} - - -/* - * Set a palette value from rgb components - */ -static int w100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int trans, struct fb_info *info) -{ - unsigned int val; - int ret = 1; - - /* - * If greyscale is true, then we convert the RGB value - * to greyscale no matter what visual we are using. - */ - if (info->var.grayscale) - red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16; - - /* - * 16-bit True Colour. We encode the RGB value - * according to the RGB bitfield information. - */ - if (regno < MAX_PALETTES) { - u32 *pal = info->pseudo_palette; - - val = (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); - pal[regno] = val; - ret = 0; - } - return ret; -} - - -/* - * Blank the display based on value in blank_mode - */ -static int w100fb_blank(int blank_mode, struct fb_info *info) -{ - struct w100fb_par *par = info->par; - struct w100_tg_info *tg = par->mach->tg; - - switch(blank_mode) { - - case FB_BLANK_NORMAL: /* Normal blanking */ - case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */ - case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */ - case FB_BLANK_POWERDOWN: /* Poweroff */ - if (par->blanked == 0) { - if(tg && tg->suspend) - tg->suspend(par); - par->blanked = 1; - } - break; - - case FB_BLANK_UNBLANK: /* Unblanking */ - if (par->blanked != 0) { - if(tg && tg->resume) - tg->resume(par); - par->blanked = 0; - } - break; - } - return 0; -} - - -static void w100_fifo_wait(int entries) -{ - union rbbm_status_u status; - int i; - - for (i = 0; i < 2000000; i++) { - status.val = readl(remapped_regs + mmRBBM_STATUS); - if (status.f.cmdfifo_avail >= entries) - return; - udelay(1); - } - printk(KERN_ERR "w100fb: FIFO Timeout!\n"); -} - - -static int w100fb_sync(struct fb_info *info) -{ - union rbbm_status_u status; - int i; - - for (i = 0; i < 2000000; i++) { - status.val = readl(remapped_regs + mmRBBM_STATUS); - if (!status.f.gui_active) - return 0; - udelay(1); - } - printk(KERN_ERR "w100fb: Graphic engine timeout!\n"); - return -EBUSY; -} - - -static void w100_init_graphic_engine(struct w100fb_par *par) -{ - union dp_gui_master_cntl_u gmc; - union dp_mix_u dp_mix; - union dp_datatype_u dp_datatype; - union dp_cntl_u dp_cntl; - - w100_fifo_wait(4); - writel(W100_FB_BASE, remapped_regs + mmDST_OFFSET); - writel(par->xres, remapped_regs + mmDST_PITCH); - writel(W100_FB_BASE, remapped_regs + mmSRC_OFFSET); - writel(par->xres, remapped_regs + mmSRC_PITCH); - - w100_fifo_wait(3); - writel(0, remapped_regs + mmSC_TOP_LEFT); - writel((par->yres << 16) | par->xres, remapped_regs + mmSC_BOTTOM_RIGHT); - writel(0x1fff1fff, remapped_regs + mmSRC_SC_BOTTOM_RIGHT); - - w100_fifo_wait(4); - dp_cntl.val = 0; - dp_cntl.f.dst_x_dir = 1; - dp_cntl.f.dst_y_dir = 1; - dp_cntl.f.src_x_dir = 1; - dp_cntl.f.src_y_dir = 1; - dp_cntl.f.dst_major_x = 1; - dp_cntl.f.src_major_x = 1; - writel(dp_cntl.val, remapped_regs + mmDP_CNTL); - - gmc.val = 0; - gmc.f.gmc_src_pitch_offset_cntl = 1; - gmc.f.gmc_dst_pitch_offset_cntl = 1; - gmc.f.gmc_src_clipping = 1; - gmc.f.gmc_dst_clipping = 1; - gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE; - gmc.f.gmc_dst_datatype = 3; /* from DstType_16Bpp_444 */ - gmc.f.gmc_src_datatype = SRC_DATATYPE_EQU_DST; - gmc.f.gmc_byte_pix_order = 1; - gmc.f.gmc_default_sel = 0; - gmc.f.gmc_rop3 = ROP3_SRCCOPY; - gmc.f.gmc_dp_src_source = DP_SRC_MEM_RECTANGULAR; - gmc.f.gmc_clr_cmp_fcn_dis = 1; - gmc.f.gmc_wr_msk_dis = 1; - gmc.f.gmc_dp_op = DP_OP_ROP; - writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL); - - dp_datatype.val = dp_mix.val = 0; - dp_datatype.f.dp_dst_datatype = gmc.f.gmc_dst_datatype; - dp_datatype.f.dp_brush_datatype = gmc.f.gmc_brush_datatype; - dp_datatype.f.dp_src2_type = 0; - dp_datatype.f.dp_src2_datatype = gmc.f.gmc_src_datatype; - dp_datatype.f.dp_src_datatype = gmc.f.gmc_src_datatype; - dp_datatype.f.dp_byte_pix_order = gmc.f.gmc_byte_pix_order; - writel(dp_datatype.val, remapped_regs + mmDP_DATATYPE); - - dp_mix.f.dp_src_source = gmc.f.gmc_dp_src_source; - dp_mix.f.dp_src2_source = 1; - dp_mix.f.dp_rop3 = gmc.f.gmc_rop3; - dp_mix.f.dp_op = gmc.f.gmc_dp_op; - writel(dp_mix.val, remapped_regs + mmDP_MIX); -} - - -static void w100fb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - union dp_gui_master_cntl_u gmc; - - if (info->state != FBINFO_STATE_RUNNING) - return; - if (info->flags & FBINFO_HWACCEL_DISABLED) { - cfb_fillrect(info, rect); - return; - } - - gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL); - gmc.f.gmc_rop3 = ROP3_PATCOPY; - gmc.f.gmc_brush_datatype = GMC_BRUSH_SOLID_COLOR; - w100_fifo_wait(2); - writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL); - writel(rect->color, remapped_regs + mmDP_BRUSH_FRGD_CLR); - - w100_fifo_wait(2); - writel((rect->dy << 16) | (rect->dx & 0xffff), remapped_regs + mmDST_Y_X); - writel((rect->width << 16) | (rect->height & 0xffff), - remapped_regs + mmDST_WIDTH_HEIGHT); -} - - -static void w100fb_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy; - u32 h = area->height, w = area->width; - union dp_gui_master_cntl_u gmc; - - if (info->state != FBINFO_STATE_RUNNING) - return; - if (info->flags & FBINFO_HWACCEL_DISABLED) { - cfb_copyarea(info, area); - return; - } - - gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL); - gmc.f.gmc_rop3 = ROP3_SRCCOPY; - gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE; - w100_fifo_wait(1); - writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL); - - w100_fifo_wait(3); - writel((sy << 16) | (sx & 0xffff), remapped_regs + mmSRC_Y_X); - writel((dy << 16) | (dx & 0xffff), remapped_regs + mmDST_Y_X); - writel((w << 16) | (h & 0xffff), remapped_regs + mmDST_WIDTH_HEIGHT); -} - - -/* - * Change the resolution by calling the appropriate hardware functions - */ -static void w100fb_activate_var(struct w100fb_par *par) -{ - struct w100_tg_info *tg = par->mach->tg; - - w100_pwm_setup(par); - w100_setup_memory(par); - w100_init_clocks(par); - w100fb_clear_screen(par); - w100_vsync(); - - w100_update_disable(); - w100_init_lcd(par); - w100_set_dispregs(par); - w100_update_enable(); - w100_init_graphic_engine(par); - - calc_hsync(par); - - if (!par->blanked && tg && tg->change) - tg->change(par); -} - - -/* Select the smallest mode that allows the desired resolution to be - * displayed. If desired, the x and y parameters can be rounded up to - * match the selected mode. - */ -static struct w100_mode *w100fb_get_mode(struct w100fb_par *par, unsigned int *x, unsigned int *y, int saveval) -{ - struct w100_mode *mode = NULL; - struct w100_mode *modelist = par->mach->modelist; - unsigned int best_x = 0xffffffff, best_y = 0xffffffff; - unsigned int i; - - for (i = 0 ; i < par->mach->num_modes ; i++) { - if (modelist[i].xres >= *x && modelist[i].yres >= *y && - modelist[i].xres < best_x && modelist[i].yres < best_y) { - best_x = modelist[i].xres; - best_y = modelist[i].yres; - mode = &modelist[i]; - } else if(modelist[i].xres >= *y && modelist[i].yres >= *x && - modelist[i].xres < best_y && modelist[i].yres < best_x) { - best_x = modelist[i].yres; - best_y = modelist[i].xres; - mode = &modelist[i]; - } - } - - if (mode && saveval) { - *x = best_x; - *y = best_y; - } - - return mode; -} - - -/* - * w100fb_check_var(): - * Get the video params out of 'var'. If a value doesn't fit, round it up, - * if it's too big, return -EINVAL. - */ -static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct w100fb_par *par=info->par; - - if(!w100fb_get_mode(par, &var->xres, &var->yres, 1)) - return -EINVAL; - - if (par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (par->mach->mem->size+1))) - return -EINVAL; - - if (!par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1))) - return -EINVAL; - - var->xres_virtual = max(var->xres_virtual, var->xres); - var->yres_virtual = max(var->yres_virtual, var->yres); - - if (var->bits_per_pixel > BITS_PER_PIXEL) - return -EINVAL; - else - var->bits_per_pixel = BITS_PER_PIXEL; - - var->red.offset = 11; - var->red.length = 5; - var->green.offset = 5; - var->green.length = 6; - var->blue.offset = 0; - var->blue.length = 5; - var->transp.offset = var->transp.length = 0; - - var->nonstd = 0; - var->height = -1; - var->width = -1; - var->vmode = FB_VMODE_NONINTERLACED; - var->sync = 0; - var->pixclock = 0x04; /* 171521; */ - - return 0; -} - - -/* - * w100fb_set_par(): - * Set the user defined part of the display for the specified console - * by looking at the values in info.var - */ -static int w100fb_set_par(struct fb_info *info) -{ - struct w100fb_par *par=info->par; - - if (par->xres != info->var.xres || par->yres != info->var.yres) { - par->xres = info->var.xres; - par->yres = info->var.yres; - par->mode = w100fb_get_mode(par, &par->xres, &par->yres, 0); - - info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.ypanstep = 0; - info->fix.ywrapstep = 0; - info->fix.line_length = par->xres * BITS_PER_PIXEL / 8; - - mutex_lock(&info->mm_lock); - if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) { - par->extmem_active = 1; - info->fix.smem_len = par->mach->mem->size+1; - } else { - par->extmem_active = 0; - info->fix.smem_len = MEM_INT_SIZE+1; - } - mutex_unlock(&info->mm_lock); - - w100fb_activate_var(par); - } - return 0; -} - - -/* - * Frame buffer operations - */ -static const struct fb_ops w100fb_ops = { - .owner = THIS_MODULE, - .fb_check_var = w100fb_check_var, - .fb_set_par = w100fb_set_par, - .fb_setcolreg = w100fb_setcolreg, - .fb_blank = w100fb_blank, - .fb_fillrect = w100fb_fillrect, - .fb_copyarea = w100fb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_sync = w100fb_sync, -}; - -#ifdef CONFIG_PM -static void w100fb_save_vidmem(struct w100fb_par *par) -{ - int memsize; - - if (par->extmem_active) { - memsize=par->mach->mem->size; - par->saved_extmem = vmalloc(memsize); - if (par->saved_extmem) - memcpy_fromio(par->saved_extmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize); - } - memsize=MEM_INT_SIZE; - par->saved_intmem = vmalloc(memsize); - if (par->saved_intmem && par->extmem_active) - memcpy_fromio(par->saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), memsize); - else if (par->saved_intmem) - memcpy_fromio(par->saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize); -} - -static void w100fb_restore_vidmem(struct w100fb_par *par) -{ - int memsize; - - if (par->extmem_active && par->saved_extmem) { - memsize=par->mach->mem->size; - memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_extmem, memsize); - vfree(par->saved_extmem); - par->saved_extmem = NULL; - } - if (par->saved_intmem) { - memsize=MEM_INT_SIZE; - if (par->extmem_active) - memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), par->saved_intmem, memsize); - else - memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_intmem, memsize); - vfree(par->saved_intmem); - par->saved_intmem = NULL; - } -} - -static int w100fb_suspend(struct platform_device *dev, pm_message_t state) -{ - struct fb_info *info = platform_get_drvdata(dev); - struct w100fb_par *par=info->par; - struct w100_tg_info *tg = par->mach->tg; - - w100fb_save_vidmem(par); - if(tg && tg->suspend) - tg->suspend(par); - w100_suspend(W100_SUSPEND_ALL); - par->blanked = 1; - - return 0; -} - -static int w100fb_resume(struct platform_device *dev) -{ - struct fb_info *info = platform_get_drvdata(dev); - struct w100fb_par *par=info->par; - struct w100_tg_info *tg = par->mach->tg; - - w100_hw_init(par); - w100fb_activate_var(par); - w100fb_restore_vidmem(par); - if(tg && tg->resume) - tg->resume(par); - par->blanked = 0; - - return 0; -} -#else -#define w100fb_suspend NULL -#define w100fb_resume NULL -#endif - - -static int w100fb_probe(struct platform_device *pdev) -{ - int err = -EIO; - struct w100fb_mach_info *inf; - struct fb_info *info = NULL; - struct w100fb_par *par; - struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - unsigned int chip_id; - - if (!mem) - return -EINVAL; - - /* Remap the chip base address */ - remapped_base = ioremap(mem->start+W100_CFG_BASE, W100_CFG_LEN); - if (remapped_base == NULL) - goto out; - - /* Map the register space */ - remapped_regs = ioremap(mem->start+W100_REG_BASE, W100_REG_LEN); - if (remapped_regs == NULL) - goto out; - - /* Identify the chip */ - printk("Found "); - chip_id = readl(remapped_regs + mmCHIP_ID); - switch(chip_id) { - case CHIP_ID_W100: printk("w100"); break; - case CHIP_ID_W3200: printk("w3200"); break; - case CHIP_ID_W3220: printk("w3220"); break; - default: - printk("Unknown imageon chip ID\n"); - err = -ENODEV; - goto out; - } - printk(" at 0x%08lx.\n", (unsigned long) mem->start+W100_CFG_BASE); - - /* Remap the framebuffer */ - remapped_fbuf = ioremap(mem->start+MEM_WINDOW_BASE, MEM_WINDOW_SIZE); - if (remapped_fbuf == NULL) - goto out; - - info=framebuffer_alloc(sizeof(struct w100fb_par), &pdev->dev); - if (!info) { - err = -ENOMEM; - goto out; - } - - par = info->par; - platform_set_drvdata(pdev, info); - - inf = dev_get_platdata(&pdev->dev); - par->chip_id = chip_id; - par->mach = inf; - par->fastpll_mode = 0; - par->blanked = 0; - - par->pll_table=w100_get_xtal_table(inf->xtal_freq); - if (!par->pll_table) { - printk(KERN_ERR "No matching Xtal definition found\n"); - err = -EINVAL; - goto out; - } - - info->pseudo_palette = kmalloc_array(MAX_PALETTES, sizeof(u32), - GFP_KERNEL); - if (!info->pseudo_palette) { - err = -ENOMEM; - goto out; - } - - info->fbops = &w100fb_ops; - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | - FBINFO_HWACCEL_FILLRECT; - info->node = -1; - info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE); - info->screen_size = REMAPPED_FB_LEN; - - strcpy(info->fix.id, "w100fb"); - info->fix.type = FB_TYPE_PACKED_PIXELS; - info->fix.type_aux = 0; - info->fix.accel = FB_ACCEL_NONE; - info->fix.smem_start = mem->start+W100_FB_BASE; - info->fix.mmio_start = mem->start+W100_REG_BASE; - info->fix.mmio_len = W100_REG_LEN; - - if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { - err = -ENOMEM; - goto out; - } - - par->mode = &inf->modelist[0]; - if(inf->init_mode & INIT_MODE_ROTATED) { - info->var.xres = par->mode->yres; - info->var.yres = par->mode->xres; - } - else { - info->var.xres = par->mode->xres; - info->var.yres = par->mode->yres; - } - - if(inf->init_mode &= INIT_MODE_FLIPPED) - par->flip = 1; - else - par->flip = 0; - - info->var.xres_virtual = info->var.xres; - info->var.yres_virtual = info->var.yres; - info->var.pixclock = 0x04; /* 171521; */ - info->var.sync = 0; - info->var.grayscale = 0; - info->var.xoffset = info->var.yoffset = 0; - info->var.accel_flags = 0; - info->var.activate = FB_ACTIVATE_NOW; - - w100_hw_init(par); - - if (w100fb_check_var(&info->var, info) < 0) { - err = -EINVAL; - goto out; - } - - if (register_framebuffer(info) < 0) { - err = -EINVAL; - goto out; - } - - fb_info(info, "%s frame buffer device\n", info->fix.id); - return 0; -out: - if (info) { - fb_dealloc_cmap(&info->cmap); - kfree(info->pseudo_palette); - } - if (remapped_fbuf != NULL) { - iounmap(remapped_fbuf); - remapped_fbuf = NULL; - } - if (remapped_regs != NULL) { - iounmap(remapped_regs); - remapped_regs = NULL; - } - if (remapped_base != NULL) { - iounmap(remapped_base); - remapped_base = NULL; - } - if (info) - framebuffer_release(info); - return err; -} - - -static int w100fb_remove(struct platform_device *pdev) -{ - struct fb_info *info = platform_get_drvdata(pdev); - struct w100fb_par *par=info->par; - - unregister_framebuffer(info); - - vfree(par->saved_intmem); - vfree(par->saved_extmem); - kfree(info->pseudo_palette); - fb_dealloc_cmap(&info->cmap); - - iounmap(remapped_base); - remapped_base = NULL; - iounmap(remapped_regs); - remapped_regs = NULL; - iounmap(remapped_fbuf); - remapped_fbuf = NULL; - - framebuffer_release(info); - - return 0; -} - - -/* ------------------- chipset specific functions -------------------------- */ - - -static void w100_soft_reset(void) -{ - u16 val = readw((u16 __iomem *)remapped_base + cfgSTATUS); - - writew(val | 0x08, (u16 __iomem *)remapped_base + cfgSTATUS); - udelay(100); - writew(0x00, (u16 __iomem *)remapped_base + cfgSTATUS); - udelay(100); -} - -static void w100_update_disable(void) -{ - union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl; - - /* Prevent display updates */ - disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e; - disp_db_buf_wr_cntl.f.update_db_buf = 0; - disp_db_buf_wr_cntl.f.en_db_buf = 0; - writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL); -} - -static void w100_update_enable(void) -{ - union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl; - - /* Enable display updates */ - disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e; - disp_db_buf_wr_cntl.f.update_db_buf = 1; - disp_db_buf_wr_cntl.f.en_db_buf = 1; - writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL); -} - -unsigned long w100fb_gpio_read(int port) -{ - unsigned long value; - - if (port==W100_GPIO_PORT_A) - value = readl(remapped_regs + mmGPIO_DATA); - else - value = readl(remapped_regs + mmGPIO_DATA2); - - return value; -} - -void w100fb_gpio_write(int port, unsigned long value) -{ - if (port==W100_GPIO_PORT_A) - writel(value, remapped_regs + mmGPIO_DATA); - else - writel(value, remapped_regs + mmGPIO_DATA2); -} -EXPORT_SYMBOL(w100fb_gpio_read); -EXPORT_SYMBOL(w100fb_gpio_write); - -/* - * Initialization of critical w100 hardware - */ -static void w100_hw_init(struct w100fb_par *par) -{ - u32 temp32; - union cif_cntl_u cif_cntl; - union intf_cntl_u intf_cntl; - union cfgreg_base_u cfgreg_base; - union wrap_top_dir_u wrap_top_dir; - union cif_read_dbg_u cif_read_dbg; - union cpu_defaults_u cpu_default; - union cif_write_dbg_u cif_write_dbg; - union wrap_start_dir_u wrap_start_dir; - union cif_io_u cif_io; - struct w100_gpio_regs *gpio = par->mach->gpio; - - w100_soft_reset(); - - /* This is what the fpga_init code does on reset. May be wrong - but there is little info available */ - writel(0x31, remapped_regs + mmSCRATCH_UMSK); - for (temp32 = 0; temp32 < 10000; temp32++) - readl(remapped_regs + mmSCRATCH_UMSK); - writel(0x30, remapped_regs + mmSCRATCH_UMSK); - - /* Set up CIF */ - cif_io.val = defCIF_IO; - writel((u32)(cif_io.val), remapped_regs + mmCIF_IO); - - cif_write_dbg.val = readl(remapped_regs + mmCIF_WRITE_DBG); - cif_write_dbg.f.dis_packer_ful_during_rbbm_timeout = 0; - cif_write_dbg.f.en_dword_split_to_rbbm = 1; - cif_write_dbg.f.dis_timeout_during_rbbm = 1; - writel((u32) (cif_write_dbg.val), remapped_regs + mmCIF_WRITE_DBG); - - cif_read_dbg.val = readl(remapped_regs + mmCIF_READ_DBG); - cif_read_dbg.f.dis_rd_same_byte_to_trig_fetch = 1; - writel((u32) (cif_read_dbg.val), remapped_regs + mmCIF_READ_DBG); - - cif_cntl.val = readl(remapped_regs + mmCIF_CNTL); - cif_cntl.f.dis_system_bits = 1; - cif_cntl.f.dis_mr = 1; - cif_cntl.f.en_wait_to_compensate_dq_prop_dly = 0; - cif_cntl.f.intb_oe = 1; - cif_cntl.f.interrupt_active_high = 1; - writel((u32) (cif_cntl.val), remapped_regs + mmCIF_CNTL); - - /* Setup cfgINTF_CNTL and cfgCPU defaults */ - intf_cntl.val = defINTF_CNTL; - intf_cntl.f.ad_inc_a = 1; - intf_cntl.f.ad_inc_b = 1; - intf_cntl.f.rd_data_rdy_a = 0; - intf_cntl.f.rd_data_rdy_b = 0; - writeb((u8) (intf_cntl.val), remapped_base + cfgINTF_CNTL); - - cpu_default.val = defCPU_DEFAULTS; - cpu_default.f.access_ind_addr_a = 1; - cpu_default.f.access_ind_addr_b = 1; - cpu_default.f.access_scratch_reg = 1; - cpu_default.f.transition_size = 0; - writeb((u8) (cpu_default.val), remapped_base + cfgCPU_DEFAULTS); - - /* set up the apertures */ - writeb((u8) (W100_REG_BASE >> 16), remapped_base + cfgREG_BASE); - - cfgreg_base.val = defCFGREG_BASE; - cfgreg_base.f.cfgreg_base = W100_CFG_BASE; - writel((u32) (cfgreg_base.val), remapped_regs + mmCFGREG_BASE); - - wrap_start_dir.val = defWRAP_START_DIR; - wrap_start_dir.f.start_addr = WRAP_BUF_BASE_VALUE >> 1; - writel((u32) (wrap_start_dir.val), remapped_regs + mmWRAP_START_DIR); - - wrap_top_dir.val = defWRAP_TOP_DIR; - wrap_top_dir.f.top_addr = WRAP_BUF_TOP_VALUE >> 1; - writel((u32) (wrap_top_dir.val), remapped_regs + mmWRAP_TOP_DIR); - - writel((u32) 0x2440, remapped_regs + mmRBBM_CNTL); - - /* Set the hardware to 565 colour */ - temp32 = readl(remapped_regs + mmDISP_DEBUG2); - temp32 &= 0xff7fffff; - temp32 |= 0x00800000; - writel(temp32, remapped_regs + mmDISP_DEBUG2); - - /* Initialise the GPIO lines */ - if (gpio) { - writel(gpio->init_data1, remapped_regs + mmGPIO_DATA); - writel(gpio->init_data2, remapped_regs + mmGPIO_DATA2); - writel(gpio->gpio_dir1, remapped_regs + mmGPIO_CNTL1); - writel(gpio->gpio_oe1, remapped_regs + mmGPIO_CNTL2); - writel(gpio->gpio_dir2, remapped_regs + mmGPIO_CNTL3); - writel(gpio->gpio_oe2, remapped_regs + mmGPIO_CNTL4); - } -} - - -struct power_state { - union clk_pin_cntl_u clk_pin_cntl; - union pll_ref_fb_div_u pll_ref_fb_div; - union pll_cntl_u pll_cntl; - union sclk_cntl_u sclk_cntl; - union pclk_cntl_u pclk_cntl; - union pwrmgt_cntl_u pwrmgt_cntl; - int auto_mode; /* system clock auto changing? */ -}; - - -static struct power_state w100_pwr_state; - -/* The PLL Fout is determined by (XtalFreq/(M+1)) * ((N_int+1) + (N_fac/8)) */ - -/* 12.5MHz Crystal PLL Table */ -static struct w100_pll_info xtal_12500000[] = { - /*freq M N_int N_fac tfgoal lock_time */ - { 50, 0, 1, 0, 0xe0, 56}, /* 50.00 MHz */ - { 75, 0, 5, 0, 0xde, 37}, /* 75.00 MHz */ - {100, 0, 7, 0, 0xe0, 28}, /* 100.00 MHz */ - {125, 0, 9, 0, 0xe0, 22}, /* 125.00 MHz */ - {150, 0, 11, 0, 0xe0, 17}, /* 150.00 MHz */ - { 0, 0, 0, 0, 0, 0}, /* Terminator */ -}; - -/* 14.318MHz Crystal PLL Table */ -static struct w100_pll_info xtal_14318000[] = { - /*freq M N_int N_fac tfgoal lock_time */ - { 40, 4, 13, 0, 0xe0, 80}, /* tfgoal guessed */ - { 50, 1, 6, 0, 0xe0, 64}, /* 50.05 MHz */ - { 57, 2, 11, 0, 0xe0, 53}, /* tfgoal guessed */ - { 75, 0, 4, 3, 0xe0, 43}, /* 75.08 MHz */ - {100, 0, 6, 0, 0xe0, 32}, /* 100.10 MHz */ - { 0, 0, 0, 0, 0, 0}, -}; - -/* 16MHz Crystal PLL Table */ -static struct w100_pll_info xtal_16000000[] = { - /*freq M N_int N_fac tfgoal lock_time */ - { 72, 1, 8, 0, 0xe0, 48}, /* tfgoal guessed */ - { 80, 1, 9, 0, 0xe0, 13}, /* tfgoal guessed */ - { 95, 1, 10, 7, 0xe0, 38}, /* tfgoal guessed */ - { 96, 1, 11, 0, 0xe0, 36}, /* tfgoal guessed */ - { 0, 0, 0, 0, 0, 0}, -}; - -static struct pll_entries { - int xtal_freq; - struct w100_pll_info *pll_table; -} w100_pll_tables[] = { - { 12500000, &xtal_12500000[0] }, - { 14318000, &xtal_14318000[0] }, - { 16000000, &xtal_16000000[0] }, - { 0 }, -}; - -struct w100_pll_info *w100_get_xtal_table(unsigned int freq) -{ - struct pll_entries *pll_entry = w100_pll_tables; - - do { - if (freq == pll_entry->xtal_freq) - return pll_entry->pll_table; - pll_entry++; - } while (pll_entry->xtal_freq); - - return NULL; -} - - -static unsigned int w100_get_testcount(unsigned int testclk_sel) -{ - union clk_test_cntl_u clk_test_cntl; - - udelay(5); - - /* Select the test clock source and reset */ - clk_test_cntl.f.start_check_freq = 0x0; - clk_test_cntl.f.testclk_sel = testclk_sel; - clk_test_cntl.f.tstcount_rst = 0x1; /* set reset */ - writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); - - clk_test_cntl.f.tstcount_rst = 0x0; /* clear reset */ - writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); - - /* Run clock test */ - clk_test_cntl.f.start_check_freq = 0x1; - writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); - - /* Give the test time to complete */ - udelay(20); - - /* Return the result */ - clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL); - clk_test_cntl.f.start_check_freq = 0x0; - writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); - - return clk_test_cntl.f.test_count; -} - - -static int w100_pll_adjust(struct w100_pll_info *pll) -{ - unsigned int tf80; - unsigned int tf20; - - /* Initial Settings */ - w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0; /* power down */ - w100_pwr_state.pll_cntl.f.pll_reset = 0x0; /* not reset */ - w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1; /* Hi-Z */ - w100_pwr_state.pll_cntl.f.pll_pvg = 0x0; /* VCO gain = 0 */ - w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0; /* VCO frequency range control = off */ - w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; /* current offset inside VCO = 0 */ - w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0; - - /* Wai Ming 80 percent of VDD 1.3V gives 1.04V, minimum operating voltage is 1.08V - * therefore, commented out the following lines - * tf80 meant tf100 - */ - do { - /* set VCO input = 0.8 * VDD */ - w100_pwr_state.pll_cntl.f.pll_dactal = 0xd; - writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); - - tf80 = w100_get_testcount(TESTCLK_SRC_PLL); - if (tf80 >= (pll->tfgoal)) { - /* set VCO input = 0.2 * VDD */ - w100_pwr_state.pll_cntl.f.pll_dactal = 0x7; - writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); - - tf20 = w100_get_testcount(TESTCLK_SRC_PLL); - if (tf20 <= (pll->tfgoal)) - return 1; /* Success */ - - if ((w100_pwr_state.pll_cntl.f.pll_vcofr == 0x0) && - ((w100_pwr_state.pll_cntl.f.pll_pvg == 0x7) || - (w100_pwr_state.pll_cntl.f.pll_ioffset == 0x0))) { - /* slow VCO config */ - w100_pwr_state.pll_cntl.f.pll_vcofr = 0x1; - w100_pwr_state.pll_cntl.f.pll_pvg = 0x0; - w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; - continue; - } - } - if ((w100_pwr_state.pll_cntl.f.pll_ioffset) < 0x3) { - w100_pwr_state.pll_cntl.f.pll_ioffset += 0x1; - } else if ((w100_pwr_state.pll_cntl.f.pll_pvg) < 0x7) { - w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; - w100_pwr_state.pll_cntl.f.pll_pvg += 0x1; - } else { - return 0; /* Error */ - } - } while(1); -} - - -/* - * w100_pll_calibration - */ -static int w100_pll_calibration(struct w100_pll_info *pll) -{ - int status; - - status = w100_pll_adjust(pll); - - /* PLL Reset And Lock */ - /* set VCO input = 0.5 * VDD */ - w100_pwr_state.pll_cntl.f.pll_dactal = 0xa; - writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); - - udelay(1); /* reset time */ - - /* enable charge pump */ - w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0; /* normal */ - writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); - - /* set VCO input = Hi-Z, disable DAC */ - w100_pwr_state.pll_cntl.f.pll_dactal = 0x0; - writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); - - udelay(400); /* lock time */ - - /* PLL locked */ - - return status; -} - - -static int w100_pll_set_clk(struct w100_pll_info *pll) -{ - int status; - - if (w100_pwr_state.auto_mode == 1) /* auto mode */ - { - w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0; /* disable fast to normal */ - w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0; /* disable normal to fast */ - writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); - } - - /* Set system clock source to XTAL whilst adjusting the PLL! */ - w100_pwr_state.sclk_cntl.f.sclk_src_sel = CLK_SRC_XTAL; - writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); - - w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = pll->M; - w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = pll->N_int; - w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = pll->N_fac; - w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = pll->lock_time; - writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV); - - w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0; - writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); - - status = w100_pll_calibration(pll); - - if (w100_pwr_state.auto_mode == 1) /* auto mode */ - { - w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x1; /* reenable fast to normal */ - w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x1; /* reenable normal to fast */ - writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); - } - return status; -} - -/* freq = target frequency of the PLL */ -static int w100_set_pll_freq(struct w100fb_par *par, unsigned int freq) -{ - struct w100_pll_info *pll = par->pll_table; - - do { - if (freq == pll->freq) { - return w100_pll_set_clk(pll); - } - pll++; - } while(pll->freq); - return 0; -} - -/* Set up an initial state. Some values/fields set - here will be overwritten. */ -static void w100_pwm_setup(struct w100fb_par *par) -{ - w100_pwr_state.clk_pin_cntl.f.osc_en = 0x1; - w100_pwr_state.clk_pin_cntl.f.osc_gain = 0x1f; - w100_pwr_state.clk_pin_cntl.f.dont_use_xtalin = 0x0; - w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x0; - w100_pwr_state.clk_pin_cntl.f.xtalin_dbl_en = par->mach->xtal_dbl ? 1 : 0; - w100_pwr_state.clk_pin_cntl.f.cg_debug = 0x0; - writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL); - - w100_pwr_state.sclk_cntl.f.sclk_src_sel = CLK_SRC_XTAL; - w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = 0x0; /* Pfast = 1 */ - w100_pwr_state.sclk_cntl.f.sclk_clkon_hys = 0x3; - w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0; /* Pslow = 1 */ - w100_pwr_state.sclk_cntl.f.disp_cg_ok2switch_en = 0x0; - w100_pwr_state.sclk_cntl.f.sclk_force_reg = 0x0; /* Dynamic */ - w100_pwr_state.sclk_cntl.f.sclk_force_disp = 0x0; /* Dynamic */ - w100_pwr_state.sclk_cntl.f.sclk_force_mc = 0x0; /* Dynamic */ - w100_pwr_state.sclk_cntl.f.sclk_force_extmc = 0x0; /* Dynamic */ - w100_pwr_state.sclk_cntl.f.sclk_force_cp = 0x0; /* Dynamic */ - w100_pwr_state.sclk_cntl.f.sclk_force_e2 = 0x0; /* Dynamic */ - w100_pwr_state.sclk_cntl.f.sclk_force_e3 = 0x0; /* Dynamic */ - w100_pwr_state.sclk_cntl.f.sclk_force_idct = 0x0; /* Dynamic */ - w100_pwr_state.sclk_cntl.f.sclk_force_bist = 0x0; /* Dynamic */ - w100_pwr_state.sclk_cntl.f.busy_extend_cp = 0x0; - w100_pwr_state.sclk_cntl.f.busy_extend_e2 = 0x0; - w100_pwr_state.sclk_cntl.f.busy_extend_e3 = 0x0; - w100_pwr_state.sclk_cntl.f.busy_extend_idct = 0x0; - writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); - - w100_pwr_state.pclk_cntl.f.pclk_src_sel = CLK_SRC_XTAL; - w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x1; /* P = 2 */ - w100_pwr_state.pclk_cntl.f.pclk_force_disp = 0x0; /* Dynamic */ - writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL); - - w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = 0x0; /* M = 1 */ - w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = 0x0; /* N = 1.0 */ - w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = 0x0; - w100_pwr_state.pll_ref_fb_div.f.pll_reset_time = 0x5; - w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = 0xff; - writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV); - - w100_pwr_state.pll_cntl.f.pll_pwdn = 0x1; - w100_pwr_state.pll_cntl.f.pll_reset = 0x1; - w100_pwr_state.pll_cntl.f.pll_pm_en = 0x0; - w100_pwr_state.pll_cntl.f.pll_mode = 0x0; /* uses VCO clock */ - w100_pwr_state.pll_cntl.f.pll_refclk_sel = 0x0; - w100_pwr_state.pll_cntl.f.pll_fbclk_sel = 0x0; - w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0; - w100_pwr_state.pll_cntl.f.pll_pcp = 0x4; - w100_pwr_state.pll_cntl.f.pll_pvg = 0x0; - w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0; - w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; - w100_pwr_state.pll_cntl.f.pll_pecc_mode = 0x0; - w100_pwr_state.pll_cntl.f.pll_pecc_scon = 0x0; - w100_pwr_state.pll_cntl.f.pll_dactal = 0x0; /* Hi-Z */ - w100_pwr_state.pll_cntl.f.pll_cp_clip = 0x3; - w100_pwr_state.pll_cntl.f.pll_conf = 0x2; - w100_pwr_state.pll_cntl.f.pll_mbctrl = 0x2; - w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0; - writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); - - w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x0; - w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1; /* normal mode (0, 1, 3) */ - w100_pwr_state.pwrmgt_cntl.f.pwm_wakeup_cond = 0x0; - w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0; - w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0; - w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_cond = 0x1; /* PM4,ENG */ - w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_cond = 0x1; /* PM4,ENG */ - w100_pwr_state.pwrmgt_cntl.f.pwm_idle_timer = 0xFF; - w100_pwr_state.pwrmgt_cntl.f.pwm_busy_timer = 0xFF; - writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); - - w100_pwr_state.auto_mode = 0; /* manual mode */ -} - - -/* - * Setup the w100 clocks for the specified mode - */ -static void w100_init_clocks(struct w100fb_par *par) -{ - struct w100_mode *mode = par->mode; - - if (mode->pixclk_src == CLK_SRC_PLL || mode->sysclk_src == CLK_SRC_PLL) - w100_set_pll_freq(par, (par->fastpll_mode && mode->fast_pll_freq) ? mode->fast_pll_freq : mode->pll_freq); - - w100_pwr_state.sclk_cntl.f.sclk_src_sel = mode->sysclk_src; - w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = mode->sysclk_divider; - w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = mode->sysclk_divider; - writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); -} - -static void w100_init_lcd(struct w100fb_par *par) -{ - u32 temp32; - struct w100_mode *mode = par->mode; - struct w100_gen_regs *regs = par->mach->regs; - union active_h_disp_u active_h_disp; - union active_v_disp_u active_v_disp; - union graphic_h_disp_u graphic_h_disp; - union graphic_v_disp_u graphic_v_disp; - union crtc_total_u crtc_total; - - /* w3200 doesn't like undefined bits being set so zero register values first */ - - active_h_disp.val = 0; - active_h_disp.f.active_h_start=mode->left_margin; - active_h_disp.f.active_h_end=mode->left_margin + mode->xres; - writel(active_h_disp.val, remapped_regs + mmACTIVE_H_DISP); - - active_v_disp.val = 0; - active_v_disp.f.active_v_start=mode->upper_margin; - active_v_disp.f.active_v_end=mode->upper_margin + mode->yres; - writel(active_v_disp.val, remapped_regs + mmACTIVE_V_DISP); - - graphic_h_disp.val = 0; - graphic_h_disp.f.graphic_h_start=mode->left_margin; - graphic_h_disp.f.graphic_h_end=mode->left_margin + mode->xres; - writel(graphic_h_disp.val, remapped_regs + mmGRAPHIC_H_DISP); - - graphic_v_disp.val = 0; - graphic_v_disp.f.graphic_v_start=mode->upper_margin; - graphic_v_disp.f.graphic_v_end=mode->upper_margin + mode->yres; - writel(graphic_v_disp.val, remapped_regs + mmGRAPHIC_V_DISP); - - crtc_total.val = 0; - crtc_total.f.crtc_h_total=mode->left_margin + mode->xres + mode->right_margin; - crtc_total.f.crtc_v_total=mode->upper_margin + mode->yres + mode->lower_margin; - writel(crtc_total.val, remapped_regs + mmCRTC_TOTAL); - - writel(mode->crtc_ss, remapped_regs + mmCRTC_SS); - writel(mode->crtc_ls, remapped_regs + mmCRTC_LS); - writel(mode->crtc_gs, remapped_regs + mmCRTC_GS); - writel(mode->crtc_vpos_gs, remapped_regs + mmCRTC_VPOS_GS); - writel(mode->crtc_rev, remapped_regs + mmCRTC_REV); - writel(mode->crtc_dclk, remapped_regs + mmCRTC_DCLK); - writel(mode->crtc_gclk, remapped_regs + mmCRTC_GCLK); - writel(mode->crtc_goe, remapped_regs + mmCRTC_GOE); - writel(mode->crtc_ps1_active, remapped_regs + mmCRTC_PS1_ACTIVE); - - writel(regs->lcd_format, remapped_regs + mmLCD_FORMAT); - writel(regs->lcdd_cntl1, remapped_regs + mmLCDD_CNTL1); - writel(regs->lcdd_cntl2, remapped_regs + mmLCDD_CNTL2); - writel(regs->genlcd_cntl1, remapped_regs + mmGENLCD_CNTL1); - writel(regs->genlcd_cntl2, remapped_regs + mmGENLCD_CNTL2); - writel(regs->genlcd_cntl3, remapped_regs + mmGENLCD_CNTL3); - - writel(0x00000000, remapped_regs + mmCRTC_FRAME); - writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS); - writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT); - writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR); - - /* Hack for overlay in ext memory */ - temp32 = readl(remapped_regs + mmDISP_DEBUG2); - temp32 |= 0xc0000000; - writel(temp32, remapped_regs + mmDISP_DEBUG2); -} - - -static void w100_setup_memory(struct w100fb_par *par) -{ - union mc_ext_mem_location_u extmem_location; - union mc_fb_location_u intmem_location; - struct w100_mem_info *mem = par->mach->mem; - struct w100_bm_mem_info *bm_mem = par->mach->bm_mem; - - if (!par->extmem_active) { - w100_suspend(W100_SUSPEND_EXTMEM); - - /* Map Internal Memory at FB Base */ - intmem_location.f.mc_fb_start = W100_FB_BASE >> 8; - intmem_location.f.mc_fb_top = (W100_FB_BASE+MEM_INT_SIZE) >> 8; - writel((u32) (intmem_location.val), remapped_regs + mmMC_FB_LOCATION); - - /* Unmap External Memory - value is *probably* irrelevant but may have meaning - to acceleration libraries */ - extmem_location.f.mc_ext_mem_start = MEM_EXT_BASE_VALUE >> 8; - extmem_location.f.mc_ext_mem_top = (MEM_EXT_BASE_VALUE-1) >> 8; - writel((u32) (extmem_location.val), remapped_regs + mmMC_EXT_MEM_LOCATION); - } else { - /* Map Internal Memory to its default location */ - intmem_location.f.mc_fb_start = MEM_INT_BASE_VALUE >> 8; - intmem_location.f.mc_fb_top = (MEM_INT_BASE_VALUE+MEM_INT_SIZE) >> 8; - writel((u32) (intmem_location.val), remapped_regs + mmMC_FB_LOCATION); - - /* Map External Memory at FB Base */ - extmem_location.f.mc_ext_mem_start = W100_FB_BASE >> 8; - extmem_location.f.mc_ext_mem_top = (W100_FB_BASE+par->mach->mem->size) >> 8; - writel((u32) (extmem_location.val), remapped_regs + mmMC_EXT_MEM_LOCATION); - - writel(0x00007800, remapped_regs + mmMC_BIST_CTRL); - writel(mem->ext_cntl, remapped_regs + mmMEM_EXT_CNTL); - writel(0x00200021, remapped_regs + mmMEM_SDRAM_MODE_REG); - udelay(100); - writel(0x80200021, remapped_regs + mmMEM_SDRAM_MODE_REG); - udelay(100); - writel(mem->sdram_mode_reg, remapped_regs + mmMEM_SDRAM_MODE_REG); - udelay(100); - writel(mem->ext_timing_cntl, remapped_regs + mmMEM_EXT_TIMING_CNTL); - writel(mem->io_cntl, remapped_regs + mmMEM_IO_CNTL); - if (bm_mem) { - writel(bm_mem->ext_mem_bw, remapped_regs + mmBM_EXT_MEM_BANDWIDTH); - writel(bm_mem->offset, remapped_regs + mmBM_OFFSET); - writel(bm_mem->ext_timing_ctl, remapped_regs + mmBM_MEM_EXT_TIMING_CNTL); - writel(bm_mem->ext_cntl, remapped_regs + mmBM_MEM_EXT_CNTL); - writel(bm_mem->mode_reg, remapped_regs + mmBM_MEM_MODE_REG); - writel(bm_mem->io_cntl, remapped_regs + mmBM_MEM_IO_CNTL); - writel(bm_mem->config, remapped_regs + mmBM_CONFIG); - } - } -} - -static void w100_set_dispregs(struct w100fb_par *par) -{ - unsigned long rot=0, divider, offset=0; - union graphic_ctrl_u graphic_ctrl; - - /* See if the mode has been rotated */ - if (par->xres == par->mode->xres) { - if (par->flip) { - rot=3; /* 180 degree */ - offset=(par->xres * par->yres) - 1; - } /* else 0 degree */ - divider = par->mode->pixclk_divider; - } else { - if (par->flip) { - rot=2; /* 270 degree */ - offset=par->xres - 1; - } else { - rot=1; /* 90 degree */ - offset=par->xres * (par->yres - 1); - } - divider = par->mode->pixclk_divider_rotated; - } - - graphic_ctrl.val = 0; /* w32xx doesn't like undefined bits */ - switch (par->chip_id) { - case CHIP_ID_W100: - graphic_ctrl.f_w100.color_depth=6; - graphic_ctrl.f_w100.en_crtc=1; - graphic_ctrl.f_w100.en_graphic_req=1; - graphic_ctrl.f_w100.en_graphic_crtc=1; - graphic_ctrl.f_w100.lcd_pclk_on=1; - graphic_ctrl.f_w100.lcd_sclk_on=1; - graphic_ctrl.f_w100.low_power_on=0; - graphic_ctrl.f_w100.req_freq=0; - graphic_ctrl.f_w100.portrait_mode=rot; - - /* Zaurus needs this */ - switch(par->xres) { - case 240: - case 320: - default: - graphic_ctrl.f_w100.total_req_graphic=0xa0; - break; - case 480: - case 640: - switch(rot) { - case 0: /* 0 */ - case 3: /* 180 */ - graphic_ctrl.f_w100.low_power_on=1; - graphic_ctrl.f_w100.req_freq=5; - break; - case 1: /* 90 */ - case 2: /* 270 */ - graphic_ctrl.f_w100.req_freq=4; - break; - default: - break; - } - graphic_ctrl.f_w100.total_req_graphic=0xf0; - break; - } - break; - case CHIP_ID_W3200: - case CHIP_ID_W3220: - graphic_ctrl.f_w32xx.color_depth=6; - graphic_ctrl.f_w32xx.en_crtc=1; - graphic_ctrl.f_w32xx.en_graphic_req=1; - graphic_ctrl.f_w32xx.en_graphic_crtc=1; - graphic_ctrl.f_w32xx.lcd_pclk_on=1; - graphic_ctrl.f_w32xx.lcd_sclk_on=1; - graphic_ctrl.f_w32xx.low_power_on=0; - graphic_ctrl.f_w32xx.req_freq=0; - graphic_ctrl.f_w32xx.total_req_graphic=par->mode->xres >> 1; /* panel xres, not mode */ - graphic_ctrl.f_w32xx.portrait_mode=rot; - break; - } - - /* Set the pixel clock source and divider */ - w100_pwr_state.pclk_cntl.f.pclk_src_sel = par->mode->pixclk_src; - w100_pwr_state.pclk_cntl.f.pclk_post_div = divider; - writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL); - - writel(graphic_ctrl.val, remapped_regs + mmGRAPHIC_CTRL); - writel(W100_FB_BASE + ((offset * BITS_PER_PIXEL/8)&~0x03UL), remapped_regs + mmGRAPHIC_OFFSET); - writel((par->xres*BITS_PER_PIXEL/8), remapped_regs + mmGRAPHIC_PITCH); -} - - -/* - * Work out how long the sync pulse lasts - * Value is 1/(time in seconds) - */ -static void calc_hsync(struct w100fb_par *par) -{ - unsigned long hsync; - struct w100_mode *mode = par->mode; - union crtc_ss_u crtc_ss; - - if (mode->pixclk_src == CLK_SRC_XTAL) - hsync=par->mach->xtal_freq; - else - hsync=((par->fastpll_mode && mode->fast_pll_freq) ? mode->fast_pll_freq : mode->pll_freq)*100000; - - hsync /= (w100_pwr_state.pclk_cntl.f.pclk_post_div + 1); - - crtc_ss.val = readl(remapped_regs + mmCRTC_SS); - if (crtc_ss.val) - par->hsync_len = hsync / (crtc_ss.f.ss_end-crtc_ss.f.ss_start); - else - par->hsync_len = 0; -} - -static void w100_suspend(u32 mode) -{ - u32 val; - - writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION); - writel(0x00FF0000, remapped_regs + mmMC_PERF_MON_CNTL); - - val = readl(remapped_regs + mmMEM_EXT_TIMING_CNTL); - val &= ~(0x00100000); /* bit20=0 */ - val |= 0xFF000000; /* bit31:24=0xff */ - writel(val, remapped_regs + mmMEM_EXT_TIMING_CNTL); - - val = readl(remapped_regs + mmMEM_EXT_CNTL); - val &= ~(0x00040000); /* bit18=0 */ - val |= 0x00080000; /* bit19=1 */ - writel(val, remapped_regs + mmMEM_EXT_CNTL); - - udelay(1); /* wait 1us */ - - if (mode == W100_SUSPEND_EXTMEM) { - /* CKE: Tri-State */ - val = readl(remapped_regs + mmMEM_EXT_CNTL); - val |= 0x40000000; /* bit30=1 */ - writel(val, remapped_regs + mmMEM_EXT_CNTL); - - /* CLK: Stop */ - val = readl(remapped_regs + mmMEM_EXT_CNTL); - val &= ~(0x00000001); /* bit0=0 */ - writel(val, remapped_regs + mmMEM_EXT_CNTL); - } else { - writel(0x00000000, remapped_regs + mmSCLK_CNTL); - writel(0x000000BF, remapped_regs + mmCLK_PIN_CNTL); - writel(0x00000015, remapped_regs + mmPWRMGT_CNTL); - - udelay(5); - - val = readl(remapped_regs + mmPLL_CNTL); - val |= 0x00000004; /* bit2=1 */ - writel(val, remapped_regs + mmPLL_CNTL); - - writel(0x00000000, remapped_regs + mmLCDD_CNTL1); - writel(0x00000000, remapped_regs + mmLCDD_CNTL2); - writel(0x00000000, remapped_regs + mmGENLCD_CNTL1); - writel(0x00000000, remapped_regs + mmGENLCD_CNTL2); - writel(0x00000000, remapped_regs + mmGENLCD_CNTL3); - - val = readl(remapped_regs + mmMEM_EXT_CNTL); - val |= 0xF0000000; - val &= ~(0x00000001); - writel(val, remapped_regs + mmMEM_EXT_CNTL); - - writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL); - } -} - -static void w100_vsync(void) -{ - u32 tmp; - int timeout = 30000; /* VSync timeout = 30[ms] > 16.8[ms] */ - - tmp = readl(remapped_regs + mmACTIVE_V_DISP); - - /* set vline pos */ - writel((tmp >> 16) & 0x3ff, remapped_regs + mmDISP_INT_CNTL); - - /* disable vline irq */ - tmp = readl(remapped_regs + mmGEN_INT_CNTL); - - tmp &= ~0x00000002; - writel(tmp, remapped_regs + mmGEN_INT_CNTL); - - /* clear vline irq status */ - writel(0x00000002, remapped_regs + mmGEN_INT_STATUS); - - /* enable vline irq */ - writel((tmp | 0x00000002), remapped_regs + mmGEN_INT_CNTL); - - /* clear vline irq status */ - writel(0x00000002, remapped_regs + mmGEN_INT_STATUS); - - while(timeout > 0) { - if (readl(remapped_regs + mmGEN_INT_STATUS) & 0x00000002) - break; - udelay(1); - timeout--; - } - - /* disable vline irq */ - writel(tmp, remapped_regs + mmGEN_INT_CNTL); - - /* clear vline irq status */ - writel(0x00000002, remapped_regs + mmGEN_INT_STATUS); -} - -static struct platform_driver w100fb_driver = { - .probe = w100fb_probe, - .remove = w100fb_remove, - .suspend = w100fb_suspend, - .resume = w100fb_resume, - .driver = { - .name = "w100fb", - .dev_groups = w100fb_groups, - }, -}; - -module_platform_driver(w100fb_driver); - -MODULE_DESCRIPTION("ATI Imageon w100 framebuffer driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/w100fb.h b/drivers/video/fbdev/w100fb.h deleted file mode 100644 index 52c96d155b4c..000000000000 --- a/drivers/video/fbdev/w100fb.h +++ /dev/null @@ -1,924 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * linux/drivers/video/w100fb.h - * - * Frame Buffer Device for ATI w100 (Wallaby) - * - * Copyright (C) 2002, ATI Corp. - * Copyright (C) 2004-2005 Richard Purdie - * Copyright (c) 2005 Ian Molton <spyro@f2s.com> - * - * Modified to work with 2.6 by Richard Purdie <rpurdie@rpsys.net> - * - * w32xx support by Ian Molton - */ - -#if !defined (_W100FB_H) -#define _W100FB_H - -/* Block CIF Start: */ -#define mmCHIP_ID 0x0000 -#define mmREVISION_ID 0x0004 -#define mmWRAP_BUF_A 0x0008 -#define mmWRAP_BUF_B 0x000C -#define mmWRAP_TOP_DIR 0x0010 -#define mmWRAP_START_DIR 0x0014 -#define mmCIF_CNTL 0x0018 -#define mmCFGREG_BASE 0x001C -#define mmCIF_IO 0x0020 -#define mmCIF_READ_DBG 0x0024 -#define mmCIF_WRITE_DBG 0x0028 -#define cfgIND_ADDR_A_0 0x0000 -#define cfgIND_ADDR_A_1 0x0001 -#define cfgIND_ADDR_A_2 0x0002 -#define cfgIND_DATA_A 0x0003 -#define cfgREG_BASE 0x0004 -#define cfgINTF_CNTL 0x0005 -#define cfgSTATUS 0x0006 -#define cfgCPU_DEFAULTS 0x0007 -#define cfgIND_ADDR_B_0 0x0008 -#define cfgIND_ADDR_B_1 0x0009 -#define cfgIND_ADDR_B_2 0x000A -#define cfgIND_DATA_B 0x000B -#define cfgPM4_RPTR 0x000C -#define cfgSCRATCH 0x000D -#define cfgPM4_WRPTR_0 0x000E -#define cfgPM4_WRPTR_1 0x000F -/* Block CIF End: */ - -/* Block CP Start: */ -#define mmSCRATCH_UMSK 0x0280 -#define mmSCRATCH_ADDR 0x0284 -#define mmGEN_INT_CNTL 0x0200 -#define mmGEN_INT_STATUS 0x0204 -/* Block CP End: */ - -/* Block DISPLAY Start: */ -#define mmLCD_FORMAT 0x0410 -#define mmGRAPHIC_CTRL 0x0414 -#define mmGRAPHIC_OFFSET 0x0418 -#define mmGRAPHIC_PITCH 0x041C -#define mmCRTC_TOTAL 0x0420 -#define mmACTIVE_H_DISP 0x0424 -#define mmACTIVE_V_DISP 0x0428 -#define mmGRAPHIC_H_DISP 0x042C -#define mmGRAPHIC_V_DISP 0x0430 -#define mmVIDEO_CTRL 0x0434 -#define mmGRAPHIC_KEY 0x0438 -#define mmBRIGHTNESS_CNTL 0x045C -#define mmDISP_INT_CNTL 0x0488 -#define mmCRTC_SS 0x048C -#define mmCRTC_LS 0x0490 -#define mmCRTC_REV 0x0494 -#define mmCRTC_DCLK 0x049C -#define mmCRTC_GS 0x04A0 -#define mmCRTC_VPOS_GS 0x04A4 -#define mmCRTC_GCLK 0x04A8 -#define mmCRTC_GOE 0x04AC -#define mmCRTC_FRAME 0x04B0 -#define mmCRTC_FRAME_VPOS 0x04B4 -#define mmGPIO_DATA 0x04B8 -#define mmGPIO_CNTL1 0x04BC -#define mmGPIO_CNTL2 0x04C0 -#define mmLCDD_CNTL1 0x04C4 -#define mmLCDD_CNTL2 0x04C8 -#define mmGENLCD_CNTL1 0x04CC -#define mmGENLCD_CNTL2 0x04D0 -#define mmDISP_DEBUG 0x04D4 -#define mmDISP_DB_BUF_CNTL 0x04D8 -#define mmDISP_CRC_SIG 0x04DC -#define mmCRTC_DEFAULT_COUNT 0x04E0 -#define mmLCD_BACKGROUND_COLOR 0x04E4 -#define mmCRTC_PS2 0x04E8 -#define mmCRTC_PS2_VPOS 0x04EC -#define mmCRTC_PS1_ACTIVE 0x04F0 -#define mmCRTC_PS1_NACTIVE 0x04F4 -#define mmCRTC_GCLK_EXT 0x04F8 -#define mmCRTC_ALW 0x04FC -#define mmCRTC_ALW_VPOS 0x0500 -#define mmCRTC_PSK 0x0504 -#define mmCRTC_PSK_HPOS 0x0508 -#define mmCRTC_CV4_START 0x050C -#define mmCRTC_CV4_END 0x0510 -#define mmCRTC_CV4_HPOS 0x0514 -#define mmCRTC_ECK 0x051C -#define mmREFRESH_CNTL 0x0520 -#define mmGENLCD_CNTL3 0x0524 -#define mmGPIO_DATA2 0x0528 -#define mmGPIO_CNTL3 0x052C -#define mmGPIO_CNTL4 0x0530 -#define mmCHIP_STRAP 0x0534 -#define mmDISP_DEBUG2 0x0538 -#define mmDEBUG_BUS_CNTL 0x053C -#define mmGAMMA_VALUE1 0x0540 -#define mmGAMMA_VALUE2 0x0544 -#define mmGAMMA_SLOPE 0x0548 -#define mmGEN_STATUS 0x054C -#define mmHW_INT 0x0550 -/* Block DISPLAY End: */ - -/* Block GFX Start: */ -#define mmDST_OFFSET 0x1004 -#define mmDST_PITCH 0x1008 -#define mmDST_Y_X 0x1038 -#define mmDST_WIDTH_HEIGHT 0x1198 -#define mmDP_GUI_MASTER_CNTL 0x106C -#define mmBRUSH_OFFSET 0x108C -#define mmBRUSH_Y_X 0x1074 -#define mmDP_BRUSH_FRGD_CLR 0x107C -#define mmSRC_OFFSET 0x11AC -#define mmSRC_PITCH 0x11B0 -#define mmSRC_Y_X 0x1034 -#define mmDEFAULT_PITCH_OFFSET 0x10A0 -#define mmDEFAULT_SC_BOTTOM_RIGHT 0x10A8 -#define mmDEFAULT2_SC_BOTTOM_RIGHT 0x10AC -#define mmSC_TOP_LEFT 0x11BC -#define mmSC_BOTTOM_RIGHT 0x11C0 -#define mmSRC_SC_BOTTOM_RIGHT 0x11C4 -#define mmGLOBAL_ALPHA 0x1210 -#define mmFILTER_COEF 0x1214 -#define mmMVC_CNTL_START 0x11E0 -#define mmE2_ARITHMETIC_CNTL 0x1220 -#define mmDP_CNTL 0x11C8 -#define mmDP_CNTL_DST_DIR 0x11CC -#define mmDP_DATATYPE 0x12C4 -#define mmDP_MIX 0x12C8 -#define mmDP_WRITE_MSK 0x12CC -#define mmENG_CNTL 0x13E8 -#define mmENG_PERF_CNT 0x13F0 -/* Block GFX End: */ - -/* Block IDCT Start: */ -#define mmIDCT_RUNS 0x0C00 -#define mmIDCT_LEVELS 0x0C04 -#define mmIDCT_CONTROL 0x0C3C -#define mmIDCT_AUTH_CONTROL 0x0C08 -#define mmIDCT_AUTH 0x0C0C -/* Block IDCT End: */ - -/* Block MC Start: */ -#define mmMEM_CNTL 0x0180 -#define mmMEM_ARB 0x0184 -#define mmMC_FB_LOCATION 0x0188 -#define mmMEM_EXT_CNTL 0x018C -#define mmMC_EXT_MEM_LOCATION 0x0190 -#define mmMEM_EXT_TIMING_CNTL 0x0194 -#define mmMEM_SDRAM_MODE_REG 0x0198 -#define mmMEM_IO_CNTL 0x019C -#define mmMC_DEBUG 0x01A0 -#define mmMC_BIST_CTRL 0x01A4 -#define mmMC_BIST_COLLAR_READ 0x01A8 -#define mmTC_MISMATCH 0x01AC -#define mmMC_PERF_MON_CNTL 0x01B0 -#define mmMC_PERF_COUNTERS 0x01B4 -/* Block MC End: */ - -/* Block BM Start: */ -#define mmBM_EXT_MEM_BANDWIDTH 0x0A00 -#define mmBM_OFFSET 0x0A04 -#define mmBM_MEM_EXT_TIMING_CNTL 0x0A08 -#define mmBM_MEM_EXT_CNTL 0x0A0C -#define mmBM_MEM_MODE_REG 0x0A10 -#define mmBM_MEM_IO_CNTL 0x0A18 -#define mmBM_CONFIG 0x0A1C -#define mmBM_STATUS 0x0A20 -#define mmBM_DEBUG 0x0A24 -#define mmBM_PERF_MON_CNTL 0x0A28 -#define mmBM_PERF_COUNTERS 0x0A2C -#define mmBM_PERF2_MON_CNTL 0x0A30 -#define mmBM_PERF2_COUNTERS 0x0A34 -/* Block BM End: */ - -/* Block RBBM Start: */ -#define mmWAIT_UNTIL 0x1400 -#define mmISYNC_CNTL 0x1404 -#define mmRBBM_STATUS 0x0140 -#define mmRBBM_CNTL 0x0144 -#define mmNQWAIT_UNTIL 0x0150 -/* Block RBBM End: */ - -/* Block CG Start: */ -#define mmCLK_PIN_CNTL 0x0080 -#define mmPLL_REF_FB_DIV 0x0084 -#define mmPLL_CNTL 0x0088 -#define mmSCLK_CNTL 0x008C -#define mmPCLK_CNTL 0x0090 -#define mmCLK_TEST_CNTL 0x0094 -#define mmPWRMGT_CNTL 0x0098 -#define mmPWRMGT_STATUS 0x009C -/* Block CG End: */ - -/* default value definitions */ -#define defWRAP_TOP_DIR 0x00000000 -#define defWRAP_START_DIR 0x00000000 -#define defCFGREG_BASE 0x00000000 -#define defCIF_IO 0x000C0902 -#define defINTF_CNTL 0x00000011 -#define defCPU_DEFAULTS 0x00000006 -#define defHW_INT 0x00000000 -#define defMC_EXT_MEM_LOCATION 0x07ff0000 -#define defTC_MISMATCH 0x00000000 - -#define W100_CFG_BASE 0x0 -#define W100_CFG_LEN 0x10 -#define W100_REG_BASE 0x10000 -#define W100_REG_LEN 0x2000 -#define MEM_INT_BASE_VALUE 0x100000 -#define MEM_EXT_BASE_VALUE 0x800000 -#define MEM_INT_SIZE 0x05ffff -#define MEM_WINDOW_BASE 0x100000 -#define MEM_WINDOW_SIZE 0xf00000 - -#define WRAP_BUF_BASE_VALUE 0x80000 -#define WRAP_BUF_TOP_VALUE 0xbffff - -#define CHIP_ID_W100 0x57411002 -#define CHIP_ID_W3200 0x56441002 -#define CHIP_ID_W3220 0x57441002 - -/* Register structure definitions */ - -struct wrap_top_dir_t { - u32 top_addr : 23; - u32 : 9; -} __attribute__((packed)); - -union wrap_top_dir_u { - u32 val : 32; - struct wrap_top_dir_t f; -} __attribute__((packed)); - -struct wrap_start_dir_t { - u32 start_addr : 23; - u32 : 9; -} __attribute__((packed)); - -union wrap_start_dir_u { - u32 val : 32; - struct wrap_start_dir_t f; -} __attribute__((packed)); - -struct cif_cntl_t { - u32 swap_reg : 2; - u32 swap_fbuf_1 : 2; - u32 swap_fbuf_2 : 2; - u32 swap_fbuf_3 : 2; - u32 pmi_int_disable : 1; - u32 pmi_schmen_disable : 1; - u32 intb_oe : 1; - u32 en_wait_to_compensate_dq_prop_dly : 1; - u32 compensate_wait_rd_size : 2; - u32 wait_asserted_timeout_val : 2; - u32 wait_masked_val : 2; - u32 en_wait_timeout : 1; - u32 en_one_clk_setup_before_wait : 1; - u32 interrupt_active_high : 1; - u32 en_overwrite_straps : 1; - u32 strap_wait_active_hi : 1; - u32 lat_busy_count : 2; - u32 lat_rd_pm4_sclk_busy : 1; - u32 dis_system_bits : 1; - u32 dis_mr : 1; - u32 cif_spare_1 : 4; -} __attribute__((packed)); - -union cif_cntl_u { - u32 val : 32; - struct cif_cntl_t f; -} __attribute__((packed)); - -struct cfgreg_base_t { - u32 cfgreg_base : 24; - u32 : 8; -} __attribute__((packed)); - -union cfgreg_base_u { - u32 val : 32; - struct cfgreg_base_t f; -} __attribute__((packed)); - -struct cif_io_t { - u32 dq_srp : 1; - u32 dq_srn : 1; - u32 dq_sp : 4; - u32 dq_sn : 4; - u32 waitb_srp : 1; - u32 waitb_srn : 1; - u32 waitb_sp : 4; - u32 waitb_sn : 4; - u32 intb_srp : 1; - u32 intb_srn : 1; - u32 intb_sp : 4; - u32 intb_sn : 4; - u32 : 2; -} __attribute__((packed)); - -union cif_io_u { - u32 val : 32; - struct cif_io_t f; -} __attribute__((packed)); - -struct cif_read_dbg_t { - u32 unpacker_pre_fetch_trig_gen : 2; - u32 dly_second_rd_fetch_trig : 1; - u32 rst_rd_burst_id : 1; - u32 dis_rd_burst_id : 1; - u32 en_block_rd_when_packer_is_not_emp : 1; - u32 dis_pre_fetch_cntl_sm : 1; - u32 rbbm_chrncy_dis : 1; - u32 rbbm_rd_after_wr_lat : 2; - u32 dis_be_during_rd : 1; - u32 one_clk_invalidate_pulse : 1; - u32 dis_chnl_priority : 1; - u32 rst_read_path_a_pls : 1; - u32 rst_read_path_b_pls : 1; - u32 dis_reg_rd_fetch_trig : 1; - u32 dis_rd_fetch_trig_from_ind_addr : 1; - u32 dis_rd_same_byte_to_trig_fetch : 1; - u32 dis_dir_wrap : 1; - u32 dis_ring_buf_to_force_dec : 1; - u32 dis_addr_comp_in_16bit : 1; - u32 clr_w : 1; - u32 err_rd_tag_is_3 : 1; - u32 err_load_when_ful_a : 1; - u32 err_load_when_ful_b : 1; - u32 : 7; -} __attribute__((packed)); - -union cif_read_dbg_u { - u32 val : 32; - struct cif_read_dbg_t f; -} __attribute__((packed)); - -struct cif_write_dbg_t { - u32 packer_timeout_count : 2; - u32 en_upper_load_cond : 1; - u32 en_chnl_change_cond : 1; - u32 dis_addr_comp_cond : 1; - u32 dis_load_same_byte_addr_cond : 1; - u32 dis_timeout_cond : 1; - u32 dis_timeout_during_rbbm : 1; - u32 dis_packer_ful_during_rbbm_timeout : 1; - u32 en_dword_split_to_rbbm : 1; - u32 en_dummy_val : 1; - u32 dummy_val_sel : 1; - u32 mask_pm4_wrptr_dec : 1; - u32 dis_mc_clean_cond : 1; - u32 err_two_reqi_during_ful : 1; - u32 err_reqi_during_idle_clk : 1; - u32 err_global : 1; - u32 en_wr_buf_dbg_load : 1; - u32 en_wr_buf_dbg_path : 1; - u32 sel_wr_buf_byte : 3; - u32 dis_rd_flush_wr : 1; - u32 dis_packer_ful_cond : 1; - u32 dis_invalidate_by_ops_chnl : 1; - u32 en_halt_when_reqi_err : 1; - u32 cif_spare_2 : 5; - u32 : 1; -} __attribute__((packed)); - -union cif_write_dbg_u { - u32 val : 32; - struct cif_write_dbg_t f; -} __attribute__((packed)); - - -struct intf_cntl_t { - unsigned char ad_inc_a : 1; - unsigned char ring_buf_a : 1; - unsigned char rd_fetch_trigger_a : 1; - unsigned char rd_data_rdy_a : 1; - unsigned char ad_inc_b : 1; - unsigned char ring_buf_b : 1; - unsigned char rd_fetch_trigger_b : 1; - unsigned char rd_data_rdy_b : 1; -} __attribute__((packed)); - -union intf_cntl_u { - unsigned char val : 8; - struct intf_cntl_t f; -} __attribute__((packed)); - -struct cpu_defaults_t { - unsigned char unpack_rd_data : 1; - unsigned char access_ind_addr_a : 1; - unsigned char access_ind_addr_b : 1; - unsigned char access_scratch_reg : 1; - unsigned char pack_wr_data : 1; - unsigned char transition_size : 1; - unsigned char en_read_buf_mode : 1; - unsigned char rd_fetch_scratch : 1; -} __attribute__((packed)); - -union cpu_defaults_u { - unsigned char val : 8; - struct cpu_defaults_t f; -} __attribute__((packed)); - -struct crtc_total_t { - u32 crtc_h_total : 10; - u32 : 6; - u32 crtc_v_total : 10; - u32 : 6; -} __attribute__((packed)); - -union crtc_total_u { - u32 val : 32; - struct crtc_total_t f; -} __attribute__((packed)); - -struct crtc_ss_t { - u32 ss_start : 10; - u32 : 6; - u32 ss_end : 10; - u32 : 2; - u32 ss_align : 1; - u32 ss_pol : 1; - u32 ss_run_mode : 1; - u32 ss_en : 1; -} __attribute__((packed)); - -union crtc_ss_u { - u32 val : 32; - struct crtc_ss_t f; -} __attribute__((packed)); - -struct active_h_disp_t { - u32 active_h_start : 10; - u32 : 6; - u32 active_h_end : 10; - u32 : 6; -} __attribute__((packed)); - -union active_h_disp_u { - u32 val : 32; - struct active_h_disp_t f; -} __attribute__((packed)); - -struct active_v_disp_t { - u32 active_v_start : 10; - u32 : 6; - u32 active_v_end : 10; - u32 : 6; -} __attribute__((packed)); - -union active_v_disp_u { - u32 val : 32; - struct active_v_disp_t f; -} __attribute__((packed)); - -struct graphic_h_disp_t { - u32 graphic_h_start : 10; - u32 : 6; - u32 graphic_h_end : 10; - u32 : 6; -} __attribute__((packed)); - -union graphic_h_disp_u { - u32 val : 32; - struct graphic_h_disp_t f; -} __attribute__((packed)); - -struct graphic_v_disp_t { - u32 graphic_v_start : 10; - u32 : 6; - u32 graphic_v_end : 10; - u32 : 6; -} __attribute__((packed)); - -union graphic_v_disp_u{ - u32 val : 32; - struct graphic_v_disp_t f; -} __attribute__((packed)); - -struct graphic_ctrl_t_w100 { - u32 color_depth : 3; - u32 portrait_mode : 2; - u32 low_power_on : 1; - u32 req_freq : 4; - u32 en_crtc : 1; - u32 en_graphic_req : 1; - u32 en_graphic_crtc : 1; - u32 total_req_graphic : 9; - u32 lcd_pclk_on : 1; - u32 lcd_sclk_on : 1; - u32 pclk_running : 1; - u32 sclk_running : 1; - u32 : 6; -} __attribute__((packed)); - -struct graphic_ctrl_t_w32xx { - u32 color_depth : 3; - u32 portrait_mode : 2; - u32 low_power_on : 1; - u32 req_freq : 4; - u32 en_crtc : 1; - u32 en_graphic_req : 1; - u32 en_graphic_crtc : 1; - u32 total_req_graphic : 10; - u32 lcd_pclk_on : 1; - u32 lcd_sclk_on : 1; - u32 pclk_running : 1; - u32 sclk_running : 1; - u32 : 5; -} __attribute__((packed)); - -union graphic_ctrl_u { - u32 val : 32; - struct graphic_ctrl_t_w100 f_w100; - struct graphic_ctrl_t_w32xx f_w32xx; -} __attribute__((packed)); - -struct video_ctrl_t { - u32 video_mode : 1; - u32 keyer_en : 1; - u32 en_video_req : 1; - u32 en_graphic_req_video : 1; - u32 en_video_crtc : 1; - u32 video_hor_exp : 2; - u32 video_ver_exp : 2; - u32 uv_combine : 1; - u32 total_req_video : 9; - u32 video_ch_sel : 1; - u32 video_portrait : 2; - u32 yuv2rgb_en : 1; - u32 yuv2rgb_option : 1; - u32 video_inv_hor : 1; - u32 video_inv_ver : 1; - u32 gamma_sel : 2; - u32 dis_limit : 1; - u32 en_uv_hblend : 1; - u32 rgb_gamma_sel : 2; -} __attribute__((packed)); - -union video_ctrl_u { - u32 val : 32; - struct video_ctrl_t f; -} __attribute__((packed)); - -struct disp_db_buf_cntl_rd_t { - u32 en_db_buf : 1; - u32 update_db_buf_done : 1; - u32 db_buf_cntl : 6; - u32 : 24; -} __attribute__((packed)); - -union disp_db_buf_cntl_rd_u { - u32 val : 32; - struct disp_db_buf_cntl_rd_t f; -} __attribute__((packed)); - -struct disp_db_buf_cntl_wr_t { - u32 en_db_buf : 1; - u32 update_db_buf : 1; - u32 db_buf_cntl : 6; - u32 : 24; -} __attribute__((packed)); - -union disp_db_buf_cntl_wr_u { - u32 val : 32; - struct disp_db_buf_cntl_wr_t f; -} __attribute__((packed)); - -struct gamma_value1_t { - u32 gamma1 : 8; - u32 gamma2 : 8; - u32 gamma3 : 8; - u32 gamma4 : 8; -} __attribute__((packed)); - -union gamma_value1_u { - u32 val : 32; - struct gamma_value1_t f; -} __attribute__((packed)); - -struct gamma_value2_t { - u32 gamma5 : 8; - u32 gamma6 : 8; - u32 gamma7 : 8; - u32 gamma8 : 8; -} __attribute__((packed)); - -union gamma_value2_u { - u32 val : 32; - struct gamma_value2_t f; -} __attribute__((packed)); - -struct gamma_slope_t { - u32 slope1 : 3; - u32 slope2 : 3; - u32 slope3 : 3; - u32 slope4 : 3; - u32 slope5 : 3; - u32 slope6 : 3; - u32 slope7 : 3; - u32 slope8 : 3; - u32 : 8; -} __attribute__((packed)); - -union gamma_slope_u { - u32 val : 32; - struct gamma_slope_t f; -} __attribute__((packed)); - -struct mc_ext_mem_location_t { - u32 mc_ext_mem_start : 16; - u32 mc_ext_mem_top : 16; -} __attribute__((packed)); - -union mc_ext_mem_location_u { - u32 val : 32; - struct mc_ext_mem_location_t f; -} __attribute__((packed)); - -struct mc_fb_location_t { - u32 mc_fb_start : 16; - u32 mc_fb_top : 16; -} __attribute__((packed)); - -union mc_fb_location_u { - u32 val : 32; - struct mc_fb_location_t f; -} __attribute__((packed)); - -struct clk_pin_cntl_t { - u32 osc_en : 1; - u32 osc_gain : 5; - u32 dont_use_xtalin : 1; - u32 xtalin_pm_en : 1; - u32 xtalin_dbl_en : 1; - u32 : 7; - u32 cg_debug : 16; -} __attribute__((packed)); - -union clk_pin_cntl_u { - u32 val : 32; - struct clk_pin_cntl_t f; -} __attribute__((packed)); - -struct pll_ref_fb_div_t { - u32 pll_ref_div : 4; - u32 : 4; - u32 pll_fb_div_int : 6; - u32 : 2; - u32 pll_fb_div_frac : 3; - u32 : 1; - u32 pll_reset_time : 4; - u32 pll_lock_time : 8; -} __attribute__((packed)); - -union pll_ref_fb_div_u { - u32 val : 32; - struct pll_ref_fb_div_t f; -} __attribute__((packed)); - -struct pll_cntl_t { - u32 pll_pwdn : 1; - u32 pll_reset : 1; - u32 pll_pm_en : 1; - u32 pll_mode : 1; - u32 pll_refclk_sel : 1; - u32 pll_fbclk_sel : 1; - u32 pll_tcpoff : 1; - u32 pll_pcp : 3; - u32 pll_pvg : 3; - u32 pll_vcofr : 1; - u32 pll_ioffset : 2; - u32 pll_pecc_mode : 2; - u32 pll_pecc_scon : 2; - u32 pll_dactal : 4; - u32 pll_cp_clip : 2; - u32 pll_conf : 3; - u32 pll_mbctrl : 2; - u32 pll_ring_off : 1; -} __attribute__((packed)); - -union pll_cntl_u { - u32 val : 32; - struct pll_cntl_t f; -} __attribute__((packed)); - -struct sclk_cntl_t { - u32 sclk_src_sel : 2; - u32 : 2; - u32 sclk_post_div_fast : 4; - u32 sclk_clkon_hys : 3; - u32 sclk_post_div_slow : 4; - u32 disp_cg_ok2switch_en : 1; - u32 sclk_force_reg : 1; - u32 sclk_force_disp : 1; - u32 sclk_force_mc : 1; - u32 sclk_force_extmc : 1; - u32 sclk_force_cp : 1; - u32 sclk_force_e2 : 1; - u32 sclk_force_e3 : 1; - u32 sclk_force_idct : 1; - u32 sclk_force_bist : 1; - u32 busy_extend_cp : 1; - u32 busy_extend_e2 : 1; - u32 busy_extend_e3 : 1; - u32 busy_extend_idct : 1; - u32 : 3; -} __attribute__((packed)); - -union sclk_cntl_u { - u32 val : 32; - struct sclk_cntl_t f; -} __attribute__((packed)); - -struct pclk_cntl_t { - u32 pclk_src_sel : 2; - u32 : 2; - u32 pclk_post_div : 4; - u32 : 8; - u32 pclk_force_disp : 1; - u32 : 15; -} __attribute__((packed)); - -union pclk_cntl_u { - u32 val : 32; - struct pclk_cntl_t f; -} __attribute__((packed)); - - -#define TESTCLK_SRC_PLL 0x01 -#define TESTCLK_SRC_SCLK 0x02 -#define TESTCLK_SRC_PCLK 0x03 -/* 4 and 5 seem to by XTAL/M */ -#define TESTCLK_SRC_XTAL 0x06 - -struct clk_test_cntl_t { - u32 testclk_sel : 4; - u32 : 3; - u32 start_check_freq : 1; - u32 tstcount_rst : 1; - u32 : 15; - u32 test_count : 8; -} __attribute__((packed)); - -union clk_test_cntl_u { - u32 val : 32; - struct clk_test_cntl_t f; -} __attribute__((packed)); - -struct pwrmgt_cntl_t { - u32 pwm_enable : 1; - u32 : 1; - u32 pwm_mode_req : 2; - u32 pwm_wakeup_cond : 2; - u32 pwm_fast_noml_hw_en : 1; - u32 pwm_noml_fast_hw_en : 1; - u32 pwm_fast_noml_cond : 4; - u32 pwm_noml_fast_cond : 4; - u32 pwm_idle_timer : 8; - u32 pwm_busy_timer : 8; -} __attribute__((packed)); - -union pwrmgt_cntl_u { - u32 val : 32; - struct pwrmgt_cntl_t f; -} __attribute__((packed)); - -#define SRC_DATATYPE_EQU_DST 3 - -#define ROP3_SRCCOPY 0xcc -#define ROP3_PATCOPY 0xf0 - -#define GMC_BRUSH_SOLID_COLOR 13 -#define GMC_BRUSH_NONE 15 - -#define DP_SRC_MEM_RECTANGULAR 2 - -#define DP_OP_ROP 0 - -struct dp_gui_master_cntl_t { - u32 gmc_src_pitch_offset_cntl : 1; - u32 gmc_dst_pitch_offset_cntl : 1; - u32 gmc_src_clipping : 1; - u32 gmc_dst_clipping : 1; - u32 gmc_brush_datatype : 4; - u32 gmc_dst_datatype : 4; - u32 gmc_src_datatype : 3; - u32 gmc_byte_pix_order : 1; - u32 gmc_default_sel : 1; - u32 gmc_rop3 : 8; - u32 gmc_dp_src_source : 3; - u32 gmc_clr_cmp_fcn_dis : 1; - u32 : 1; - u32 gmc_wr_msk_dis : 1; - u32 gmc_dp_op : 1; -} __attribute__((packed)); - -union dp_gui_master_cntl_u { - u32 val : 32; - struct dp_gui_master_cntl_t f; -} __attribute__((packed)); - -struct rbbm_status_t { - u32 cmdfifo_avail : 7; - u32 : 1; - u32 hirq_on_rbb : 1; - u32 cprq_on_rbb : 1; - u32 cfrq_on_rbb : 1; - u32 hirq_in_rtbuf : 1; - u32 cprq_in_rtbuf : 1; - u32 cfrq_in_rtbuf : 1; - u32 cf_pipe_busy : 1; - u32 eng_ev_busy : 1; - u32 cp_cmdstrm_busy : 1; - u32 e2_busy : 1; - u32 rb2d_busy : 1; - u32 rb3d_busy : 1; - u32 se_busy : 1; - u32 re_busy : 1; - u32 tam_busy : 1; - u32 tdm_busy : 1; - u32 pb_busy : 1; - u32 : 6; - u32 gui_active : 1; -} __attribute__((packed)); - -union rbbm_status_u { - u32 val : 32; - struct rbbm_status_t f; -} __attribute__((packed)); - -struct dp_datatype_t { - u32 dp_dst_datatype : 4; - u32 : 4; - u32 dp_brush_datatype : 4; - u32 dp_src2_type : 1; - u32 dp_src2_datatype : 3; - u32 dp_src_datatype : 3; - u32 : 11; - u32 dp_byte_pix_order : 1; - u32 : 1; -} __attribute__((packed)); - -union dp_datatype_u { - u32 val : 32; - struct dp_datatype_t f; -} __attribute__((packed)); - -struct dp_mix_t { - u32 : 8; - u32 dp_src_source : 3; - u32 dp_src2_source : 3; - u32 : 2; - u32 dp_rop3 : 8; - u32 dp_op : 1; - u32 : 7; -} __attribute__((packed)); - -union dp_mix_u { - u32 val : 32; - struct dp_mix_t f; -} __attribute__((packed)); - -struct eng_cntl_t { - u32 erc_reg_rd_ws : 1; - u32 erc_reg_wr_ws : 1; - u32 erc_idle_reg_wr : 1; - u32 dis_engine_triggers : 1; - u32 dis_rop_src_uses_dst_w_h : 1; - u32 dis_src_uses_dst_dirmaj : 1; - u32 : 6; - u32 force_3dclk_when_2dclk : 1; - u32 : 19; -} __attribute__((packed)); - -union eng_cntl_u { - u32 val : 32; - struct eng_cntl_t f; -} __attribute__((packed)); - -struct dp_cntl_t { - u32 dst_x_dir : 1; - u32 dst_y_dir : 1; - u32 src_x_dir : 1; - u32 src_y_dir : 1; - u32 dst_major_x : 1; - u32 src_major_x : 1; - u32 : 26; -} __attribute__((packed)); - -union dp_cntl_u { - u32 val : 32; - struct dp_cntl_t f; -} __attribute__((packed)); - -struct dp_cntl_dst_dir_t { - u32 : 15; - u32 dst_y_dir : 1; - u32 : 15; - u32 dst_x_dir : 1; -} __attribute__((packed)); - -union dp_cntl_dst_dir_u { - u32 val : 32; - struct dp_cntl_dst_dir_t f; -} __attribute__((packed)); - -#endif - |