From d2c4025de87f3f38cfa627ff8523f459f6651a20 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 1 Mar 2012 16:49:25 +0200 Subject: [PATCH] gfx: display: initialize backlight PWM frequency Some DV1s, and DV1.5s and later use I2C to adjust the backlight. We have PWM based backlight control enabled for compatibility with older, non-CABC devices. The PWM clock divider was not initialized, causing the PWM signal to run at the base clock frequency of 19.2 MHz. Initialize the clock divider, setting the PWM frequency to 9600 Hz. The panel specification has no recommendation on the frequency, but the bug ANDROID-1342 has this experimental value. Issue: ANDROID-1342 Signed-off-by: Jani Nikula Signed-off-by: Kirill A. Shutemov --- drivers/staging/mrst/drv/mdfld_dsi_output.c | 22 ------------- drivers/staging/mrst/drv/tc35876x-dsi-lvds.c | 49 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/drivers/staging/mrst/drv/mdfld_dsi_output.c b/drivers/staging/mrst/drv/mdfld_dsi_output.c index 25b0a8b..a5ab577 100644 --- a/drivers/staging/mrst/drv/mdfld_dsi_output.c +++ b/drivers/staging/mrst/drv/mdfld_dsi_output.c @@ -110,23 +110,6 @@ void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u3 * FIXME: this is exported to OSPM code. should work out an specific * display interface to OSPM. */ -#define PWM0_CLK_DIV 64000 -#define PWM0CLKDIV0 0x62 -#define PWM0CLKDIV1 0x61 -static void tc35876x_brightness_init(struct mdfld_dsi_config *dsi_config, - int pipe) -{ - struct drm_device *dev = dsi_config->dev; - int ret; - - dev_dbg(&dev->pdev->dev, "Enter %s\n", __func__); - - /* Set PWM frequency to 300 Hz = (19.2*1000*1000)/64000 */ - ret = intel_scu_ipc_iowrite8(PWM0CLKDIV0, PWM0_CLK_DIV & 0xff); - ret |= intel_scu_ipc_iowrite8(PWM0CLKDIV1, (PWM0_CLK_DIV >> 8) & 0xff); - if (ret) - dev_err(&dev->pdev->dev, "%s: ipc write fail\n", __func__); -} void mdfld_dsi_brightness_init (struct mdfld_dsi_config * dsi_config, int pipe) { @@ -135,11 +118,6 @@ void mdfld_dsi_brightness_init (struct mdfld_dsi_config * dsi_config, int pipe) struct drm_psb_private * dev_priv = dev->dev_private; u32 gen_ctrl_val; - if (get_panel_type(dev, pipe) == TC35876X) { - tc35876x_brightness_init(dsi_config, pipe); - return; - } - if(!sender) { DRM_ERROR("No sender found\n"); } diff --git a/drivers/staging/mrst/drv/tc35876x-dsi-lvds.c b/drivers/staging/mrst/drv/tc35876x-dsi-lvds.c index 8826c51..6a6bbb4 100644 --- a/drivers/staging/mrst/drv/tc35876x-dsi-lvds.c +++ b/drivers/staging/mrst/drv/tc35876x-dsi-lvds.c @@ -423,6 +423,53 @@ void tc35876x_configure_lvds_bridge(struct drm_device *dev) tc35876x_regw(i2c, DSI_INTCLR, FLD_MASK(31, 30) | FLD_MASK(22, 0)); } +#define GPIOPWMCTRL 0x38F +#define PWM0CLKDIV0 0x62 /* low byte */ +#define PWM0CLKDIV1 0x61 /* high byte */ + +#define SYSTEMCLK 19200000UL /* 19.2 MHz */ +#define PWM_FREQUENCY 9600 /* Hz */ + +/* f = baseclk / (clkdiv + 1) => clkdiv = (baseclk - f) / f */ +static inline u16 calc_clkdiv(unsigned long baseclk, unsigned int f) +{ + return (baseclk - f) / f; +} + +static void tc35876x_brightness_init(struct drm_device *dev) +{ + int ret; + u8 pwmctrl; + u16 clkdiv; + + /* Make sure the PWM reference is the 19.2 MHz system clock. Read first + * instead of setting directly to catch potential conflicts between PWM + * users. */ + ret = intel_scu_ipc_ioread8(GPIOPWMCTRL, &pwmctrl); + if (ret || pwmctrl != 0x01) { + if (ret) + dev_err(&dev->pdev->dev, "GPIOPWMCTRL read failed\n"); + else + dev_warn(&dev->pdev->dev, "GPIOPWMCTRL was not set to system clock (pwmctrl = 0x%02x)\n", pwmctrl); + + ret = intel_scu_ipc_iowrite8(GPIOPWMCTRL, 0x01); + if (ret) + dev_err(&dev->pdev->dev, "GPIOPWMCTRL set failed\n"); + } + + clkdiv = calc_clkdiv(SYSTEMCLK, PWM_FREQUENCY); + + ret = intel_scu_ipc_iowrite8(PWM0CLKDIV1, (clkdiv >> 8) & 0xff); + if (!ret) + ret = intel_scu_ipc_iowrite8(PWM0CLKDIV0, clkdiv & 0xff); + + if (ret) + dev_err(&dev->pdev->dev, "PWM0CLKDIV set failed\n"); + else + dev_dbg(&dev->pdev->dev, "PWM0CLKDIV set to 0x%04x (%d Hz)\n", + clkdiv, PWM_FREQUENCY); +} + #define PWM0DUTYCYCLE 0x67 void tc35876x_brightness_control(struct drm_device *dev, int level) @@ -765,6 +812,8 @@ void tc35876x_init(struct drm_device *dev, struct panel_funcs *pf) dev_err(&dev->pdev->dev, "%s: i2c_add_driver() for %s failed (%d)\n", __func__, tc35876x_bridge_i2c_driver.driver.name, r); + + tc35876x_brightness_init(dev); } void tc35876x_exit(void) -- 2.7.4