Commit 1a13e36a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fbdev-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux

Pull fbdev updates from Tomi Valkeinen:

 - ssd1307fb: various fixes and improvements, SSD1305 support

 - use architecture agnostic functions instead of MTRR functions in
   various fbdev drivers

 - TI DRA7xx SoC display support (arch/arm/ side)

 - OMAPDSS componentization to fix probing order issues

 - OMAPDSS scaling fixes

 - msm_fb: remove obsoleted driver

* tag 'fbdev-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (77 commits)
  msm: msm_fb: Remove dead code
  OMAPDSS: HDMI: wait for framedone when stopping video
  OMAPDSS: HDMI4: fix error handling
  OMAPDSS: DISPC: scaler debug print
  OMAPDSS: DISPC: do only y decimation on OMAP3
  OMAPDSS: DISPC: check if scaling setup failed
  OMAPDSS: DISPC: fix 64 bit issue in 5-tap
  OMAPDSS: DISPC: fix row_inc for OMAP3
  OMAPDSS: DISPC: add check for scaling limits
  OMAPDSS: DISPC: fix check_horiz_timing_omap3 args
  OMAPDSS: DISPC: fix predecimation for YUV modes
  OMAPDSS: DISPC: work-around for errata i631
  OMAPDSS: simplify submodule reg/unreg code
  OMAPDSS: componentize omapdss
  OMAPDSS: reorder uninit calls
  OMAPDSS: remove uses of __init/__exit
  OMAPDSS: fix dss_init_ports error handling
  OMAPDSS: refactor dss probe function
  OMAPDSS: move 'dss_initialized' to dss driver
  fbdev: propagate result of fb_videomode_from_videomode()
  ...
parents 36a1624d f778dad3
......@@ -182,6 +182,7 @@ skyworks Skyworks Solutions, Inc.
smsc Standard Microsystems Corporation
snps Synopsys, Inc.
solidrun SolidRun
solomon Solomon Systech Limited
sony Sony Corporation
spansion Spansion Inc.
sprd Spreadtrum Communications Inc.
......
......@@ -2,7 +2,7 @@
Required properties:
- compatible: Should be "solomon,<chip>fb-<bus>". The only supported bus for
now is i2c, and the supported chips are ssd1306 and ssd1307.
now is i2c, and the supported chips are ssd1305, ssd1306 and ssd1307.
- reg: Should contain address of the controller on the I2C bus. Most likely
0x3c or 0x3d
- pwm: Should contain the pwm to use according to the OF device tree PWM
......@@ -15,6 +15,16 @@ Required properties:
Optional properties:
- reset-active-low: Is the reset gpio is active on physical low?
- solomon,segment-no-remap: Display needs normal (non-inverted) data column
to segment mapping
- solomon,com-seq: Display uses sequential COM pin configuration
- solomon,com-lrremap: Display uses left-right COM pin remap
- solomon,com-invdir: Display uses inverted COM pin scan direction
- solomon,com-offset: Number of the COM pin wired to the first display line
- solomon,prechargep1: Length of deselect period (phase 1) in clock cycles.
- solomon,prechargep2: Length of precharge period (phase 2) in clock cycles.
This needs to be the higher, the higher the capacitance
of the OLED's pixels is
[0]: Documentation/devicetree/bindings/pwm/pwm.txt
......@@ -26,3 +36,14 @@ ssd1307: oled@3c {
reset-gpios = <&gpio2 7>;
reset-active-low;
};
ssd1306: oled@3c {
compatible = "solomon,ssd1306fb-i2c";
reg = <0x3c>;
pwms = <&pwm 4 3000>;
reset-gpios = <&gpio2 7>;
reset-active-low;
solomon,com-lrremap;
solomon,com-invdir;
solomon,com-offset = <32>;
};
......@@ -19,6 +19,7 @@ aliases {
rtc0 = &mcp_rtc;
rtc1 = &tps659038_rtc;
rtc2 = &rtc;
display0 = &hdmi0;
};
memory {
......@@ -103,6 +104,51 @@ extcon_usb2: extcon_usb2 {
pinctrl-names = "default";
pinctrl-0 = <&extcon_usb2_pins>;
};
hdmi0: connector {
compatible = "hdmi-connector";
label = "hdmi";
type = "a";
port {
hdmi_connector_in: endpoint {
remote-endpoint = <&tpd12s015_out>;
};
};
};
tpd12s015: encoder {
compatible = "ti,tpd12s015";
pinctrl-names = "default";
pinctrl-0 = <&tpd12s015_pins>;
gpios = <&gpio7 10 GPIO_ACTIVE_HIGH>, /* gpio7_10, CT CP HPD */
<&gpio6 28 GPIO_ACTIVE_HIGH>, /* gpio6_28, LS OE */
<&gpio7 12 GPIO_ACTIVE_HIGH>; /* gpio7_12/sp1_cs2, HPD */
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
tpd12s015_in: endpoint {
remote-endpoint = <&hdmi_out>;
};
};
port@1 {
reg = <1>;
tpd12s015_out: endpoint {
remote-endpoint = <&hdmi_connector_in>;
};
};
};
};
};
&dra7_pmx_core {
......@@ -122,6 +168,13 @@ i2c1_pins_default: i2c1_pins_default {
>;
};
hdmi_pins: pinmux_hdmi_pins {
pinctrl-single,pins = <
0x408 (PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
0x40c (PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
>;
};
i2c3_pins_default: i2c3_pins_default {
pinctrl-single,pins = <
0x2a4 (PIN_INPUT| MUX_MODE10) /* mcasp1_aclkx.i2c3_sda */
......@@ -278,6 +331,14 @@ extcon_usb2_pins: extcon_usb2_pins {
0x3e8 (PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_ctsn.gpio7_24 */
>;
};
tpd12s015_pins: pinmux_tpd12s015_pins {
pinctrl-single,pins = <
0x3b0 (PIN_OUTPUT | MUX_MODE14) /* gpio7_10 CT_CP_HPD */
0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
0x370 (PIN_OUTPUT | MUX_MODE14) /* gpio6_28 LS_OE */
>;
};
};
&i2c1 {
......@@ -608,3 +669,23 @@ map0 {
};
};
};
&dss {
status = "ok";
vdda_video-supply = <&ldoln_reg>;
};
&hdmi {
status = "ok";
vdda-supply = <&ldo3_reg>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_pins>;
port {
hdmi_out: endpoint {
remote-endpoint = <&tpd12s015_in>;
};
};
};
......@@ -131,6 +131,11 @@ pbias_mmc_reg: pbias_mmc_omap5 {
regulator-max-microvolt = <3000000>;
};
};
scm_conf_clocks: clocks {
#address-cells = <1>;
#size-cells = <0>;
};
};
dra7_pmx_core: pinmux@1400 {
......@@ -1469,6 +1474,44 @@ dcan2: can@481d0000 {
clocks = <&sys_clkin1>;
status = "disabled";
};
dss: dss@58000000 {
compatible = "ti,dra7-dss";
/* 'reg' defined in dra72x.dtsi and dra74x.dtsi */
/* 'clocks' defined in dra72x.dtsi and dra74x.dtsi */
status = "disabled";
ti,hwmods = "dss_core";
/* CTRL_CORE_DSS_PLL_CONTROL */
syscon-pll-ctrl = <&scm_conf 0x538>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
dispc@58001000 {
compatible = "ti,dra7-dispc";
reg = <0x58001000 0x1000>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
ti,hwmods = "dss_dispc";
clocks = <&dss_dss_clk>;
clock-names = "fck";
/* CTRL_CORE_SMA_SW_1 */
syscon-pol = <&scm_conf 0x534>;
};
hdmi: encoder@58060000 {
compatible = "ti,dra7-hdmi";
reg = <0x58040000 0x200>,
<0x58040200 0x80>,
<0x58040300 0x80>,
<0x58060000 0x19000>;
reg-names = "wp", "pll", "phy", "core";
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
ti,hwmods = "dss_hdmi";
clocks = <&dss_48mhz_clk>, <&dss_hdmi_clk>;
clock-names = "fck", "sys_clk";
};
};
};
thermal_zones: thermal-zones {
......
......@@ -19,6 +19,10 @@ memory {
reg = <0x80000000 0x40000000>; /* 1024 MB */
};
aliases {
display0 = &hdmi0;
};
evm_3v3: fixedregulator-evm_3v3 {
compatible = "regulator-fixed";
regulator-name = "evm_3v3";
......@@ -35,6 +39,51 @@ extcon_usb2: extcon_usb2 {
compatible = "linux,extcon-usb-gpio";
id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>;
};
hdmi0: connector {
compatible = "hdmi-connector";
label = "hdmi";
type = "a";
port {
hdmi_connector_in: endpoint {
remote-endpoint = <&tpd12s015_out>;
};
};
};
tpd12s015: encoder {
compatible = "ti,tpd12s015";
pinctrl-names = "default";
pinctrl-0 = <&tpd12s015_pins>;
gpios = <&pcf_hdmi 4 GPIO_ACTIVE_HIGH>, /* P4, CT CP HPD */
<&pcf_hdmi 5 GPIO_ACTIVE_HIGH>, /* P5, LS OE */
<&gpio7 12 GPIO_ACTIVE_HIGH>; /* gpio7_12/sp1_cs2, HPD */
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
tpd12s015_in: endpoint {
remote-endpoint = <&hdmi_out>;
};
};
port@1 {
reg = <1>;
tpd12s015_out: endpoint {
remote-endpoint = <&hdmi_connector_in>;
};
};
};
};
};
&dra7_pmx_core {
......@@ -45,6 +94,13 @@ i2c1_pins: pinmux_i2c1_pins {
>;
};
i2c5_pins: pinmux_i2c5_pins {
pinctrl-single,pins = <
0x2b4 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
0x2b8 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
>;
};
nand_default: nand_default {
pinctrl-single,pins = <
0x0 (PIN_INPUT | MUX_MODE0) /* gpmc_ad0 */
......@@ -142,6 +198,19 @@ qspi1_pins: pinmux_qspi1_pins {
0xb8 (PIN_OUTPUT | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */
>;
};
hdmi_pins: pinmux_hdmi_pins {
pinctrl-single,pins = <
0x408 (PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
0x40c (PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
>;
};
tpd12s015_pins: pinmux_tpd12s015_pins {
pinctrl-single,pins = <
0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
>;
};
};
&i2c1 {
......@@ -277,6 +346,27 @@ pcf_gpio_21: gpio@21 {
};
};
&i2c5 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c5_pins>;
clock-frequency = <400000>;
pcf_hdmi: pcf8575@26 {
compatible = "nxp,pcf8575";
reg = <0x26>;
gpio-controller;
#gpio-cells = <2>;
/*
* initial state is used here to keep the mdio interface
* selected on RU89 through SEL_VIN4_MUX_S0, VIN2_S1 and
* VIN2_S0 driven high otherwise Ethernet stops working
* VIN6_SEL_S0 is low, thus selecting McASP3 over VIN6
*/
lines-initial-states = <0x0f2b>;
};
};
&uart1 {
status = "okay";
};
......@@ -566,3 +656,23 @@ partition@9 {
};
};
};
&dss {
status = "ok";
vdda_video-supply = <&ldo5_reg>;
};
&hdmi {
status = "ok";
vdda-supply = <&ldo3_reg>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_pins>;
port {
hdmi_out: endpoint {
remote-endpoint = <&tpd12s015_in>;
};
};
};
......@@ -34,3 +34,14 @@ pmu {
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
};
};
&dss {
reg = <0x58000000 0x80>,
<0x58004054 0x4>,
<0x58004300 0x20>;
reg-names = "dss", "pll1_clkctrl", "pll1";
clocks = <&dss_dss_clk>,
<&dss_video1_clk>;
clock-names = "fck", "video1_clk";
};
......@@ -73,3 +73,18 @@ usb4: usb@48950000 {
};
};
};
&dss {
reg = <0x58000000 0x80>,
<0x58004054 0x4>,
<0x58004300 0x20>,
<0x58005054 0x4>,
<0x58005300 0x20>;
reg-names = "dss", "pll1_clkctrl", "pll1",
"pll2_clkctrl", "pll2";
clocks = <&dss_dss_clk>,
<&dss_video1_clk>,
<&dss_video2_clk>;
clock-names = "fck", "video1_clk", "video2_clk";
};
......@@ -1531,6 +1531,7 @@ dss_dss_clk: dss_dss_clk {
clocks = <&dpll_per_h12x2_ck>;
ti,bit-shift = <8>;
reg = <0x1120>;
ti,set-rate-parent;
};
dss_hdmi_clk: dss_hdmi_clk {
......@@ -2136,3 +2137,13 @@ coreaon_clkdm: coreaon_clkdm {
clocks = <&dpll_usb_ck>;
};
};
&scm_conf_clocks {
dss_deshdcp_clk: dss_deshdcp_clk {
#clock-cells = <0>;
compatible = "ti,gate-clock";
clocks = <&l3_iclk_div>;
ti,bit-shift = <0>;
reg = <0x558>;
};
};
......@@ -99,6 +99,9 @@ ssd1306: oled@3c {
solomon,height = <32>;
solomon,width = <128>;
solomon,page-offset = <0>;
solomon,com-lrremap;
solomon,com-invdir;
solomon,com-offset = <32>;
};
};
......
......@@ -287,6 +287,8 @@ static enum omapdss_version __init omap_display_get_version(void)
return OMAPDSS_VER_OMAP5;
else if (soc_is_am43xx())
return OMAPDSS_VER_AM43xx;
else if (soc_is_dra7xx())
return OMAPDSS_VER_DRA7xx;
else
return OMAPDSS_VER_UNKNOWN;
}
......@@ -568,25 +570,25 @@ void __init omapdss_early_init_of(void)
}
static const char * const omapdss_compat_names[] __initconst = {
"ti,omap2-dss",
"ti,omap3-dss",
"ti,omap4-dss",
"ti,omap5-dss",
"ti,dra7-dss",
};
struct device_node * __init omapdss_find_dss_of_node(void)
{
struct device_node *node;
int i;
node = of_find_compatible_node(NULL, NULL, "ti,omap2-dss");
if (node)
return node;
node = of_find_compatible_node(NULL, NULL, "ti,omap3-dss");
if (node)
return node;
node = of_find_compatible_node(NULL, NULL, "ti,omap4-dss");
if (node)
return node;
node = of_find_compatible_node(NULL, NULL, "ti,omap5-dss");
if (node)
return node;
for (i = 0; i < ARRAY_SIZE(omapdss_compat_names); ++i) {
node = of_find_compatible_node(NULL, NULL,
omapdss_compat_names[i]);
if (node)
return node;
}
return NULL;
}
......
......@@ -48,6 +48,27 @@
* IP blocks
*/
/*
* 'dmm' class
* instance(s): dmm
*/
static struct omap_hwmod_class dra7xx_dmm_hwmod_class = {
.name = "dmm",
};
/* dmm */
static struct omap_hwmod dra7xx_dmm_hwmod = {
.name = "dmm",
.class = &dra7xx_dmm_hwmod_class,
.clkdm_name = "emif_clkdm",
.prcm = {
.omap4 = {
.clkctrl_offs = DRA7XX_CM_EMIF_DMM_CLKCTRL_OFFSET,
.context_offs = DRA7XX_RM_EMIF_DMM_CONTEXT_OFFSET,
},
},
};
/*
* 'l3' class
* instance(s): l3_instr, l3_main_1, l3_main_2
......@@ -438,6 +459,7 @@ static struct omap_hwmod_opt_clk dss_opt_clks[] = {
{ .role = "video2_clk", .clk = "dss_video2_clk" },
{ .role = "video1_clk", .clk = "dss_video1_clk" },
{ .role = "hdmi_clk", .clk = "dss_hdmi_clk" },
{ .role = "hdcp_clk", .clk = "dss_deshdcp_clk" },
};
static struct omap_hwmod dra7xx_dss_hwmod = {
......@@ -500,6 +522,7 @@ static struct omap_hwmod dra7xx_dss_dispc_hwmod = {
},
},
.dev_attr = &dss_dispc_dev_attr,
.parent_hwmod = &dra7xx_dss_hwmod,
};
/*
......@@ -541,6 +564,7 @@ static struct omap_hwmod dra7xx_dss_hdmi_hwmod = {
},
.opt_clks = dss_hdmi_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks),
.parent_hwmod = &dra7xx_dss_hwmod,
};
/*
......@@ -2321,6 +2345,14 @@ static struct omap_hwmod dra7xx_wd_timer2_hwmod = {
* Interfaces
*/
/* l3_main_1 -> dmm */
static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dmm = {
.master = &dra7xx_l3_main_1_hwmod,
.slave = &dra7xx_dmm_hwmod,
.clk = "l3_iclk_div",
.user = OCP_USER_SDMA,
};
/* l3_main_2 -> l3_instr */
static struct omap_hwmod_ocp_if dra7xx_l3_main_2__l3_instr = {
.master = &dra7xx_l3_main_2_hwmod,
......@@ -3289,6 +3321,7 @@ static struct omap_hwmod_ocp_if dra7xx_l4_wkup__wd_timer2 = {
};
static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
&dra7xx_l3_main_1__dmm,
&dra7xx_l3_main_2__l3_instr,
&dra7xx_l4_cfg__l3_main_1,
&dra7xx_mpu__l3_main_1,
......
......@@ -305,13 +305,14 @@ static struct ti_dt_clk dra7xx_clks[] = {
DT_CLK("4882c000.timer", "timer_sys_ck", "timer_sys_clk_div"),
DT_CLK("4882e000.timer", "timer_sys_ck", "timer_sys_clk_div"),
DT_CLK(NULL, "sys_clkin", "sys_clkin1"),
DT_CLK(NULL, "dss_deshdcp_clk", "dss_deshdcp_clk"),
{ .node_name = NULL },
};
int __init dra7xx_dt_clk_init(void)
{
int rc;
struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck;
struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck, *hdcp_ck;
ti_dt_clocks_register(dra7xx_clks);
......@@ -347,5 +348,10 @@ int __init dra7xx_dt_clk_init(void)
if (rc)
pr_err("%s: failed to set USB_DPLL M2 OUT\n", __func__);
hdcp_ck = clk_get_sys(NULL, "dss_deshdcp_clk");
rc = clk_prepare_enable(hdcp_ck);
if (rc)
pr_err("%s: failed to set dss_deshdcp_clk\n", __func__);
return rc;
}
......@@ -687,7 +687,7 @@ static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
int dx, int h, int w)
{
short xs, ys, xe, ye, xoffs, yoffs, tmp;
short xs, ys, xe, ye, xoffs, yoffs;
xs = sx << 3;
xe = ((sx + w) << 3) - 1;
......@@ -701,9 +701,7 @@ static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
yoffs = (dy - sy) << 4;
if (xoffs > 0) {
/* move to the right, exchange starting points */
tmp = xe;
xe = xs;
xs = tmp;
swap(xe, xs);
}
newport_wait(npregs);
npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
......
......@@ -2326,13 +2326,6 @@ config FB_PRE_INIT_FB
Select this option if display contents should be inherited as set by
the bootloader.
config FB_MSM
tristate "MSM Framebuffer support"
depends on FB && ARCH_MSM
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
config FB_MX3
tristate "MX3 Framebuffer support"
depends on FB && MX3_IPU
......@@ -2478,6 +2471,7 @@ config FB_SSD1307
select FB_SYS_IMAGEBLIT
select FB_DEFERRED_IO
select PWM
select FB_BACKLIGHT
help
This driver implements support for the Solomon SSD1307
OLED controller over I2C.
......@@ -126,7 +126,6 @@ obj-y += omap2/
obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
obj-$(CONFIG_FB_CARMINE) += carminefb.o
obj-$(CONFIG_FB_MB862XX) += mb862xx/
obj-$(CONFIG_FB_MSM) += msm/
obj-$(CONFIG_FB_NUC900) += nuc900fb.o
obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
......
......@@ -2052,7 +2052,7 @@ static void ami_set_sprite(const struct amifb_par *par)
{
copins *copl, *cops;
u_short hs, vs, ve;
u_long pl, ps, pt;
u_long pl, ps;
short mx, my;
cops = copdisplay.list[currentcop][0];
......@@ -2078,7 +2078,7 @@ static void ami_set_sprite(const struct amifb_par *par)
if (mod2(vs)) {
lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve + 1);
pt = pl; pl = ps; ps = pt;
swap(pl, ps);
} else {
lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve + 1);
shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve);
......
......@@ -1266,7 +1266,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
goto stop_clk;
}
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
info->screen_base = ioremap_wc(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base) {
ret = -ENOMEM;
goto release_intmem;
......
......@@ -80,10 +80,6 @@
#include <asm/btext.h>
#endif /* CONFIG_BOOTX_TEXT */
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <video/aty128.h>
/* Debug flag */
......@@ -399,10 +395,7 @@ static int default_cmode = CMODE_8;
static int default_crt_on = 0;
static int default_lcd_on = 1;
#ifdef CONFIG_MTRR
static bool mtrr = true;
#endif
#ifdef CONFIG_FB_ATY128_BACKLIGHT
#ifdef CONFIG_PMAC_BACKLIGHT
......@@ -456,9 +449,7 @@ struct aty128fb_par {
u32 vram_size; /* onboard video ram */
int chip_gen;
const struct aty128_meminfo *mem; /* onboard mem info */
#ifdef CONFIG_MTRR
struct { int vram; int vram_valid; } mtrr;
#endif
int wc_cookie;
int blitter_may_be_busy;
int fifo_slots; /* free slots in FIFO (64 max) */
......@@ -1725,12 +1716,10 @@ static int aty128fb_setup(char *options)
#endif
continue;
}
#ifdef CONFIG_MTRR
if(!strncmp(this_opt, "nomtrr", 6)) {
mtrr = 0;
continue;
}
#endif
#ifdef CONFIG_PPC_PMAC
/* vmode and cmode deprecated */
if (!strncmp(this_opt, "vmode:", 6)) {
......@@ -2133,7 +2122,7 @@ static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF;
/* Virtualize the framebuffer */
info->screen_base = ioremap(fb_addr, par->vram_size);
info->screen_base = ioremap_wc(fb_addr, par->vram_size);
if (!info->screen_base)
goto err_unmap_out;
......@@ -2170,15 +2159,9 @@ static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!aty128_init(pdev, ent))
goto err_out;
#ifdef CONFIG_MTRR
if (mtrr) {
par->mtrr.vram = mtrr_add(info->fix.smem_start,
par->vram_size, MTRR_TYPE_WRCOMB, 1);
par->mtrr.vram_valid = 1;
/* let there be speed */
printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n");
}
#endif /* CONFIG_MTRR */
if (mtrr)
par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
par->vram_size);
return 0;
err_out:
......@@ -2212,11 +2195,7 @@ static void aty128_remove(struct pci_dev *pdev)
aty128_bl_exit(info->bl_dev);
#endif
#ifdef CONFIG_MTRR
if (par->mtrr.vram_valid)
mtrr_del(par->mtrr.vram, info->fix.smem_start,
par->vram_size);
#endif /* CONFIG_MTRR */
arch_phys_wc_del(par->wc_cookie);
iounmap(par->regbase);
iounmap(info->screen_base);
......@@ -2625,8 +2604,5 @@ MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
MODULE_LICENSE("GPL");
module_param(mode_option, charp, 0);
MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
#ifdef CONFIG_MTRR
module_param_named(nomtrr, mtrr, invbool, 0);
MODULE_PARM_DESC(nomtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)");
#endif
......@@ -85,10 +85,6 @@
#endif /* CONFIG_PPC */
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <video/radeon.h>
#include <linux/radeonfb.h>
......@@ -271,9 +267,7 @@ static bool mirror = 0;
static int panel_yres = 0;
static bool force_dfp = 0;
static bool force_measure_pll = 0;
#ifdef CONFIG_MTRR
static bool nomtrr = 0;
#endif
static bool force_sleep;
static bool ignore_devlist;
#ifdef CONFIG_PMAC_BACKLIGHT
......@@ -2260,8 +2254,8 @@ static int radeonfb_pci_register(struct pci_dev *pdev,
rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram);
do {
rinfo->fb_base = ioremap (rinfo->fb_base_phys,
rinfo->mapped_vram);
rinfo->fb_base = ioremap_wc(rinfo->fb_base_phys,
rinfo->mapped_vram);
} while (rinfo->fb_base == NULL &&
((rinfo->mapped_vram /= 2) >= MIN_MAPPED_VRAM));
......@@ -2359,11 +2353,9 @@ static int radeonfb_pci_register(struct pci_dev *pdev,
goto err_unmap_fb;
}
#ifdef CONFIG_MTRR
rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
rinfo->video_ram,
MTRR_TYPE_WRCOMB, 1);
#endif
if (!nomtrr)
rinfo->wc_cookie = arch_phys_wc_add(rinfo->fb_base_phys,
rinfo->video_ram);
if (backlight)
radeonfb_bl_init(rinfo);
......@@ -2428,12 +2420,7 @@ static void radeonfb_pci_unregister(struct pci_dev *pdev)
#endif
del_timer_sync(&rinfo->lvds_timer);
#ifdef CONFIG_MTRR
if (rinfo->mtrr_hdl >= 0)
mtrr_del(rinfo->mtrr_hdl, 0, 0);
#endif
arch_phys_wc_del(rinfo->wc_cookie);
unregister_framebuffer(info);
radeonfb_bl_exit(rinfo);
......@@ -2489,10 +2476,8 @@ static int __init radeonfb_setup (char *options)
panel_yres = simple_strtoul((this_opt+11), NULL, 0);
} else if (!strncmp(this_opt, "backlight:", 10)) {
backlight = simple_strtoul(this_opt+10, NULL, 0);
#ifdef CONFIG_MTRR
} else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1;
#endif
} else if (!strncmp(this_opt, "nomodeset", 9)) {
nomodeset = 1;
} else if (!strncmp(this_opt, "force_measure_pll", 17)) {
......@@ -2552,10 +2537,8 @@ module_param(monitor_layout, charp, 0);
MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)");
module_param(force_measure_pll, bool, 0);
MODULE_PARM_DESC(force_measure_pll, "Force measurement of PLL (debug)");
#ifdef CONFIG_MTRR
module_param(nomtrr, bool, 0);
MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");
#endif
module_param(panel_yres, int, 0);
MODULE_PARM_DESC(panel_yres, "int: set panel yres");
module_param(mode_option, charp, 0);
......
......@@ -340,7 +340,7 @@ struct radeonfb_info {
struct pll_info pll;
int mtrr_hdl;
int wc_cookie;
u32 save_regs[100];
int asleep;
......
......@@ -3,6 +3,7 @@ obj-$(CONFIG_FB_CMDLINE) += fb_cmdline.o
obj-$(CONFIG_FB) += fb.o
fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
modedb.o fbcvt.o
fb-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
fb-objs := $(fb-y)
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
......@@ -14,4 +15,3 @@ obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
obj-$(CONFIG_FB_SVGALIB) += svgalib.o
obj-$(CONFIG_FB_DDC) += fb_ddc.o
obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
......@@ -242,5 +242,3 @@ void fb_deferred_io_cleanup(struct fb_info *info)
mutex_destroy(&fbdefio->lock);
}
EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
MODULE_LICENSE("GPL");
......@@ -1475,7 +1475,9 @@ int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb,
if (ret)
return ret;
fb_videomode_from_videomode(&vm, fb);
ret = fb_videomode_from_videomode(&vm, fb);
if (ret)
return ret;
pr_debug("%s: got %dx%d display mode from %s\n",
of_node_full_name(np), vm.hactive, vm.vactive, np->name);
......
......@@ -22,9 +22,6 @@
#include <linux/module.h>
#include <linux/io.h>
#ifdef CONFIG_X86
#include <asm/mtrr.h>
#endif
#ifdef CONFIG_MIPS
#include <asm/addrspace.h>
#endif
......@@ -38,6 +35,7 @@ static struct sgi_gbe *gbe;
struct gbefb_par {
struct fb_var_screeninfo var;
struct gbe_timing_info timing;
int wc_cookie;
int valid;
};
......@@ -1175,8 +1173,8 @@ static int gbefb_probe(struct platform_device *p_dev)
if (gbe_mem_phys) {
/* memory was allocated at boot time */
gbe_mem = devm_ioremap_nocache(&p_dev->dev, gbe_mem_phys,
gbe_mem_size);
gbe_mem = devm_ioremap_wc(&p_dev->dev, gbe_mem_phys,
gbe_mem_size);
if (!gbe_mem) {
printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
ret = -ENOMEM;
......@@ -1187,8 +1185,8 @@ static int gbefb_probe(struct platform_device *p_dev)
} else {
/* try to allocate memory with the classical allocator
* this has high chance to fail on low memory machines */
gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
GFP_KERNEL);
gbe_mem = dma_alloc_writecombine(NULL, gbe_mem_size,
&gbe_dma_addr, GFP_KERNEL);
if (!gbe_mem) {
printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
ret = -ENOMEM;
......@@ -1198,9 +1196,8 @@ static int gbefb_probe(struct platform_device *p_dev)
gbe_mem_phys = (unsigned long) gbe_dma_addr;
}
#ifdef CONFIG_X86
mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
#endif
par = info->par;
par->wc_cookie = arch_phys_wc_add(gbe_mem_phys, gbe_mem_size);
/* map framebuffer memory into tiles table */
for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
......@@ -1215,7 +1212,6 @@ static int gbefb_probe(struct platform_device *p_dev)
/* reset GBE */
gbe_reset();
par = info->par;
/* turn on default video mode */
if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
default_mode, 8) == 0)
......@@ -1240,8 +1236,9 @@ static int gbefb_probe(struct platform_device *p_dev)
return 0;
out_gbe_unmap:
arch_phys_wc_del(par->wc_cookie);
if (gbe_dma_addr)
dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
dma_free_writecombine(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
out_tiles_free:
dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
(void *)gbe_tiles.cpu, gbe_tiles.dma);
......@@ -1256,11 +1253,13 @@ static int gbefb_probe(struct platform_device *p_dev)
static int gbefb_remove(struct platform_device* p_dev)
{
struct fb_info *info = platform_get_drvdata(p_dev);
struct gbefb_par *par = info->par;
unregister_framebuffer(info);
gbe_turn_off();
arch_phys_wc_del(par->wc_cookie);
if (gbe_dma_addr)
dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
dma_free_writecombine(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
(void *)gbe_tiles.cpu, gbe_tiles.dma);
release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
......
......@@ -263,7 +263,8 @@ static int gxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
info->fix.smem_start = pci_resource_start(dev, 0);
info->fix.smem_len = vram ? vram : gx_frame_buffer_size();
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
info->screen_base = ioremap_wc(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base)
return -ENOMEM;
......
......@@ -199,7 +199,6 @@
#define HAS_FONTCACHE 8
/* driver flags */
#define HAS_MTRR 1
#define HAS_ACCELERATION 2
#define ALWAYS_SYNC 4
#define LOCKUP 8
......@@ -281,7 +280,7 @@ struct i810fb_par {
u32 ovract;
u32 cur_state;
u32 ddc_num;
int mtrr_reg;
int wc_cookie;
u16 bltcntl;
u8 interlace;
};
......
......@@ -41,6 +41,7 @@
#include <linux/resource.h>
#include <linux/unistd.h>
#include <linux/console.h>
#include <linux/io.h>
#include <asm/io.h>
#include <asm/div64.h>
......@@ -1816,7 +1817,9 @@ static void i810_init_device(struct i810fb_par *par)
u8 reg;
u8 __iomem *mmio = par->mmio_start_virtual;
if (mtrr) set_mtrr(par);
if (mtrr)
par->wc_cookie= arch_phys_wc_add((u32) par->aperture.physical,
par->aperture.size);
i810_init_cursor(par);
......@@ -1865,8 +1868,8 @@ static int i810_allocate_pci_resource(struct i810fb_par *par,
}
par->res_flags |= FRAMEBUFFER_REQ;
par->aperture.virtual = ioremap_nocache(par->aperture.physical,
par->aperture.size);
par->aperture.virtual = ioremap_wc(par->aperture.physical,
par->aperture.size);
if (!par->aperture.virtual) {
printk("i810fb_init: cannot remap framebuffer region\n");
return -ENODEV;
......@@ -2096,7 +2099,7 @@ static void i810fb_release_resource(struct fb_info *info,
struct i810fb_par *par)
{
struct gtt_data *gtt = &par->i810_gtt;
unset_mtrr(par);
arch_phys_wc_del(par->wc_cookie);
i810_delete_i2c_busses(par);
......
......@@ -60,32 +60,6 @@ static inline void flush_cache(void)
#define flush_cache() do { } while(0)
#endif
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
static inline void set_mtrr(struct i810fb_par *par)
{
par->mtrr_reg = mtrr_add((u32) par->aperture.physical,
par->aperture.size, MTRR_TYPE_WRCOMB, 1);
if (par->mtrr_reg < 0) {
printk(KERN_ERR "set_mtrr: unable to set MTRR\n");
return;
}
par->dev_flags |= HAS_MTRR;
}
static inline void unset_mtrr(struct i810fb_par *par)
{
if (par->dev_flags & HAS_MTRR)
mtrr_del(par->mtrr_reg, (u32) par->aperture.physical,
par->aperture.size);
}
#else
#define set_mtrr(x) printk("set_mtrr: MTRR is disabled in the kernel\n")
#define unset_mtrr(x) do { } while (0)
#endif /* CONFIG_MTRR */
#ifdef CONFIG_FB_I810_GTF
#define IS_DVT (0)
#else
......
......@@ -170,7 +170,7 @@ struct imxfb_info {
struct regulator *lcd_pwr;
};
static struct platform_device_id imxfb_devtype[] = {
static const struct platform_device_id imxfb_devtype[] = {
{
.name = "imx1-fb",
.driver_data = IMX1_FB,
......
......@@ -285,9 +285,7 @@ struct intelfb_info {
/* use a gart reserved fb mem */
u8 fbmem_gart;
/* mtrr support */
int mtrr_reg;
u32 has_mtrr;
int wc_cookie;
/* heap data */
struct intelfb_heap_data aperture;
......
......@@ -124,10 +124,6 @@
#include <asm/io.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include "intelfb.h"
#include "intelfbhw.h"
#include "../edid.h"
......@@ -410,33 +406,6 @@ static void __exit intelfb_exit(void)
module_init(intelfb_init);
module_exit(intelfb_exit);
/***************************************************************
* mtrr support functions *
***************************************************************/
#ifdef CONFIG_MTRR
static inline void set_mtrr(struct intelfb_info *dinfo)
{
dinfo->mtrr_reg = mtrr_add(dinfo->aperture.physical,
dinfo->aperture.size, MTRR_TYPE_WRCOMB, 1);
if (dinfo->mtrr_reg < 0) {
ERR_MSG("unable to set MTRR\n");
return;
}
dinfo->has_mtrr = 1;
}
static inline void unset_mtrr(struct intelfb_info *dinfo)
{
if (dinfo->has_mtrr)
mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical,
dinfo->aperture.size);
}
#else
#define set_mtrr(x) WRN_MSG("MTRR is disabled in the kernel\n")
#define unset_mtrr(x) do { } while (0)
#endif /* CONFIG_MTRR */
/***************************************************************
* driver init / cleanup *
***************************************************************/
......@@ -456,7 +425,7 @@ static void cleanup(struct intelfb_info *dinfo)
if (dinfo->registered)
unregister_framebuffer(dinfo->info);
unset_mtrr(dinfo);
arch_phys_wc_del(dinfo->wc_cookie);
if (dinfo->fbmem_gart && dinfo->gtt_fb_mem) {
agp_unbind_memory(dinfo->gtt_fb_mem);
......@@ -675,7 +644,7 @@ static int intelfb_pci_register(struct pci_dev *pdev,
/* Allocate memories (which aren't stolen) */
/* Map the fb and MMIO regions */
/* ioremap only up to the end of used aperture */
dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
dinfo->aperture.virtual = (u8 __iomem *)ioremap_wc
(dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12)
+ dinfo->fb.size);
if (!dinfo->aperture.virtual) {
......@@ -772,7 +741,8 @@ static int intelfb_pci_register(struct pci_dev *pdev,
agp_backend_release(bridge);
if (mtrr)
set_mtrr(dinfo);
dinfo->wc_cookie = arch_phys_wc_add(dinfo->aperture.physical,
dinfo->aperture.size);
DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%p)\n",
dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size,
......
......@@ -370,12 +370,9 @@ static void matroxfb_remove(struct matrox_fb_info *minfo, int dummy)
matroxfb_unregister_device(minfo);
unregister_framebuffer(&minfo->fbcon);
matroxfb_g450_shutdown(minfo);
#ifdef CONFIG_MTRR
if (minfo->mtrr.vram_valid)
mtrr_del(minfo->mtrr.vram, minfo->video.base, minfo->video.len);
#endif
mga_iounmap(minfo->mmio.vbase);
mga_iounmap(minfo->video.vbase);
arch_phys_wc_del(minfo->wc_cookie);
iounmap(minfo->mmio.vbase.vaddr);
iounmap(minfo->video.vbase.vaddr);
release_mem_region(minfo->video.base, minfo->video.len_maximum);
release_mem_region(minfo->mmio.base, 16384);
kfree(minfo);
......@@ -591,12 +588,8 @@ static int matroxfb_decode_var(const struct matrox_fb_info *minfo,
unsigned int max_yres;
while (m1) {
int t;
while (m2 >= m1) m2 -= m1;
t = m1;
m1 = m2;
m2 = t;
swap(m1, m2);
}
m2 = linelen * PAGE_SIZE / m2;
*ydstorg = m2 = 0x400000 % m2;
......@@ -1256,9 +1249,7 @@ static int nobios; /* "matroxfb:nobios" */
static int noinit = 1; /* "matroxfb:init" */
static int inverse; /* "matroxfb:inverse" */
static int sgram; /* "matroxfb:sgram" */
#ifdef CONFIG_MTRR
static int mtrr = 1; /* "matroxfb:nomtrr" */
#endif
static int grayscale; /* "matroxfb:grayscale" */
static int dev = -1; /* "matroxfb:dev:xxxxx" */
static unsigned int vesa = ~0; /* "matroxfb:vesa:xxxxx" */
......@@ -1717,14 +1708,17 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
if (mem && (mem < memsize))
memsize = mem;
err = -ENOMEM;
if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &minfo->mmio.vbase)) {
minfo->mmio.vbase.vaddr = ioremap_nocache(ctrlptr_phys, 16384);
if (!minfo->mmio.vbase.vaddr) {
printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys);
goto failVideoMR;
}
minfo->mmio.base = ctrlptr_phys;
minfo->mmio.len = 16384;
minfo->video.base = video_base_phys;
if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &minfo->video.vbase)) {
minfo->video.vbase.vaddr = ioremap_wc(video_base_phys, memsize);
if (!minfo->video.vbase.vaddr) {
printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n",
video_base_phys, memsize);
goto failCtrlIO;
......@@ -1772,13 +1766,9 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
minfo->video.len_usable = minfo->video.len;
if (minfo->video.len_usable > b->base->maxdisplayable)
minfo->video.len_usable = b->base->maxdisplayable;
#ifdef CONFIG_MTRR
if (mtrr) {
minfo->mtrr.vram = mtrr_add(video_base_phys, minfo->video.len, MTRR_TYPE_WRCOMB, 1);
minfo->mtrr.vram_valid = 1;
printk(KERN_INFO "matroxfb: MTRR's turned on\n");
}
#endif /* CONFIG_MTRR */
if (mtrr)
minfo->wc_cookie = arch_phys_wc_add(video_base_phys,
minfo->video.len);
if (!minfo->devflags.novga)
request_region(0x3C0, 32, "matrox");
......@@ -1947,9 +1937,9 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
return 0;
failVideoIO:;
matroxfb_g450_shutdown(minfo);
mga_iounmap(minfo->video.vbase);
iounmap(minfo->video.vbase.vaddr);
failCtrlIO:;
mga_iounmap(minfo->mmio.vbase);
iounmap(minfo->mmio.vbase.vaddr);
failVideoMR:;
release_mem_region(video_base_phys, minfo->video.len_maximum);
failCtrlMR:;
......@@ -2443,10 +2433,8 @@ static int __init matroxfb_setup(char *options) {
nobios = !value;
else if (!strcmp(this_opt, "init"))
noinit = !value;
#ifdef CONFIG_MTRR
else if (!strcmp(this_opt, "mtrr"))
mtrr = value;
#endif
else if (!strcmp(this_opt, "inv24"))
inv24 = value;
else if (!strcmp(this_opt, "cross4MB"))
......@@ -2515,10 +2503,8 @@ module_param(noinit, int, 0);
MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)");
module_param(memtype, int, 0);
MODULE_PARM_DESC(memtype, "Memory type for G200/G400 (see Documentation/fb/matroxfb.txt for explanation) (default=3 for G200, 0 for G400)");
#ifdef CONFIG_MTRR
module_param(mtrr, int, 0);
MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
#endif
module_param(sgram, int, 0);
MODULE_PARM_DESC(sgram, "Indicates that G100/G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
module_param(inv24, int, 0);
......
......@@ -44,9 +44,6 @@
#include <asm/io.h>
#include <asm/unaligned.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#if defined(CONFIG_PPC_PMAC)
#include <asm/prom.h>
......@@ -187,23 +184,6 @@ static inline void __iomem* vaddr_va(vaddr_t va) {
return va.vaddr;
}
#define MGA_IOREMAP_NORMAL 0
#define MGA_IOREMAP_NOCACHE 1
#define MGA_IOREMAP_FB MGA_IOREMAP_NOCACHE
#define MGA_IOREMAP_MMIO MGA_IOREMAP_NOCACHE
static inline int mga_ioremap(unsigned long phys, unsigned long size, int flags, vaddr_t* virt) {
if (flags & MGA_IOREMAP_NOCACHE)
virt->vaddr = ioremap_nocache(phys, size);
else
virt->vaddr = ioremap(phys, size);
return (virt->vaddr == NULL); /* 0, !0... 0, error_code in future */
}
static inline void mga_iounmap(vaddr_t va) {
iounmap(va.vaddr);
}
struct my_timming {
unsigned int pixclock;
int mnp;
......@@ -449,12 +429,7 @@ struct matrox_fb_info {
int plnwt;
int srcorg;
} capable;
#ifdef CONFIG_MTRR
struct {
int vram;
int vram_valid;
} mtrr;
#endif
int wc_cookie;
struct {
int precise_width;
int mga_24bpp_fix;
......
# core framebuffer
#
obj-y := msm_fb.o
# MDP DMA/PPP engine
#
obj-y += mdp.o mdp_scale_tables.o mdp_ppp.o
# MDDI interface
#
obj-y += mddi.o
# MDDI client/panel drivers
#
obj-y += mddi_client_dummy.o
obj-y += mddi_client_toshiba.o
obj-y += mddi_client_nt35399.o
This diff is collapsed.
/* drivers/video/msm_fb/mddi_client_dummy.c
*
* Support for "dummy" mddi client devices which require no
* special initialization code.
*
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/platform_data/video-msm_fb.h>
struct panel_info {
struct platform_device pdev;
struct msm_panel_data panel_data;
};
static int mddi_dummy_suspend(struct msm_panel_data *panel_data)
{
return 0;
}
static int mddi_dummy_resume(struct msm_panel_data *panel_data)
{
return 0;
}
static int mddi_dummy_blank(struct msm_panel_data *panel_data)
{
return 0;
}
static int mddi_dummy_unblank(struct msm_panel_data *panel_data)
{
return 0;
}
static int mddi_dummy_probe(struct platform_device *pdev)
{
struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
struct panel_info *panel =
devm_kzalloc(&pdev->dev, sizeof(struct panel_info), GFP_KERNEL);
if (!panel)
return -ENOMEM;
platform_set_drvdata(pdev, panel);
panel->panel_data.suspend = mddi_dummy_suspend;
panel->panel_data.resume = mddi_dummy_resume;
panel->panel_data.blank = mddi_dummy_blank;
panel->panel_data.unblank = mddi_dummy_unblank;
panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
panel->pdev.name = "msm_panel";
panel->pdev.id = pdev->id;
platform_device_add_resources(&panel->pdev,
client_data->fb_resource, 1);
panel->panel_data.fb_data = client_data->private_client_data;
panel->pdev.dev.platform_data = &panel->panel_data;
return platform_device_register(&panel->pdev);
}
static struct platform_driver mddi_client_dummy = {
.probe = mddi_dummy_probe,
.driver = { .name = "mddi_c_dummy" },
};
static int __init mddi_client_dummy_init(void)
{
platform_driver_register(&mddi_client_dummy);
return 0;
}
module_init(mddi_client_dummy_init);
/* drivers/video/msm_fb/mddi_client_nt35399.c
*
* Support for Novatek NT35399 MDDI client of Sapphire
*
* Copyright (C) 2008 HTC Incorporated
* Author: Solomon Chiu (solomon_chiu@htc.com)
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/platform_data/video-msm_fb.h>
static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
struct panel_info {
struct msm_mddi_client_data *client_data;
struct platform_device pdev;
struct msm_panel_data panel_data;
struct msmfb_callback *fb_callback;
struct work_struct panel_work;
struct workqueue_struct *fb_wq;
int nt35399_got_int;
};
static void
nt35399_request_vsync(struct msm_panel_data *panel_data,
struct msmfb_callback *callback)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
panel->fb_callback = callback;
if (panel->nt35399_got_int) {
panel->nt35399_got_int = 0;
client_data->activate_link(client_data); /* clears interrupt */
}
}
static void nt35399_wait_vsync(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
if (panel->nt35399_got_int) {
panel->nt35399_got_int = 0;
client_data->activate_link(client_data); /* clears interrupt */
}
if (wait_event_timeout(nt35399_vsync_wait, panel->nt35399_got_int,
HZ/2) == 0)
printk(KERN_ERR "timeout waiting for VSYNC\n");
panel->nt35399_got_int = 0;
/* interrupt clears when screen dma starts */
}
static int nt35399_suspend(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
ret = bridge_data->uninit(bridge_data, client_data);
if (ret) {
printk(KERN_INFO "mddi nt35399 client: non zero return from "
"uninit\n");
return ret;
}
client_data->suspend(client_data);
return 0;
}
static int nt35399_resume(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
client_data->resume(client_data);
ret = bridge_data->init(bridge_data, client_data);
if (ret)
return ret;
return 0;
}
static int nt35399_blank(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
return bridge_data->blank(bridge_data, client_data);
}
static int nt35399_unblank(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
return bridge_data->unblank(bridge_data, client_data);
}
irqreturn_t nt35399_vsync_interrupt(int irq, void *data)
{
struct panel_info *panel = data;
panel->nt35399_got_int = 1;
if (panel->fb_callback) {
panel->fb_callback->func(panel->fb_callback);
panel->fb_callback = NULL;
}
wake_up(&nt35399_vsync_wait);
return IRQ_HANDLED;
}
static int setup_vsync(struct panel_info *panel, int init)
{
int ret;
int gpio = 97;
unsigned int irq;
if (!init) {
ret = 0;
goto uninit;
}
ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
if (ret)
goto err_request_gpio_failed;
ret = irq = gpio_to_irq(gpio);
if (ret < 0)
goto err_get_irq_num_failed;
ret = request_irq(irq, nt35399_vsync_interrupt, IRQF_TRIGGER_RISING,
"vsync", panel);
if (ret)
goto err_request_irq_failed;
printk(KERN_INFO "vsync on gpio %d now %d\n",
gpio, gpio_get_value(gpio));
return 0;
uninit:
free_irq(gpio_to_irq(gpio), panel->client_data);
err_request_irq_failed:
err_get_irq_num_failed:
gpio_free(gpio);
err_request_gpio_failed:
return ret;
}
static int mddi_nt35399_probe(struct platform_device *pdev)
{
struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
struct panel_info *panel = devm_kzalloc(&pdev->dev,
sizeof(struct panel_info),
GFP_KERNEL);
printk(KERN_DEBUG "%s: enter.\n", __func__);
if (!panel)
return -ENOMEM;
platform_set_drvdata(pdev, panel);
ret = setup_vsync(panel, 1);
if (ret) {
dev_err(&pdev->dev, "mddi_nt35399_setup_vsync failed\n");
return ret;
}
panel->client_data = client_data;
panel->panel_data.suspend = nt35399_suspend;
panel->panel_data.resume = nt35399_resume;
panel->panel_data.wait_vsync = nt35399_wait_vsync;
panel->panel_data.request_vsync = nt35399_request_vsync;
panel->panel_data.blank = nt35399_blank;
panel->panel_data.unblank = nt35399_unblank;
panel->panel_data.fb_data = &bridge_data->fb_data;
panel->panel_data.caps = 0;
panel->pdev.name = "msm_panel";
panel->pdev.id = pdev->id;
panel->pdev.resource = client_data->fb_resource;
panel->pdev.num_resources = 1;
panel->pdev.dev.platform_data = &panel->panel_data;
if (bridge_data->init)
bridge_data->init(bridge_data, client_data);
platform_device_register(&panel->pdev);
return 0;
}
static int mddi_nt35399_remove(struct platform_device *pdev)
{
struct panel_info *panel = platform_get_drvdata(pdev);
setup_vsync(panel, 0);
return 0;
}
static struct platform_driver mddi_client_0bda_8a47 = {
.probe = mddi_nt35399_probe,
.remove = mddi_nt35399_remove,
.driver = { .name = "mddi_c_0bda_8a47" },
};
static int __init mddi_client_nt35399_init(void)
{
return platform_driver_register(&mddi_client_0bda_8a47);
}
module_init(mddi_client_nt35399_init);
/* drivers/video/msm_fb/mddi_client_toshiba.c
*
* Support for Toshiba TC358720XBG mddi client devices which require no
* special initialization code.
*
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/platform_data/video-msm_fb.h>
#define LCD_CONTROL_BLOCK_BASE 0x110000
#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
#define VPOS (LCD_CONTROL_BLOCK_BASE|0xC0)
#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
#define BASE5 0x150000
#define BASE6 0x160000
#define BASE7 0x170000
#define GPIOIEV (BASE5 + 0x10)
#define GPIOIE (BASE5 + 0x14)
#define GPIORIS (BASE5 + 0x18)
#define GPIOMIS (BASE5 + 0x1C)
#define GPIOIC (BASE5 + 0x20)
#define INTMASK (BASE6 + 0x0C)
#define INTMASK_VWAKEOUT (1U << 0)
#define INTMASK_VWAKEOUT_ACTIVE_LOW (1U << 8)
#define GPIOSEL (BASE7 + 0x00)
#define GPIOSEL_VWAKEINT (1U << 0)
static DECLARE_WAIT_QUEUE_HEAD(toshiba_vsync_wait);
struct panel_info {
struct msm_mddi_client_data *client_data;
struct platform_device pdev;
struct msm_panel_data panel_data;
struct msmfb_callback *toshiba_callback;
int toshiba_got_int;
};
static void toshiba_request_vsync(struct msm_panel_data *panel_data,
struct msmfb_callback *callback)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
panel->toshiba_callback = callback;
if (panel->toshiba_got_int) {
panel->toshiba_got_int = 0;
client_data->activate_link(client_data);
}
}
static void toshiba_clear_vsync(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
client_data->activate_link(client_data);
}
static void toshiba_wait_vsync(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
if (panel->toshiba_got_int) {
panel->toshiba_got_int = 0;
client_data->activate_link(client_data); /* clears interrupt */
}
if (wait_event_timeout(toshiba_vsync_wait, panel->toshiba_got_int,
HZ/2) == 0)
printk(KERN_ERR "timeout waiting for VSYNC\n");
panel->toshiba_got_int = 0;
/* interrupt clears when screen dma starts */
}
static int toshiba_suspend(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
ret = bridge_data->uninit(bridge_data, client_data);
if (ret) {
printk(KERN_INFO "mddi toshiba client: non zero return from "
"uninit\n");
return ret;
}
client_data->suspend(client_data);
return 0;
}
static int toshiba_resume(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
client_data->resume(client_data);
ret = bridge_data->init(bridge_data, client_data);
if (ret)
return ret;
return 0;
}
static int toshiba_blank(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
return bridge_data->blank(bridge_data, client_data);
}
static int toshiba_unblank(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
return bridge_data->unblank(bridge_data, client_data);
}
irqreturn_t toshiba_vsync_interrupt(int irq, void *data)
{
struct panel_info *panel = data;
panel->toshiba_got_int = 1;
if (panel->toshiba_callback) {
panel->toshiba_callback->func(panel->toshiba_callback);
panel->toshiba_callback = 0;
}
wake_up(&toshiba_vsync_wait);
return IRQ_HANDLED;
}
static int setup_vsync(struct panel_info *panel,
int init)
{
int ret;
int gpio = 97;
unsigned int irq;
if (!init) {
ret = 0;
goto uninit;
}
ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
if (ret)
goto err_request_gpio_failed;
ret = irq = gpio_to_irq(gpio);
if (ret < 0)
goto err_get_irq_num_failed;
ret = request_irq(irq, toshiba_vsync_interrupt, IRQF_TRIGGER_RISING,
"vsync", panel);
if (ret)
goto err_request_irq_failed;
printk(KERN_INFO "vsync on gpio %d now %d\n",
gpio, gpio_get_value(gpio));
return 0;
uninit:
free_irq(gpio_to_irq(gpio), panel);
err_request_irq_failed:
err_get_irq_num_failed:
gpio_free(gpio);
err_request_gpio_failed:
return ret;
}
static int mddi_toshiba_probe(struct platform_device *pdev)
{
int ret;
struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
struct panel_info *panel =
kzalloc(sizeof(struct panel_info), GFP_KERNEL);
if (!panel)
return -ENOMEM;
platform_set_drvdata(pdev, panel);
/* mddi_remote_write(mddi, 0, WAKEUP); */
client_data->remote_write(client_data, GPIOSEL_VWAKEINT, GPIOSEL);
client_data->remote_write(client_data, INTMASK_VWAKEOUT, INTMASK);
ret = setup_vsync(panel, 1);
if (ret) {
dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n");
return ret;
}
panel->client_data = client_data;
panel->panel_data.suspend = toshiba_suspend;
panel->panel_data.resume = toshiba_resume;
panel->panel_data.wait_vsync = toshiba_wait_vsync;
panel->panel_data.request_vsync = toshiba_request_vsync;
panel->panel_data.clear_vsync = toshiba_clear_vsync;
panel->panel_data.blank = toshiba_blank;
panel->panel_data.unblank = toshiba_unblank;
panel->panel_data.fb_data = &bridge_data->fb_data;
panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
panel->pdev.name = "msm_panel";
panel->pdev.id = pdev->id;
panel->pdev.resource = client_data->fb_resource;
panel->pdev.num_resources = 1;
panel->pdev.dev.platform_data = &panel->panel_data;
bridge_data->init(bridge_data, client_data);
platform_device_register(&panel->pdev);
return 0;
}
static int mddi_toshiba_remove(struct platform_device *pdev)
{
struct panel_info *panel = platform_get_drvdata(pdev);
setup_vsync(panel, 0);
kfree(panel);
return 0;
}
static struct platform_driver mddi_client_d263_0000 = {
.probe = mddi_toshiba_probe,
.remove = mddi_toshiba_remove,
.driver = { .name = "mddi_c_d263_0000" },
};
static int __init mddi_client_toshiba_init(void)
{
platform_driver_register(&mddi_client_d263_0000);
return 0;
}
module_init(mddi_client_toshiba_init);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* drivers/video/msm_fb/mdp_scale_tables.h
*
* Copyright (C) 2007 QUALCOMM Incorporated
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _MDP_SCALE_TABLES_H_
#define _MDP_SCALE_TABLES_H_
#include <linux/types.h>
struct mdp_table_entry {
uint32_t reg;
uint32_t val;
};
extern struct mdp_table_entry mdp_upscale_table[64];
enum {
MDP_DOWNSCALE_PT2TOPT4,
MDP_DOWNSCALE_PT4TOPT6,
MDP_DOWNSCALE_PT6TOPT8,
MDP_DOWNSCALE_PT8TO1,
MDP_DOWNSCALE_MAX,
};
extern struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX];
extern struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX];
extern struct mdp_table_entry mdp_gaussian_blur_table[];
#endif
This diff is collapsed.
......@@ -316,6 +316,18 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var,
return 0;
}
static inline void mxsfb_enable_axi_clk(struct mxsfb_info *host)
{
if (host->clk_axi)
clk_prepare_enable(host->clk_axi);
}
static inline void mxsfb_disable_axi_clk(struct mxsfb_info *host)
{
if (host->clk_axi)
clk_disable_unprepare(host->clk_axi);
}
static void mxsfb_enable_controller(struct fb_info *fb_info)
{
struct mxsfb_info *host = to_imxfb_host(fb_info);
......@@ -333,14 +345,13 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
}
}
if (host->clk_axi)
clk_prepare_enable(host->clk_axi);
if (host->clk_disp_axi)
clk_prepare_enable(host->clk_disp_axi);
clk_prepare_enable(host->clk);
clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
mxsfb_enable_axi_clk(host);
/* if it was disabled, re-enable the mode again */
writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET);
......@@ -380,11 +391,11 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
reg = readl(host->base + LCDC_VDCTRL4);
writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
mxsfb_disable_axi_clk(host);
clk_disable_unprepare(host->clk);
if (host->clk_disp_axi)
clk_disable_unprepare(host->clk_disp_axi);
if (host->clk_axi)
clk_disable_unprepare(host->clk_axi);
host->enabled = 0;
......@@ -421,6 +432,8 @@ static int mxsfb_set_par(struct fb_info *fb_info)
mxsfb_disable_controller(fb_info);
}
mxsfb_enable_axi_clk(host);
/* clear the FIFOs */
writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
......@@ -438,6 +451,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)
ctrl |= CTRL_SET_WORD_LENGTH(3);
switch (host->ld_intf_width) {
case STMLCDIF_8BIT:
mxsfb_disable_axi_clk(host);
dev_err(&host->pdev->dev,
"Unsupported LCD bus width mapping\n");
return -EINVAL;
......@@ -451,6 +465,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)
writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1);
break;
default:
mxsfb_disable_axi_clk(host);
dev_err(&host->pdev->dev, "Unhandled color depth of %u\n",
fb_info->var.bits_per_pixel);
return -EINVAL;
......@@ -504,6 +519,8 @@ static int mxsfb_set_par(struct fb_info *fb_info)
fb_info->fix.line_length * fb_info->var.yoffset,
host->base + host->devdata->next_buf);
mxsfb_disable_axi_clk(host);
if (reenable)
mxsfb_enable_controller(fb_info);
......@@ -582,10 +599,14 @@ static int mxsfb_pan_display(struct fb_var_screeninfo *var,
offset = fb_info->fix.line_length * var->yoffset;
mxsfb_enable_axi_clk(host);
/* update on next VSYNC */
writel(fb_info->fix.smem_start + offset,
host->base + host->devdata->next_buf);
mxsfb_disable_axi_clk(host);
return 0;
}
......@@ -608,13 +629,17 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
unsigned line_count;
unsigned period;
unsigned long pa, fbsize;
int bits_per_pixel, ofs;
int bits_per_pixel, ofs, ret = 0;
u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl;
mxsfb_enable_axi_clk(host);
/* Only restore the mode when the controller is running */
ctrl = readl(host->base + LCDC_CTRL);
if (!(ctrl & CTRL_RUN))
return -EINVAL;
if (!(ctrl & CTRL_RUN)) {
ret = -EINVAL;
goto err;
}
vdctrl0 = readl(host->base + LCDC_VDCTRL0);
vdctrl2 = readl(host->base + LCDC_VDCTRL2);
......@@ -635,7 +660,8 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
break;
case 1:
default:
return -EINVAL;
ret = -EINVAL;
goto err;
}
fb_info->var.bits_per_pixel = bits_per_pixel;
......@@ -673,10 +699,14 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
pa = readl(host->base + host->devdata->cur_buf);
fbsize = fb_info->fix.line_length * vmode->yres;
if (pa < fb_info->fix.smem_start)
return -EINVAL;
if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len)
return -EINVAL;
if (pa < fb_info->fix.smem_start) {
ret = -EINVAL;
goto err;
}
if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) {
ret = -EINVAL;
goto err;
}
ofs = pa - fb_info->fix.smem_start;
if (ofs) {
memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize);
......@@ -689,7 +719,11 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
clk_prepare_enable(host->clk);
host->enabled = 1;
return 0;
err:
if (ret)
mxsfb_disable_axi_clk(host);
return ret;
}
static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
......@@ -814,7 +848,7 @@ static void mxsfb_free_videomem(struct mxsfb_info *host)
free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
}
static struct platform_device_id mxsfb_devtype[] = {
static const struct platform_device_id mxsfb_devtype[] = {
{
.name = "imx23-fb",
.driver_data = MXSFB_V3,
......@@ -915,7 +949,9 @@ static int mxsfb_probe(struct platform_device *pdev)
}
if (!host->enabled) {
mxsfb_enable_axi_clk(host);
writel(0, host->base + LCDC_CTRL);
mxsfb_disable_axi_clk(host);
mxsfb_set_par(fb_info);
mxsfb_enable_controller(fb_info);
}
......@@ -954,11 +990,15 @@ static void mxsfb_shutdown(struct platform_device *pdev)
struct fb_info *fb_info = platform_get_drvdata(pdev);
struct mxsfb_info *host = to_imxfb_host(fb_info);
mxsfb_enable_axi_clk(host);
/*
* Force stop the LCD controller as keeping it running during reboot
* might interfere with the BootROM's boot mode pads sampling.
*/
writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR);
mxsfb_disable_axi_clk(host);
}
static struct platform_driver mxsfb_driver = {
......
......@@ -71,11 +71,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <video/vga.h>
#include <video/neomagic.h>
......@@ -1710,6 +1705,7 @@ static int neo_map_video(struct fb_info *info, struct pci_dev *dev,
int video_len)
{
//unsigned long addr;
struct neofb_par *par = info->par;
DBG("neo_map_video");
......@@ -1723,7 +1719,7 @@ static int neo_map_video(struct fb_info *info, struct pci_dev *dev,
}
info->screen_base =
ioremap(info->fix.smem_start, info->fix.smem_len);
ioremap_wc(info->fix.smem_start, info->fix.smem_len);
if (!info->screen_base) {
printk("neofb: unable to map screen memory\n");
release_mem_region(info->fix.smem_start,
......@@ -1733,11 +1729,8 @@ static int neo_map_video(struct fb_info *info, struct pci_dev *dev,
printk(KERN_INFO "neofb: mapped framebuffer at %p\n",
info->screen_base);
#ifdef CONFIG_MTRR
((struct neofb_par *)(info->par))->mtrr =
mtrr_add(info->fix.smem_start, pci_resource_len(dev, 0),
MTRR_TYPE_WRCOMB, 1);
#endif
par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
pci_resource_len(dev, 0));
/* Clear framebuffer, it's all white in memory after boot */
memset_io(info->screen_base, 0, info->fix.smem_len);
......@@ -1754,16 +1747,11 @@ static int neo_map_video(struct fb_info *info, struct pci_dev *dev,
static void neo_unmap_video(struct fb_info *info)
{
DBG("neo_unmap_video");
struct neofb_par *par = info->par;
#ifdef CONFIG_MTRR
{
struct neofb_par *par = info->par;
DBG("neo_unmap_video");
mtrr_del(par->mtrr, info->fix.smem_start,
info->fix.smem_len);
}
#endif
arch_phys_wc_del(par->wc_cookie);
iounmap(info->screen_base);
info->screen_base = NULL;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment