Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'fbdev-updates-for-3.5' of git://github.com/schandinat/linux-2.6

Pull fbdev updates from Florian Tobias Schandinat:
- driver for AUO-K1900 and AUO-K1901 epaper controller
- large updates for OMAP (e.g. decouple HDMI audio and video)
- some updates for Exynos and SH Mobile
- various other small fixes and cleanups

* tag 'fbdev-updates-for-3.5' of git://github.com/schandinat/linux-2.6: (130 commits)
video: bfin_adv7393fb: Fix cleanup code
video: exynos_dp: reduce delay time when configuring video setting
video: exynos_dp: move sw reset prioir to enabling sw defined function
video: exynos_dp: use devm_ functions
fb: handle NULL pointers in framebuffer release
OMAPDSS: HDMI: OMAP4: Update IRQ flags for the HPD IRQ request
OMAPDSS: Apply VENC timings even if panel is disabled
OMAPDSS: VENC/DISPC: Delay dividing Y resolution for managers connected to VENC
OMAPDSS: DISPC: Support rotation through TILER
OMAPDSS: VRFB: remove compiler warnings when CONFIG_BUG=n
OMAPFB: remove compiler warnings when CONFIG_BUG=n
OMAPDSS: remove compiler warnings when CONFIG_BUG=n
OMAPDSS: DISPC: fix usage of dispc_ovl_set_accu_uv
OMAPDSS: use DSI_FIFO_BUG workaround only for manual update displays
OMAPDSS: DSI: Support command mode interleaving during video mode blanking periods
OMAPDSS: DISPC: Update Accumulator configuration for chroma plane
drivers/video: fsl-diu-fb: don't initialize the THRESHOLDS registers
video: exynos mipi dsi: support reverse panel type
video: exynos mipi dsi: Properly interpret the interrupt source flags
video: exynos mipi dsi: Avoid races in probe()
...

+5485 -2173
+46
Documentation/arm/OMAP/DSS
··· 47 47 modelling the hardware overlays, omapdss supports virtual overlays and overlay 48 48 managers. These can be used when updating a display with CPU or system DMA. 49 49 50 + omapdss driver support for audio 51 + -------------------------------- 52 + There exist several display technologies and standards that support audio as 53 + well. Hence, it is relevant to update the DSS device driver to provide an audio 54 + interface that may be used by an audio driver or any other driver interested in 55 + the functionality. 56 + 57 + The audio_enable function is intended to prepare the relevant 58 + IP for playback (e.g., enabling an audio FIFO, taking in/out of reset 59 + some IP, enabling companion chips, etc). It is intended to be called before 60 + audio_start. The audio_disable function performs the reverse operation and is 61 + intended to be called after audio_stop. 62 + 63 + While a given DSS device driver may support audio, it is possible that for 64 + certain configurations audio is not supported (e.g., an HDMI display using a 65 + VESA video timing). The audio_supported function is intended to query whether 66 + the current configuration of the display supports audio. 67 + 68 + The audio_config function is intended to configure all the relevant audio 69 + parameters of the display. In order to make the function independent of any 70 + specific DSS device driver, a struct omap_dss_audio is defined. Its purpose 71 + is to contain all the required parameters for audio configuration. At the 72 + moment, such structure contains pointers to IEC-60958 channel status word 73 + and CEA-861 audio infoframe structures. This should be enough to support 74 + HDMI and DisplayPort, as both are based on CEA-861 and IEC-60958. 75 + 76 + The audio_enable/disable, audio_config and audio_supported functions could be 77 + implemented as functions that may sleep. Hence, they should not be called 78 + while holding a spinlock or a readlock. 79 + 80 + The audio_start/audio_stop function is intended to effectively start/stop audio 81 + playback after the configuration has taken place. These functions are designed 82 + to be used in an atomic context. Hence, audio_start should return quickly and be 83 + called only after all the needed resources for audio playback (audio FIFOs, 84 + DMA channels, companion chips, etc) have been enabled to begin data transfers. 85 + audio_stop is designed to only stop the audio transfers. The resources used 86 + for playback are released using audio_disable. 87 + 88 + The enum omap_dss_audio_state may be used to help the implementations of 89 + the interface to keep track of the audio state. The initial state is _DISABLED; 90 + then, the state transitions to _CONFIGURED, and then, when it is ready to 91 + play audio, to _ENABLED. The state _PLAYING is used when the audio is being 92 + rendered. 93 + 94 + 50 95 Panel and controller drivers 51 96 ---------------------------- 52 97 ··· 201 156 "pal" and "ntsc" 202 157 panel_name 203 158 tear_elim Tearing elimination 0=off, 1=on 159 + output_type Output type (video encoder only): "composite" or "svideo" 204 160 205 161 There are also some debugfs files at <debugfs>/omapdss/ which show information 206 162 about clocks and registers.
+15 -11
arch/arm/mach-exynos/mach-nuri.c
··· 237 237 #else 238 238 /* Frame Buffer */ 239 239 static struct s3c_fb_pd_win nuri_fb_win0 = { 240 - .win_mode = { 241 - .left_margin = 64, 242 - .right_margin = 16, 243 - .upper_margin = 64, 244 - .lower_margin = 1, 245 - .hsync_len = 48, 246 - .vsync_len = 3, 247 - .xres = 1024, 248 - .yres = 600, 249 - .refresh = 60, 250 - }, 251 240 .max_bpp = 24, 252 241 .default_bpp = 16, 242 + .xres = 1024, 243 + .yres = 600, 253 244 .virtual_x = 1024, 254 245 .virtual_y = 2 * 600, 255 246 }; 256 247 248 + static struct fb_videomode nuri_lcd_timing = { 249 + .left_margin = 64, 250 + .right_margin = 16, 251 + .upper_margin = 64, 252 + .lower_margin = 1, 253 + .hsync_len = 48, 254 + .vsync_len = 3, 255 + .xres = 1024, 256 + .yres = 600, 257 + .refresh = 60, 258 + }; 259 + 257 260 static struct s3c_fb_platdata nuri_fb_pdata __initdata = { 258 261 .win[0] = &nuri_fb_win0, 262 + .vtiming = &nuri_lcd_timing, 259 263 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB | 260 264 VIDCON0_CLKSEL_LCD, 261 265 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+14 -10
arch/arm/mach-exynos/mach-origen.c
··· 604 604 }; 605 605 #else 606 606 static struct s3c_fb_pd_win origen_fb_win0 = { 607 - .win_mode = { 608 - .left_margin = 64, 609 - .right_margin = 16, 610 - .upper_margin = 64, 611 - .lower_margin = 16, 612 - .hsync_len = 48, 613 - .vsync_len = 3, 614 - .xres = 1024, 615 - .yres = 600, 616 - }, 607 + .xres = 1024, 608 + .yres = 600, 617 609 .max_bpp = 32, 618 610 .default_bpp = 24, 619 611 .virtual_x = 1024, 620 612 .virtual_y = 2 * 600, 621 613 }; 622 614 615 + static struct fb_videomode origen_lcd_timing = { 616 + .left_margin = 64, 617 + .right_margin = 16, 618 + .upper_margin = 64, 619 + .lower_margin = 16, 620 + .hsync_len = 48, 621 + .vsync_len = 3, 622 + .xres = 1024, 623 + .yres = 600, 624 + }; 625 + 623 626 static struct s3c_fb_platdata origen_lcd_pdata __initdata = { 624 627 .win[0] = &origen_fb_win0, 628 + .vtiming = &origen_lcd_timing, 625 629 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 626 630 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC | 627 631 VIDCON1_INV_VCLK,
+16 -12
arch/arm/mach-exynos/mach-smdkv310.c
··· 178 178 }; 179 179 #else 180 180 static struct s3c_fb_pd_win smdkv310_fb_win0 = { 181 - .win_mode = { 182 - .left_margin = 13, 183 - .right_margin = 8, 184 - .upper_margin = 7, 185 - .lower_margin = 5, 186 - .hsync_len = 3, 187 - .vsync_len = 1, 188 - .xres = 800, 189 - .yres = 480, 190 - }, 191 - .max_bpp = 32, 192 - .default_bpp = 24, 181 + .max_bpp = 32, 182 + .default_bpp = 24, 183 + .xres = 800, 184 + .yres = 480, 185 + }; 186 + 187 + static struct fb_videomode smdkv310_lcd_timing = { 188 + .left_margin = 13, 189 + .right_margin = 8, 190 + .upper_margin = 7, 191 + .lower_margin = 5, 192 + .hsync_len = 3, 193 + .vsync_len = 1, 194 + .xres = 800, 195 + .yres = 480, 193 196 }; 194 197 195 198 static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = { 196 199 .win[0] = &smdkv310_fb_win0, 200 + .vtiming = &smdkv310_lcd_timing, 197 201 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 198 202 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 199 203 .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+15 -11
arch/arm/mach-exynos/mach-universal_c210.c
··· 843 843 #else 844 844 /* Frame Buffer */ 845 845 static struct s3c_fb_pd_win universal_fb_win0 = { 846 - .win_mode = { 847 - .left_margin = 16, 848 - .right_margin = 16, 849 - .upper_margin = 2, 850 - .lower_margin = 28, 851 - .hsync_len = 2, 852 - .vsync_len = 1, 853 - .xres = 480, 854 - .yres = 800, 855 - .refresh = 55, 856 - }, 857 846 .max_bpp = 32, 858 847 .default_bpp = 16, 848 + .xres = 480, 849 + .yres = 800, 859 850 .virtual_x = 480, 860 851 .virtual_y = 2 * 800, 861 852 }; 862 853 854 + static struct fb_videomode universal_lcd_timing = { 855 + .left_margin = 16, 856 + .right_margin = 16, 857 + .upper_margin = 2, 858 + .lower_margin = 28, 859 + .hsync_len = 2, 860 + .vsync_len = 1, 861 + .xres = 480, 862 + .yres = 800, 863 + .refresh = 55, 864 + }; 865 + 863 866 static struct s3c_fb_platdata universal_lcd_pdata __initdata = { 864 867 .win[0] = &universal_fb_win0, 868 + .vtiming = &universal_lcd_timing, 865 869 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB | 866 870 VIDCON0_CLKSEL_LCD, 867 871 .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
+167 -31
arch/arm/mach-omap2/display.c
··· 180 180 omap4_dsi_mux_pads(dsi_id, 0); 181 181 } 182 182 183 + static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput) 184 + { 185 + return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput); 186 + } 187 + 188 + static struct platform_device *create_dss_pdev(const char *pdev_name, 189 + int pdev_id, const char *oh_name, void *pdata, int pdata_len, 190 + struct platform_device *parent) 191 + { 192 + struct platform_device *pdev; 193 + struct omap_device *od; 194 + struct omap_hwmod *ohs[1]; 195 + struct omap_hwmod *oh; 196 + int r; 197 + 198 + oh = omap_hwmod_lookup(oh_name); 199 + if (!oh) { 200 + pr_err("Could not look up %s\n", oh_name); 201 + r = -ENODEV; 202 + goto err; 203 + } 204 + 205 + pdev = platform_device_alloc(pdev_name, pdev_id); 206 + if (!pdev) { 207 + pr_err("Could not create pdev for %s\n", pdev_name); 208 + r = -ENOMEM; 209 + goto err; 210 + } 211 + 212 + if (parent != NULL) 213 + pdev->dev.parent = &parent->dev; 214 + 215 + if (pdev->id != -1) 216 + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); 217 + else 218 + dev_set_name(&pdev->dev, "%s", pdev->name); 219 + 220 + ohs[0] = oh; 221 + od = omap_device_alloc(pdev, ohs, 1, NULL, 0); 222 + if (!od) { 223 + pr_err("Could not alloc omap_device for %s\n", pdev_name); 224 + r = -ENOMEM; 225 + goto err; 226 + } 227 + 228 + r = platform_device_add_data(pdev, pdata, pdata_len); 229 + if (r) { 230 + pr_err("Could not set pdata for %s\n", pdev_name); 231 + goto err; 232 + } 233 + 234 + r = omap_device_register(pdev); 235 + if (r) { 236 + pr_err("Could not register omap_device for %s\n", pdev_name); 237 + goto err; 238 + } 239 + 240 + return pdev; 241 + 242 + err: 243 + return ERR_PTR(r); 244 + } 245 + 246 + static struct platform_device *create_simple_dss_pdev(const char *pdev_name, 247 + int pdev_id, void *pdata, int pdata_len, 248 + struct platform_device *parent) 249 + { 250 + struct platform_device *pdev; 251 + int r; 252 + 253 + pdev = platform_device_alloc(pdev_name, pdev_id); 254 + if (!pdev) { 255 + pr_err("Could not create pdev for %s\n", pdev_name); 256 + r = -ENOMEM; 257 + goto err; 258 + } 259 + 260 + if (parent != NULL) 261 + pdev->dev.parent = &parent->dev; 262 + 263 + if (pdev->id != -1) 264 + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); 265 + else 266 + dev_set_name(&pdev->dev, "%s", pdev->name); 267 + 268 + r = platform_device_add_data(pdev, pdata, pdata_len); 269 + if (r) { 270 + pr_err("Could not set pdata for %s\n", pdev_name); 271 + goto err; 272 + } 273 + 274 + r = omap_device_register(pdev); 275 + if (r) { 276 + pr_err("Could not register omap_device for %s\n", pdev_name); 277 + goto err; 278 + } 279 + 280 + return pdev; 281 + 282 + err: 283 + return ERR_PTR(r); 284 + } 285 + 183 286 int __init omap_display_init(struct omap_dss_board_info *board_data) 184 287 { 185 288 int r = 0; 186 - struct omap_hwmod *oh; 187 289 struct platform_device *pdev; 188 290 int i, oh_count; 189 - struct omap_display_platform_data pdata; 190 291 const struct omap_dss_hwmod_data *curr_dss_hwmod; 292 + struct platform_device *dss_pdev; 191 293 192 - memset(&pdata, 0, sizeof(pdata)); 294 + /* create omapdss device */ 295 + 296 + board_data->dsi_enable_pads = omap_dsi_enable_pads; 297 + board_data->dsi_disable_pads = omap_dsi_disable_pads; 298 + board_data->get_context_loss_count = omap_pm_get_dev_context_loss_count; 299 + board_data->set_min_bus_tput = omap_dss_set_min_bus_tput; 300 + 301 + omap_display_device.dev.platform_data = board_data; 302 + 303 + r = platform_device_register(&omap_display_device); 304 + if (r < 0) { 305 + pr_err("Unable to register omapdss device\n"); 306 + return r; 307 + } 308 + 309 + /* create devices for dss hwmods */ 193 310 194 311 if (cpu_is_omap24xx()) { 195 312 curr_dss_hwmod = omap2_dss_hwmod_data; ··· 319 202 oh_count = ARRAY_SIZE(omap4_dss_hwmod_data); 320 203 } 321 204 322 - if (board_data->dsi_enable_pads == NULL) 323 - board_data->dsi_enable_pads = omap_dsi_enable_pads; 324 - if (board_data->dsi_disable_pads == NULL) 325 - board_data->dsi_disable_pads = omap_dsi_disable_pads; 205 + /* 206 + * First create the pdev for dss_core, which is used as a parent device 207 + * by the other dss pdevs. Note: dss_core has to be the first item in 208 + * the hwmod list. 209 + */ 210 + dss_pdev = create_dss_pdev(curr_dss_hwmod[0].dev_name, 211 + curr_dss_hwmod[0].id, 212 + curr_dss_hwmod[0].oh_name, 213 + board_data, sizeof(*board_data), 214 + NULL); 326 215 327 - pdata.board_data = board_data; 328 - pdata.board_data->get_context_loss_count = 329 - omap_pm_get_dev_context_loss_count; 216 + if (IS_ERR(dss_pdev)) { 217 + pr_err("Could not build omap_device for %s\n", 218 + curr_dss_hwmod[0].oh_name); 330 219 331 - for (i = 0; i < oh_count; i++) { 332 - oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name); 333 - if (!oh) { 334 - pr_err("Could not look up %s\n", 335 - curr_dss_hwmod[i].oh_name); 336 - return -ENODEV; 337 - } 338 - 339 - pdev = omap_device_build(curr_dss_hwmod[i].dev_name, 340 - curr_dss_hwmod[i].id, oh, &pdata, 341 - sizeof(struct omap_display_platform_data), 342 - NULL, 0, 0); 343 - 344 - if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n", 345 - curr_dss_hwmod[i].oh_name)) 346 - return -ENODEV; 220 + return PTR_ERR(dss_pdev); 347 221 } 348 - omap_display_device.dev.platform_data = board_data; 349 222 350 - r = platform_device_register(&omap_display_device); 351 - if (r < 0) 352 - printk(KERN_ERR "Unable to register OMAP-Display device\n"); 223 + for (i = 1; i < oh_count; i++) { 224 + pdev = create_dss_pdev(curr_dss_hwmod[i].dev_name, 225 + curr_dss_hwmod[i].id, 226 + curr_dss_hwmod[i].oh_name, 227 + board_data, sizeof(*board_data), 228 + dss_pdev); 353 229 354 - return r; 230 + if (IS_ERR(pdev)) { 231 + pr_err("Could not build omap_device for %s\n", 232 + curr_dss_hwmod[i].oh_name); 233 + 234 + return PTR_ERR(pdev); 235 + } 236 + } 237 + 238 + /* Create devices for DPI and SDI */ 239 + 240 + pdev = create_simple_dss_pdev("omapdss_dpi", -1, 241 + board_data, sizeof(*board_data), dss_pdev); 242 + if (IS_ERR(pdev)) { 243 + pr_err("Could not build platform_device for omapdss_dpi\n"); 244 + return PTR_ERR(pdev); 245 + } 246 + 247 + if (cpu_is_omap34xx()) { 248 + pdev = create_simple_dss_pdev("omapdss_sdi", -1, 249 + board_data, sizeof(*board_data), dss_pdev); 250 + if (IS_ERR(pdev)) { 251 + pr_err("Could not build platform_device for omapdss_sdi\n"); 252 + return PTR_ERR(pdev); 253 + } 254 + } 255 + 256 + return 0; 355 257 } 356 258 357 259 static void dispc_disable_outputs(void)
+15 -12
arch/arm/mach-s3c24xx/mach-smdk2416.c
··· 148 148 149 149 static struct s3c_fb_pd_win smdk2416_fb_win[] = { 150 150 [0] = { 151 - /* think this is the same as the smdk6410 */ 152 - .win_mode = { 153 - .pixclock = 41094, 154 - .left_margin = 8, 155 - .right_margin = 13, 156 - .upper_margin = 7, 157 - .lower_margin = 5, 158 - .hsync_len = 3, 159 - .vsync_len = 1, 160 - .xres = 800, 161 - .yres = 480, 162 - }, 163 151 .default_bpp = 16, 164 152 .max_bpp = 32, 153 + .xres = 800, 154 + .yres = 480, 165 155 }, 156 + }; 157 + 158 + static struct fb_videomode smdk2416_lcd_timing = { 159 + .pixclock = 41094, 160 + .left_margin = 8, 161 + .right_margin = 13, 162 + .upper_margin = 7, 163 + .lower_margin = 5, 164 + .hsync_len = 3, 165 + .vsync_len = 1, 166 + .xres = 800, 167 + .yres = 480, 166 168 }; 167 169 168 170 static void s3c2416_fb_gpio_setup_24bpp(void) ··· 189 187 190 188 static struct s3c_fb_platdata smdk2416_fb_platdata = { 191 189 .win[0] = &smdk2416_fb_win[0], 190 + .vtiming = &smdk2416_lcd_timing, 192 191 .setup_gpio = s3c2416_fb_gpio_setup_24bpp, 193 192 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 194 193 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+14 -11
arch/arm/mach-s3c64xx/mach-anw6410.c
··· 134 134 }; 135 135 136 136 static struct s3c_fb_pd_win anw6410_fb_win0 = { 137 - /* this is to ensure we use win0 */ 138 - .win_mode = { 139 - .left_margin = 8, 140 - .right_margin = 13, 141 - .upper_margin = 7, 142 - .lower_margin = 5, 143 - .hsync_len = 3, 144 - .vsync_len = 1, 145 - .xres = 800, 146 - .yres = 480, 147 - }, 148 137 .max_bpp = 32, 149 138 .default_bpp = 16, 139 + .xres = 800, 140 + .yres = 480, 141 + }; 142 + 143 + static struct fb_videomode anw6410_lcd_timing = { 144 + .left_margin = 8, 145 + .right_margin = 13, 146 + .upper_margin = 7, 147 + .lower_margin = 5, 148 + .hsync_len = 3, 149 + .vsync_len = 1, 150 + .xres = 800, 151 + .yres = 480, 150 152 }; 151 153 152 154 /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ 153 155 static struct s3c_fb_platdata anw6410_lcd_pdata __initdata = { 154 156 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 157 + .vtiming = &anw6410_lcd_timing, 155 158 .win[0] = &anw6410_fb_win0, 156 159 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 157 160 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+14 -11
arch/arm/mach-s3c64xx/mach-crag6410.c
··· 151 151 152 152 /* 640x480 URT */ 153 153 static struct s3c_fb_pd_win crag6410_fb_win0 = { 154 - /* this is to ensure we use win0 */ 155 - .win_mode = { 156 - .left_margin = 150, 157 - .right_margin = 80, 158 - .upper_margin = 40, 159 - .lower_margin = 5, 160 - .hsync_len = 40, 161 - .vsync_len = 5, 162 - .xres = 640, 163 - .yres = 480, 164 - }, 165 154 .max_bpp = 32, 166 155 .default_bpp = 16, 156 + .xres = 640, 157 + .yres = 480, 167 158 .virtual_y = 480 * 2, 168 159 .virtual_x = 640, 160 + }; 161 + 162 + static struct fb_videomode crag6410_lcd_timing = { 163 + .left_margin = 150, 164 + .right_margin = 80, 165 + .upper_margin = 40, 166 + .lower_margin = 5, 167 + .hsync_len = 40, 168 + .vsync_len = 5, 169 + .xres = 640, 170 + .yres = 480, 169 171 }; 170 172 171 173 /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ 172 174 static struct s3c_fb_platdata crag6410_lcd_pdata __initdata = { 173 175 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 176 + .vtiming = &crag6410_lcd_timing, 174 177 .win[0] = &crag6410_fb_win0, 175 178 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 176 179 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+14 -10
arch/arm/mach-s3c64xx/mach-hmt.c
··· 129 129 }; 130 130 131 131 static struct s3c_fb_pd_win hmt_fb_win0 = { 132 - .win_mode = { 133 - .left_margin = 8, 134 - .right_margin = 13, 135 - .upper_margin = 7, 136 - .lower_margin = 5, 137 - .hsync_len = 3, 138 - .vsync_len = 1, 139 - .xres = 800, 140 - .yres = 480, 141 - }, 142 132 .max_bpp = 32, 143 133 .default_bpp = 16, 134 + .xres = 800, 135 + .yres = 480, 136 + }; 137 + 138 + static struct fb_videomode hmt_lcd_timing = { 139 + .left_margin = 8, 140 + .right_margin = 13, 141 + .upper_margin = 7, 142 + .lower_margin = 5, 143 + .hsync_len = 3, 144 + .vsync_len = 1, 145 + .xres = 800, 146 + .yres = 480, 144 147 }; 145 148 146 149 /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ 147 150 static struct s3c_fb_platdata hmt_lcd_pdata __initdata = { 148 151 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 152 + .vtiming = &hmt_lcd_timing, 149 153 .win[0] = &hmt_fb_win0, 150 154 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 151 155 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+55 -39
arch/arm/mach-s3c64xx/mach-mini6410.c
··· 140 140 .sets = mini6410_nand_sets, 141 141 }; 142 142 143 - static struct s3c_fb_pd_win mini6410_fb_win[] = { 144 - { 145 - .win_mode = { /* 4.3" 480x272 */ 146 - .left_margin = 3, 147 - .right_margin = 2, 148 - .upper_margin = 1, 149 - .lower_margin = 1, 150 - .hsync_len = 40, 151 - .vsync_len = 1, 152 - .xres = 480, 153 - .yres = 272, 154 - }, 155 - .max_bpp = 32, 156 - .default_bpp = 16, 157 - }, { 158 - .win_mode = { /* 7.0" 800x480 */ 159 - .left_margin = 8, 160 - .right_margin = 13, 161 - .upper_margin = 7, 162 - .lower_margin = 5, 163 - .hsync_len = 3, 164 - .vsync_len = 1, 165 - .xres = 800, 166 - .yres = 480, 167 - }, 168 - .max_bpp = 32, 169 - .default_bpp = 16, 170 - }, 143 + static struct s3c_fb_pd_win mini6410_lcd_type0_fb_win = { 144 + .max_bpp = 32, 145 + .default_bpp = 16, 146 + .xres = 480, 147 + .yres = 272, 171 148 }; 172 149 173 - static struct s3c_fb_platdata mini6410_lcd_pdata __initdata = { 174 - .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 175 - .win[0] = &mini6410_fb_win[0], 176 - .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 177 - .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 150 + static struct fb_videomode mini6410_lcd_type0_timing = { 151 + /* 4.3" 480x272 */ 152 + .left_margin = 3, 153 + .right_margin = 2, 154 + .upper_margin = 1, 155 + .lower_margin = 1, 156 + .hsync_len = 40, 157 + .vsync_len = 1, 158 + .xres = 480, 159 + .yres = 272, 160 + }; 161 + 162 + static struct s3c_fb_pd_win mini6410_lcd_type1_fb_win = { 163 + .max_bpp = 32, 164 + .default_bpp = 16, 165 + .xres = 800, 166 + .yres = 480, 167 + }; 168 + 169 + static struct fb_videomode mini6410_lcd_type1_timing = { 170 + /* 7.0" 800x480 */ 171 + .left_margin = 8, 172 + .right_margin = 13, 173 + .upper_margin = 7, 174 + .lower_margin = 5, 175 + .hsync_len = 3, 176 + .vsync_len = 1, 177 + .xres = 800, 178 + .yres = 480, 179 + }; 180 + 181 + static struct s3c_fb_platdata mini6410_lcd_pdata[] __initdata = { 182 + { 183 + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 184 + .vtiming = &mini6410_lcd_type0_timing, 185 + .win[0] = &mini6410_lcd_type0_fb_win, 186 + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 187 + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 188 + }, { 189 + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 190 + .vtiming = &mini6410_lcd_type1_timing, 191 + .win[0] = &mini6410_lcd_type1_fb_win, 192 + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 193 + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 194 + }, 195 + { }, 178 196 }; 179 197 180 198 static void mini6410_lcd_power_set(struct plat_lcd_data *pd, ··· 290 272 "screen type already set\n", f); 291 273 } else { 292 274 int li = f - '0'; 293 - if (li >= ARRAY_SIZE(mini6410_fb_win)) 275 + if (li >= ARRAY_SIZE(mini6410_lcd_pdata)) 294 276 printk(KERN_INFO "MINI6410: '%c' out " 295 277 "of range LCD mode\n", f); 296 278 else { ··· 314 296 /* Parse the feature string */ 315 297 mini6410_parse_features(&features, mini6410_features_str); 316 298 317 - mini6410_lcd_pdata.win[0] = &mini6410_fb_win[features.lcd_index]; 318 - 319 299 printk(KERN_INFO "MINI6410: selected LCD display is %dx%d\n", 320 - mini6410_lcd_pdata.win[0]->win_mode.xres, 321 - mini6410_lcd_pdata.win[0]->win_mode.yres); 300 + mini6410_lcd_pdata[features.lcd_index].win[0]->xres, 301 + mini6410_lcd_pdata[features.lcd_index].win[0]->yres); 322 302 323 303 s3c_nand_set_platdata(&mini6410_nand_info); 324 - s3c_fb_set_platdata(&mini6410_lcd_pdata); 304 + s3c_fb_set_platdata(&mini6410_lcd_pdata[features.lcd_index]); 325 305 s3c24xx_ts_set_platdata(NULL); 326 306 327 307 /* configure nCS1 width to 16 bits */
+53 -39
arch/arm/mach-s3c64xx/mach-real6410.c
··· 106 106 }, 107 107 }; 108 108 109 - static struct s3c_fb_pd_win real6410_fb_win[] = { 110 - { 111 - .win_mode = { /* 4.3" 480x272 */ 112 - .left_margin = 3, 113 - .right_margin = 2, 114 - .upper_margin = 1, 115 - .lower_margin = 1, 116 - .hsync_len = 40, 117 - .vsync_len = 1, 118 - .xres = 480, 119 - .yres = 272, 120 - }, 121 - .max_bpp = 32, 122 - .default_bpp = 16, 123 - }, { 124 - .win_mode = { /* 7.0" 800x480 */ 125 - .left_margin = 8, 126 - .right_margin = 13, 127 - .upper_margin = 7, 128 - .lower_margin = 5, 129 - .hsync_len = 3, 130 - .vsync_len = 1, 131 - .xres = 800, 132 - .yres = 480, 133 - }, 134 - .max_bpp = 32, 135 - .default_bpp = 16, 136 - }, 109 + static struct s3c_fb_pd_win real6410_lcd_type0_fb_win = { 110 + .max_bpp = 32, 111 + .default_bpp = 16, 112 + .xres = 480, 113 + .yres = 272, 137 114 }; 138 115 139 - static struct s3c_fb_platdata real6410_lcd_pdata __initdata = { 140 - .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 141 - .win[0] = &real6410_fb_win[0], 142 - .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 143 - .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 116 + static struct fb_videomode real6410_lcd_type0_timing = { 117 + /* 4.3" 480x272 */ 118 + .left_margin = 3, 119 + .right_margin = 2, 120 + .upper_margin = 1, 121 + .lower_margin = 1, 122 + .hsync_len = 40, 123 + .vsync_len = 1, 124 + }; 125 + 126 + static struct s3c_fb_pd_win real6410_lcd_type1_fb_win = { 127 + .max_bpp = 32, 128 + .default_bpp = 16, 129 + .xres = 800, 130 + .yres = 480, 131 + }; 132 + 133 + static struct fb_videomode real6410_lcd_type1_timing = { 134 + /* 7.0" 800x480 */ 135 + .left_margin = 8, 136 + .right_margin = 13, 137 + .upper_margin = 7, 138 + .lower_margin = 5, 139 + .hsync_len = 3, 140 + .vsync_len = 1, 141 + .xres = 800, 142 + .yres = 480, 143 + }; 144 + 145 + static struct s3c_fb_platdata real6410_lcd_pdata[] __initdata = { 146 + { 147 + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 148 + .vtiming = &real6410_lcd_type0_timing, 149 + .win[0] = &real6410_lcd_type0_fb_win, 150 + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 151 + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 152 + }, { 153 + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 154 + .vtiming = &real6410_lcd_type1_timing, 155 + .win[0] = &real6410_lcd_type1_fb_win, 156 + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 157 + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 158 + }, 159 + { }, 144 160 }; 145 161 146 162 static struct mtd_partition real6410_nand_part[] = { ··· 269 253 "screen type already set\n", f); 270 254 } else { 271 255 int li = f - '0'; 272 - if (li >= ARRAY_SIZE(real6410_fb_win)) 256 + if (li >= ARRAY_SIZE(real6410_lcd_pdata)) 273 257 printk(KERN_INFO "REAL6410: '%c' out " 274 258 "of range LCD mode\n", f); 275 259 else { ··· 293 277 /* Parse the feature string */ 294 278 real6410_parse_features(&features, real6410_features_str); 295 279 296 - real6410_lcd_pdata.win[0] = &real6410_fb_win[features.lcd_index]; 297 - 298 280 printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n", 299 - real6410_lcd_pdata.win[0]->win_mode.xres, 300 - real6410_lcd_pdata.win[0]->win_mode.yres); 281 + real6410_lcd_pdata[features.lcd_index].win[0]->xres, 282 + real6410_lcd_pdata[features.lcd_index].win[0]->yres); 301 283 302 - s3c_fb_set_platdata(&real6410_lcd_pdata); 284 + s3c_fb_set_platdata(&real6410_lcd_pdata[features.lcd_index]); 303 285 s3c_nand_set_platdata(&real6410_nand_info); 304 286 s3c24xx_ts_set_platdata(NULL); 305 287
+15 -11
arch/arm/mach-s3c64xx/mach-smartq5.c
··· 108 108 }; 109 109 110 110 static struct s3c_fb_pd_win smartq5_fb_win0 = { 111 - .win_mode = { 112 - .left_margin = 216, 113 - .right_margin = 40, 114 - .upper_margin = 35, 115 - .lower_margin = 10, 116 - .hsync_len = 1, 117 - .vsync_len = 1, 118 - .xres = 800, 119 - .yres = 480, 120 - .refresh = 80, 121 - }, 122 111 .max_bpp = 32, 123 112 .default_bpp = 16, 113 + .xres = 800, 114 + .yres = 480, 115 + }; 116 + 117 + static struct fb_videomode smartq5_lcd_timing = { 118 + .left_margin = 216, 119 + .right_margin = 40, 120 + .upper_margin = 35, 121 + .lower_margin = 10, 122 + .hsync_len = 1, 123 + .vsync_len = 1, 124 + .xres = 800, 125 + .yres = 480, 126 + .refresh = 80, 124 127 }; 125 128 126 129 static struct s3c_fb_platdata smartq5_lcd_pdata __initdata = { 127 130 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 131 + .vtiming = &smartq5_lcd_timing, 128 132 .win[0] = &smartq5_fb_win0, 129 133 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 130 134 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC |
+15 -11
arch/arm/mach-s3c64xx/mach-smartq7.c
··· 124 124 }; 125 125 126 126 static struct s3c_fb_pd_win smartq7_fb_win0 = { 127 - .win_mode = { 128 - .left_margin = 3, 129 - .right_margin = 5, 130 - .upper_margin = 1, 131 - .lower_margin = 20, 132 - .hsync_len = 10, 133 - .vsync_len = 3, 134 - .xres = 800, 135 - .yres = 480, 136 - .refresh = 80, 137 - }, 138 127 .max_bpp = 32, 139 128 .default_bpp = 16, 129 + .xres = 800, 130 + .yres = 480, 131 + }; 132 + 133 + static struct fb_videomode smartq7_lcd_timing = { 134 + .left_margin = 3, 135 + .right_margin = 5, 136 + .upper_margin = 1, 137 + .lower_margin = 20, 138 + .hsync_len = 10, 139 + .vsync_len = 3, 140 + .xres = 800, 141 + .yres = 480, 142 + .refresh = 80, 140 143 }; 141 144 142 145 static struct s3c_fb_platdata smartq7_lcd_pdata __initdata = { 143 146 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 147 + .vtiming = &smartq7_lcd_timing, 144 148 .win[0] = &smartq7_fb_win0, 145 149 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 146 150 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC |
+14 -11
arch/arm/mach-s3c64xx/mach-smdk6410.c
··· 146 146 }; 147 147 148 148 static struct s3c_fb_pd_win smdk6410_fb_win0 = { 149 - /* this is to ensure we use win0 */ 150 - .win_mode = { 151 - .left_margin = 8, 152 - .right_margin = 13, 153 - .upper_margin = 7, 154 - .lower_margin = 5, 155 - .hsync_len = 3, 156 - .vsync_len = 1, 157 - .xres = 800, 158 - .yres = 480, 159 - }, 160 149 .max_bpp = 32, 161 150 .default_bpp = 16, 151 + .xres = 800, 152 + .yres = 480, 162 153 .virtual_y = 480 * 2, 163 154 .virtual_x = 800, 155 + }; 156 + 157 + static struct fb_videomode smdk6410_lcd_timing = { 158 + .left_margin = 8, 159 + .right_margin = 13, 160 + .upper_margin = 7, 161 + .lower_margin = 5, 162 + .hsync_len = 3, 163 + .vsync_len = 1, 164 + .xres = 800, 165 + .yres = 480, 164 166 }; 165 167 166 168 /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ 167 169 static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = { 168 170 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 171 + .vtiming = &smdk6410_lcd_timing, 169 172 .win[0] = &smdk6410_fb_win0, 170 173 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 171 174 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+14 -10
arch/arm/mach-s5p64x0/mach-smdk6440.c
··· 103 103 104 104 /* Frame Buffer */ 105 105 static struct s3c_fb_pd_win smdk6440_fb_win0 = { 106 - .win_mode = { 107 - .left_margin = 8, 108 - .right_margin = 13, 109 - .upper_margin = 7, 110 - .lower_margin = 5, 111 - .hsync_len = 3, 112 - .vsync_len = 1, 113 - .xres = 800, 114 - .yres = 480, 115 - }, 116 106 .max_bpp = 32, 117 107 .default_bpp = 24, 108 + .xres = 800, 109 + .yres = 480, 110 + }; 111 + 112 + static struct fb_videomode smdk6440_lcd_timing = { 113 + .left_margin = 8, 114 + .right_margin = 13, 115 + .upper_margin = 7, 116 + .lower_margin = 5, 117 + .hsync_len = 3, 118 + .vsync_len = 1, 119 + .xres = 800, 120 + .yres = 480, 118 121 }; 119 122 120 123 static struct s3c_fb_platdata smdk6440_lcd_pdata __initdata = { 121 124 .win[0] = &smdk6440_fb_win0, 125 + .vtiming = &smdk6440_lcd_timing, 122 126 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 123 127 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 124 128 .setup_gpio = s5p64x0_fb_gpio_setup_24bpp,
+14 -10
arch/arm/mach-s5p64x0/mach-smdk6450.c
··· 121 121 122 122 /* Frame Buffer */ 123 123 static struct s3c_fb_pd_win smdk6450_fb_win0 = { 124 - .win_mode = { 125 - .left_margin = 8, 126 - .right_margin = 13, 127 - .upper_margin = 7, 128 - .lower_margin = 5, 129 - .hsync_len = 3, 130 - .vsync_len = 1, 131 - .xres = 800, 132 - .yres = 480, 133 - }, 134 124 .max_bpp = 32, 135 125 .default_bpp = 24, 126 + .xres = 800, 127 + .yres = 480, 128 + }; 129 + 130 + static struct fb_videomode smdk6450_lcd_timing = { 131 + .left_margin = 8, 132 + .right_margin = 13, 133 + .upper_margin = 7, 134 + .lower_margin = 5, 135 + .hsync_len = 3, 136 + .vsync_len = 1, 137 + .xres = 800, 138 + .yres = 480, 136 139 }; 137 140 138 141 static struct s3c_fb_platdata smdk6450_lcd_pdata __initdata = { 139 142 .win[0] = &smdk6450_fb_win0, 143 + .vtiming = &smdk6450_lcd_timing, 140 144 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 141 145 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 142 146 .setup_gpio = s5p64x0_fb_gpio_setup_24bpp,
+15 -12
arch/arm/mach-s5pc100/mach-smdkc100.c
··· 136 136 137 137 /* Frame Buffer */ 138 138 static struct s3c_fb_pd_win smdkc100_fb_win0 = { 139 - /* this is to ensure we use win0 */ 140 - .win_mode = { 141 - .left_margin = 8, 142 - .right_margin = 13, 143 - .upper_margin = 7, 144 - .lower_margin = 5, 145 - .hsync_len = 3, 146 - .vsync_len = 1, 147 - .xres = 800, 148 - .yres = 480, 149 - .refresh = 80, 150 - }, 151 139 .max_bpp = 32, 152 140 .default_bpp = 16, 141 + .xres = 800, 142 + .yres = 480, 143 + }; 144 + 145 + static struct fb_videomode smdkc100_lcd_timing = { 146 + .left_margin = 8, 147 + .right_margin = 13, 148 + .upper_margin = 7, 149 + .lower_margin = 5, 150 + .hsync_len = 3, 151 + .vsync_len = 1, 152 + .xres = 800, 153 + .yres = 480, 154 + .refresh = 80, 153 155 }; 154 156 155 157 static struct s3c_fb_platdata smdkc100_lcd_pdata __initdata = { 156 158 .win[0] = &smdkc100_fb_win0, 159 + .vtiming = &smdkc100_lcd_timing, 157 160 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 158 161 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 159 162 .setup_gpio = s5pc100_fb_gpio_setup_24bpp,
+16 -20
arch/arm/mach-s5pv210/mach-aquila.c
··· 96 96 97 97 /* Frame Buffer */ 98 98 static struct s3c_fb_pd_win aquila_fb_win0 = { 99 - .win_mode = { 100 - .left_margin = 16, 101 - .right_margin = 16, 102 - .upper_margin = 3, 103 - .lower_margin = 28, 104 - .hsync_len = 2, 105 - .vsync_len = 2, 106 - .xres = 480, 107 - .yres = 800, 108 - }, 109 99 .max_bpp = 32, 110 100 .default_bpp = 16, 101 + .xres = 480, 102 + .yres = 800, 111 103 }; 112 104 113 105 static struct s3c_fb_pd_win aquila_fb_win1 = { 114 - .win_mode = { 115 - .left_margin = 16, 116 - .right_margin = 16, 117 - .upper_margin = 3, 118 - .lower_margin = 28, 119 - .hsync_len = 2, 120 - .vsync_len = 2, 121 - .xres = 480, 122 - .yres = 800, 123 - }, 124 106 .max_bpp = 32, 125 107 .default_bpp = 16, 108 + .xres = 480, 109 + .yres = 800, 110 + }; 111 + 112 + static struct fb_videomode aquila_lcd_timing = { 113 + .left_margin = 16, 114 + .right_margin = 16, 115 + .upper_margin = 3, 116 + .lower_margin = 28, 117 + .hsync_len = 2, 118 + .vsync_len = 2, 119 + .xres = 480, 120 + .yres = 800, 126 121 }; 127 122 128 123 static struct s3c_fb_platdata aquila_lcd_pdata __initdata = { 129 124 .win[0] = &aquila_fb_win0, 130 125 .win[1] = &aquila_fb_win1, 126 + .vtiming = &aquila_lcd_timing, 131 127 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 132 128 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC | 133 129 VIDCON1_INV_VCLK | VIDCON1_INV_VDEN,
+15 -11
arch/arm/mach-s5pv210/mach-goni.c
··· 107 107 108 108 /* Frame Buffer */ 109 109 static struct s3c_fb_pd_win goni_fb_win0 = { 110 - .win_mode = { 111 - .left_margin = 16, 112 - .right_margin = 16, 113 - .upper_margin = 2, 114 - .lower_margin = 28, 115 - .hsync_len = 2, 116 - .vsync_len = 1, 117 - .xres = 480, 118 - .yres = 800, 119 - .refresh = 55, 120 - }, 121 110 .max_bpp = 32, 122 111 .default_bpp = 16, 112 + .xres = 480, 113 + .yres = 800, 123 114 .virtual_x = 480, 124 115 .virtual_y = 2 * 800, 125 116 }; 126 117 118 + static struct fb_videomode goni_lcd_timing = { 119 + .left_margin = 16, 120 + .right_margin = 16, 121 + .upper_margin = 2, 122 + .lower_margin = 28, 123 + .hsync_len = 2, 124 + .vsync_len = 1, 125 + .xres = 480, 126 + .yres = 800, 127 + .refresh = 55, 128 + }; 129 + 127 130 static struct s3c_fb_platdata goni_lcd_pdata __initdata = { 128 131 .win[0] = &goni_fb_win0, 132 + .vtiming = &goni_lcd_timing, 129 133 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB | 130 134 VIDCON0_CLKSEL_LCD, 131 135 .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
+14 -10
arch/arm/mach-s5pv210/mach-smdkv210.c
··· 178 178 }; 179 179 180 180 static struct s3c_fb_pd_win smdkv210_fb_win0 = { 181 - .win_mode = { 182 - .left_margin = 13, 183 - .right_margin = 8, 184 - .upper_margin = 7, 185 - .lower_margin = 5, 186 - .hsync_len = 3, 187 - .vsync_len = 1, 188 - .xres = 800, 189 - .yres = 480, 190 - }, 191 181 .max_bpp = 32, 192 182 .default_bpp = 24, 183 + .xres = 800, 184 + .yres = 480, 185 + }; 186 + 187 + static struct fb_videomode smdkv210_lcd_timing = { 188 + .left_margin = 13, 189 + .right_margin = 8, 190 + .upper_margin = 7, 191 + .lower_margin = 5, 192 + .hsync_len = 3, 193 + .vsync_len = 1, 194 + .xres = 800, 195 + .yres = 480, 193 196 }; 194 197 195 198 static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = { 196 199 .win[0] = &smdkv210_fb_win0, 200 + .vtiming = &smdkv210_lcd_timing, 197 201 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 198 202 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 199 203 .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
+6 -5
arch/arm/plat-samsung/include/plat/fb.h
··· 24 24 25 25 /** 26 26 * struct s3c_fb_pd_win - per window setup data 27 - * @win_mode: The display parameters to initialise (not for window 0) 27 + * @xres : The window X size. 28 + * @yres : The window Y size. 28 29 * @virtual_x: The virtual X size. 29 30 * @virtual_y: The virtual Y size. 30 31 */ 31 32 struct s3c_fb_pd_win { 32 - struct fb_videomode win_mode; 33 - 34 33 unsigned short default_bpp; 35 34 unsigned short max_bpp; 35 + unsigned short xres; 36 + unsigned short yres; 36 37 unsigned short virtual_x; 37 38 unsigned short virtual_y; 38 39 }; ··· 46 45 * @default_win: default window layer number to be used for UI layer. 47 46 * @vidcon0: The base vidcon0 values to control the panel data format. 48 47 * @vidcon1: The base vidcon1 values to control the panel data output. 48 + * @vtiming: Video timing when connected to a RGB type panel. 49 49 * @win: The setup data for each hardware window, or NULL for unused. 50 50 * @display_mode: The LCD output display mode. 51 51 * ··· 60 58 void (*setup_gpio)(void); 61 59 62 60 struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN]; 63 - 64 - u32 default_win; 61 + struct fb_videomode *vtiming; 65 62 66 63 u32 vidcon0; 67 64 u32 vidcon1;
+34 -1
drivers/video/Kconfig
··· 2210 2210 2211 2211 config FB_COBALT 2212 2212 tristate "Cobalt server LCD frame buffer support" 2213 - depends on FB && MIPS_COBALT 2213 + depends on FB && (MIPS_COBALT || MIPS_SEAD3) 2214 2214 2215 2215 config FB_SH7760 2216 2216 bool "SH7760/SH7763/SH7720/SH7721 LCDC support" ··· 2381 2381 controller. The release name for this device was Epson S1D13521 2382 2382 and could also have been called by other names when coupled with 2383 2383 a bridge adapter. 2384 + 2385 + config FB_AUO_K190X 2386 + tristate "AUO-K190X EPD controller support" 2387 + depends on FB 2388 + select FB_SYS_FILLRECT 2389 + select FB_SYS_COPYAREA 2390 + select FB_SYS_IMAGEBLIT 2391 + select FB_SYS_FOPS 2392 + select FB_DEFERRED_IO 2393 + help 2394 + Provides support for epaper controllers from the K190X series 2395 + of AUO. These controllers can be used to drive epaper displays 2396 + from Sipix. 2397 + 2398 + This option enables the common support, shared by the individual 2399 + controller drivers. You will also have to enable the driver 2400 + for the controller type used in your device. 2401 + 2402 + config FB_AUO_K1900 2403 + tristate "AUO-K1900 EPD controller support" 2404 + depends on FB && FB_AUO_K190X 2405 + help 2406 + This driver implements support for the AUO K1900 epd-controller. 2407 + This controller can drive Sipix epaper displays but can only do 2408 + serial updates, reducing the number of possible frames per second. 2409 + 2410 + config FB_AUO_K1901 2411 + tristate "AUO-K1901 EPD controller support" 2412 + depends on FB && FB_AUO_K190X 2413 + help 2414 + This driver implements support for the AUO K1901 epd-controller. 2415 + This controller can drive Sipix epaper displays and supports 2416 + concurrent updates, making higher frames per second possible. 2384 2417 2385 2418 config FB_JZ4740 2386 2419 tristate "JZ4740 LCD framebuffer support"
+3
drivers/video/Makefile
··· 118 118 obj-$(CONFIG_FB_MAXINE) += maxinefb.o 119 119 obj-$(CONFIG_FB_METRONOME) += metronomefb.o 120 120 obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o 121 + obj-$(CONFIG_FB_AUO_K190X) += auo_k190x.o 122 + obj-$(CONFIG_FB_AUO_K1900) += auo_k1900fb.o 123 + obj-$(CONFIG_FB_AUO_K1901) += auo_k1901fb.o 121 124 obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o 122 125 obj-$(CONFIG_FB_SH7760) += sh7760fb.o 123 126 obj-$(CONFIG_FB_IMX) += imxfb.o
+198
drivers/video/auo_k1900fb.c
··· 1 + /* 2 + * auok190xfb.c -- FB driver for AUO-K1900 controllers 3 + * 4 + * Copyright (C) 2011, 2012 Heiko Stuebner <heiko@sntech.de> 5 + * 6 + * based on broadsheetfb.c 7 + * 8 + * Copyright (C) 2008, Jaya Kumar 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + * 14 + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. 15 + * 16 + * This driver is written to be used with the AUO-K1900 display controller. 17 + * 18 + * It is intended to be architecture independent. A board specific driver 19 + * must be used to perform all the physical IO interactions. 20 + * 21 + * The controller supports different update modes: 22 + * mode0+1 16 step gray (4bit) 23 + * mode2 4 step gray (2bit) - FIXME: add strange refresh 24 + * mode3 2 step gray (1bit) - FIXME: add strange refresh 25 + * mode4 handwriting mode (strange behaviour) 26 + * mode5 automatic selection of update mode 27 + */ 28 + 29 + #include <linux/module.h> 30 + #include <linux/kernel.h> 31 + #include <linux/errno.h> 32 + #include <linux/string.h> 33 + #include <linux/mm.h> 34 + #include <linux/slab.h> 35 + #include <linux/delay.h> 36 + #include <linux/interrupt.h> 37 + #include <linux/fb.h> 38 + #include <linux/init.h> 39 + #include <linux/platform_device.h> 40 + #include <linux/list.h> 41 + #include <linux/firmware.h> 42 + #include <linux/gpio.h> 43 + #include <linux/pm_runtime.h> 44 + 45 + #include <video/auo_k190xfb.h> 46 + 47 + #include "auo_k190x.h" 48 + 49 + /* 50 + * AUO-K1900 specific commands 51 + */ 52 + 53 + #define AUOK1900_CMD_PARTIALDISP 0x1001 54 + #define AUOK1900_CMD_ROTATION 0x1006 55 + #define AUOK1900_CMD_LUT_STOP 0x1009 56 + 57 + #define AUOK1900_INIT_TEMP_AVERAGE (1 << 13) 58 + #define AUOK1900_INIT_ROTATE(_x) ((_x & 0x3) << 10) 59 + #define AUOK1900_INIT_RESOLUTION(_res) ((_res & 0x7) << 2) 60 + 61 + static void auok1900_init(struct auok190xfb_par *par) 62 + { 63 + struct auok190x_board *board = par->board; 64 + u16 init_param = 0; 65 + 66 + init_param |= AUOK1900_INIT_TEMP_AVERAGE; 67 + init_param |= AUOK1900_INIT_ROTATE(par->rotation); 68 + init_param |= AUOK190X_INIT_INVERSE_WHITE; 69 + init_param |= AUOK190X_INIT_FORMAT0; 70 + init_param |= AUOK1900_INIT_RESOLUTION(par->resolution); 71 + init_param |= AUOK190X_INIT_SHIFT_RIGHT; 72 + 73 + auok190x_send_cmdargs(par, AUOK190X_CMD_INIT, 1, &init_param); 74 + 75 + /* let the controller finish */ 76 + board->wait_for_rdy(par); 77 + } 78 + 79 + static void auok1900_update_region(struct auok190xfb_par *par, int mode, 80 + u16 y1, u16 y2) 81 + { 82 + struct device *dev = par->info->device; 83 + unsigned char *buf = (unsigned char *)par->info->screen_base; 84 + int xres = par->info->var.xres; 85 + u16 args[4]; 86 + 87 + pm_runtime_get_sync(dev); 88 + 89 + mutex_lock(&(par->io_lock)); 90 + 91 + /* y1 and y2 must be a multiple of 2 so drop the lowest bit */ 92 + y1 &= 0xfffe; 93 + y2 &= 0xfffe; 94 + 95 + dev_dbg(dev, "update (x,y,w,h,mode)=(%d,%d,%d,%d,%d)\n", 96 + 1, y1+1, xres, y2-y1, mode); 97 + 98 + /* to FIX handle different partial update modes */ 99 + args[0] = mode | 1; 100 + args[1] = y1 + 1; 101 + args[2] = xres; 102 + args[3] = y2 - y1; 103 + buf += y1 * xres; 104 + auok190x_send_cmdargs_pixels(par, AUOK1900_CMD_PARTIALDISP, 4, args, 105 + ((y2 - y1) * xres)/2, (u16 *) buf); 106 + auok190x_send_command(par, AUOK190X_CMD_DATA_STOP); 107 + 108 + par->update_cnt++; 109 + 110 + mutex_unlock(&(par->io_lock)); 111 + 112 + pm_runtime_mark_last_busy(dev); 113 + pm_runtime_put_autosuspend(dev); 114 + } 115 + 116 + static void auok1900fb_dpy_update_pages(struct auok190xfb_par *par, 117 + u16 y1, u16 y2) 118 + { 119 + int mode; 120 + 121 + if (par->update_mode < 0) { 122 + mode = AUOK190X_UPDATE_MODE(1); 123 + par->last_mode = -1; 124 + } else { 125 + mode = AUOK190X_UPDATE_MODE(par->update_mode); 126 + par->last_mode = par->update_mode; 127 + } 128 + 129 + if (par->flash) 130 + mode |= AUOK190X_UPDATE_NONFLASH; 131 + 132 + auok1900_update_region(par, mode, y1, y2); 133 + } 134 + 135 + static void auok1900fb_dpy_update(struct auok190xfb_par *par) 136 + { 137 + int mode; 138 + 139 + if (par->update_mode < 0) { 140 + mode = AUOK190X_UPDATE_MODE(0); 141 + par->last_mode = -1; 142 + } else { 143 + mode = AUOK190X_UPDATE_MODE(par->update_mode); 144 + par->last_mode = par->update_mode; 145 + } 146 + 147 + if (par->flash) 148 + mode |= AUOK190X_UPDATE_NONFLASH; 149 + 150 + auok1900_update_region(par, mode, 0, par->info->var.yres); 151 + par->update_cnt = 0; 152 + } 153 + 154 + static bool auok1900fb_need_refresh(struct auok190xfb_par *par) 155 + { 156 + return (par->update_cnt > 10); 157 + } 158 + 159 + static int __devinit auok1900fb_probe(struct platform_device *pdev) 160 + { 161 + struct auok190x_init_data init; 162 + struct auok190x_board *board; 163 + 164 + /* pick up board specific routines */ 165 + board = pdev->dev.platform_data; 166 + if (!board) 167 + return -EINVAL; 168 + 169 + /* fill temporary init struct for common init */ 170 + init.id = "auo_k1900fb"; 171 + init.board = board; 172 + init.update_partial = auok1900fb_dpy_update_pages; 173 + init.update_all = auok1900fb_dpy_update; 174 + init.need_refresh = auok1900fb_need_refresh; 175 + init.init = auok1900_init; 176 + 177 + return auok190x_common_probe(pdev, &init); 178 + } 179 + 180 + static int __devexit auok1900fb_remove(struct platform_device *pdev) 181 + { 182 + return auok190x_common_remove(pdev); 183 + } 184 + 185 + static struct platform_driver auok1900fb_driver = { 186 + .probe = auok1900fb_probe, 187 + .remove = __devexit_p(auok1900fb_remove), 188 + .driver = { 189 + .owner = THIS_MODULE, 190 + .name = "auo_k1900fb", 191 + .pm = &auok190x_pm, 192 + }, 193 + }; 194 + module_platform_driver(auok1900fb_driver); 195 + 196 + MODULE_DESCRIPTION("framebuffer driver for the AUO-K1900 EPD controller"); 197 + MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 198 + MODULE_LICENSE("GPL");
+251
drivers/video/auo_k1901fb.c
··· 1 + /* 2 + * auok190xfb.c -- FB driver for AUO-K1901 controllers 3 + * 4 + * Copyright (C) 2011, 2012 Heiko Stuebner <heiko@sntech.de> 5 + * 6 + * based on broadsheetfb.c 7 + * 8 + * Copyright (C) 2008, Jaya Kumar 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + * 14 + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. 15 + * 16 + * This driver is written to be used with the AUO-K1901 display controller. 17 + * 18 + * It is intended to be architecture independent. A board specific driver 19 + * must be used to perform all the physical IO interactions. 20 + * 21 + * The controller supports different update modes: 22 + * mode0+1 16 step gray (4bit) 23 + * mode2+3 4 step gray (2bit) 24 + * mode4+5 2 step gray (1bit) 25 + * - mode4 is described as "without LUT" 26 + * mode7 automatic selection of update mode 27 + * 28 + * The most interesting difference to the K1900 is the ability to do screen 29 + * updates in an asynchronous fashion. Where the K1900 needs to wait for the 30 + * current update to complete, the K1901 can process later updates already. 31 + */ 32 + 33 + #include <linux/module.h> 34 + #include <linux/kernel.h> 35 + #include <linux/errno.h> 36 + #include <linux/string.h> 37 + #include <linux/mm.h> 38 + #include <linux/slab.h> 39 + #include <linux/delay.h> 40 + #include <linux/interrupt.h> 41 + #include <linux/fb.h> 42 + #include <linux/init.h> 43 + #include <linux/platform_device.h> 44 + #include <linux/list.h> 45 + #include <linux/firmware.h> 46 + #include <linux/gpio.h> 47 + #include <linux/pm_runtime.h> 48 + 49 + #include <video/auo_k190xfb.h> 50 + 51 + #include "auo_k190x.h" 52 + 53 + /* 54 + * AUO-K1901 specific commands 55 + */ 56 + 57 + #define AUOK1901_CMD_LUT_INTERFACE 0x0005 58 + #define AUOK1901_CMD_DMA_START 0x1001 59 + #define AUOK1901_CMD_CURSOR_START 0x1007 60 + #define AUOK1901_CMD_CURSOR_STOP AUOK190X_CMD_DATA_STOP 61 + #define AUOK1901_CMD_DDMA_START 0x1009 62 + 63 + #define AUOK1901_INIT_GATE_PULSE_LOW (0 << 14) 64 + #define AUOK1901_INIT_GATE_PULSE_HIGH (1 << 14) 65 + #define AUOK1901_INIT_SINGLE_GATE (0 << 13) 66 + #define AUOK1901_INIT_DOUBLE_GATE (1 << 13) 67 + 68 + /* Bits to pixels 69 + * Mode 15-12 11-8 7-4 3-0 70 + * format2 2 T 1 T 71 + * format3 1 T 2 T 72 + * format4 T 2 T 1 73 + * format5 T 1 T 2 74 + * 75 + * halftone modes: 76 + * format6 2 2 1 1 77 + * format7 1 1 2 2 78 + */ 79 + #define AUOK1901_INIT_FORMAT2 (1 << 7) 80 + #define AUOK1901_INIT_FORMAT3 ((1 << 7) | (1 << 6)) 81 + #define AUOK1901_INIT_FORMAT4 (1 << 8) 82 + #define AUOK1901_INIT_FORMAT5 ((1 << 8) | (1 << 6)) 83 + #define AUOK1901_INIT_FORMAT6 ((1 << 8) | (1 << 7)) 84 + #define AUOK1901_INIT_FORMAT7 ((1 << 8) | (1 << 7) | (1 << 6)) 85 + 86 + /* res[4] to bit 10 87 + * res[3-0] to bits 5-2 88 + */ 89 + #define AUOK1901_INIT_RESOLUTION(_res) (((_res & (1 << 4)) << 6) \ 90 + | ((_res & 0xf) << 2)) 91 + 92 + /* 93 + * portrait / landscape orientation in AUOK1901_CMD_DMA_START 94 + */ 95 + #define AUOK1901_DMA_ROTATE90(_rot) ((_rot & 1) << 13) 96 + 97 + /* 98 + * equivalent to 1 << 11, needs the ~ to have same rotation like K1900 99 + */ 100 + #define AUOK1901_DDMA_ROTATE180(_rot) ((~_rot & 2) << 10) 101 + 102 + static void auok1901_init(struct auok190xfb_par *par) 103 + { 104 + struct auok190x_board *board = par->board; 105 + u16 init_param = 0; 106 + 107 + init_param |= AUOK190X_INIT_INVERSE_WHITE; 108 + init_param |= AUOK190X_INIT_FORMAT0; 109 + init_param |= AUOK1901_INIT_RESOLUTION(par->resolution); 110 + init_param |= AUOK190X_INIT_SHIFT_LEFT; 111 + 112 + auok190x_send_cmdargs(par, AUOK190X_CMD_INIT, 1, &init_param); 113 + 114 + /* let the controller finish */ 115 + board->wait_for_rdy(par); 116 + } 117 + 118 + static void auok1901_update_region(struct auok190xfb_par *par, int mode, 119 + u16 y1, u16 y2) 120 + { 121 + struct device *dev = par->info->device; 122 + unsigned char *buf = (unsigned char *)par->info->screen_base; 123 + int xres = par->info->var.xres; 124 + u16 args[5]; 125 + 126 + pm_runtime_get_sync(dev); 127 + 128 + mutex_lock(&(par->io_lock)); 129 + 130 + /* y1 and y2 must be a multiple of 2 so drop the lowest bit */ 131 + y1 &= 0xfffe; 132 + y2 &= 0xfffe; 133 + 134 + dev_dbg(dev, "update (x,y,w,h,mode)=(%d,%d,%d,%d,%d)\n", 135 + 1, y1+1, xres, y2-y1, mode); 136 + 137 + /* K1901: first transfer the region data */ 138 + args[0] = AUOK1901_DMA_ROTATE90(par->rotation) | 1; 139 + args[1] = y1 + 1; 140 + args[2] = xres; 141 + args[3] = y2 - y1; 142 + buf += y1 * xres; 143 + auok190x_send_cmdargs_pixels_nowait(par, AUOK1901_CMD_DMA_START, 4, 144 + args, ((y2 - y1) * xres)/2, 145 + (u16 *) buf); 146 + auok190x_send_command_nowait(par, AUOK190X_CMD_DATA_STOP); 147 + 148 + /* K1901: second tell the controller to update the region with mode */ 149 + args[0] = mode | AUOK1901_DDMA_ROTATE180(par->rotation); 150 + args[1] = 1; 151 + args[2] = y1 + 1; 152 + args[3] = xres; 153 + args[4] = y2 - y1; 154 + auok190x_send_cmdargs_nowait(par, AUOK1901_CMD_DDMA_START, 5, args); 155 + 156 + par->update_cnt++; 157 + 158 + mutex_unlock(&(par->io_lock)); 159 + 160 + pm_runtime_mark_last_busy(dev); 161 + pm_runtime_put_autosuspend(dev); 162 + } 163 + 164 + static void auok1901fb_dpy_update_pages(struct auok190xfb_par *par, 165 + u16 y1, u16 y2) 166 + { 167 + int mode; 168 + 169 + if (par->update_mode < 0) { 170 + mode = AUOK190X_UPDATE_MODE(1); 171 + par->last_mode = -1; 172 + } else { 173 + mode = AUOK190X_UPDATE_MODE(par->update_mode); 174 + par->last_mode = par->update_mode; 175 + } 176 + 177 + if (par->flash) 178 + mode |= AUOK190X_UPDATE_NONFLASH; 179 + 180 + auok1901_update_region(par, mode, y1, y2); 181 + } 182 + 183 + static void auok1901fb_dpy_update(struct auok190xfb_par *par) 184 + { 185 + int mode; 186 + 187 + /* When doing full updates, wait for the controller to be ready 188 + * This will hopefully catch some hangs of the K1901 189 + */ 190 + par->board->wait_for_rdy(par); 191 + 192 + if (par->update_mode < 0) { 193 + mode = AUOK190X_UPDATE_MODE(0); 194 + par->last_mode = -1; 195 + } else { 196 + mode = AUOK190X_UPDATE_MODE(par->update_mode); 197 + par->last_mode = par->update_mode; 198 + } 199 + 200 + if (par->flash) 201 + mode |= AUOK190X_UPDATE_NONFLASH; 202 + 203 + auok1901_update_region(par, mode, 0, par->info->var.yres); 204 + par->update_cnt = 0; 205 + } 206 + 207 + static bool auok1901fb_need_refresh(struct auok190xfb_par *par) 208 + { 209 + return (par->update_cnt > 10); 210 + } 211 + 212 + static int __devinit auok1901fb_probe(struct platform_device *pdev) 213 + { 214 + struct auok190x_init_data init; 215 + struct auok190x_board *board; 216 + 217 + /* pick up board specific routines */ 218 + board = pdev->dev.platform_data; 219 + if (!board) 220 + return -EINVAL; 221 + 222 + /* fill temporary init struct for common init */ 223 + init.id = "auo_k1901fb"; 224 + init.board = board; 225 + init.update_partial = auok1901fb_dpy_update_pages; 226 + init.update_all = auok1901fb_dpy_update; 227 + init.need_refresh = auok1901fb_need_refresh; 228 + init.init = auok1901_init; 229 + 230 + return auok190x_common_probe(pdev, &init); 231 + } 232 + 233 + static int __devexit auok1901fb_remove(struct platform_device *pdev) 234 + { 235 + return auok190x_common_remove(pdev); 236 + } 237 + 238 + static struct platform_driver auok1901fb_driver = { 239 + .probe = auok1901fb_probe, 240 + .remove = __devexit_p(auok1901fb_remove), 241 + .driver = { 242 + .owner = THIS_MODULE, 243 + .name = "auo_k1901fb", 244 + .pm = &auok190x_pm, 245 + }, 246 + }; 247 + module_platform_driver(auok1901fb_driver); 248 + 249 + MODULE_DESCRIPTION("framebuffer driver for the AUO-K1901 EPD controller"); 250 + MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 251 + MODULE_LICENSE("GPL");
+1046
drivers/video/auo_k190x.c
··· 1 + /* 2 + * Common code for AUO-K190X framebuffer drivers 3 + * 4 + * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/kernel.h> 13 + #include <linux/gpio.h> 14 + #include <linux/pm_runtime.h> 15 + #include <linux/fb.h> 16 + #include <linux/delay.h> 17 + #include <linux/uaccess.h> 18 + #include <linux/vmalloc.h> 19 + #include <linux/regulator/consumer.h> 20 + 21 + #include <video/auo_k190xfb.h> 22 + 23 + #include "auo_k190x.h" 24 + 25 + struct panel_info { 26 + int w; 27 + int h; 28 + }; 29 + 30 + /* table of panel specific parameters to be indexed into by the board drivers */ 31 + static struct panel_info panel_table[] = { 32 + /* standard 6" */ 33 + [AUOK190X_RESOLUTION_800_600] = { 34 + .w = 800, 35 + .h = 600, 36 + }, 37 + /* standard 9" */ 38 + [AUOK190X_RESOLUTION_1024_768] = { 39 + .w = 1024, 40 + .h = 768, 41 + }, 42 + }; 43 + 44 + /* 45 + * private I80 interface to the board driver 46 + */ 47 + 48 + static void auok190x_issue_data(struct auok190xfb_par *par, u16 data) 49 + { 50 + par->board->set_ctl(par, AUOK190X_I80_WR, 0); 51 + par->board->set_hdb(par, data); 52 + par->board->set_ctl(par, AUOK190X_I80_WR, 1); 53 + } 54 + 55 + static void auok190x_issue_cmd(struct auok190xfb_par *par, u16 data) 56 + { 57 + par->board->set_ctl(par, AUOK190X_I80_DC, 0); 58 + auok190x_issue_data(par, data); 59 + par->board->set_ctl(par, AUOK190X_I80_DC, 1); 60 + } 61 + 62 + static int auok190x_issue_pixels(struct auok190xfb_par *par, int size, 63 + u16 *data) 64 + { 65 + struct device *dev = par->info->device; 66 + int i; 67 + u16 tmp; 68 + 69 + if (size & 3) { 70 + dev_err(dev, "issue_pixels: size %d must be a multiple of 4\n", 71 + size); 72 + return -EINVAL; 73 + } 74 + 75 + for (i = 0; i < (size >> 1); i++) { 76 + par->board->set_ctl(par, AUOK190X_I80_WR, 0); 77 + 78 + /* simple reduction of 8bit staticgray to 4bit gray 79 + * combines 4 * 4bit pixel values into a 16bit value 80 + */ 81 + tmp = (data[2*i] & 0xF0) >> 4; 82 + tmp |= (data[2*i] & 0xF000) >> 8; 83 + tmp |= (data[2*i+1] & 0xF0) << 4; 84 + tmp |= (data[2*i+1] & 0xF000); 85 + 86 + par->board->set_hdb(par, tmp); 87 + par->board->set_ctl(par, AUOK190X_I80_WR, 1); 88 + } 89 + 90 + return 0; 91 + } 92 + 93 + static u16 auok190x_read_data(struct auok190xfb_par *par) 94 + { 95 + u16 data; 96 + 97 + par->board->set_ctl(par, AUOK190X_I80_OE, 0); 98 + data = par->board->get_hdb(par); 99 + par->board->set_ctl(par, AUOK190X_I80_OE, 1); 100 + 101 + return data; 102 + } 103 + 104 + /* 105 + * Command interface for the controller drivers 106 + */ 107 + 108 + void auok190x_send_command_nowait(struct auok190xfb_par *par, u16 data) 109 + { 110 + par->board->set_ctl(par, AUOK190X_I80_CS, 0); 111 + auok190x_issue_cmd(par, data); 112 + par->board->set_ctl(par, AUOK190X_I80_CS, 1); 113 + } 114 + EXPORT_SYMBOL_GPL(auok190x_send_command_nowait); 115 + 116 + void auok190x_send_cmdargs_nowait(struct auok190xfb_par *par, u16 cmd, 117 + int argc, u16 *argv) 118 + { 119 + int i; 120 + 121 + par->board->set_ctl(par, AUOK190X_I80_CS, 0); 122 + auok190x_issue_cmd(par, cmd); 123 + 124 + for (i = 0; i < argc; i++) 125 + auok190x_issue_data(par, argv[i]); 126 + par->board->set_ctl(par, AUOK190X_I80_CS, 1); 127 + } 128 + EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_nowait); 129 + 130 + int auok190x_send_command(struct auok190xfb_par *par, u16 data) 131 + { 132 + int ret; 133 + 134 + ret = par->board->wait_for_rdy(par); 135 + if (ret) 136 + return ret; 137 + 138 + auok190x_send_command_nowait(par, data); 139 + return 0; 140 + } 141 + EXPORT_SYMBOL_GPL(auok190x_send_command); 142 + 143 + int auok190x_send_cmdargs(struct auok190xfb_par *par, u16 cmd, 144 + int argc, u16 *argv) 145 + { 146 + int ret; 147 + 148 + ret = par->board->wait_for_rdy(par); 149 + if (ret) 150 + return ret; 151 + 152 + auok190x_send_cmdargs_nowait(par, cmd, argc, argv); 153 + return 0; 154 + } 155 + EXPORT_SYMBOL_GPL(auok190x_send_cmdargs); 156 + 157 + int auok190x_read_cmdargs(struct auok190xfb_par *par, u16 cmd, 158 + int argc, u16 *argv) 159 + { 160 + int i, ret; 161 + 162 + ret = par->board->wait_for_rdy(par); 163 + if (ret) 164 + return ret; 165 + 166 + par->board->set_ctl(par, AUOK190X_I80_CS, 0); 167 + auok190x_issue_cmd(par, cmd); 168 + 169 + for (i = 0; i < argc; i++) 170 + argv[i] = auok190x_read_data(par); 171 + par->board->set_ctl(par, AUOK190X_I80_CS, 1); 172 + 173 + return 0; 174 + } 175 + EXPORT_SYMBOL_GPL(auok190x_read_cmdargs); 176 + 177 + void auok190x_send_cmdargs_pixels_nowait(struct auok190xfb_par *par, u16 cmd, 178 + int argc, u16 *argv, int size, u16 *data) 179 + { 180 + int i; 181 + 182 + par->board->set_ctl(par, AUOK190X_I80_CS, 0); 183 + 184 + auok190x_issue_cmd(par, cmd); 185 + 186 + for (i = 0; i < argc; i++) 187 + auok190x_issue_data(par, argv[i]); 188 + 189 + auok190x_issue_pixels(par, size, data); 190 + 191 + par->board->set_ctl(par, AUOK190X_I80_CS, 1); 192 + } 193 + EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels_nowait); 194 + 195 + int auok190x_send_cmdargs_pixels(struct auok190xfb_par *par, u16 cmd, 196 + int argc, u16 *argv, int size, u16 *data) 197 + { 198 + int ret; 199 + 200 + ret = par->board->wait_for_rdy(par); 201 + if (ret) 202 + return ret; 203 + 204 + auok190x_send_cmdargs_pixels_nowait(par, cmd, argc, argv, size, data); 205 + 206 + return 0; 207 + } 208 + EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels); 209 + 210 + /* 211 + * fbdefio callbacks - common on both controllers. 212 + */ 213 + 214 + static void auok190xfb_dpy_first_io(struct fb_info *info) 215 + { 216 + /* tell runtime-pm that we wish to use the device in a short time */ 217 + pm_runtime_get(info->device); 218 + } 219 + 220 + /* this is called back from the deferred io workqueue */ 221 + static void auok190xfb_dpy_deferred_io(struct fb_info *info, 222 + struct list_head *pagelist) 223 + { 224 + struct fb_deferred_io *fbdefio = info->fbdefio; 225 + struct auok190xfb_par *par = info->par; 226 + u16 yres = info->var.yres; 227 + u16 xres = info->var.xres; 228 + u16 y1 = 0, h = 0; 229 + int prev_index = -1; 230 + struct page *cur; 231 + int h_inc; 232 + int threshold; 233 + 234 + if (!list_empty(pagelist)) 235 + /* the device resume should've been requested through first_io, 236 + * if the resume did not finish until now, wait for it. 237 + */ 238 + pm_runtime_barrier(info->device); 239 + else 240 + /* We reached this via the fsync or some other way. 241 + * In either case the first_io function did not run, 242 + * so we runtime_resume the device here synchronously. 243 + */ 244 + pm_runtime_get_sync(info->device); 245 + 246 + /* Do a full screen update every n updates to prevent 247 + * excessive darkening of the Sipix display. 248 + * If we do this, there is no need to walk the pages. 249 + */ 250 + if (par->need_refresh(par)) { 251 + par->update_all(par); 252 + goto out; 253 + } 254 + 255 + /* height increment is fixed per page */ 256 + h_inc = DIV_ROUND_UP(PAGE_SIZE , xres); 257 + 258 + /* calculate number of pages from pixel height */ 259 + threshold = par->consecutive_threshold / h_inc; 260 + if (threshold < 1) 261 + threshold = 1; 262 + 263 + /* walk the written page list and swizzle the data */ 264 + list_for_each_entry(cur, &fbdefio->pagelist, lru) { 265 + if (prev_index < 0) { 266 + /* just starting so assign first page */ 267 + y1 = (cur->index << PAGE_SHIFT) / xres; 268 + h = h_inc; 269 + } else if ((cur->index - prev_index) <= threshold) { 270 + /* page is within our threshold for single updates */ 271 + h += h_inc * (cur->index - prev_index); 272 + } else { 273 + /* page not consecutive, issue previous update first */ 274 + par->update_partial(par, y1, y1 + h); 275 + 276 + /* start over with our non consecutive page */ 277 + y1 = (cur->index << PAGE_SHIFT) / xres; 278 + h = h_inc; 279 + } 280 + prev_index = cur->index; 281 + } 282 + 283 + /* if we still have any pages to update we do so now */ 284 + if (h >= yres) 285 + /* its a full screen update, just do it */ 286 + par->update_all(par); 287 + else 288 + par->update_partial(par, y1, min((u16) (y1 + h), yres)); 289 + 290 + out: 291 + pm_runtime_mark_last_busy(info->device); 292 + pm_runtime_put_autosuspend(info->device); 293 + } 294 + 295 + /* 296 + * framebuffer operations 297 + */ 298 + 299 + /* 300 + * this is the slow path from userspace. they can seek and write to 301 + * the fb. it's inefficient to do anything less than a full screen draw 302 + */ 303 + static ssize_t auok190xfb_write(struct fb_info *info, const char __user *buf, 304 + size_t count, loff_t *ppos) 305 + { 306 + struct auok190xfb_par *par = info->par; 307 + unsigned long p = *ppos; 308 + void *dst; 309 + int err = 0; 310 + unsigned long total_size; 311 + 312 + if (info->state != FBINFO_STATE_RUNNING) 313 + return -EPERM; 314 + 315 + total_size = info->fix.smem_len; 316 + 317 + if (p > total_size) 318 + return -EFBIG; 319 + 320 + if (count > total_size) { 321 + err = -EFBIG; 322 + count = total_size; 323 + } 324 + 325 + if (count + p > total_size) { 326 + if (!err) 327 + err = -ENOSPC; 328 + 329 + count = total_size - p; 330 + } 331 + 332 + dst = (void *)(info->screen_base + p); 333 + 334 + if (copy_from_user(dst, buf, count)) 335 + err = -EFAULT; 336 + 337 + if (!err) 338 + *ppos += count; 339 + 340 + par->update_all(par); 341 + 342 + return (err) ? err : count; 343 + } 344 + 345 + static void auok190xfb_fillrect(struct fb_info *info, 346 + const struct fb_fillrect *rect) 347 + { 348 + struct auok190xfb_par *par = info->par; 349 + 350 + sys_fillrect(info, rect); 351 + 352 + par->update_all(par); 353 + } 354 + 355 + static void auok190xfb_copyarea(struct fb_info *info, 356 + const struct fb_copyarea *area) 357 + { 358 + struct auok190xfb_par *par = info->par; 359 + 360 + sys_copyarea(info, area); 361 + 362 + par->update_all(par); 363 + } 364 + 365 + static void auok190xfb_imageblit(struct fb_info *info, 366 + const struct fb_image *image) 367 + { 368 + struct auok190xfb_par *par = info->par; 369 + 370 + sys_imageblit(info, image); 371 + 372 + par->update_all(par); 373 + } 374 + 375 + static int auok190xfb_check_var(struct fb_var_screeninfo *var, 376 + struct fb_info *info) 377 + { 378 + if (info->var.xres != var->xres || info->var.yres != var->yres || 379 + info->var.xres_virtual != var->xres_virtual || 380 + info->var.yres_virtual != var->yres_virtual) { 381 + pr_info("%s: Resolution not supported: X%u x Y%u\n", 382 + __func__, var->xres, var->yres); 383 + return -EINVAL; 384 + } 385 + 386 + /* 387 + * Memory limit 388 + */ 389 + 390 + if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) { 391 + pr_info("%s: Memory Limit requested yres_virtual = %u\n", 392 + __func__, var->yres_virtual); 393 + return -ENOMEM; 394 + } 395 + 396 + return 0; 397 + } 398 + 399 + static struct fb_ops auok190xfb_ops = { 400 + .owner = THIS_MODULE, 401 + .fb_read = fb_sys_read, 402 + .fb_write = auok190xfb_write, 403 + .fb_fillrect = auok190xfb_fillrect, 404 + .fb_copyarea = auok190xfb_copyarea, 405 + .fb_imageblit = auok190xfb_imageblit, 406 + .fb_check_var = auok190xfb_check_var, 407 + }; 408 + 409 + /* 410 + * Controller-functions common to both K1900 and K1901 411 + */ 412 + 413 + static int auok190x_read_temperature(struct auok190xfb_par *par) 414 + { 415 + struct device *dev = par->info->device; 416 + u16 data[4]; 417 + int temp; 418 + 419 + pm_runtime_get_sync(dev); 420 + 421 + mutex_lock(&(par->io_lock)); 422 + 423 + auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data); 424 + 425 + mutex_unlock(&(par->io_lock)); 426 + 427 + pm_runtime_mark_last_busy(dev); 428 + pm_runtime_put_autosuspend(dev); 429 + 430 + /* sanitize and split of half-degrees for now */ 431 + temp = ((data[0] & AUOK190X_VERSION_TEMP_MASK) >> 1); 432 + 433 + /* handle positive and negative temperatures */ 434 + if (temp >= 201) 435 + return (255 - temp + 1) * (-1); 436 + else 437 + return temp; 438 + } 439 + 440 + static void auok190x_identify(struct auok190xfb_par *par) 441 + { 442 + struct device *dev = par->info->device; 443 + u16 data[4]; 444 + 445 + pm_runtime_get_sync(dev); 446 + 447 + mutex_lock(&(par->io_lock)); 448 + 449 + auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data); 450 + 451 + mutex_unlock(&(par->io_lock)); 452 + 453 + par->epd_type = data[1] & AUOK190X_VERSION_TEMP_MASK; 454 + 455 + par->panel_size_int = AUOK190X_VERSION_SIZE_INT(data[2]); 456 + par->panel_size_float = AUOK190X_VERSION_SIZE_FLOAT(data[2]); 457 + par->panel_model = AUOK190X_VERSION_MODEL(data[2]); 458 + 459 + par->tcon_version = AUOK190X_VERSION_TCON(data[3]); 460 + par->lut_version = AUOK190X_VERSION_LUT(data[3]); 461 + 462 + dev_dbg(dev, "panel %d.%din, model 0x%x, EPD 0x%x TCON-rev 0x%x, LUT-rev 0x%x", 463 + par->panel_size_int, par->panel_size_float, par->panel_model, 464 + par->epd_type, par->tcon_version, par->lut_version); 465 + 466 + pm_runtime_mark_last_busy(dev); 467 + pm_runtime_put_autosuspend(dev); 468 + } 469 + 470 + /* 471 + * Sysfs functions 472 + */ 473 + 474 + static ssize_t update_mode_show(struct device *dev, 475 + struct device_attribute *attr, char *buf) 476 + { 477 + struct fb_info *info = dev_get_drvdata(dev); 478 + struct auok190xfb_par *par = info->par; 479 + 480 + return sprintf(buf, "%d\n", par->update_mode); 481 + } 482 + 483 + static ssize_t update_mode_store(struct device *dev, 484 + struct device_attribute *attr, 485 + const char *buf, size_t count) 486 + { 487 + struct fb_info *info = dev_get_drvdata(dev); 488 + struct auok190xfb_par *par = info->par; 489 + int mode, ret; 490 + 491 + ret = kstrtoint(buf, 10, &mode); 492 + if (ret) 493 + return ret; 494 + 495 + par->update_mode = mode; 496 + 497 + /* if we enter a better mode, do a full update */ 498 + if (par->last_mode > 1 && mode < par->last_mode) 499 + par->update_all(par); 500 + 501 + return count; 502 + } 503 + 504 + static ssize_t flash_show(struct device *dev, struct device_attribute *attr, 505 + char *buf) 506 + { 507 + struct fb_info *info = dev_get_drvdata(dev); 508 + struct auok190xfb_par *par = info->par; 509 + 510 + return sprintf(buf, "%d\n", par->flash); 511 + } 512 + 513 + static ssize_t flash_store(struct device *dev, struct device_attribute *attr, 514 + const char *buf, size_t count) 515 + { 516 + struct fb_info *info = dev_get_drvdata(dev); 517 + struct auok190xfb_par *par = info->par; 518 + int flash, ret; 519 + 520 + ret = kstrtoint(buf, 10, &flash); 521 + if (ret) 522 + return ret; 523 + 524 + if (flash > 0) 525 + par->flash = 1; 526 + else 527 + par->flash = 0; 528 + 529 + return count; 530 + } 531 + 532 + static ssize_t temp_show(struct device *dev, struct device_attribute *attr, 533 + char *buf) 534 + { 535 + struct fb_info *info = dev_get_drvdata(dev); 536 + struct auok190xfb_par *par = info->par; 537 + int temp; 538 + 539 + temp = auok190x_read_temperature(par); 540 + return sprintf(buf, "%d\n", temp); 541 + } 542 + 543 + static DEVICE_ATTR(update_mode, 0644, update_mode_show, update_mode_store); 544 + static DEVICE_ATTR(flash, 0644, flash_show, flash_store); 545 + static DEVICE_ATTR(temp, 0644, temp_show, NULL); 546 + 547 + static struct attribute *auok190x_attributes[] = { 548 + &dev_attr_update_mode.attr, 549 + &dev_attr_flash.attr, 550 + &dev_attr_temp.attr, 551 + NULL 552 + }; 553 + 554 + static const struct attribute_group auok190x_attr_group = { 555 + .attrs = auok190x_attributes, 556 + }; 557 + 558 + static int auok190x_power(struct auok190xfb_par *par, bool on) 559 + { 560 + struct auok190x_board *board = par->board; 561 + int ret; 562 + 563 + if (on) { 564 + /* We should maintain POWER up for at least 80ms before set 565 + * RST_N and SLP_N to high (TCON spec 20100803_v35 p59) 566 + */ 567 + ret = regulator_enable(par->regulator); 568 + if (ret) 569 + return ret; 570 + 571 + msleep(200); 572 + gpio_set_value(board->gpio_nrst, 1); 573 + gpio_set_value(board->gpio_nsleep, 1); 574 + msleep(200); 575 + } else { 576 + regulator_disable(par->regulator); 577 + gpio_set_value(board->gpio_nrst, 0); 578 + gpio_set_value(board->gpio_nsleep, 0); 579 + } 580 + 581 + return 0; 582 + } 583 + 584 + /* 585 + * Recovery - powercycle the controller 586 + */ 587 + 588 + static void auok190x_recover(struct auok190xfb_par *par) 589 + { 590 + auok190x_power(par, 0); 591 + msleep(100); 592 + auok190x_power(par, 1); 593 + 594 + par->init(par); 595 + 596 + /* wait for init to complete */ 597 + par->board->wait_for_rdy(par); 598 + } 599 + 600 + /* 601 + * Power-management 602 + */ 603 + 604 + #ifdef CONFIG_PM 605 + static int auok190x_runtime_suspend(struct device *dev) 606 + { 607 + struct platform_device *pdev = to_platform_device(dev); 608 + struct fb_info *info = platform_get_drvdata(pdev); 609 + struct auok190xfb_par *par = info->par; 610 + struct auok190x_board *board = par->board; 611 + u16 standby_param; 612 + 613 + /* take and keep the lock until we are resumed, as the controller 614 + * will never reach the non-busy state when in standby mode 615 + */ 616 + mutex_lock(&(par->io_lock)); 617 + 618 + if (par->standby) { 619 + dev_warn(dev, "already in standby, runtime-pm pairing mismatch\n"); 620 + mutex_unlock(&(par->io_lock)); 621 + return 0; 622 + } 623 + 624 + /* according to runtime_pm.txt runtime_suspend only means, that the 625 + * device will not process data and will not communicate with the CPU 626 + * As we hold the lock, this stays true even without standby 627 + */ 628 + if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) { 629 + dev_dbg(dev, "runtime suspend without standby\n"); 630 + goto finish; 631 + } else if (board->quirks & AUOK190X_QUIRK_STANDBYPARAM) { 632 + /* for some TCON versions STANDBY expects a parameter (0) but 633 + * it seems the real tcon version has to be determined yet. 634 + */ 635 + dev_dbg(dev, "runtime suspend with additional empty param\n"); 636 + standby_param = 0; 637 + auok190x_send_cmdargs(par, AUOK190X_CMD_STANDBY, 1, 638 + &standby_param); 639 + } else { 640 + dev_dbg(dev, "runtime suspend without param\n"); 641 + auok190x_send_command(par, AUOK190X_CMD_STANDBY); 642 + } 643 + 644 + msleep(64); 645 + 646 + finish: 647 + par->standby = 1; 648 + 649 + return 0; 650 + } 651 + 652 + static int auok190x_runtime_resume(struct device *dev) 653 + { 654 + struct platform_device *pdev = to_platform_device(dev); 655 + struct fb_info *info = platform_get_drvdata(pdev); 656 + struct auok190xfb_par *par = info->par; 657 + struct auok190x_board *board = par->board; 658 + 659 + if (!par->standby) { 660 + dev_warn(dev, "not in standby, runtime-pm pairing mismatch\n"); 661 + return 0; 662 + } 663 + 664 + if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) { 665 + dev_dbg(dev, "runtime resume without standby\n"); 666 + } else { 667 + /* when in standby, controller is always busy 668 + * and only accepts the wakeup command 669 + */ 670 + dev_dbg(dev, "runtime resume from standby\n"); 671 + auok190x_send_command_nowait(par, AUOK190X_CMD_WAKEUP); 672 + 673 + msleep(160); 674 + 675 + /* wait for the controller to be ready and release the lock */ 676 + board->wait_for_rdy(par); 677 + } 678 + 679 + par->standby = 0; 680 + 681 + mutex_unlock(&(par->io_lock)); 682 + 683 + return 0; 684 + } 685 + 686 + static int auok190x_suspend(struct device *dev) 687 + { 688 + struct platform_device *pdev = to_platform_device(dev); 689 + struct fb_info *info = platform_get_drvdata(pdev); 690 + struct auok190xfb_par *par = info->par; 691 + struct auok190x_board *board = par->board; 692 + int ret; 693 + 694 + dev_dbg(dev, "suspend\n"); 695 + if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) { 696 + /* suspend via powering off the ic */ 697 + dev_dbg(dev, "suspend with broken standby\n"); 698 + 699 + auok190x_power(par, 0); 700 + } else { 701 + dev_dbg(dev, "suspend using sleep\n"); 702 + 703 + /* the sleep state can only be entered from the standby state. 704 + * pm_runtime_get_noresume gets called before the suspend call. 705 + * So the devices usage count is >0 but it is not necessarily 706 + * active. 707 + */ 708 + if (!pm_runtime_status_suspended(dev)) { 709 + ret = auok190x_runtime_suspend(dev); 710 + if (ret < 0) { 711 + dev_err(dev, "auok190x_runtime_suspend failed with %d\n", 712 + ret); 713 + return ret; 714 + } 715 + par->manual_standby = 1; 716 + } 717 + 718 + gpio_direction_output(board->gpio_nsleep, 0); 719 + } 720 + 721 + msleep(100); 722 + 723 + return 0; 724 + } 725 + 726 + static int auok190x_resume(struct device *dev) 727 + { 728 + struct platform_device *pdev = to_platform_device(dev); 729 + struct fb_info *info = platform_get_drvdata(pdev); 730 + struct auok190xfb_par *par = info->par; 731 + struct auok190x_board *board = par->board; 732 + 733 + dev_dbg(dev, "resume\n"); 734 + if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) { 735 + dev_dbg(dev, "resume with broken standby\n"); 736 + 737 + auok190x_power(par, 1); 738 + 739 + par->init(par); 740 + } else { 741 + dev_dbg(dev, "resume from sleep\n"); 742 + 743 + /* device should be in runtime suspend when we were suspended 744 + * and pm_runtime_put_sync gets called after this function. 745 + * So there is no need to touch the standby mode here at all. 746 + */ 747 + gpio_direction_output(board->gpio_nsleep, 1); 748 + msleep(100); 749 + 750 + /* an additional init call seems to be necessary after sleep */ 751 + auok190x_runtime_resume(dev); 752 + par->init(par); 753 + 754 + /* if we were runtime-suspended before, suspend again*/ 755 + if (!par->manual_standby) 756 + auok190x_runtime_suspend(dev); 757 + else 758 + par->manual_standby = 0; 759 + } 760 + 761 + return 0; 762 + } 763 + #endif 764 + 765 + const struct dev_pm_ops auok190x_pm = { 766 + SET_RUNTIME_PM_OPS(auok190x_runtime_suspend, auok190x_runtime_resume, 767 + NULL) 768 + SET_SYSTEM_SLEEP_PM_OPS(auok190x_suspend, auok190x_resume) 769 + }; 770 + EXPORT_SYMBOL_GPL(auok190x_pm); 771 + 772 + /* 773 + * Common probe and remove code 774 + */ 775 + 776 + int __devinit auok190x_common_probe(struct platform_device *pdev, 777 + struct auok190x_init_data *init) 778 + { 779 + struct auok190x_board *board = init->board; 780 + struct auok190xfb_par *par; 781 + struct fb_info *info; 782 + struct panel_info *panel; 783 + int videomemorysize, ret; 784 + unsigned char *videomemory; 785 + 786 + /* check board contents */ 787 + if (!board->init || !board->cleanup || !board->wait_for_rdy 788 + || !board->set_ctl || !board->set_hdb || !board->get_hdb 789 + || !board->setup_irq) 790 + return -EINVAL; 791 + 792 + info = framebuffer_alloc(sizeof(struct auok190xfb_par), &pdev->dev); 793 + if (!info) 794 + return -ENOMEM; 795 + 796 + par = info->par; 797 + par->info = info; 798 + par->board = board; 799 + par->recover = auok190x_recover; 800 + par->update_partial = init->update_partial; 801 + par->update_all = init->update_all; 802 + par->need_refresh = init->need_refresh; 803 + par->init = init->init; 804 + 805 + /* init update modes */ 806 + par->update_cnt = 0; 807 + par->update_mode = -1; 808 + par->last_mode = -1; 809 + par->flash = 0; 810 + 811 + par->regulator = regulator_get(info->device, "vdd"); 812 + if (IS_ERR(par->regulator)) { 813 + ret = PTR_ERR(par->regulator); 814 + dev_err(info->device, "Failed to get regulator: %d\n", ret); 815 + goto err_reg; 816 + } 817 + 818 + ret = board->init(par); 819 + if (ret) { 820 + dev_err(info->device, "board init failed, %d\n", ret); 821 + goto err_board; 822 + } 823 + 824 + ret = gpio_request(board->gpio_nsleep, "AUOK190x sleep"); 825 + if (ret) { 826 + dev_err(info->device, "could not request sleep gpio, %d\n", 827 + ret); 828 + goto err_gpio1; 829 + } 830 + 831 + ret = gpio_direction_output(board->gpio_nsleep, 0); 832 + if (ret) { 833 + dev_err(info->device, "could not set sleep gpio, %d\n", ret); 834 + goto err_gpio2; 835 + } 836 + 837 + ret = gpio_request(board->gpio_nrst, "AUOK190x reset"); 838 + if (ret) { 839 + dev_err(info->device, "could not request reset gpio, %d\n", 840 + ret); 841 + goto err_gpio2; 842 + } 843 + 844 + ret = gpio_direction_output(board->gpio_nrst, 0); 845 + if (ret) { 846 + dev_err(info->device, "could not set reset gpio, %d\n", ret); 847 + goto err_gpio3; 848 + } 849 + 850 + ret = auok190x_power(par, 1); 851 + if (ret) { 852 + dev_err(info->device, "could not power on the device, %d\n", 853 + ret); 854 + goto err_gpio3; 855 + } 856 + 857 + mutex_init(&par->io_lock); 858 + 859 + init_waitqueue_head(&par->waitq); 860 + 861 + ret = par->board->setup_irq(par->info); 862 + if (ret) { 863 + dev_err(info->device, "could not setup ready-irq, %d\n", ret); 864 + goto err_irq; 865 + } 866 + 867 + /* wait for init to complete */ 868 + par->board->wait_for_rdy(par); 869 + 870 + /* 871 + * From here on the controller can talk to us 872 + */ 873 + 874 + /* initialise fix, var, resolution and rotation */ 875 + 876 + strlcpy(info->fix.id, init->id, 16); 877 + info->fix.type = FB_TYPE_PACKED_PIXELS; 878 + info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; 879 + info->fix.xpanstep = 0; 880 + info->fix.ypanstep = 0; 881 + info->fix.ywrapstep = 0; 882 + info->fix.accel = FB_ACCEL_NONE; 883 + 884 + info->var.bits_per_pixel = 8; 885 + info->var.grayscale = 1; 886 + info->var.red.length = 8; 887 + info->var.green.length = 8; 888 + info->var.blue.length = 8; 889 + 890 + panel = &panel_table[board->resolution]; 891 + 892 + /* if 90 degree rotation, switch width and height */ 893 + if (board->rotation & 1) { 894 + info->var.xres = panel->h; 895 + info->var.yres = panel->w; 896 + info->var.xres_virtual = panel->h; 897 + info->var.yres_virtual = panel->w; 898 + info->fix.line_length = panel->h; 899 + } else { 900 + info->var.xres = panel->w; 901 + info->var.yres = panel->h; 902 + info->var.xres_virtual = panel->w; 903 + info->var.yres_virtual = panel->h; 904 + info->fix.line_length = panel->w; 905 + } 906 + 907 + par->resolution = board->resolution; 908 + par->rotation = board->rotation; 909 + 910 + /* videomemory handling */ 911 + 912 + videomemorysize = roundup((panel->w * panel->h), PAGE_SIZE); 913 + videomemory = vmalloc(videomemorysize); 914 + if (!videomemory) { 915 + ret = -ENOMEM; 916 + goto err_irq; 917 + } 918 + 919 + memset(videomemory, 0, videomemorysize); 920 + info->screen_base = (char *)videomemory; 921 + info->fix.smem_len = videomemorysize; 922 + 923 + info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB; 924 + info->fbops = &auok190xfb_ops; 925 + 926 + /* deferred io init */ 927 + 928 + info->fbdefio = devm_kzalloc(info->device, 929 + sizeof(struct fb_deferred_io), 930 + GFP_KERNEL); 931 + if (!info->fbdefio) { 932 + dev_err(info->device, "Failed to allocate memory\n"); 933 + ret = -ENOMEM; 934 + goto err_defio; 935 + } 936 + 937 + dev_dbg(info->device, "targetting %d frames per second\n", board->fps); 938 + info->fbdefio->delay = HZ / board->fps; 939 + info->fbdefio->first_io = auok190xfb_dpy_first_io, 940 + info->fbdefio->deferred_io = auok190xfb_dpy_deferred_io, 941 + fb_deferred_io_init(info); 942 + 943 + /* color map */ 944 + 945 + ret = fb_alloc_cmap(&info->cmap, 256, 0); 946 + if (ret < 0) { 947 + dev_err(info->device, "Failed to allocate colormap\n"); 948 + goto err_cmap; 949 + } 950 + 951 + /* controller init */ 952 + 953 + par->consecutive_threshold = 100; 954 + par->init(par); 955 + auok190x_identify(par); 956 + 957 + platform_set_drvdata(pdev, info); 958 + 959 + ret = register_framebuffer(info); 960 + if (ret < 0) 961 + goto err_regfb; 962 + 963 + ret = sysfs_create_group(&info->device->kobj, &auok190x_attr_group); 964 + if (ret) 965 + goto err_sysfs; 966 + 967 + dev_info(info->device, "fb%d: %dx%d using %dK of video memory\n", 968 + info->node, info->var.xres, info->var.yres, 969 + videomemorysize >> 10); 970 + 971 + /* increase autosuspend_delay when we use alternative methods 972 + * for runtime_pm 973 + */ 974 + par->autosuspend_delay = (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) 975 + ? 1000 : 200; 976 + 977 + pm_runtime_set_active(info->device); 978 + pm_runtime_enable(info->device); 979 + pm_runtime_set_autosuspend_delay(info->device, par->autosuspend_delay); 980 + pm_runtime_use_autosuspend(info->device); 981 + 982 + return 0; 983 + 984 + err_sysfs: 985 + unregister_framebuffer(info); 986 + err_regfb: 987 + fb_dealloc_cmap(&info->cmap); 988 + err_cmap: 989 + fb_deferred_io_cleanup(info); 990 + kfree(info->fbdefio); 991 + err_defio: 992 + vfree((void *)info->screen_base); 993 + err_irq: 994 + auok190x_power(par, 0); 995 + err_gpio3: 996 + gpio_free(board->gpio_nrst); 997 + err_gpio2: 998 + gpio_free(board->gpio_nsleep); 999 + err_gpio1: 1000 + board->cleanup(par); 1001 + err_board: 1002 + regulator_put(par->regulator); 1003 + err_reg: 1004 + framebuffer_release(info); 1005 + 1006 + return ret; 1007 + } 1008 + EXPORT_SYMBOL_GPL(auok190x_common_probe); 1009 + 1010 + int __devexit auok190x_common_remove(struct platform_device *pdev) 1011 + { 1012 + struct fb_info *info = platform_get_drvdata(pdev); 1013 + struct auok190xfb_par *par = info->par; 1014 + struct auok190x_board *board = par->board; 1015 + 1016 + pm_runtime_disable(info->device); 1017 + 1018 + sysfs_remove_group(&info->device->kobj, &auok190x_attr_group); 1019 + 1020 + unregister_framebuffer(info); 1021 + 1022 + fb_dealloc_cmap(&info->cmap); 1023 + 1024 + fb_deferred_io_cleanup(info); 1025 + kfree(info->fbdefio); 1026 + 1027 + vfree((void *)info->screen_base); 1028 + 1029 + auok190x_power(par, 0); 1030 + 1031 + gpio_free(board->gpio_nrst); 1032 + gpio_free(board->gpio_nsleep); 1033 + 1034 + board->cleanup(par); 1035 + 1036 + regulator_put(par->regulator); 1037 + 1038 + framebuffer_release(info); 1039 + 1040 + return 0; 1041 + } 1042 + EXPORT_SYMBOL_GPL(auok190x_common_remove); 1043 + 1044 + MODULE_DESCRIPTION("Common code for AUO-K190X controllers"); 1045 + MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 1046 + MODULE_LICENSE("GPL");
+129
drivers/video/auo_k190x.h
··· 1 + /* 2 + * Private common definitions for AUO-K190X framebuffer drivers 3 + * 4 + * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + /* 12 + * I80 interface specific defines 13 + */ 14 + 15 + #define AUOK190X_I80_CS 0x01 16 + #define AUOK190X_I80_DC 0x02 17 + #define AUOK190X_I80_WR 0x03 18 + #define AUOK190X_I80_OE 0x04 19 + 20 + /* 21 + * AUOK190x commands, common to both controllers 22 + */ 23 + 24 + #define AUOK190X_CMD_INIT 0x0000 25 + #define AUOK190X_CMD_STANDBY 0x0001 26 + #define AUOK190X_CMD_WAKEUP 0x0002 27 + #define AUOK190X_CMD_TCON_RESET 0x0003 28 + #define AUOK190X_CMD_DATA_STOP 0x1002 29 + #define AUOK190X_CMD_LUT_START 0x1003 30 + #define AUOK190X_CMD_DISP_REFRESH 0x1004 31 + #define AUOK190X_CMD_DISP_RESET 0x1005 32 + #define AUOK190X_CMD_PRE_DISPLAY_START 0x100D 33 + #define AUOK190X_CMD_PRE_DISPLAY_STOP 0x100F 34 + #define AUOK190X_CMD_FLASH_W 0x2000 35 + #define AUOK190X_CMD_FLASH_E 0x2001 36 + #define AUOK190X_CMD_FLASH_STS 0x2002 37 + #define AUOK190X_CMD_FRAMERATE 0x3000 38 + #define AUOK190X_CMD_READ_VERSION 0x4000 39 + #define AUOK190X_CMD_READ_STATUS 0x4001 40 + #define AUOK190X_CMD_READ_LUT 0x4003 41 + #define AUOK190X_CMD_DRIVERTIMING 0x5000 42 + #define AUOK190X_CMD_LBALANCE 0x5001 43 + #define AUOK190X_CMD_AGINGMODE 0x6000 44 + #define AUOK190X_CMD_AGINGEXIT 0x6001 45 + 46 + /* 47 + * Common settings for AUOK190X_CMD_INIT 48 + */ 49 + 50 + #define AUOK190X_INIT_DATA_FILTER (0 << 12) 51 + #define AUOK190X_INIT_DATA_BYPASS (1 << 12) 52 + #define AUOK190X_INIT_INVERSE_WHITE (0 << 9) 53 + #define AUOK190X_INIT_INVERSE_BLACK (1 << 9) 54 + #define AUOK190X_INIT_SCAN_DOWN (0 << 1) 55 + #define AUOK190X_INIT_SCAN_UP (1 << 1) 56 + #define AUOK190X_INIT_SHIFT_LEFT (0 << 0) 57 + #define AUOK190X_INIT_SHIFT_RIGHT (1 << 0) 58 + 59 + /* Common bits to pixels 60 + * Mode 15-12 11-8 7-4 3-0 61 + * format0 4 3 2 1 62 + * format1 3 4 1 2 63 + */ 64 + 65 + #define AUOK190X_INIT_FORMAT0 0 66 + #define AUOK190X_INIT_FORMAT1 (1 << 6) 67 + 68 + /* 69 + * settings for AUOK190X_CMD_RESET 70 + */ 71 + 72 + #define AUOK190X_RESET_TCON (0 << 0) 73 + #define AUOK190X_RESET_NORMAL (1 << 0) 74 + #define AUOK190X_RESET_PON (1 << 1) 75 + 76 + /* 77 + * AUOK190X_CMD_VERSION 78 + */ 79 + 80 + #define AUOK190X_VERSION_TEMP_MASK (0x1ff) 81 + #define AUOK190X_VERSION_EPD_MASK (0xff) 82 + #define AUOK190X_VERSION_SIZE_INT(_val) ((_val & 0xfc00) >> 10) 83 + #define AUOK190X_VERSION_SIZE_FLOAT(_val) ((_val & 0x3c0) >> 6) 84 + #define AUOK190X_VERSION_MODEL(_val) (_val & 0x3f) 85 + #define AUOK190X_VERSION_LUT(_val) (_val & 0xff) 86 + #define AUOK190X_VERSION_TCON(_val) ((_val & 0xff00) >> 8) 87 + 88 + /* 89 + * update modes for CMD_PARTIALDISP on K1900 and CMD_DDMA on K1901 90 + */ 91 + 92 + #define AUOK190X_UPDATE_MODE(_res) ((_res & 0x7) << 12) 93 + #define AUOK190X_UPDATE_NONFLASH (1 << 15) 94 + 95 + /* 96 + * track panel specific parameters for common init 97 + */ 98 + 99 + struct auok190x_init_data { 100 + char *id; 101 + struct auok190x_board *board; 102 + 103 + void (*update_partial)(struct auok190xfb_par *par, u16 y1, u16 y2); 104 + void (*update_all)(struct auok190xfb_par *par); 105 + bool (*need_refresh)(struct auok190xfb_par *par); 106 + void (*init)(struct auok190xfb_par *par); 107 + }; 108 + 109 + 110 + extern void auok190x_send_command_nowait(struct auok190xfb_par *par, u16 data); 111 + extern int auok190x_send_command(struct auok190xfb_par *par, u16 data); 112 + extern void auok190x_send_cmdargs_nowait(struct auok190xfb_par *par, u16 cmd, 113 + int argc, u16 *argv); 114 + extern int auok190x_send_cmdargs(struct auok190xfb_par *par, u16 cmd, 115 + int argc, u16 *argv); 116 + extern void auok190x_send_cmdargs_pixels_nowait(struct auok190xfb_par *par, 117 + u16 cmd, int argc, u16 *argv, 118 + int size, u16 *data); 119 + extern int auok190x_send_cmdargs_pixels(struct auok190xfb_par *par, u16 cmd, 120 + int argc, u16 *argv, int size, 121 + u16 *data); 122 + extern int auok190x_read_cmdargs(struct auok190xfb_par *par, u16 cmd, 123 + int argc, u16 *argv); 124 + 125 + extern int auok190x_common_probe(struct platform_device *pdev, 126 + struct auok190x_init_data *init); 127 + extern int auok190x_common_remove(struct platform_device *pdev); 128 + 129 + extern const struct dev_pm_ops auok190x_pm;
+23 -20
drivers/video/bfin_adv7393fb.c
··· 414 414 if (ret) { 415 415 dev_err(&client->dev, "PPI0_FS3 GPIO request failed\n"); 416 416 ret = -EBUSY; 417 - goto out_8; 417 + goto free_fbdev; 418 418 } 419 419 } 420 420 421 421 if (peripheral_request_list(ppi_pins, DRIVER_NAME)) { 422 422 dev_err(&client->dev, "requesting PPI peripheral failed\n"); 423 423 ret = -EFAULT; 424 - goto out_8; 424 + goto free_gpio; 425 425 } 426 426 427 427 fbdev->fb_mem = ··· 432 432 dev_err(&client->dev, "couldn't allocate dma buffer (%d bytes)\n", 433 433 (u32) fbdev->fb_len); 434 434 ret = -ENOMEM; 435 - goto out_7; 435 + goto free_ppi_pins; 436 436 } 437 437 438 438 fbdev->info.screen_base = (void *)fbdev->fb_mem; ··· 464 464 if (!fbdev->info.pseudo_palette) { 465 465 dev_err(&client->dev, "failed to allocate pseudo_palette\n"); 466 466 ret = -ENOMEM; 467 - goto out_6; 467 + goto free_fb_mem; 468 468 } 469 469 470 470 if (fb_alloc_cmap(&fbdev->info.cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { 471 471 dev_err(&client->dev, "failed to allocate colormap (%d entries)\n", 472 472 BFIN_LCD_NBR_PALETTE_ENTRIES); 473 473 ret = -EFAULT; 474 - goto out_5; 474 + goto free_palette; 475 475 } 476 476 477 477 if (request_dma(CH_PPI, "BF5xx_PPI_DMA") < 0) { 478 478 dev_err(&client->dev, "unable to request PPI DMA\n"); 479 479 ret = -EFAULT; 480 - goto out_4; 480 + goto free_cmap; 481 481 } 482 482 483 483 if (request_irq(IRQ_PPI_ERROR, ppi_irq_error, 0, 484 484 "PPI ERROR", fbdev) < 0) { 485 485 dev_err(&client->dev, "unable to request PPI ERROR IRQ\n"); 486 486 ret = -EFAULT; 487 - goto out_3; 487 + goto free_ch_ppi; 488 488 } 489 489 490 490 fbdev->open = 0; ··· 494 494 495 495 if (ret) { 496 496 dev_err(&client->dev, "i2c attach: init error\n"); 497 - goto out_1; 497 + goto free_irq_ppi; 498 498 } 499 499 500 500 501 501 if (register_framebuffer(&fbdev->info) < 0) { 502 502 dev_err(&client->dev, "unable to register framebuffer\n"); 503 503 ret = -EFAULT; 504 - goto out_1; 504 + goto free_irq_ppi; 505 505 } 506 506 507 507 dev_info(&client->dev, "fb%d: %s frame buffer device\n", ··· 512 512 if (!entry) { 513 513 dev_err(&client->dev, "unable to create /proc entry\n"); 514 514 ret = -EFAULT; 515 - goto out_0; 515 + goto free_fb; 516 516 } 517 517 518 518 entry->read_proc = adv7393_read_proc; ··· 521 521 522 522 return 0; 523 523 524 - out_0: 524 + free_fb: 525 525 unregister_framebuffer(&fbdev->info); 526 - out_1: 526 + free_irq_ppi: 527 527 free_irq(IRQ_PPI_ERROR, fbdev); 528 - out_3: 528 + free_ch_ppi: 529 529 free_dma(CH_PPI); 530 - out_4: 530 + free_cmap: 531 + fb_dealloc_cmap(&fbdev->info.cmap); 532 + free_palette: 533 + kfree(fbdev->info.pseudo_palette); 534 + free_fb_mem: 531 535 dma_free_coherent(NULL, fbdev->fb_len, fbdev->fb_mem, 532 536 fbdev->dma_handle); 533 - out_5: 534 - fb_dealloc_cmap(&fbdev->info.cmap); 535 - out_6: 536 - kfree(fbdev->info.pseudo_palette); 537 - out_7: 537 + free_ppi_pins: 538 538 peripheral_free_list(ppi_pins); 539 - out_8: 539 + free_gpio: 540 + if (ANOMALY_05000400) 541 + gpio_free(P_IDENT(P_PPI0_FS3)); 542 + free_fbdev: 540 543 kfree(fbdev); 541 544 542 545 return ret;
+44 -1
drivers/video/cobalt_lcdfb.c
··· 1 1 /* 2 - * Cobalt server LCD frame buffer driver. 2 + * Cobalt/SEAD3 LCD frame buffer driver. 3 3 * 4 4 * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org> 5 + * Copyright (C) 2012 MIPS Technologies, Inc. 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify 7 8 * it under the terms of the GNU General Public License as published by ··· 63 62 #define LCD_CUR_POS(x) ((x) & LCD_CUR_POS_MASK) 64 63 #define LCD_TEXT_POS(x) ((x) | LCD_TEXT_MODE) 65 64 65 + #ifdef CONFIG_MIPS_COBALT 66 66 static inline void lcd_write_control(struct fb_info *info, u8 control) 67 67 { 68 68 writel((u32)control << 24, info->screen_base); ··· 83 81 { 84 82 return readl(info->screen_base + LCD_DATA_REG_OFFSET) >> 24; 85 83 } 84 + #else 85 + 86 + #define LCD_CTL 0x00 87 + #define LCD_DATA 0x08 88 + #define CPLD_STATUS 0x10 89 + #define CPLD_DATA 0x18 90 + 91 + static inline void cpld_wait(struct fb_info *info) 92 + { 93 + do { 94 + } while (readl(info->screen_base + CPLD_STATUS) & 1); 95 + } 96 + 97 + static inline void lcd_write_control(struct fb_info *info, u8 control) 98 + { 99 + cpld_wait(info); 100 + writel(control, info->screen_base + LCD_CTL); 101 + } 102 + 103 + static inline u8 lcd_read_control(struct fb_info *info) 104 + { 105 + cpld_wait(info); 106 + readl(info->screen_base + LCD_CTL); 107 + cpld_wait(info); 108 + return readl(info->screen_base + CPLD_DATA) & 0xff; 109 + } 110 + 111 + static inline void lcd_write_data(struct fb_info *info, u8 data) 112 + { 113 + cpld_wait(info); 114 + writel(data, info->screen_base + LCD_DATA); 115 + } 116 + 117 + static inline u8 lcd_read_data(struct fb_info *info) 118 + { 119 + cpld_wait(info); 120 + readl(info->screen_base + LCD_DATA); 121 + cpld_wait(info); 122 + return readl(info->screen_base + CPLD_DATA) & 0xff; 123 + } 124 + #endif 86 125 87 126 static int lcd_busy_wait(struct fb_info *info) 88 127 {
+17 -15
drivers/video/ep93xx-fb.c
··· 507 507 508 508 err = fb_alloc_cmap(&info->cmap, 256, 0); 509 509 if (err) 510 - goto failed; 510 + goto failed_cmap; 511 511 512 512 err = ep93xxfb_alloc_videomem(info); 513 513 if (err) 514 - goto failed; 514 + goto failed_videomem; 515 515 516 516 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 517 517 if (!res) { 518 518 err = -ENXIO; 519 - goto failed; 519 + goto failed_resource; 520 520 } 521 521 522 522 /* ··· 532 532 fbi->mmio_base = ioremap(res->start, resource_size(res)); 533 533 if (!fbi->mmio_base) { 534 534 err = -ENXIO; 535 - goto failed; 535 + goto failed_resource; 536 536 } 537 537 538 538 strcpy(info->fix.id, pdev->name); ··· 553 553 if (err == 0) { 554 554 dev_err(info->dev, "No suitable video mode found\n"); 555 555 err = -EINVAL; 556 - goto failed; 556 + goto failed_mode; 557 557 } 558 558 559 559 if (mach_info->setup) { 560 560 err = mach_info->setup(pdev); 561 561 if (err) 562 - return err; 562 + goto failed_mode; 563 563 } 564 564 565 565 err = ep93xxfb_check_var(&info->var, info); 566 566 if (err) 567 - goto failed; 567 + goto failed_check; 568 568 569 569 fbi->clk = clk_get(info->dev, NULL); 570 570 if (IS_ERR(fbi->clk)) { 571 571 err = PTR_ERR(fbi->clk); 572 572 fbi->clk = NULL; 573 - goto failed; 573 + goto failed_check; 574 574 } 575 575 576 576 ep93xxfb_set_par(info); ··· 585 585 return 0; 586 586 587 587 failed: 588 - if (fbi->clk) 589 - clk_put(fbi->clk); 590 - if (fbi->mmio_base) 591 - iounmap(fbi->mmio_base); 592 - ep93xxfb_dealloc_videomem(info); 593 - if (&info->cmap) 594 - fb_dealloc_cmap(&info->cmap); 588 + clk_put(fbi->clk); 589 + failed_check: 595 590 if (fbi->mach_info->teardown) 596 591 fbi->mach_info->teardown(pdev); 592 + failed_mode: 593 + iounmap(fbi->mmio_base); 594 + failed_resource: 595 + ep93xxfb_dealloc_videomem(info); 596 + failed_videomem: 597 + fb_dealloc_cmap(&info->cmap); 598 + failed_cmap: 597 599 kfree(info); 598 600 platform_set_drvdata(pdev, NULL); 599 601
+22 -47
drivers/video/exynos/exynos_dp_core.c
··· 21 21 22 22 #include <video/exynos_dp.h> 23 23 24 - #include <plat/cpu.h> 25 - 26 24 #include "exynos_dp_core.h" 27 25 28 26 static int exynos_dp_init_dp(struct exynos_dp_device *dp) 29 27 { 30 28 exynos_dp_reset(dp); 29 + 30 + exynos_dp_swreset(dp); 31 31 32 32 /* SW defined function Normal operation */ 33 33 exynos_dp_enable_sw_function(dp); ··· 478 478 int lane_count; 479 479 u8 buf[5]; 480 480 481 - u8 *adjust_request; 481 + u8 adjust_request[2]; 482 482 u8 voltage_swing; 483 483 u8 pre_emphasis; 484 484 u8 training_lane; ··· 493 493 /* set training pattern 2 for EQ */ 494 494 exynos_dp_set_training_pattern(dp, TRAINING_PTN2); 495 495 496 - adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1 497 - - DPCD_ADDR_LANE0_1_STATUS); 496 + adjust_request[0] = link_status[4]; 497 + adjust_request[1] = link_status[5]; 498 498 499 499 exynos_dp_get_adjust_train(dp, adjust_request); 500 500 ··· 566 566 u8 buf[5]; 567 567 u32 reg; 568 568 569 - u8 *adjust_request; 569 + u8 adjust_request[2]; 570 570 571 571 udelay(400); 572 572 ··· 575 575 lane_count = dp->link_train.lane_count; 576 576 577 577 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { 578 - adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1 579 - - DPCD_ADDR_LANE0_1_STATUS); 578 + adjust_request[0] = link_status[4]; 579 + adjust_request[1] = link_status[5]; 580 580 581 581 if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) { 582 582 /* traing pattern Set to Normal */ ··· 770 770 return -ETIMEDOUT; 771 771 } 772 772 773 - mdelay(100); 773 + udelay(1); 774 774 } 775 775 776 776 /* Set to use the register calculated M/N video */ ··· 804 804 return -ETIMEDOUT; 805 805 } 806 806 807 - mdelay(100); 807 + mdelay(1); 808 808 } 809 809 810 810 if (retval != 0) ··· 860 860 return -EINVAL; 861 861 } 862 862 863 - dp = kzalloc(sizeof(struct exynos_dp_device), GFP_KERNEL); 863 + dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), 864 + GFP_KERNEL); 864 865 if (!dp) { 865 866 dev_err(&pdev->dev, "no memory for device data\n"); 866 867 return -ENOMEM; ··· 872 871 dp->clock = clk_get(&pdev->dev, "dp"); 873 872 if (IS_ERR(dp->clock)) { 874 873 dev_err(&pdev->dev, "failed to get clock\n"); 875 - ret = PTR_ERR(dp->clock); 876 - goto err_dp; 874 + return PTR_ERR(dp->clock); 877 875 } 878 876 879 877 clk_enable(dp->clock); ··· 884 884 goto err_clock; 885 885 } 886 886 887 - res = request_mem_region(res->start, resource_size(res), 888 - dev_name(&pdev->dev)); 889 - if (!res) { 890 - dev_err(&pdev->dev, "failed to request registers region\n"); 891 - ret = -EINVAL; 892 - goto err_clock; 893 - } 894 - 895 - dp->res = res; 896 - 897 - dp->reg_base = ioremap(res->start, resource_size(res)); 887 + dp->reg_base = devm_request_and_ioremap(&pdev->dev, res); 898 888 if (!dp->reg_base) { 899 889 dev_err(&pdev->dev, "failed to ioremap\n"); 900 890 ret = -ENOMEM; 901 - goto err_req_region; 891 + goto err_clock; 902 892 } 903 893 904 894 dp->irq = platform_get_irq(pdev, 0); 905 895 if (!dp->irq) { 906 896 dev_err(&pdev->dev, "failed to get irq\n"); 907 897 ret = -ENODEV; 908 - goto err_ioremap; 898 + goto err_clock; 909 899 } 910 900 911 - ret = request_irq(dp->irq, exynos_dp_irq_handler, 0, 912 - "exynos-dp", dp); 901 + ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0, 902 + "exynos-dp", dp); 913 903 if (ret) { 914 904 dev_err(&pdev->dev, "failed to request irq\n"); 915 - goto err_ioremap; 905 + goto err_clock; 916 906 } 917 907 918 908 dp->video_info = pdata->video_info; ··· 914 924 ret = exynos_dp_detect_hpd(dp); 915 925 if (ret) { 916 926 dev_err(&pdev->dev, "unable to detect hpd\n"); 917 - goto err_irq; 927 + goto err_clock; 918 928 } 919 929 920 930 exynos_dp_handle_edid(dp); ··· 923 933 dp->video_info->link_rate); 924 934 if (ret) { 925 935 dev_err(&pdev->dev, "unable to do link train\n"); 926 - goto err_irq; 936 + goto err_clock; 927 937 } 928 938 929 939 exynos_dp_enable_scramble(dp, 1); ··· 937 947 ret = exynos_dp_config_video(dp, dp->video_info); 938 948 if (ret) { 939 949 dev_err(&pdev->dev, "unable to config video\n"); 940 - goto err_irq; 950 + goto err_clock; 941 951 } 942 952 943 953 platform_set_drvdata(pdev, dp); 944 954 945 955 return 0; 946 956 947 - err_irq: 948 - free_irq(dp->irq, dp); 949 - err_ioremap: 950 - iounmap(dp->reg_base); 951 - err_req_region: 952 - release_mem_region(res->start, resource_size(res)); 953 957 err_clock: 954 958 clk_put(dp->clock); 955 - err_dp: 956 - kfree(dp); 957 959 958 960 return ret; 959 961 } ··· 958 976 if (pdata && pdata->phy_exit) 959 977 pdata->phy_exit(); 960 978 961 - free_irq(dp->irq, dp); 962 - iounmap(dp->reg_base); 963 - 964 979 clk_disable(dp->clock); 965 980 clk_put(dp->clock); 966 - 967 - release_mem_region(dp->res->start, resource_size(dp->res)); 968 - 969 - kfree(dp); 970 981 971 982 return 0; 972 983 }
+2 -1
drivers/video/exynos/exynos_dp_core.h
··· 26 26 27 27 struct exynos_dp_device { 28 28 struct device *dev; 29 - struct resource *res; 30 29 struct clk *clock; 31 30 unsigned int irq; 32 31 void __iomem *reg_base; ··· 38 39 void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable); 39 40 void exynos_dp_stop_video(struct exynos_dp_device *dp); 40 41 void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable); 42 + void exynos_dp_init_analog_param(struct exynos_dp_device *dp); 41 43 void exynos_dp_init_interrupt(struct exynos_dp_device *dp); 42 44 void exynos_dp_reset(struct exynos_dp_device *dp); 45 + void exynos_dp_swreset(struct exynos_dp_device *dp); 43 46 void exynos_dp_config_interrupt(struct exynos_dp_device *dp); 44 47 u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp); 45 48 void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
+40 -5
drivers/video/exynos/exynos_dp_reg.c
··· 16 16 17 17 #include <video/exynos_dp.h> 18 18 19 - #include <plat/cpu.h> 20 - 21 19 #include "exynos_dp_core.h" 22 20 #include "exynos_dp_reg.h" 23 21 ··· 63 65 writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP); 64 66 } 65 67 68 + void exynos_dp_init_analog_param(struct exynos_dp_device *dp) 69 + { 70 + u32 reg; 71 + 72 + reg = TX_TERMINAL_CTRL_50_OHM; 73 + writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1); 74 + 75 + reg = SEL_24M | TX_DVDD_BIT_1_0625V; 76 + writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2); 77 + 78 + reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO; 79 + writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3); 80 + 81 + reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | 82 + TX_CUR1_2X | TX_CUR_8_MA; 83 + writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1); 84 + 85 + reg = CH3_AMP_400_MV | CH2_AMP_400_MV | 86 + CH1_AMP_400_MV | CH0_AMP_400_MV; 87 + writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL); 88 + } 89 + 66 90 void exynos_dp_init_interrupt(struct exynos_dp_device *dp) 67 91 { 68 92 /* Set interrupt pin assertion polarity as high */ ··· 108 88 void exynos_dp_reset(struct exynos_dp_device *dp) 109 89 { 110 90 u32 reg; 111 - 112 - writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET); 113 91 114 92 exynos_dp_stop_video(dp); 115 93 exynos_dp_enable_video_mute(dp, 0); ··· 149 131 150 132 writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 151 133 134 + exynos_dp_init_analog_param(dp); 152 135 exynos_dp_init_interrupt(dp); 136 + } 137 + 138 + void exynos_dp_swreset(struct exynos_dp_device *dp) 139 + { 140 + writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET); 153 141 } 154 142 155 143 void exynos_dp_config_interrupt(struct exynos_dp_device *dp) ··· 295 271 void exynos_dp_init_analog_func(struct exynos_dp_device *dp) 296 272 { 297 273 u32 reg; 274 + int timeout_loop = 0; 298 275 299 276 exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); 300 277 ··· 307 282 writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL); 308 283 309 284 /* Power up PLL */ 310 - if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) 285 + if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 311 286 exynos_dp_set_pll_power_down(dp, 0); 287 + 288 + while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 289 + timeout_loop++; 290 + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 291 + dev_err(dp->dev, "failed to get pll lock status\n"); 292 + return; 293 + } 294 + usleep_range(10, 20); 295 + } 296 + } 312 297 313 298 /* Enable Serdes FIFO function and Link symbol clock domain module */ 314 299 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+29
drivers/video/exynos/exynos_dp_reg.h
··· 24 24 25 25 #define EXYNOS_DP_LANE_MAP 0x35C 26 26 27 + #define EXYNOS_DP_ANALOG_CTL_1 0x370 28 + #define EXYNOS_DP_ANALOG_CTL_2 0x374 29 + #define EXYNOS_DP_ANALOG_CTL_3 0x378 30 + #define EXYNOS_DP_PLL_FILTER_CTL_1 0x37C 31 + #define EXYNOS_DP_TX_AMP_TUNING_CTL 0x380 32 + 27 33 #define EXYNOS_DP_AUX_HW_RETRY_CTL 0x390 28 34 29 35 #define EXYNOS_DP_COMMON_INT_STA_1 0x3C4 ··· 171 165 #define LANE0_MAP_LOGIC_LANE_1 (0x1 << 0) 172 166 #define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0) 173 167 #define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0) 168 + 169 + /* EXYNOS_DP_ANALOG_CTL_1 */ 170 + #define TX_TERMINAL_CTRL_50_OHM (0x1 << 4) 171 + 172 + /* EXYNOS_DP_ANALOG_CTL_2 */ 173 + #define SEL_24M (0x1 << 3) 174 + #define TX_DVDD_BIT_1_0625V (0x4 << 0) 175 + 176 + /* EXYNOS_DP_ANALOG_CTL_3 */ 177 + #define DRIVE_DVDD_BIT_1_0625V (0x4 << 5) 178 + #define VCO_BIT_600_MICRO (0x5 << 0) 179 + 180 + /* EXYNOS_DP_PLL_FILTER_CTL_1 */ 181 + #define PD_RING_OSC (0x1 << 6) 182 + #define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4) 183 + #define TX_CUR1_2X (0x1 << 2) 184 + #define TX_CUR_8_MA (0x2 << 0) 185 + 186 + /* EXYNOS_DP_TX_AMP_TUNING_CTL */ 187 + #define CH3_AMP_400_MV (0x0 << 24) 188 + #define CH2_AMP_400_MV (0x0 << 16) 189 + #define CH1_AMP_400_MV (0x0 << 8) 190 + #define CH0_AMP_400_MV (0x0 << 0) 174 191 175 192 /* EXYNOS_DP_AUX_HW_RETRY_CTL */ 176 193 #define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8)
+27 -22
drivers/video/exynos/exynos_mipi_dsi.c
··· 58 58 } 59 59 60 60 static struct regulator_bulk_data supplies[] = { 61 - { .supply = "vdd10", }, 61 + { .supply = "vdd11", }, 62 62 { .supply = "vdd18", }, 63 63 }; 64 64 ··· 101 101 102 102 /* set display timing. */ 103 103 exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config); 104 + 105 + exynos_mipi_dsi_init_interrupt(dsim); 104 106 105 107 /* 106 108 * data from Display controller(FIMD) is transferred in video mode ··· 415 413 goto err_platform_get_irq; 416 414 } 417 415 416 + init_completion(&dsim_wr_comp); 417 + init_completion(&dsim_rd_comp); 418 + platform_set_drvdata(pdev, dsim); 419 + 418 420 ret = request_irq(dsim->irq, exynos_mipi_dsi_interrupt_handler, 419 - IRQF_SHARED, pdev->name, dsim); 421 + IRQF_SHARED, dev_name(&pdev->dev), dsim); 420 422 if (ret != 0) { 421 423 dev_err(&pdev->dev, "failed to request dsim irq\n"); 422 424 ret = -EINVAL; 423 425 goto err_bind; 424 426 } 425 427 426 - init_completion(&dsim_wr_comp); 427 - init_completion(&dsim_rd_comp); 428 - 429 - /* enable interrupt */ 428 + /* enable interrupts */ 430 429 exynos_mipi_dsi_init_interrupt(dsim); 431 430 432 431 /* initialize mipi-dsi client(lcd panel). */ 433 432 if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->probe) 434 433 dsim_ddi->dsim_lcd_drv->probe(dsim_ddi->dsim_lcd_dev); 435 434 436 - /* in case that mipi got enabled at bootloader. */ 437 - if (dsim_pd->enabled) 438 - goto out; 435 + /* in case mipi-dsi has been enabled by bootloader */ 436 + if (dsim_pd->enabled) { 437 + exynos_mipi_regulator_enable(dsim); 438 + goto done; 439 + } 439 440 440 441 /* lcd panel power on. */ 441 442 if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->power_on) ··· 458 453 459 454 dsim->suspended = false; 460 455 461 - out: 456 + done: 462 457 platform_set_drvdata(pdev, dsim); 463 458 464 - dev_dbg(&pdev->dev, "mipi-dsi driver(%s mode) has been probed.\n", 465 - (dsim_config->e_interface == DSIM_COMMAND) ? 466 - "CPU" : "RGB"); 459 + dev_dbg(&pdev->dev, "%s() completed sucessfuly (%s mode)\n", __func__, 460 + dsim_config->e_interface == DSIM_COMMAND ? "CPU" : "RGB"); 467 461 468 462 return 0; 469 463 ··· 519 515 return 0; 520 516 } 521 517 522 - #ifdef CONFIG_PM 523 - static int exynos_mipi_dsi_suspend(struct platform_device *pdev, 524 - pm_message_t state) 518 + #ifdef CONFIG_PM_SLEEP 519 + static int exynos_mipi_dsi_suspend(struct device *dev) 525 520 { 521 + struct platform_device *pdev = to_platform_device(dev); 526 522 struct mipi_dsim_device *dsim = platform_get_drvdata(pdev); 527 523 struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv; 528 524 struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev; ··· 548 544 return 0; 549 545 } 550 546 551 - static int exynos_mipi_dsi_resume(struct platform_device *pdev) 547 + static int exynos_mipi_dsi_resume(struct device *dev) 552 548 { 549 + struct platform_device *pdev = to_platform_device(dev); 553 550 struct mipi_dsim_device *dsim = platform_get_drvdata(pdev); 554 551 struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv; 555 552 struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev; ··· 582 577 583 578 return 0; 584 579 } 585 - #else 586 - #define exynos_mipi_dsi_suspend NULL 587 - #define exynos_mipi_dsi_resume NULL 588 580 #endif 581 + 582 + static const struct dev_pm_ops exynos_mipi_dsi_pm_ops = { 583 + SET_SYSTEM_SLEEP_PM_OPS(exynos_mipi_dsi_suspend, exynos_mipi_dsi_resume) 584 + }; 589 585 590 586 static struct platform_driver exynos_mipi_dsi_driver = { 591 587 .probe = exynos_mipi_dsi_probe, 592 588 .remove = __devexit_p(exynos_mipi_dsi_remove), 593 - .suspend = exynos_mipi_dsi_suspend, 594 - .resume = exynos_mipi_dsi_resume, 595 589 .driver = { 596 590 .name = "exynos-mipi-dsim", 597 591 .owner = THIS_MODULE, 592 + .pm = &exynos_mipi_dsi_pm_ops, 598 593 }, 599 594 }; 600 595
+13 -21
drivers/video/exynos/exynos_mipi_dsi_common.c
··· 76 76 77 77 irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id) 78 78 { 79 - unsigned int intsrc = 0; 80 - unsigned int intmsk = 0; 81 - struct mipi_dsim_device *dsim = NULL; 79 + struct mipi_dsim_device *dsim = dev_id; 80 + unsigned int intsrc, intmsk; 82 81 83 - dsim = dev_id; 84 - if (!dsim) { 85 - dev_dbg(dsim->dev, KERN_ERR "%s:error: wrong parameter\n", 86 - __func__); 87 - return IRQ_HANDLED; 82 + if (dsim == NULL) { 83 + dev_err(dsim->dev, "%s: wrong parameter\n", __func__); 84 + return IRQ_NONE; 88 85 } 89 86 90 87 intsrc = exynos_mipi_dsi_read_interrupt(dsim); 91 88 intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim); 89 + intmsk = ~intmsk & intsrc; 92 90 93 - intmsk = ~(intmsk) & intsrc; 94 - 95 - switch (intmsk) { 96 - case INTMSK_RX_DONE: 91 + if (intsrc & INTMSK_RX_DONE) { 97 92 complete(&dsim_rd_comp); 98 93 dev_dbg(dsim->dev, "MIPI INTMSK_RX_DONE\n"); 99 - break; 100 - case INTMSK_FIFO_EMPTY: 94 + } 95 + if (intsrc & INTMSK_FIFO_EMPTY) { 101 96 complete(&dsim_wr_comp); 102 97 dev_dbg(dsim->dev, "MIPI INTMSK_FIFO_EMPTY\n"); 103 - break; 104 - default: 105 - break; 106 98 } 107 99 108 100 exynos_mipi_dsi_clear_interrupt(dsim, intmsk); ··· 730 738 if (dsim_config->auto_vertical_cnt == 0) { 731 739 exynos_mipi_dsi_set_main_disp_vporch(dsim, 732 740 dsim_config->cmd_allow, 733 - timing->upper_margin, 734 - timing->lower_margin); 741 + timing->lower_margin, 742 + timing->upper_margin); 735 743 exynos_mipi_dsi_set_main_disp_hporch(dsim, 736 - timing->left_margin, 737 - timing->right_margin); 744 + timing->right_margin, 745 + timing->left_margin); 738 746 exynos_mipi_dsi_set_main_disp_sync_area(dsim, 739 747 timing->vsync_len, 740 748 timing->hsync_len);
+13 -2
drivers/video/exynos/s6e8ax0.c
··· 293 293 0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x23, 0xc0, 294 294 0xc8, 0x08, 0x48, 0xc1, 0x00, 0xc1, 0xff, 0xff, 0xc8 295 295 }; 296 + static const unsigned char data_to_send_panel_reverse[] = { 297 + 0xf8, 0x19, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3c, 0x7d, 298 + 0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08, 299 + 0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x23, 0xc0, 300 + 0xc1, 0x01, 0x41, 0xc1, 0x00, 0xc1, 0xf6, 0xf6, 0xc1 301 + }; 296 302 297 - ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE, 298 - data_to_send, ARRAY_SIZE(data_to_send)); 303 + if (lcd->dsim_dev->panel_reverse) 304 + ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE, 305 + data_to_send_panel_reverse, 306 + ARRAY_SIZE(data_to_send_panel_reverse)); 307 + else 308 + ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE, 309 + data_to_send, ARRAY_SIZE(data_to_send)); 299 310 } 300 311 301 312 static void s6e8ax0_display_cond(struct s6e8ax0 *lcd)
+5 -1
drivers/video/fb_defio.c
··· 23 23 #include <linux/rmap.h> 24 24 #include <linux/pagemap.h> 25 25 26 - struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs) 26 + static struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs) 27 27 { 28 28 void *screen_base = (void __force *) info->screen_base; 29 29 struct page *page; ··· 106 106 107 107 /* protect against the workqueue changing the page list */ 108 108 mutex_lock(&fbdefio->lock); 109 + 110 + /* first write in this cycle, notify the driver */ 111 + if (fbdefio->first_io && list_empty(&fbdefio->pagelist)) 112 + fbdefio->first_io(info); 109 113 110 114 /* 111 115 * We want the page to remain locked from ->page_mkwrite until
+2
drivers/video/fbsysfs.c
··· 80 80 */ 81 81 void framebuffer_release(struct fb_info *info) 82 82 { 83 + if (!info) 84 + return; 83 85 kfree(info->apertures); 84 86 kfree(info); 85 87 }
-1
drivers/video/fsl-diu-fb.c
··· 834 834 diu_ops.set_pixel_clock(var->pixclock); 835 835 836 836 out_be32(&hw->syn_pol, 0); /* SYNC SIGNALS POLARITY */ 837 - out_be32(&hw->thresholds, 0x00037800); /* The Thresholds */ 838 837 out_be32(&hw->int_status, 0); /* INTERRUPT STATUS */ 839 838 out_be32(&hw->plut, 0x01F5F666); 840 839
+2
drivers/video/intelfb/intelfbdrv.c
··· 680 680 + dinfo->fb.size); 681 681 if (!dinfo->aperture.virtual) { 682 682 ERR_MSG("Cannot remap FB region.\n"); 683 + agp_backend_release(bridge); 683 684 cleanup(dinfo); 684 685 return -ENODEV; 685 686 } ··· 690 689 INTEL_REG_SIZE); 691 690 if (!dinfo->mmio_base) { 692 691 ERR_MSG("Cannot remap MMIO region.\n"); 692 + agp_backend_release(bridge); 693 693 cleanup(dinfo); 694 694 return -ENODEV; 695 695 }
+1 -1
drivers/video/mb862xx/mb862xx-i2c.c
··· 68 68 return 1; 69 69 } 70 70 71 - void mb862xx_i2c_stop(struct i2c_adapter *adap) 71 + static void mb862xx_i2c_stop(struct i2c_adapter *adap) 72 72 { 73 73 struct mb862xxfb_par *par = adap->algo_data; 74 74
+1 -1
drivers/video/mb862xx/mb862xxfbdrv.c
··· 579 579 580 580 static DEVICE_ATTR(dispregs, 0444, mb862xxfb_show_dispregs, NULL); 581 581 582 - irqreturn_t mb862xx_intr(int irq, void *dev_id) 582 + static irqreturn_t mb862xx_intr(int irq, void *dev_id) 583 583 { 584 584 struct mb862xxfb_par *par = (struct mb862xxfb_par *) dev_id; 585 585 unsigned long reg_ist, mask;
+1 -1
drivers/video/mbx/mbxfb.c
··· 950 950 951 951 mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr, 952 952 res_size(mfbi->fb_req)); 953 - if (!mfbi->reg_virt_addr) { 953 + if (!mfbi->fb_virt_addr) { 954 954 dev_err(&dev->dev, "failed to ioremap frame buffer\n"); 955 955 ret = -EINVAL; 956 956 goto err4;
+13
drivers/video/mxsfb.c
··· 889 889 return 0; 890 890 } 891 891 892 + static void mxsfb_shutdown(struct platform_device *pdev) 893 + { 894 + struct fb_info *fb_info = platform_get_drvdata(pdev); 895 + struct mxsfb_info *host = to_imxfb_host(fb_info); 896 + 897 + /* 898 + * Force stop the LCD controller as keeping it running during reboot 899 + * might interfere with the BootROM's boot mode pads sampling. 900 + */ 901 + writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR); 902 + } 903 + 892 904 static struct platform_device_id mxsfb_devtype[] = { 893 905 { 894 906 .name = "imx23-fb", ··· 917 905 static struct platform_driver mxsfb_driver = { 918 906 .probe = mxsfb_probe, 919 907 .remove = __devexit_p(mxsfb_remove), 908 + .shutdown = mxsfb_shutdown, 920 909 .id_table = mxsfb_devtype, 921 910 .driver = { 922 911 .name = DRIVER_NAME,
-8
drivers/video/omap/Kconfig
··· 39 39 the Mobile Industry Processor Interface DBI-C/DCS 40 40 specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3) 41 41 42 - config FB_OMAP_BOOTLOADER_INIT 43 - bool "Check bootloader initialization" 44 - depends on FB_OMAP 45 - help 46 - Say Y here if you want to enable checking if the bootloader has 47 - already initialized the display controller. In this case the 48 - driver will skip the initialization. 49 - 50 42 config FB_OMAP_CONSISTENT_DMA_SIZE 51 43 int "Consistent DMA memory size (MB)" 52 44 depends on FB_OMAP
-7
drivers/video/omap2/displays/panel-acx565akm.c
··· 739 739 } 740 740 } 741 741 742 - static void acx_panel_get_timings(struct omap_dss_device *dssdev, 743 - struct omap_video_timings *timings) 744 - { 745 - *timings = dssdev->panel.timings; 746 - } 747 - 748 742 static int acx_panel_check_timings(struct omap_dss_device *dssdev, 749 743 struct omap_video_timings *timings) 750 744 { ··· 756 762 .resume = acx_panel_resume, 757 763 758 764 .set_timings = acx_panel_set_timings, 759 - .get_timings = acx_panel_get_timings, 760 765 .check_timings = acx_panel_check_timings, 761 766 762 767 .get_recommended_bpp = acx_get_recommended_bpp,
+100 -7
drivers/video/omap2/displays/panel-generic-dpi.c
··· 386 386 387 387 .name = "innolux_at080tn52", 388 388 }, 389 + 390 + /* Mitsubishi AA084SB01 */ 391 + { 392 + { 393 + .x_res = 800, 394 + .y_res = 600, 395 + .pixel_clock = 40000, 396 + 397 + .hsw = 1, 398 + .hfp = 254, 399 + .hbp = 1, 400 + 401 + .vsw = 1, 402 + .vfp = 26, 403 + .vbp = 1, 404 + }, 405 + .config = OMAP_DSS_LCD_TFT, 406 + .name = "mitsubishi_aa084sb01", 407 + }, 408 + /* EDT ET0500G0DH6 */ 409 + { 410 + { 411 + .x_res = 800, 412 + .y_res = 480, 413 + .pixel_clock = 33260, 414 + 415 + .hsw = 128, 416 + .hfp = 216, 417 + .hbp = 40, 418 + 419 + .vsw = 2, 420 + .vfp = 35, 421 + .vbp = 10, 422 + }, 423 + .config = OMAP_DSS_LCD_TFT, 424 + .name = "edt_et0500g0dh6", 425 + }, 426 + 427 + /* Prime-View PD050VL1 */ 428 + { 429 + { 430 + .x_res = 640, 431 + .y_res = 480, 432 + 433 + .pixel_clock = 25000, 434 + 435 + .hsw = 96, 436 + .hfp = 18, 437 + .hbp = 46, 438 + 439 + .vsw = 2, 440 + .vfp = 10, 441 + .vbp = 33, 442 + }, 443 + .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | 444 + OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, 445 + .name = "primeview_pd050vl1", 446 + }, 447 + 448 + /* Prime-View PM070WL4 */ 449 + { 450 + { 451 + .x_res = 800, 452 + .y_res = 480, 453 + 454 + .pixel_clock = 32000, 455 + 456 + .hsw = 128, 457 + .hfp = 42, 458 + .hbp = 86, 459 + 460 + .vsw = 2, 461 + .vfp = 10, 462 + .vbp = 33, 463 + }, 464 + .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | 465 + OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, 466 + .name = "primeview_pm070wl4", 467 + }, 468 + 469 + /* Prime-View PD104SLF */ 470 + { 471 + { 472 + .x_res = 800, 473 + .y_res = 600, 474 + 475 + .pixel_clock = 40000, 476 + 477 + .hsw = 128, 478 + .hfp = 42, 479 + .hbp = 86, 480 + 481 + .vsw = 4, 482 + .vfp = 1, 483 + .vbp = 23, 484 + }, 485 + .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | 486 + OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, 487 + .name = "primeview_pd104slf", 488 + }, 389 489 }; 390 490 391 491 struct panel_drv_data { ··· 649 549 dpi_set_timings(dssdev, timings); 650 550 } 651 551 652 - static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev, 653 - struct omap_video_timings *timings) 654 - { 655 - *timings = dssdev->panel.timings; 656 - } 657 - 658 552 static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, 659 553 struct omap_video_timings *timings) 660 554 { ··· 665 571 .resume = generic_dpi_panel_resume, 666 572 667 573 .set_timings = generic_dpi_panel_set_timings, 668 - .get_timings = generic_dpi_panel_get_timings, 669 574 .check_timings = generic_dpi_panel_check_timings, 670 575 671 576 .driver = {
-8
drivers/video/omap2/displays/panel-n8x0.c
··· 610 610 return 0; 611 611 } 612 612 613 - static void n8x0_panel_get_timings(struct omap_dss_device *dssdev, 614 - struct omap_video_timings *timings) 615 - { 616 - *timings = dssdev->panel.timings; 617 - } 618 - 619 613 static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev, 620 614 u16 *xres, u16 *yres) 621 615 { ··· 671 677 672 678 .get_resolution = n8x0_panel_get_resolution, 673 679 .get_recommended_bpp = omapdss_default_get_recommended_bpp, 674 - 675 - .get_timings = n8x0_panel_get_timings, 676 680 677 681 .driver = { 678 682 .name = "n8x0_panel",
-88
drivers/video/omap2/displays/panel-taal.c
··· 30 30 #include <linux/gpio.h> 31 31 #include <linux/workqueue.h> 32 32 #include <linux/slab.h> 33 - #include <linux/regulator/consumer.h> 34 33 #include <linux/mutex.h> 35 34 36 35 #include <video/omapdss.h> ··· 53 54 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); 54 55 55 56 static int taal_panel_reset(struct omap_dss_device *dssdev); 56 - 57 - struct panel_regulator { 58 - struct regulator *regulator; 59 - const char *name; 60 - int min_uV; 61 - int max_uV; 62 - }; 63 - 64 - static void free_regulators(struct panel_regulator *regulators, int n) 65 - { 66 - int i; 67 - 68 - for (i = 0; i < n; i++) { 69 - /* disable/put in reverse order */ 70 - regulator_disable(regulators[n - i - 1].regulator); 71 - regulator_put(regulators[n - i - 1].regulator); 72 - } 73 - } 74 - 75 - static int init_regulators(struct omap_dss_device *dssdev, 76 - struct panel_regulator *regulators, int n) 77 - { 78 - int r, i, v; 79 - 80 - for (i = 0; i < n; i++) { 81 - struct regulator *reg; 82 - 83 - reg = regulator_get(&dssdev->dev, regulators[i].name); 84 - if (IS_ERR(reg)) { 85 - dev_err(&dssdev->dev, "failed to get regulator %s\n", 86 - regulators[i].name); 87 - r = PTR_ERR(reg); 88 - goto err; 89 - } 90 - 91 - /* FIXME: better handling of fixed vs. variable regulators */ 92 - v = regulator_get_voltage(reg); 93 - if (v < regulators[i].min_uV || v > regulators[i].max_uV) { 94 - r = regulator_set_voltage(reg, regulators[i].min_uV, 95 - regulators[i].max_uV); 96 - if (r) { 97 - dev_err(&dssdev->dev, 98 - "failed to set regulator %s voltage\n", 99 - regulators[i].name); 100 - regulator_put(reg); 101 - goto err; 102 - } 103 - } 104 - 105 - r = regulator_enable(reg); 106 - if (r) { 107 - dev_err(&dssdev->dev, "failed to enable regulator %s\n", 108 - regulators[i].name); 109 - regulator_put(reg); 110 - goto err; 111 - } 112 - 113 - regulators[i].regulator = reg; 114 - } 115 - 116 - return 0; 117 - 118 - err: 119 - free_regulators(regulators, i); 120 - 121 - return r; 122 - } 123 57 124 58 /** 125 59 * struct panel_config - panel configuration ··· 82 150 unsigned int low; 83 151 } reset_sequence; 84 152 85 - struct panel_regulator *regulators; 86 - int num_regulators; 87 153 }; 88 154 89 155 enum { ··· 507 577 .update_status = taal_bl_update_status, 508 578 }; 509 579 510 - static void taal_get_timings(struct omap_dss_device *dssdev, 511 - struct omap_video_timings *timings) 512 - { 513 - *timings = dssdev->panel.timings; 514 - } 515 - 516 580 static void taal_get_resolution(struct omap_dss_device *dssdev, 517 581 u16 *xres, u16 *yres) 518 582 { ··· 901 977 902 978 atomic_set(&td->do_update, 0); 903 979 904 - r = init_regulators(dssdev, panel_config->regulators, 905 - panel_config->num_regulators); 906 - if (r) 907 - goto err_reg; 908 - 909 980 td->workqueue = create_singlethread_workqueue("taal_esd"); 910 981 if (td->workqueue == NULL) { 911 982 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); ··· 1006 1087 err_rst_gpio: 1007 1088 destroy_workqueue(td->workqueue); 1008 1089 err_wq: 1009 - free_regulators(panel_config->regulators, panel_config->num_regulators); 1010 - err_reg: 1011 1090 kfree(td); 1012 1091 err: 1013 1092 return r; ··· 1041 1124 1042 1125 /* reset, to be sure that the panel is in a valid state */ 1043 1126 taal_hw_reset(dssdev); 1044 - 1045 - free_regulators(td->panel_config->regulators, 1046 - td->panel_config->num_regulators); 1047 1127 1048 1128 if (gpio_is_valid(panel_data->reset_gpio)) 1049 1129 gpio_free(panel_data->reset_gpio); ··· 1822 1908 .get_mirror = taal_get_mirror, 1823 1909 .run_test = taal_run_test, 1824 1910 .memory_read = taal_memory_read, 1825 - 1826 - .get_timings = taal_get_timings, 1827 1911 1828 1912 .driver = { 1829 1913 .name = "taal",
+40 -36
drivers/video/omap2/displays/panel-tfp410.c
··· 47 47 struct mutex lock; 48 48 49 49 int pd_gpio; 50 - }; 51 50 52 - static inline struct tfp410_platform_data 53 - *get_pdata(const struct omap_dss_device *dssdev) 54 - { 55 - return dssdev->data; 56 - } 51 + struct i2c_adapter *i2c_adapter; 52 + }; 57 53 58 54 static int tfp410_power_on(struct omap_dss_device *dssdev) 59 55 { ··· 64 68 goto err0; 65 69 66 70 if (gpio_is_valid(ddata->pd_gpio)) 67 - gpio_set_value(ddata->pd_gpio, 1); 71 + gpio_set_value_cansleep(ddata->pd_gpio, 1); 68 72 69 73 return 0; 70 74 err0: ··· 79 83 return; 80 84 81 85 if (gpio_is_valid(ddata->pd_gpio)) 82 - gpio_set_value(ddata->pd_gpio, 0); 86 + gpio_set_value_cansleep(ddata->pd_gpio, 0); 83 87 84 88 omapdss_dpi_display_disable(dssdev); 85 89 } 86 90 87 91 static int tfp410_probe(struct omap_dss_device *dssdev) 88 92 { 89 - struct tfp410_platform_data *pdata = get_pdata(dssdev); 90 93 struct panel_drv_data *ddata; 91 94 int r; 95 + int i2c_bus_num; 92 96 93 - ddata = kzalloc(sizeof(*ddata), GFP_KERNEL); 97 + ddata = devm_kzalloc(&dssdev->dev, sizeof(*ddata), GFP_KERNEL); 94 98 if (!ddata) 95 99 return -ENOMEM; 96 100 ··· 100 104 ddata->dssdev = dssdev; 101 105 mutex_init(&ddata->lock); 102 106 103 - if (pdata) 107 + if (dssdev->data) { 108 + struct tfp410_platform_data *pdata = dssdev->data; 109 + 104 110 ddata->pd_gpio = pdata->power_down_gpio; 105 - else 111 + i2c_bus_num = pdata->i2c_bus_num; 112 + } else { 106 113 ddata->pd_gpio = -1; 114 + i2c_bus_num = -1; 115 + } 107 116 108 117 if (gpio_is_valid(ddata->pd_gpio)) { 109 118 r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW, ··· 116 115 if (r) { 117 116 dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", 118 117 ddata->pd_gpio); 119 - ddata->pd_gpio = -1; 118 + return r; 120 119 } 120 + } 121 + 122 + if (i2c_bus_num != -1) { 123 + struct i2c_adapter *adapter; 124 + 125 + adapter = i2c_get_adapter(i2c_bus_num); 126 + if (!adapter) { 127 + dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", 128 + i2c_bus_num); 129 + r = -EINVAL; 130 + goto err_i2c; 131 + } 132 + 133 + ddata->i2c_adapter = adapter; 121 134 } 122 135 123 136 dev_set_drvdata(&dssdev->dev, ddata); 124 137 125 138 return 0; 139 + err_i2c: 140 + if (gpio_is_valid(ddata->pd_gpio)) 141 + gpio_free(ddata->pd_gpio); 142 + return r; 126 143 } 127 144 128 145 static void __exit tfp410_remove(struct omap_dss_device *dssdev) ··· 149 130 150 131 mutex_lock(&ddata->lock); 151 132 133 + if (ddata->i2c_adapter) 134 + i2c_put_adapter(ddata->i2c_adapter); 135 + 152 136 if (gpio_is_valid(ddata->pd_gpio)) 153 137 gpio_free(ddata->pd_gpio); 154 138 155 139 dev_set_drvdata(&dssdev->dev, NULL); 156 140 157 141 mutex_unlock(&ddata->lock); 158 - 159 - kfree(ddata); 160 142 } 161 143 162 144 static int tfp410_enable(struct omap_dss_device *dssdev) ··· 289 269 u8 *edid, int len) 290 270 { 291 271 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 292 - struct tfp410_platform_data *pdata = get_pdata(dssdev); 293 - struct i2c_adapter *adapter; 294 272 int r, l, bytes_read; 295 273 296 274 mutex_lock(&ddata->lock); 297 275 298 - if (pdata->i2c_bus_num == 0) { 276 + if (!ddata->i2c_adapter) { 299 277 r = -ENODEV; 300 278 goto err; 301 279 } 302 280 303 - adapter = i2c_get_adapter(pdata->i2c_bus_num); 304 - if (!adapter) { 305 - dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", 306 - pdata->i2c_bus_num); 307 - r = -EINVAL; 308 - goto err; 309 - } 310 - 311 281 l = min(EDID_LENGTH, len); 312 - r = tfp410_ddc_read(adapter, edid, l, 0); 282 + r = tfp410_ddc_read(ddata->i2c_adapter, edid, l, 0); 313 283 if (r) 314 284 goto err; 315 285 ··· 309 299 if (len > EDID_LENGTH && edid[0x7e] > 0) { 310 300 l = min(EDID_LENGTH, len - EDID_LENGTH); 311 301 312 - r = tfp410_ddc_read(adapter, edid + EDID_LENGTH, 302 + r = tfp410_ddc_read(ddata->i2c_adapter, edid + EDID_LENGTH, 313 303 l, EDID_LENGTH); 314 304 if (r) 315 305 goto err; ··· 329 319 static bool tfp410_detect(struct omap_dss_device *dssdev) 330 320 { 331 321 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 332 - struct tfp410_platform_data *pdata = get_pdata(dssdev); 333 - struct i2c_adapter *adapter; 334 322 unsigned char out; 335 323 int r; 336 324 337 325 mutex_lock(&ddata->lock); 338 326 339 - if (pdata->i2c_bus_num == 0) 327 + if (!ddata->i2c_adapter) 340 328 goto out; 341 329 342 - adapter = i2c_get_adapter(pdata->i2c_bus_num); 343 - if (!adapter) 344 - goto out; 345 - 346 - r = tfp410_ddc_read(adapter, &out, 1, 0); 330 + r = tfp410_ddc_read(ddata->i2c_adapter, &out, 1, 0); 347 331 348 332 mutex_unlock(&ddata->lock); 349 333
+20 -2
drivers/video/omap2/displays/panel-tpo-td043mtea1.c
··· 272 272 static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) 273 273 { 274 274 int nreset_gpio = tpo_td043->nreset_gpio; 275 + int r; 275 276 276 277 if (tpo_td043->powered_on) 277 278 return 0; 278 279 279 - regulator_enable(tpo_td043->vcc_reg); 280 + r = regulator_enable(tpo_td043->vcc_reg); 281 + if (r != 0) 282 + return r; 280 283 281 - /* wait for regulator to stabilize */ 284 + /* wait for panel to stabilize */ 282 285 msleep(160); 283 286 284 287 if (gpio_is_valid(nreset_gpio)) ··· 473 470 gpio_free(nreset_gpio); 474 471 } 475 472 473 + static void tpo_td043_set_timings(struct omap_dss_device *dssdev, 474 + struct omap_video_timings *timings) 475 + { 476 + dpi_set_timings(dssdev, timings); 477 + } 478 + 479 + static int tpo_td043_check_timings(struct omap_dss_device *dssdev, 480 + struct omap_video_timings *timings) 481 + { 482 + return dpi_check_timings(dssdev, timings); 483 + } 484 + 476 485 static struct omap_dss_driver tpo_td043_driver = { 477 486 .probe = tpo_td043_probe, 478 487 .remove = tpo_td043_remove, ··· 495 480 .resume = tpo_td043_resume, 496 481 .set_mirror = tpo_td043_set_hmirror, 497 482 .get_mirror = tpo_td043_get_hmirror, 483 + 484 + .set_timings = tpo_td043_set_timings, 485 + .check_timings = tpo_td043_check_timings, 498 486 499 487 .driver = { 500 488 .name = "tpo_td043mtea1_panel",
+4 -9
drivers/video/omap2/dss/Kconfig
··· 68 68 HDMI Interface. This adds the High Definition Multimedia Interface. 69 69 See http://www.hdmi.org/ for HDMI specification. 70 70 71 + config OMAP4_DSS_HDMI_AUDIO 72 + bool 73 + depends on OMAP4_DSS_HDMI 74 + 71 75 config OMAP2_DSS_SDI 72 76 bool "SDI support" 73 77 depends on ARCH_OMAP3 ··· 93 89 processor and a peripheral, such as a display or a framebuffer chip. 94 90 95 91 See http://www.mipi.org/ for DSI spesifications. 96 - 97 - config OMAP2_DSS_FAKE_VSYNC 98 - bool "Fake VSYNC irq from manual update displays" 99 - default n 100 - help 101 - If this is selected, DSI will generate a fake DISPC VSYNC interrupt 102 - when DSI has sent a frame. This is only needed with DSI or RFBI 103 - displays using manual mode, and you want VSYNC to, for example, 104 - time animation. 105 92 106 93 config OMAP2_DSS_MIN_FCK_PER_PCK 107 94 int "Minimum FCK/PCK ratio (for scaling)"
+101 -33
drivers/video/omap2/dss/apply.c
··· 99 99 100 100 /* If true, a display is enabled using this manager */ 101 101 bool enabled; 102 + 103 + bool extra_info_dirty; 104 + bool shadow_extra_info_dirty; 105 + 106 + struct omap_video_timings timings; 102 107 }; 103 108 104 109 static struct { ··· 181 176 } 182 177 183 178 static int dss_check_settings_low(struct omap_overlay_manager *mgr, 184 - struct omap_dss_device *dssdev, bool applying) 179 + bool applying) 185 180 { 186 181 struct omap_overlay_info *oi; 187 182 struct omap_overlay_manager_info *mi; ··· 191 186 struct mgr_priv_data *mp; 192 187 193 188 mp = get_mgr_priv(mgr); 189 + 190 + if (!mp->enabled) 191 + return 0; 194 192 195 193 if (applying && mp->user_info_dirty) 196 194 mi = &mp->user_info; ··· 214 206 ois[ovl->id] = oi; 215 207 } 216 208 217 - return dss_mgr_check(mgr, dssdev, mi, ois); 209 + return dss_mgr_check(mgr, mi, &mp->timings, ois); 218 210 } 219 211 220 212 /* 221 213 * check manager and overlay settings using overlay_info from data->info 222 214 */ 223 - static int dss_check_settings(struct omap_overlay_manager *mgr, 224 - struct omap_dss_device *dssdev) 215 + static int dss_check_settings(struct omap_overlay_manager *mgr) 225 216 { 226 - return dss_check_settings_low(mgr, dssdev, false); 217 + return dss_check_settings_low(mgr, false); 227 218 } 228 219 229 220 /* 230 221 * check manager and overlay settings using overlay_info from ovl->info if 231 222 * dirty and from data->info otherwise 232 223 */ 233 - static int dss_check_settings_apply(struct omap_overlay_manager *mgr, 234 - struct omap_dss_device *dssdev) 224 + static int dss_check_settings_apply(struct omap_overlay_manager *mgr) 235 225 { 236 - return dss_check_settings_low(mgr, dssdev, true); 226 + return dss_check_settings_low(mgr, true); 237 227 } 238 228 239 229 static bool need_isr(void) ··· 265 259 266 260 /* to set GO bit */ 267 261 if (mp->shadow_info_dirty) 262 + return true; 263 + 264 + /* 265 + * NOTE: we don't check extra_info flags for disabled 266 + * managers, once the manager is enabled, the extra_info 267 + * related manager changes will be taken in by HW. 268 + */ 269 + 270 + /* to write new values to registers */ 271 + if (mp->extra_info_dirty) 272 + return true; 273 + 274 + /* to set GO bit */ 275 + if (mp->shadow_extra_info_dirty) 268 276 return true; 269 277 270 278 list_for_each_entry(ovl, &mgr->overlays, list) { ··· 325 305 326 306 mp = get_mgr_priv(mgr); 327 307 328 - if (mp->shadow_info_dirty) 308 + if (mp->shadow_info_dirty || mp->shadow_extra_info_dirty) 329 309 return true; 330 310 331 311 list_for_each_entry(ovl, &mgr->overlays, list) { ··· 340 320 /* returns true if an extra_info field is currently being updated */ 341 321 static bool extra_info_update_ongoing(void) 342 322 { 343 - const int num_ovls = omap_dss_get_num_overlays(); 344 - struct ovl_priv_data *op; 345 - struct omap_overlay *ovl; 346 - struct mgr_priv_data *mp; 323 + const int num_mgrs = dss_feat_get_num_mgrs(); 347 324 int i; 348 325 349 - for (i = 0; i < num_ovls; ++i) { 350 - ovl = omap_dss_get_overlay(i); 351 - op = get_ovl_priv(ovl); 326 + for (i = 0; i < num_mgrs; ++i) { 327 + struct omap_overlay_manager *mgr; 328 + struct omap_overlay *ovl; 329 + struct mgr_priv_data *mp; 352 330 353 - if (!ovl->manager) 354 - continue; 355 - 356 - mp = get_mgr_priv(ovl->manager); 331 + mgr = omap_dss_get_overlay_manager(i); 332 + mp = get_mgr_priv(mgr); 357 333 358 334 if (!mp->enabled) 359 335 continue; ··· 357 341 if (!mp->updating) 358 342 continue; 359 343 360 - if (op->extra_info_dirty || op->shadow_extra_info_dirty) 344 + if (mp->extra_info_dirty || mp->shadow_extra_info_dirty) 361 345 return true; 346 + 347 + list_for_each_entry(ovl, &mgr->overlays, list) { 348 + struct ovl_priv_data *op = get_ovl_priv(ovl); 349 + 350 + if (op->extra_info_dirty || op->shadow_extra_info_dirty) 351 + return true; 352 + } 362 353 } 363 354 364 355 return false; ··· 548 525 549 526 oi = &op->info; 550 527 528 + mp = get_mgr_priv(ovl->manager); 529 + 551 530 replication = dss_use_replication(ovl->manager->device, oi->color_mode); 552 531 553 532 ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; 554 533 555 - r = dispc_ovl_setup(ovl->id, oi, ilace, replication); 534 + r = dispc_ovl_setup(ovl->id, oi, ilace, replication, &mp->timings); 556 535 if (r) { 557 536 /* 558 537 * We can't do much here, as this function can be called from ··· 567 542 dispc_ovl_enable(ovl->id, false); 568 543 return; 569 544 } 570 - 571 - mp = get_mgr_priv(ovl->manager); 572 545 573 546 op->info_dirty = false; 574 547 if (mp->updating) ··· 624 601 } 625 602 } 626 603 604 + static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr) 605 + { 606 + struct mgr_priv_data *mp = get_mgr_priv(mgr); 607 + 608 + DSSDBGF("%d", mgr->id); 609 + 610 + if (!mp->extra_info_dirty) 611 + return; 612 + 613 + dispc_mgr_set_timings(mgr->id, &mp->timings); 614 + 615 + mp->extra_info_dirty = false; 616 + if (mp->updating) 617 + mp->shadow_extra_info_dirty = true; 618 + } 619 + 627 620 static void dss_write_regs_common(void) 628 621 { 629 622 const int num_mgrs = omap_dss_get_num_overlay_managers(); ··· 685 646 if (!mp->enabled || mgr_manual_update(mgr) || mp->busy) 686 647 continue; 687 648 688 - r = dss_check_settings(mgr, mgr->device); 649 + r = dss_check_settings(mgr); 689 650 if (r) { 690 651 DSSERR("cannot write registers for manager %s: " 691 652 "illegal configuration\n", mgr->name); ··· 693 654 } 694 655 695 656 dss_mgr_write_regs(mgr); 657 + dss_mgr_write_regs_extra(mgr); 696 658 } 697 659 } 698 660 ··· 733 693 734 694 mp = get_mgr_priv(mgr); 735 695 mp->shadow_info_dirty = false; 696 + mp->shadow_extra_info_dirty = false; 736 697 737 698 list_for_each_entry(ovl, &mgr->overlays, list) { 738 699 op = get_ovl_priv(ovl); ··· 752 711 753 712 WARN_ON(mp->updating); 754 713 755 - r = dss_check_settings(mgr, mgr->device); 714 + r = dss_check_settings(mgr); 756 715 if (r) { 757 716 DSSERR("cannot start manual update: illegal configuration\n"); 758 717 spin_unlock_irqrestore(&data_lock, flags); ··· 760 719 } 761 720 762 721 dss_mgr_write_regs(mgr); 722 + dss_mgr_write_regs_extra(mgr); 763 723 764 724 dss_write_regs_common(); 765 725 ··· 899 857 900 858 spin_lock_irqsave(&data_lock, flags); 901 859 902 - r = dss_check_settings_apply(mgr, mgr->device); 860 + r = dss_check_settings_apply(mgr); 903 861 if (r) { 904 862 spin_unlock_irqrestore(&data_lock, flags); 905 863 DSSERR("failed to apply settings: illegal configuration.\n"); ··· 960 918 bool use_fifo_merge) 961 919 { 962 920 struct ovl_priv_data *op = get_ovl_priv(ovl); 963 - struct omap_dss_device *dssdev; 964 921 u32 fifo_low, fifo_high; 965 922 966 923 if (!op->enabled && !op->enabling) 967 924 return; 968 925 969 - dssdev = ovl->manager->device; 970 - 971 926 dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, 972 - use_fifo_merge); 927 + use_fifo_merge, ovl_manual_update(ovl)); 973 928 974 929 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); 975 930 } ··· 1089 1050 1090 1051 mp->enabled = true; 1091 1052 1092 - r = dss_check_settings(mgr, mgr->device); 1053 + r = dss_check_settings(mgr); 1093 1054 if (r) { 1094 1055 DSSERR("failed to enable manager %d: check_settings failed\n", 1095 1056 mgr->id); ··· 1264 1225 return r; 1265 1226 } 1266 1227 1228 + static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr, 1229 + struct omap_video_timings *timings) 1230 + { 1231 + struct mgr_priv_data *mp = get_mgr_priv(mgr); 1232 + 1233 + mp->timings = *timings; 1234 + mp->extra_info_dirty = true; 1235 + } 1236 + 1237 + void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 1238 + struct omap_video_timings *timings) 1239 + { 1240 + unsigned long flags; 1241 + 1242 + mutex_lock(&apply_lock); 1243 + 1244 + spin_lock_irqsave(&data_lock, flags); 1245 + 1246 + dss_apply_mgr_timings(mgr, timings); 1247 + 1248 + dss_write_regs(); 1249 + dss_set_go_bits(); 1250 + 1251 + spin_unlock_irqrestore(&data_lock, flags); 1252 + 1253 + wait_pending_extra_info_updates(); 1254 + 1255 + mutex_unlock(&apply_lock); 1256 + } 1267 1257 1268 1258 int dss_ovl_set_info(struct omap_overlay *ovl, 1269 1259 struct omap_overlay_info *info) ··· 1461 1393 1462 1394 op->enabling = true; 1463 1395 1464 - r = dss_check_settings(ovl->manager, ovl->manager->device); 1396 + r = dss_check_settings(ovl->manager); 1465 1397 if (r) { 1466 1398 DSSERR("failed to enable overlay %d: check_settings failed\n", 1467 1399 ovl->id);
+152 -103
drivers/video/omap2/dss/core.c
··· 43 43 44 44 struct regulator *vdds_dsi_reg; 45 45 struct regulator *vdds_sdi_reg; 46 + 47 + const char *default_display_name; 46 48 } core; 47 49 48 50 static char *def_disp_name; ··· 55 53 bool dss_debug; 56 54 module_param_named(debug, dss_debug, bool, 0644); 57 55 #endif 58 - 59 - static int omap_dss_register_device(struct omap_dss_device *); 60 - static void omap_dss_unregister_device(struct omap_dss_device *); 61 56 62 57 /* REGULATORS */ 63 58 ··· 84 85 core.vdds_sdi_reg = reg; 85 86 86 87 return reg; 88 + } 89 + 90 + int dss_get_ctx_loss_count(struct device *dev) 91 + { 92 + struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; 93 + int cnt; 94 + 95 + if (!board_data->get_context_loss_count) 96 + return -ENOENT; 97 + 98 + cnt = board_data->get_context_loss_count(dev); 99 + 100 + WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt); 101 + 102 + return cnt; 103 + } 104 + 105 + int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask) 106 + { 107 + struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; 108 + 109 + if (!board_data->dsi_enable_pads) 110 + return -ENOENT; 111 + 112 + return board_data->dsi_enable_pads(dsi_id, lane_mask); 113 + } 114 + 115 + void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask) 116 + { 117 + struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; 118 + 119 + if (!board_data->dsi_enable_pads) 120 + return; 121 + 122 + return board_data->dsi_disable_pads(dsi_id, lane_mask); 123 + } 124 + 125 + int dss_set_min_bus_tput(struct device *dev, unsigned long tput) 126 + { 127 + struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; 128 + 129 + if (pdata->set_min_bus_tput) 130 + return pdata->set_min_bus_tput(dev, tput); 131 + else 132 + return 0; 87 133 } 88 134 89 135 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) ··· 165 121 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, 166 122 &dss_debug_dump_clocks, &dss_debug_fops); 167 123 168 - #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 169 - debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, 170 - &dispc_dump_irqs, &dss_debug_fops); 171 - #endif 172 - 173 - #if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS) 174 - dsi_create_debugfs_files_irq(dss_debugfs_dir, &dss_debug_fops); 175 - #endif 176 - 177 - debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, 178 - &dss_dump_regs, &dss_debug_fops); 179 - debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir, 180 - &dispc_dump_regs, &dss_debug_fops); 181 - #ifdef CONFIG_OMAP2_DSS_RFBI 182 - debugfs_create_file("rfbi", S_IRUGO, dss_debugfs_dir, 183 - &rfbi_dump_regs, &dss_debug_fops); 184 - #endif 185 - #ifdef CONFIG_OMAP2_DSS_DSI 186 - dsi_create_debugfs_files_reg(dss_debugfs_dir, &dss_debug_fops); 187 - #endif 188 - #ifdef CONFIG_OMAP2_DSS_VENC 189 - debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir, 190 - &venc_dump_regs, &dss_debug_fops); 191 - #endif 192 - #ifdef CONFIG_OMAP4_DSS_HDMI 193 - debugfs_create_file("hdmi", S_IRUGO, dss_debugfs_dir, 194 - &hdmi_dump_regs, &dss_debug_fops); 195 - #endif 196 124 return 0; 197 125 } 198 126 ··· 172 156 { 173 157 if (dss_debugfs_dir) 174 158 debugfs_remove_recursive(dss_debugfs_dir); 159 + } 160 + 161 + int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)) 162 + { 163 + struct dentry *d; 164 + 165 + d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, 166 + write, &dss_debug_fops); 167 + 168 + if (IS_ERR(d)) 169 + return PTR_ERR(d); 170 + 171 + return 0; 175 172 } 176 173 #else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ 177 174 static inline int dss_initialize_debugfs(void) ··· 194 165 static inline void dss_uninitialize_debugfs(void) 195 166 { 196 167 } 168 + static inline int dss_debugfs_create_file(const char *name, 169 + void (*write)(struct seq_file *)) 170 + { 171 + return 0; 172 + } 197 173 #endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ 198 174 199 175 /* PLATFORM DEVICE */ 200 - static int omap_dss_probe(struct platform_device *pdev) 176 + static int __init omap_dss_probe(struct platform_device *pdev) 201 177 { 202 178 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 203 179 int r; 204 - int i; 205 180 206 181 core.pdev = pdev; 207 182 ··· 220 187 if (r) 221 188 goto err_debugfs; 222 189 223 - for (i = 0; i < pdata->num_devices; ++i) { 224 - struct omap_dss_device *dssdev = pdata->devices[i]; 225 - 226 - r = omap_dss_register_device(dssdev); 227 - if (r) { 228 - DSSERR("device %d %s register failed %d\n", i, 229 - dssdev->name ?: "unnamed", r); 230 - 231 - while (--i >= 0) 232 - omap_dss_unregister_device(pdata->devices[i]); 233 - 234 - goto err_register; 235 - } 236 - 237 - if (def_disp_name && strcmp(def_disp_name, dssdev->name) == 0) 238 - pdata->default_device = dssdev; 239 - } 190 + if (def_disp_name) 191 + core.default_display_name = def_disp_name; 192 + else if (pdata->default_device) 193 + core.default_display_name = pdata->default_device->name; 240 194 241 195 return 0; 242 196 243 - err_register: 244 - dss_uninitialize_debugfs(); 245 197 err_debugfs: 246 198 247 199 return r; ··· 234 216 235 217 static int omap_dss_remove(struct platform_device *pdev) 236 218 { 237 - struct omap_dss_board_info *pdata = pdev->dev.platform_data; 238 - int i; 239 - 240 219 dss_uninitialize_debugfs(); 241 220 242 221 dss_uninit_overlays(pdev); 243 222 dss_uninit_overlay_managers(pdev); 244 - 245 - for (i = 0; i < pdata->num_devices; ++i) 246 - omap_dss_unregister_device(pdata->devices[i]); 247 223 248 224 return 0; 249 225 } ··· 263 251 } 264 252 265 253 static struct platform_driver omap_dss_driver = { 266 - .probe = omap_dss_probe, 267 254 .remove = omap_dss_remove, 268 255 .shutdown = omap_dss_shutdown, 269 256 .suspend = omap_dss_suspend, ··· 337 326 int r; 338 327 struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); 339 328 struct omap_dss_device *dssdev = to_dss_device(dev); 340 - struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; 341 329 bool force; 342 330 343 331 DSSDBG("driver_probe: dev %s/%s, drv %s\n", ··· 345 335 346 336 dss_init_device(core.pdev, dssdev); 347 337 348 - force = pdata->default_device == dssdev; 338 + force = core.default_display_name && 339 + strcmp(core.default_display_name, dssdev->name) == 0; 349 340 dss_recheck_connections(dssdev, force); 350 341 351 342 r = dssdrv->probe(dssdev); ··· 392 381 if (dssdriver->get_recommended_bpp == NULL) 393 382 dssdriver->get_recommended_bpp = 394 383 omapdss_default_get_recommended_bpp; 384 + if (dssdriver->get_timings == NULL) 385 + dssdriver->get_timings = omapdss_default_get_timings; 395 386 396 387 return driver_register(&dssdriver->driver); 397 388 } ··· 440 427 reset_device(dev, 0); 441 428 } 442 429 443 - static int omap_dss_register_device(struct omap_dss_device *dssdev) 430 + int omap_dss_register_device(struct omap_dss_device *dssdev, 431 + struct device *parent, int disp_num) 444 432 { 445 - static int dev_num; 446 - 447 433 WARN_ON(!dssdev->driver_name); 448 434 449 435 reset_device(&dssdev->dev, 1); 450 436 dssdev->dev.bus = &dss_bus_type; 451 - dssdev->dev.parent = &dss_bus; 437 + dssdev->dev.parent = parent; 452 438 dssdev->dev.release = omap_dss_dev_release; 453 - dev_set_name(&dssdev->dev, "display%d", dev_num++); 439 + dev_set_name(&dssdev->dev, "display%d", disp_num); 454 440 return device_register(&dssdev->dev); 455 441 } 456 442 457 - static void omap_dss_unregister_device(struct omap_dss_device *dssdev) 443 + void omap_dss_unregister_device(struct omap_dss_device *dssdev) 458 444 { 459 445 device_unregister(&dssdev->dev); 460 446 } 461 447 448 + static int dss_unregister_dss_dev(struct device *dev, void *data) 449 + { 450 + struct omap_dss_device *dssdev = to_dss_device(dev); 451 + omap_dss_unregister_device(dssdev); 452 + return 0; 453 + } 454 + 455 + void omap_dss_unregister_child_devices(struct device *parent) 456 + { 457 + device_for_each_child(parent, NULL, dss_unregister_dss_dev); 458 + } 459 + 462 460 /* BUS */ 463 - static int omap_dss_bus_register(void) 461 + static int __init omap_dss_bus_register(void) 464 462 { 465 463 int r; 466 464 ··· 493 469 } 494 470 495 471 /* INIT */ 472 + static int (*dss_output_drv_reg_funcs[])(void) __initdata = { 473 + #ifdef CONFIG_OMAP2_DSS_DPI 474 + dpi_init_platform_driver, 475 + #endif 476 + #ifdef CONFIG_OMAP2_DSS_SDI 477 + sdi_init_platform_driver, 478 + #endif 479 + #ifdef CONFIG_OMAP2_DSS_RFBI 480 + rfbi_init_platform_driver, 481 + #endif 482 + #ifdef CONFIG_OMAP2_DSS_VENC 483 + venc_init_platform_driver, 484 + #endif 485 + #ifdef CONFIG_OMAP2_DSS_DSI 486 + dsi_init_platform_driver, 487 + #endif 488 + #ifdef CONFIG_OMAP4_DSS_HDMI 489 + hdmi_init_platform_driver, 490 + #endif 491 + }; 492 + 493 + static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { 494 + #ifdef CONFIG_OMAP2_DSS_DPI 495 + dpi_uninit_platform_driver, 496 + #endif 497 + #ifdef CONFIG_OMAP2_DSS_SDI 498 + sdi_uninit_platform_driver, 499 + #endif 500 + #ifdef CONFIG_OMAP2_DSS_RFBI 501 + rfbi_uninit_platform_driver, 502 + #endif 503 + #ifdef CONFIG_OMAP2_DSS_VENC 504 + venc_uninit_platform_driver, 505 + #endif 506 + #ifdef CONFIG_OMAP2_DSS_DSI 507 + dsi_uninit_platform_driver, 508 + #endif 509 + #ifdef CONFIG_OMAP4_DSS_HDMI 510 + hdmi_uninit_platform_driver, 511 + #endif 512 + }; 513 + 514 + static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)]; 496 515 497 516 static int __init omap_dss_register_drivers(void) 498 517 { 499 518 int r; 519 + int i; 500 520 501 - r = platform_driver_register(&omap_dss_driver); 521 + r = platform_driver_probe(&omap_dss_driver, omap_dss_probe); 502 522 if (r) 503 523 return r; 504 524 ··· 558 490 goto err_dispc; 559 491 } 560 492 561 - r = rfbi_init_platform_driver(); 562 - if (r) { 563 - DSSERR("Failed to initialize rfbi platform driver\n"); 564 - goto err_rfbi; 565 - } 566 - 567 - r = venc_init_platform_driver(); 568 - if (r) { 569 - DSSERR("Failed to initialize venc platform driver\n"); 570 - goto err_venc; 571 - } 572 - 573 - r = dsi_init_platform_driver(); 574 - if (r) { 575 - DSSERR("Failed to initialize DSI platform driver\n"); 576 - goto err_dsi; 577 - } 578 - 579 - r = hdmi_init_platform_driver(); 580 - if (r) { 581 - DSSERR("Failed to initialize hdmi\n"); 582 - goto err_hdmi; 493 + /* 494 + * It's ok if the output-driver register fails. It happens, for example, 495 + * when there is no output-device (e.g. SDI for OMAP4). 496 + */ 497 + for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) { 498 + r = dss_output_drv_reg_funcs[i](); 499 + if (r == 0) 500 + dss_output_drv_loaded[i] = true; 583 501 } 584 502 585 503 return 0; 586 504 587 - err_hdmi: 588 - dsi_uninit_platform_driver(); 589 - err_dsi: 590 - venc_uninit_platform_driver(); 591 - err_venc: 592 - rfbi_uninit_platform_driver(); 593 - err_rfbi: 594 - dispc_uninit_platform_driver(); 595 505 err_dispc: 596 506 dss_uninit_platform_driver(); 597 507 err_dss: ··· 580 534 581 535 static void __exit omap_dss_unregister_drivers(void) 582 536 { 583 - hdmi_uninit_platform_driver(); 584 - dsi_uninit_platform_driver(); 585 - venc_uninit_platform_driver(); 586 - rfbi_uninit_platform_driver(); 537 + int i; 538 + 539 + for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i) { 540 + if (dss_output_drv_loaded[i]) 541 + dss_output_drv_unreg_funcs[i](); 542 + } 543 + 587 544 dispc_uninit_platform_driver(); 588 545 dss_uninit_platform_driver(); 589 546
+535 -214
drivers/video/omap2/dss/dispc.c
··· 131 131 return __raw_readl(dispc.base + idx); 132 132 } 133 133 134 - static int dispc_get_ctx_loss_count(void) 135 - { 136 - struct device *dev = &dispc.pdev->dev; 137 - struct omap_display_platform_data *pdata = dev->platform_data; 138 - struct omap_dss_board_info *board_data = pdata->board_data; 139 - int cnt; 140 - 141 - if (!board_data->get_context_loss_count) 142 - return -ENOENT; 143 - 144 - cnt = board_data->get_context_loss_count(dev); 145 - 146 - WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt); 147 - 148 - return cnt; 149 - } 150 - 151 134 #define SR(reg) \ 152 135 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) 153 136 #define RR(reg) \ ··· 234 251 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 235 252 SR(DIVISOR); 236 253 237 - dispc.ctx_loss_cnt = dispc_get_ctx_loss_count(); 254 + dispc.ctx_loss_cnt = dss_get_ctx_loss_count(&dispc.pdev->dev); 238 255 dispc.ctx_valid = true; 239 256 240 257 DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt); ··· 249 266 if (!dispc.ctx_valid) 250 267 return; 251 268 252 - ctx = dispc_get_ctx_loss_count(); 269 + ctx = dss_get_ctx_loss_count(&dispc.pdev->dev); 253 270 254 271 if (ctx >= 0 && ctx == dispc.ctx_loss_cnt) 255 272 return; ··· 396 413 return false; 397 414 } 398 415 399 - static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel) 400 - { 401 - struct omap_overlay_manager *mgr = 402 - omap_dss_get_overlay_manager(channel); 403 - 404 - return mgr ? mgr->device : NULL; 405 - } 406 - 407 416 u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) 408 417 { 409 418 switch (channel) { ··· 407 432 return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 408 433 default: 409 434 BUG(); 435 + return 0; 410 436 } 411 437 } 412 438 ··· 422 446 return 0; 423 447 default: 424 448 BUG(); 449 + return 0; 425 450 } 426 451 } 427 452 ··· 741 764 case OMAP_DSS_COLOR_XRGB16_1555: 742 765 m = 0xf; break; 743 766 default: 744 - BUG(); break; 767 + BUG(); return; 745 768 } 746 769 } else { 747 770 switch (color_mode) { ··· 778 801 case OMAP_DSS_COLOR_XRGB16_1555: 779 802 m = 0xf; break; 780 803 default: 781 - BUG(); break; 804 + BUG(); return; 782 805 } 783 806 } 784 807 785 808 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); 809 + } 810 + 811 + static void dispc_ovl_configure_burst_type(enum omap_plane plane, 812 + enum omap_dss_rotation_type rotation_type) 813 + { 814 + if (dss_has_feature(FEAT_BURST_2D) == 0) 815 + return; 816 + 817 + if (rotation_type == OMAP_DSS_ROT_TILER) 818 + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 1, 29, 29); 819 + else 820 + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 0, 29, 29); 786 821 } 787 822 788 823 void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) ··· 834 845 break; 835 846 default: 836 847 BUG(); 848 + return; 837 849 } 838 850 839 851 val = FLD_MOD(val, chan, shift, shift); ··· 862 872 break; 863 873 default: 864 874 BUG(); 875 + return 0; 865 876 } 866 877 867 878 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); ··· 974 983 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift); 975 984 } 976 985 977 - void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height) 986 + static void dispc_mgr_set_size(enum omap_channel channel, u16 width, 987 + u16 height) 978 988 { 979 989 u32 val; 980 - BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 990 + 981 991 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 982 992 dispc_write_reg(DISPC_SIZE_MGR(channel), val); 983 - } 984 - 985 - void dispc_set_digit_size(u16 width, u16 height) 986 - { 987 - u32 val; 988 - BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 989 - val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 990 - dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val); 991 993 } 992 994 993 995 static void dispc_read_plane_fifo_sizes(void) ··· 1047 1063 } 1048 1064 1049 1065 void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, 1050 - u32 *fifo_low, u32 *fifo_high, bool use_fifomerge) 1066 + u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, 1067 + bool manual_update) 1051 1068 { 1052 1069 /* 1053 1070 * All sizes are in bytes. Both the buffer and burst are made of ··· 1076 1091 * combined fifo size 1077 1092 */ 1078 1093 1079 - if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { 1094 + if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { 1080 1095 *fifo_low = ovl_fifo_size - burst_size * 2; 1081 1096 *fifo_high = total_fifo_size - burst_size; 1082 1097 } else { ··· 1170 1185 dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp); 1171 1186 } 1172 1187 1188 + static void dispc_ovl_set_accu_uv(enum omap_plane plane, 1189 + u16 orig_width, u16 orig_height, u16 out_width, u16 out_height, 1190 + bool ilace, enum omap_color_mode color_mode, u8 rotation) 1191 + { 1192 + int h_accu2_0, h_accu2_1; 1193 + int v_accu2_0, v_accu2_1; 1194 + int chroma_hinc, chroma_vinc; 1195 + int idx; 1196 + 1197 + struct accu { 1198 + s8 h0_m, h0_n; 1199 + s8 h1_m, h1_n; 1200 + s8 v0_m, v0_n; 1201 + s8 v1_m, v1_n; 1202 + }; 1203 + 1204 + const struct accu *accu_table; 1205 + const struct accu *accu_val; 1206 + 1207 + static const struct accu accu_nv12[4] = { 1208 + { 0, 1, 0, 1 , -1, 2, 0, 1 }, 1209 + { 1, 2, -3, 4 , 0, 1, 0, 1 }, 1210 + { -1, 1, 0, 1 , -1, 2, 0, 1 }, 1211 + { -1, 2, -1, 2 , -1, 1, 0, 1 }, 1212 + }; 1213 + 1214 + static const struct accu accu_nv12_ilace[4] = { 1215 + { 0, 1, 0, 1 , -3, 4, -1, 4 }, 1216 + { -1, 4, -3, 4 , 0, 1, 0, 1 }, 1217 + { -1, 1, 0, 1 , -1, 4, -3, 4 }, 1218 + { -3, 4, -3, 4 , -1, 1, 0, 1 }, 1219 + }; 1220 + 1221 + static const struct accu accu_yuv[4] = { 1222 + { 0, 1, 0, 1, 0, 1, 0, 1 }, 1223 + { 0, 1, 0, 1, 0, 1, 0, 1 }, 1224 + { -1, 1, 0, 1, 0, 1, 0, 1 }, 1225 + { 0, 1, 0, 1, -1, 1, 0, 1 }, 1226 + }; 1227 + 1228 + switch (rotation) { 1229 + case OMAP_DSS_ROT_0: 1230 + idx = 0; 1231 + break; 1232 + case OMAP_DSS_ROT_90: 1233 + idx = 1; 1234 + break; 1235 + case OMAP_DSS_ROT_180: 1236 + idx = 2; 1237 + break; 1238 + case OMAP_DSS_ROT_270: 1239 + idx = 3; 1240 + break; 1241 + default: 1242 + BUG(); 1243 + return; 1244 + } 1245 + 1246 + switch (color_mode) { 1247 + case OMAP_DSS_COLOR_NV12: 1248 + if (ilace) 1249 + accu_table = accu_nv12_ilace; 1250 + else 1251 + accu_table = accu_nv12; 1252 + break; 1253 + case OMAP_DSS_COLOR_YUV2: 1254 + case OMAP_DSS_COLOR_UYVY: 1255 + accu_table = accu_yuv; 1256 + break; 1257 + default: 1258 + BUG(); 1259 + return; 1260 + } 1261 + 1262 + accu_val = &accu_table[idx]; 1263 + 1264 + chroma_hinc = 1024 * orig_width / out_width; 1265 + chroma_vinc = 1024 * orig_height / out_height; 1266 + 1267 + h_accu2_0 = (accu_val->h0_m * chroma_hinc / accu_val->h0_n) % 1024; 1268 + h_accu2_1 = (accu_val->h1_m * chroma_hinc / accu_val->h1_n) % 1024; 1269 + v_accu2_0 = (accu_val->v0_m * chroma_vinc / accu_val->v0_n) % 1024; 1270 + v_accu2_1 = (accu_val->v1_m * chroma_vinc / accu_val->v1_n) % 1024; 1271 + 1272 + dispc_ovl_set_vid_accu2_0(plane, h_accu2_0, v_accu2_0); 1273 + dispc_ovl_set_vid_accu2_1(plane, h_accu2_1, v_accu2_1); 1274 + } 1275 + 1173 1276 static void dispc_ovl_set_scaling_common(enum omap_plane plane, 1174 1277 u16 orig_width, u16 orig_height, 1175 1278 u16 out_width, u16 out_height, ··· 1331 1258 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); 1332 1259 return; 1333 1260 } 1261 + 1262 + dispc_ovl_set_accu_uv(plane, orig_width, orig_height, out_width, 1263 + out_height, ilace, color_mode, rotation); 1264 + 1334 1265 switch (color_mode) { 1335 1266 case OMAP_DSS_COLOR_NV12: 1336 1267 /* UV is subsampled by 2 vertically*/ ··· 1357 1280 break; 1358 1281 default: 1359 1282 BUG(); 1283 + return; 1360 1284 } 1361 1285 1362 1286 if (out_width != orig_width) ··· 1375 1297 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5); 1376 1298 /* set V scaling */ 1377 1299 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6); 1378 - 1379 - dispc_ovl_set_vid_accu2_0(plane, 0x80, 0); 1380 - dispc_ovl_set_vid_accu2_1(plane, 0x80, 0); 1381 1300 } 1382 1301 1383 1302 static void dispc_ovl_set_scaling(enum omap_plane plane, ··· 1485 1410 return 32; 1486 1411 default: 1487 1412 BUG(); 1413 + return 0; 1488 1414 } 1489 1415 } 1490 1416 ··· 1499 1423 return 1 - (-pixels + 1) * ps; 1500 1424 else 1501 1425 BUG(); 1426 + return 0; 1502 1427 } 1503 1428 1504 1429 static void calc_vrfb_rotation_offset(u8 rotation, bool mirror, ··· 1508 1431 enum omap_color_mode color_mode, bool fieldmode, 1509 1432 unsigned int field_offset, 1510 1433 unsigned *offset0, unsigned *offset1, 1511 - s32 *row_inc, s32 *pix_inc) 1434 + s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim) 1512 1435 { 1513 1436 u8 ps; 1514 1437 ··· 1554 1477 else 1555 1478 *offset0 = 0; 1556 1479 1557 - *row_inc = pixinc(1 + (screen_width - width) + 1558 - (fieldmode ? screen_width : 0), 1559 - ps); 1560 - *pix_inc = pixinc(1, ps); 1480 + *row_inc = pixinc(1 + 1481 + (y_predecim * screen_width - x_predecim * width) + 1482 + (fieldmode ? screen_width : 0), ps); 1483 + *pix_inc = pixinc(x_predecim, ps); 1561 1484 break; 1562 1485 1563 1486 case OMAP_DSS_ROT_0 + 4: ··· 1575 1498 *offset0 = field_offset * screen_width * ps; 1576 1499 else 1577 1500 *offset0 = 0; 1578 - *row_inc = pixinc(1 - (screen_width + width) - 1579 - (fieldmode ? screen_width : 0), 1580 - ps); 1581 - *pix_inc = pixinc(1, ps); 1501 + *row_inc = pixinc(1 - 1502 + (y_predecim * screen_width + x_predecim * width) - 1503 + (fieldmode ? screen_width : 0), ps); 1504 + *pix_inc = pixinc(x_predecim, ps); 1582 1505 break; 1583 1506 1584 1507 default: 1585 1508 BUG(); 1509 + return; 1586 1510 } 1587 1511 } 1588 1512 ··· 1593 1515 enum omap_color_mode color_mode, bool fieldmode, 1594 1516 unsigned int field_offset, 1595 1517 unsigned *offset0, unsigned *offset1, 1596 - s32 *row_inc, s32 *pix_inc) 1518 + s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim) 1597 1519 { 1598 1520 u8 ps; 1599 1521 u16 fbw, fbh; ··· 1635 1557 *offset0 = *offset1 + field_offset * screen_width * ps; 1636 1558 else 1637 1559 *offset0 = *offset1; 1638 - *row_inc = pixinc(1 + (screen_width - fbw) + 1639 - (fieldmode ? screen_width : 0), 1640 - ps); 1641 - *pix_inc = pixinc(1, ps); 1560 + *row_inc = pixinc(1 + 1561 + (y_predecim * screen_width - fbw * x_predecim) + 1562 + (fieldmode ? screen_width : 0), ps); 1563 + if (color_mode == OMAP_DSS_COLOR_YUV2 || 1564 + color_mode == OMAP_DSS_COLOR_UYVY) 1565 + *pix_inc = pixinc(x_predecim, 2 * ps); 1566 + else 1567 + *pix_inc = pixinc(x_predecim, ps); 1642 1568 break; 1643 1569 case OMAP_DSS_ROT_90: 1644 1570 *offset1 = screen_width * (fbh - 1) * ps; ··· 1650 1568 *offset0 = *offset1 + field_offset * ps; 1651 1569 else 1652 1570 *offset0 = *offset1; 1653 - *row_inc = pixinc(screen_width * (fbh - 1) + 1 + 1654 - (fieldmode ? 1 : 0), ps); 1655 - *pix_inc = pixinc(-screen_width, ps); 1571 + *row_inc = pixinc(screen_width * (fbh * x_predecim - 1) + 1572 + y_predecim + (fieldmode ? 1 : 0), ps); 1573 + *pix_inc = pixinc(-x_predecim * screen_width, ps); 1656 1574 break; 1657 1575 case OMAP_DSS_ROT_180: 1658 1576 *offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps; ··· 1661 1579 else 1662 1580 *offset0 = *offset1; 1663 1581 *row_inc = pixinc(-1 - 1664 - (screen_width - fbw) - 1665 - (fieldmode ? screen_width : 0), 1666 - ps); 1667 - *pix_inc = pixinc(-1, ps); 1582 + (y_predecim * screen_width - fbw * x_predecim) - 1583 + (fieldmode ? screen_width : 0), ps); 1584 + if (color_mode == OMAP_DSS_COLOR_YUV2 || 1585 + color_mode == OMAP_DSS_COLOR_UYVY) 1586 + *pix_inc = pixinc(-x_predecim, 2 * ps); 1587 + else 1588 + *pix_inc = pixinc(-x_predecim, ps); 1668 1589 break; 1669 1590 case OMAP_DSS_ROT_270: 1670 1591 *offset1 = (fbw - 1) * ps; ··· 1675 1590 *offset0 = *offset1 - field_offset * ps; 1676 1591 else 1677 1592 *offset0 = *offset1; 1678 - *row_inc = pixinc(-screen_width * (fbh - 1) - 1 - 1679 - (fieldmode ? 1 : 0), ps); 1680 - *pix_inc = pixinc(screen_width, ps); 1593 + *row_inc = pixinc(-screen_width * (fbh * x_predecim - 1) - 1594 + y_predecim - (fieldmode ? 1 : 0), ps); 1595 + *pix_inc = pixinc(x_predecim * screen_width, ps); 1681 1596 break; 1682 1597 1683 1598 /* mirroring */ ··· 1687 1602 *offset0 = *offset1 + field_offset * screen_width * ps; 1688 1603 else 1689 1604 *offset0 = *offset1; 1690 - *row_inc = pixinc(screen_width * 2 - 1 + 1605 + *row_inc = pixinc(y_predecim * screen_width * 2 - 1 + 1691 1606 (fieldmode ? screen_width : 0), 1692 1607 ps); 1693 - *pix_inc = pixinc(-1, ps); 1608 + if (color_mode == OMAP_DSS_COLOR_YUV2 || 1609 + color_mode == OMAP_DSS_COLOR_UYVY) 1610 + *pix_inc = pixinc(-x_predecim, 2 * ps); 1611 + else 1612 + *pix_inc = pixinc(-x_predecim, ps); 1694 1613 break; 1695 1614 1696 1615 case OMAP_DSS_ROT_90 + 4: ··· 1703 1614 *offset0 = *offset1 + field_offset * ps; 1704 1615 else 1705 1616 *offset0 = *offset1; 1706 - *row_inc = pixinc(-screen_width * (fbh - 1) + 1 + 1707 - (fieldmode ? 1 : 0), 1617 + *row_inc = pixinc(-screen_width * (fbh * x_predecim - 1) + 1618 + y_predecim + (fieldmode ? 1 : 0), 1708 1619 ps); 1709 - *pix_inc = pixinc(screen_width, ps); 1620 + *pix_inc = pixinc(x_predecim * screen_width, ps); 1710 1621 break; 1711 1622 1712 1623 case OMAP_DSS_ROT_180 + 4: ··· 1715 1626 *offset0 = *offset1 - field_offset * screen_width * ps; 1716 1627 else 1717 1628 *offset0 = *offset1; 1718 - *row_inc = pixinc(1 - screen_width * 2 - 1629 + *row_inc = pixinc(1 - y_predecim * screen_width * 2 - 1719 1630 (fieldmode ? screen_width : 0), 1720 1631 ps); 1721 - *pix_inc = pixinc(1, ps); 1632 + if (color_mode == OMAP_DSS_COLOR_YUV2 || 1633 + color_mode == OMAP_DSS_COLOR_UYVY) 1634 + *pix_inc = pixinc(x_predecim, 2 * ps); 1635 + else 1636 + *pix_inc = pixinc(x_predecim, ps); 1722 1637 break; 1723 1638 1724 1639 case OMAP_DSS_ROT_270 + 4: ··· 1731 1638 *offset0 = *offset1 - field_offset * ps; 1732 1639 else 1733 1640 *offset0 = *offset1; 1734 - *row_inc = pixinc(screen_width * (fbh - 1) - 1 - 1735 - (fieldmode ? 1 : 0), 1641 + *row_inc = pixinc(screen_width * (fbh * x_predecim - 1) - 1642 + y_predecim - (fieldmode ? 1 : 0), 1736 1643 ps); 1737 - *pix_inc = pixinc(-screen_width, ps); 1644 + *pix_inc = pixinc(-x_predecim * screen_width, ps); 1738 1645 break; 1739 1646 1740 1647 default: 1741 1648 BUG(); 1649 + return; 1742 1650 } 1743 1651 } 1744 1652 1745 - static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width, 1653 + static void calc_tiler_rotation_offset(u16 screen_width, u16 width, 1654 + enum omap_color_mode color_mode, bool fieldmode, 1655 + unsigned int field_offset, unsigned *offset0, unsigned *offset1, 1656 + s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim) 1657 + { 1658 + u8 ps; 1659 + 1660 + switch (color_mode) { 1661 + case OMAP_DSS_COLOR_CLUT1: 1662 + case OMAP_DSS_COLOR_CLUT2: 1663 + case OMAP_DSS_COLOR_CLUT4: 1664 + case OMAP_DSS_COLOR_CLUT8: 1665 + BUG(); 1666 + return; 1667 + default: 1668 + ps = color_mode_to_bpp(color_mode) / 8; 1669 + break; 1670 + } 1671 + 1672 + DSSDBG("scrw %d, width %d\n", screen_width, width); 1673 + 1674 + /* 1675 + * field 0 = even field = bottom field 1676 + * field 1 = odd field = top field 1677 + */ 1678 + *offset1 = 0; 1679 + if (field_offset) 1680 + *offset0 = *offset1 + field_offset * screen_width * ps; 1681 + else 1682 + *offset0 = *offset1; 1683 + *row_inc = pixinc(1 + (y_predecim * screen_width - width * x_predecim) + 1684 + (fieldmode ? screen_width : 0), ps); 1685 + if (color_mode == OMAP_DSS_COLOR_YUV2 || 1686 + color_mode == OMAP_DSS_COLOR_UYVY) 1687 + *pix_inc = pixinc(x_predecim, 2 * ps); 1688 + else 1689 + *pix_inc = pixinc(x_predecim, ps); 1690 + } 1691 + 1692 + /* 1693 + * This function is used to avoid synclosts in OMAP3, because of some 1694 + * undocumented horizontal position and timing related limitations. 1695 + */ 1696 + static int check_horiz_timing_omap3(enum omap_channel channel, 1697 + const struct omap_video_timings *t, u16 pos_x, 1698 + u16 width, u16 height, u16 out_width, u16 out_height) 1699 + { 1700 + int DS = DIV_ROUND_UP(height, out_height); 1701 + unsigned long nonactive, lclk, pclk; 1702 + static const u8 limits[3] = { 8, 10, 20 }; 1703 + u64 val, blank; 1704 + int i; 1705 + 1706 + nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; 1707 + pclk = dispc_mgr_pclk_rate(channel); 1708 + if (dispc_mgr_is_lcd(channel)) 1709 + lclk = dispc_mgr_lclk_rate(channel); 1710 + else 1711 + lclk = dispc_fclk_rate(); 1712 + 1713 + i = 0; 1714 + if (out_height < height) 1715 + i++; 1716 + if (out_width < width) 1717 + i++; 1718 + blank = div_u64((u64)(t->hbp + t->hsw + t->hfp) * lclk, pclk); 1719 + DSSDBG("blanking period + ppl = %llu (limit = %u)\n", blank, limits[i]); 1720 + if (blank <= limits[i]) 1721 + return -EINVAL; 1722 + 1723 + /* 1724 + * Pixel data should be prepared before visible display point starts. 1725 + * So, atleast DS-2 lines must have already been fetched by DISPC 1726 + * during nonactive - pos_x period. 1727 + */ 1728 + val = div_u64((u64)(nonactive - pos_x) * lclk, pclk); 1729 + DSSDBG("(nonactive - pos_x) * pcd = %llu max(0, DS - 2) * width = %d\n", 1730 + val, max(0, DS - 2) * width); 1731 + if (val < max(0, DS - 2) * width) 1732 + return -EINVAL; 1733 + 1734 + /* 1735 + * All lines need to be refilled during the nonactive period of which 1736 + * only one line can be loaded during the active period. So, atleast 1737 + * DS - 1 lines should be loaded during nonactive period. 1738 + */ 1739 + val = div_u64((u64)nonactive * lclk, pclk); 1740 + DSSDBG("nonactive * pcd = %llu, max(0, DS - 1) * width = %d\n", 1741 + val, max(0, DS - 1) * width); 1742 + if (val < max(0, DS - 1) * width) 1743 + return -EINVAL; 1744 + 1745 + return 0; 1746 + } 1747 + 1748 + static unsigned long calc_core_clk_five_taps(enum omap_channel channel, 1749 + const struct omap_video_timings *mgr_timings, u16 width, 1746 1750 u16 height, u16 out_width, u16 out_height, 1747 1751 enum omap_color_mode color_mode) 1748 1752 { 1749 - u32 fclk = 0; 1753 + u32 core_clk = 0; 1750 1754 u64 tmp, pclk = dispc_mgr_pclk_rate(channel); 1751 1755 1752 1756 if (height <= out_height && width <= out_width) 1753 1757 return (unsigned long) pclk; 1754 1758 1755 1759 if (height > out_height) { 1756 - struct omap_dss_device *dssdev = dispc_mgr_get_device(channel); 1757 - unsigned int ppl = dssdev->panel.timings.x_res; 1760 + unsigned int ppl = mgr_timings->x_res; 1758 1761 1759 1762 tmp = pclk * height * out_width; 1760 1763 do_div(tmp, 2 * out_height * ppl); 1761 - fclk = tmp; 1764 + core_clk = tmp; 1762 1765 1763 1766 if (height > 2 * out_height) { 1764 1767 if (ppl == out_width) ··· 1862 1673 1863 1674 tmp = pclk * (height - 2 * out_height) * out_width; 1864 1675 do_div(tmp, 2 * out_height * (ppl - out_width)); 1865 - fclk = max(fclk, (u32) tmp); 1676 + core_clk = max_t(u32, core_clk, tmp); 1866 1677 } 1867 1678 } 1868 1679 1869 1680 if (width > out_width) { 1870 1681 tmp = pclk * width; 1871 1682 do_div(tmp, out_width); 1872 - fclk = max(fclk, (u32) tmp); 1683 + core_clk = max_t(u32, core_clk, tmp); 1873 1684 1874 1685 if (color_mode == OMAP_DSS_COLOR_RGB24U) 1875 - fclk <<= 1; 1686 + core_clk <<= 1; 1876 1687 } 1877 1688 1878 - return fclk; 1689 + return core_clk; 1879 1690 } 1880 1691 1881 - static unsigned long calc_fclk(enum omap_channel channel, u16 width, 1692 + static unsigned long calc_core_clk(enum omap_channel channel, u16 width, 1882 1693 u16 height, u16 out_width, u16 out_height) 1883 1694 { 1884 1695 unsigned int hf, vf; ··· 1919 1730 } 1920 1731 1921 1732 static int dispc_ovl_calc_scaling(enum omap_plane plane, 1922 - enum omap_channel channel, u16 width, u16 height, 1923 - u16 out_width, u16 out_height, 1924 - enum omap_color_mode color_mode, bool *five_taps) 1733 + enum omap_channel channel, 1734 + const struct omap_video_timings *mgr_timings, 1735 + u16 width, u16 height, u16 out_width, u16 out_height, 1736 + enum omap_color_mode color_mode, bool *five_taps, 1737 + int *x_predecim, int *y_predecim, u16 pos_x) 1925 1738 { 1926 1739 struct omap_overlay *ovl = omap_dss_get_overlay(plane); 1927 1740 const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); 1928 1741 const int maxsinglelinewidth = 1929 1742 dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); 1930 - unsigned long fclk = 0; 1743 + const int max_decim_limit = 16; 1744 + unsigned long core_clk = 0; 1745 + int decim_x, decim_y, error, min_factor; 1746 + u16 in_width, in_height, in_width_max = 0; 1931 1747 1932 1748 if (width == out_width && height == out_height) 1933 1749 return 0; ··· 1940 1746 if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) 1941 1747 return -EINVAL; 1942 1748 1943 - if (out_width < width / maxdownscale || 1944 - out_width > width * 8) 1749 + *x_predecim = max_decim_limit; 1750 + *y_predecim = max_decim_limit; 1751 + 1752 + if (color_mode == OMAP_DSS_COLOR_CLUT1 || 1753 + color_mode == OMAP_DSS_COLOR_CLUT2 || 1754 + color_mode == OMAP_DSS_COLOR_CLUT4 || 1755 + color_mode == OMAP_DSS_COLOR_CLUT8) { 1756 + *x_predecim = 1; 1757 + *y_predecim = 1; 1758 + *five_taps = false; 1759 + return 0; 1760 + } 1761 + 1762 + decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale); 1763 + decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale); 1764 + 1765 + min_factor = min(decim_x, decim_y); 1766 + 1767 + if (decim_x > *x_predecim || out_width > width * 8) 1945 1768 return -EINVAL; 1946 1769 1947 - if (out_height < height / maxdownscale || 1948 - out_height > height * 8) 1770 + if (decim_y > *y_predecim || out_height > height * 8) 1949 1771 return -EINVAL; 1950 1772 1951 1773 if (cpu_is_omap24xx()) { 1952 - if (width > maxsinglelinewidth) 1953 - DSSERR("Cannot scale max input width exceeded"); 1954 1774 *five_taps = false; 1955 - fclk = calc_fclk(channel, width, height, out_width, 1956 - out_height); 1775 + 1776 + do { 1777 + in_height = DIV_ROUND_UP(height, decim_y); 1778 + in_width = DIV_ROUND_UP(width, decim_x); 1779 + core_clk = calc_core_clk(channel, in_width, in_height, 1780 + out_width, out_height); 1781 + error = (in_width > maxsinglelinewidth || !core_clk || 1782 + core_clk > dispc_core_clk_rate()); 1783 + if (error) { 1784 + if (decim_x == decim_y) { 1785 + decim_x = min_factor; 1786 + decim_y++; 1787 + } else { 1788 + swap(decim_x, decim_y); 1789 + if (decim_x < decim_y) 1790 + decim_x++; 1791 + } 1792 + } 1793 + } while (decim_x <= *x_predecim && decim_y <= *y_predecim && 1794 + error); 1795 + 1796 + if (in_width > maxsinglelinewidth) { 1797 + DSSERR("Cannot scale max input width exceeded"); 1798 + return -EINVAL; 1799 + } 1957 1800 } else if (cpu_is_omap34xx()) { 1958 - if (width > (maxsinglelinewidth * 2)) { 1801 + 1802 + do { 1803 + in_height = DIV_ROUND_UP(height, decim_y); 1804 + in_width = DIV_ROUND_UP(width, decim_x); 1805 + core_clk = calc_core_clk_five_taps(channel, mgr_timings, 1806 + in_width, in_height, out_width, out_height, 1807 + color_mode); 1808 + 1809 + error = check_horiz_timing_omap3(channel, mgr_timings, 1810 + pos_x, in_width, in_height, out_width, 1811 + out_height); 1812 + 1813 + if (in_width > maxsinglelinewidth) 1814 + if (in_height > out_height && 1815 + in_height < out_height * 2) 1816 + *five_taps = false; 1817 + if (!*five_taps) 1818 + core_clk = calc_core_clk(channel, in_width, 1819 + in_height, out_width, out_height); 1820 + error = (error || in_width > maxsinglelinewidth * 2 || 1821 + (in_width > maxsinglelinewidth && *five_taps) || 1822 + !core_clk || core_clk > dispc_core_clk_rate()); 1823 + if (error) { 1824 + if (decim_x == decim_y) { 1825 + decim_x = min_factor; 1826 + decim_y++; 1827 + } else { 1828 + swap(decim_x, decim_y); 1829 + if (decim_x < decim_y) 1830 + decim_x++; 1831 + } 1832 + } 1833 + } while (decim_x <= *x_predecim && decim_y <= *y_predecim 1834 + && error); 1835 + 1836 + if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, 1837 + height, out_width, out_height)){ 1838 + DSSERR("horizontal timing too tight\n"); 1839 + return -EINVAL; 1840 + } 1841 + 1842 + if (in_width > (maxsinglelinewidth * 2)) { 1959 1843 DSSERR("Cannot setup scaling"); 1960 1844 DSSERR("width exceeds maximum width possible"); 1961 1845 return -EINVAL; 1962 1846 } 1963 - fclk = calc_fclk_five_taps(channel, width, height, out_width, 1964 - out_height, color_mode); 1965 - if (width > maxsinglelinewidth) { 1966 - if (height > out_height && height < out_height * 2) 1967 - *five_taps = false; 1968 - else { 1969 - DSSERR("cannot setup scaling with five taps"); 1970 - return -EINVAL; 1971 - } 1847 + 1848 + if (in_width > maxsinglelinewidth && *five_taps) { 1849 + DSSERR("cannot setup scaling with five taps"); 1850 + return -EINVAL; 1972 1851 } 1973 - if (!*five_taps) 1974 - fclk = calc_fclk(channel, width, height, out_width, 1975 - out_height); 1976 1852 } else { 1977 - if (width > maxsinglelinewidth) { 1853 + int decim_x_min = decim_x; 1854 + in_height = DIV_ROUND_UP(height, decim_y); 1855 + in_width_max = dispc_core_clk_rate() / 1856 + DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), 1857 + out_width); 1858 + decim_x = DIV_ROUND_UP(width, in_width_max); 1859 + 1860 + decim_x = decim_x > decim_x_min ? decim_x : decim_x_min; 1861 + if (decim_x > *x_predecim) 1862 + return -EINVAL; 1863 + 1864 + do { 1865 + in_width = DIV_ROUND_UP(width, decim_x); 1866 + } while (decim_x <= *x_predecim && 1867 + in_width > maxsinglelinewidth && decim_x++); 1868 + 1869 + if (in_width > maxsinglelinewidth) { 1978 1870 DSSERR("Cannot scale width exceeds max line width"); 1979 1871 return -EINVAL; 1980 1872 } 1981 - fclk = calc_fclk(channel, width, height, out_width, 1982 - out_height); 1873 + 1874 + core_clk = calc_core_clk(channel, in_width, in_height, 1875 + out_width, out_height); 1983 1876 } 1984 1877 1985 - DSSDBG("required fclk rate = %lu Hz\n", fclk); 1986 - DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); 1878 + DSSDBG("required core clk rate = %lu Hz\n", core_clk); 1879 + DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate()); 1987 1880 1988 - if (!fclk || fclk > dispc_fclk_rate()) { 1881 + if (!core_clk || core_clk > dispc_core_clk_rate()) { 1989 1882 DSSERR("failed to set up scaling, " 1990 - "required fclk rate = %lu Hz, " 1991 - "current fclk rate = %lu Hz\n", 1992 - fclk, dispc_fclk_rate()); 1883 + "required core clk rate = %lu Hz, " 1884 + "current core clk rate = %lu Hz\n", 1885 + core_clk, dispc_core_clk_rate()); 1993 1886 return -EINVAL; 1994 1887 } 1995 1888 1889 + *x_predecim = decim_x; 1890 + *y_predecim = decim_y; 1996 1891 return 0; 1997 1892 } 1998 1893 1999 1894 int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 2000 - bool ilace, bool replication) 1895 + bool ilace, bool replication, 1896 + const struct omap_video_timings *mgr_timings) 2001 1897 { 2002 1898 struct omap_overlay *ovl = omap_dss_get_overlay(plane); 2003 1899 bool five_taps = true; ··· 2098 1814 s32 pix_inc; 2099 1815 u16 frame_height = oi->height; 2100 1816 unsigned int field_offset = 0; 2101 - u16 outw, outh; 1817 + u16 in_height = oi->height; 1818 + u16 in_width = oi->width; 1819 + u16 out_width, out_height; 2102 1820 enum omap_channel channel; 1821 + int x_predecim = 1, y_predecim = 1; 2103 1822 2104 1823 channel = dispc_ovl_get_channel_out(plane); 2105 1824 ··· 2116 1829 if (oi->paddr == 0) 2117 1830 return -EINVAL; 2118 1831 2119 - outw = oi->out_width == 0 ? oi->width : oi->out_width; 2120 - outh = oi->out_height == 0 ? oi->height : oi->out_height; 1832 + out_width = oi->out_width == 0 ? oi->width : oi->out_width; 1833 + out_height = oi->out_height == 0 ? oi->height : oi->out_height; 2121 1834 2122 - if (ilace && oi->height == outh) 1835 + if (ilace && oi->height == out_height) 2123 1836 fieldmode = 1; 2124 1837 2125 1838 if (ilace) { 2126 1839 if (fieldmode) 2127 - oi->height /= 2; 1840 + in_height /= 2; 2128 1841 oi->pos_y /= 2; 2129 - outh /= 2; 1842 + out_height /= 2; 2130 1843 2131 1844 DSSDBG("adjusting for ilace: height %d, pos_y %d, " 2132 1845 "out_height %d\n", 2133 - oi->height, oi->pos_y, outh); 1846 + in_height, oi->pos_y, out_height); 2134 1847 } 2135 1848 2136 1849 if (!dss_feat_color_mode_supported(plane, oi->color_mode)) 2137 1850 return -EINVAL; 2138 1851 2139 - r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height, 2140 - outw, outh, oi->color_mode, 2141 - &five_taps); 1852 + r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width, 1853 + in_height, out_width, out_height, oi->color_mode, 1854 + &five_taps, &x_predecim, &y_predecim, oi->pos_x); 2142 1855 if (r) 2143 1856 return r; 1857 + 1858 + in_width = DIV_ROUND_UP(in_width, x_predecim); 1859 + in_height = DIV_ROUND_UP(in_height, y_predecim); 2144 1860 2145 1861 if (oi->color_mode == OMAP_DSS_COLOR_YUV2 || 2146 1862 oi->color_mode == OMAP_DSS_COLOR_UYVY || ··· 2158 1868 * so the integer part must be added to the base address of the 2159 1869 * bottom field. 2160 1870 */ 2161 - if (!oi->height || oi->height == outh) 1871 + if (!in_height || in_height == out_height) 2162 1872 field_offset = 0; 2163 1873 else 2164 - field_offset = oi->height / outh / 2; 1874 + field_offset = in_height / out_height / 2; 2165 1875 } 2166 1876 2167 1877 /* Fields are independent but interleaved in memory. */ 2168 1878 if (fieldmode) 2169 1879 field_offset = 1; 2170 1880 2171 - if (oi->rotation_type == OMAP_DSS_ROT_DMA) 2172 - calc_dma_rotation_offset(oi->rotation, oi->mirror, 2173 - oi->screen_width, oi->width, frame_height, 1881 + offset0 = 0; 1882 + offset1 = 0; 1883 + row_inc = 0; 1884 + pix_inc = 0; 1885 + 1886 + if (oi->rotation_type == OMAP_DSS_ROT_TILER) 1887 + calc_tiler_rotation_offset(oi->screen_width, in_width, 2174 1888 oi->color_mode, fieldmode, field_offset, 2175 - &offset0, &offset1, &row_inc, &pix_inc); 1889 + &offset0, &offset1, &row_inc, &pix_inc, 1890 + x_predecim, y_predecim); 1891 + else if (oi->rotation_type == OMAP_DSS_ROT_DMA) 1892 + calc_dma_rotation_offset(oi->rotation, oi->mirror, 1893 + oi->screen_width, in_width, frame_height, 1894 + oi->color_mode, fieldmode, field_offset, 1895 + &offset0, &offset1, &row_inc, &pix_inc, 1896 + x_predecim, y_predecim); 2176 1897 else 2177 1898 calc_vrfb_rotation_offset(oi->rotation, oi->mirror, 2178 - oi->screen_width, oi->width, frame_height, 1899 + oi->screen_width, in_width, frame_height, 2179 1900 oi->color_mode, fieldmode, field_offset, 2180 - &offset0, &offset1, &row_inc, &pix_inc); 1901 + &offset0, &offset1, &row_inc, &pix_inc, 1902 + x_predecim, y_predecim); 2181 1903 2182 1904 DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", 2183 1905 offset0, offset1, row_inc, pix_inc); 2184 1906 2185 1907 dispc_ovl_set_color_mode(plane, oi->color_mode); 1908 + 1909 + dispc_ovl_configure_burst_type(plane, oi->rotation_type); 2186 1910 2187 1911 dispc_ovl_set_ba0(plane, oi->paddr + offset0); 2188 1912 dispc_ovl_set_ba1(plane, oi->paddr + offset1); ··· 2210 1906 dispc_ovl_set_row_inc(plane, row_inc); 2211 1907 dispc_ovl_set_pix_inc(plane, pix_inc); 2212 1908 2213 - DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width, 2214 - oi->height, outw, outh); 1909 + DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width, 1910 + in_height, out_width, out_height); 2215 1911 2216 1912 dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y); 2217 1913 2218 - dispc_ovl_set_pic_size(plane, oi->width, oi->height); 1914 + dispc_ovl_set_pic_size(plane, in_width, in_height); 2219 1915 2220 1916 if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) { 2221 - dispc_ovl_set_scaling(plane, oi->width, oi->height, 2222 - outw, outh, 2223 - ilace, five_taps, fieldmode, 1917 + dispc_ovl_set_scaling(plane, in_width, in_height, out_width, 1918 + out_height, ilace, five_taps, fieldmode, 2224 1919 oi->color_mode, oi->rotation); 2225 - dispc_ovl_set_vid_size(plane, outw, outh); 1920 + dispc_ovl_set_vid_size(plane, out_width, out_height); 2226 1921 dispc_ovl_set_vid_color_conv(plane, cconv); 2227 1922 } 2228 1923 ··· 2390 2087 return !!REG_GET(DISPC_CONTROL, 1, 1); 2391 2088 else if (channel == OMAP_DSS_CHANNEL_LCD2) 2392 2089 return !!REG_GET(DISPC_CONTROL2, 0, 0); 2393 - else 2090 + else { 2394 2091 BUG(); 2092 + return false; 2093 + } 2395 2094 } 2396 2095 2397 2096 void dispc_mgr_enable(enum omap_channel channel, bool enable) ··· 2590 2285 REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11); 2591 2286 } 2592 2287 2288 + static bool _dispc_mgr_size_ok(u16 width, u16 height) 2289 + { 2290 + return width <= dss_feat_get_param_max(FEAT_PARAM_MGR_WIDTH) && 2291 + height <= dss_feat_get_param_max(FEAT_PARAM_MGR_HEIGHT); 2292 + } 2293 + 2593 2294 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, 2594 2295 int vsw, int vfp, int vbp) 2595 2296 { ··· 2620 2309 return true; 2621 2310 } 2622 2311 2623 - bool dispc_lcd_timings_ok(struct omap_video_timings *timings) 2312 + bool dispc_mgr_timings_ok(enum omap_channel channel, 2313 + const struct omap_video_timings *timings) 2624 2314 { 2625 - return _dispc_lcd_timings_ok(timings->hsw, timings->hfp, 2626 - timings->hbp, timings->vsw, 2627 - timings->vfp, timings->vbp); 2315 + bool timings_ok; 2316 + 2317 + timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); 2318 + 2319 + if (dispc_mgr_is_lcd(channel)) 2320 + timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw, 2321 + timings->hfp, timings->hbp, 2322 + timings->vsw, timings->vfp, 2323 + timings->vbp); 2324 + 2325 + return timings_ok; 2628 2326 } 2629 2327 2630 2328 static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, ··· 2660 2340 } 2661 2341 2662 2342 /* change name to mode? */ 2663 - void dispc_mgr_set_lcd_timings(enum omap_channel channel, 2343 + void dispc_mgr_set_timings(enum omap_channel channel, 2664 2344 struct omap_video_timings *timings) 2665 2345 { 2666 2346 unsigned xtot, ytot; 2667 2347 unsigned long ht, vt; 2348 + struct omap_video_timings t = *timings; 2668 2349 2669 - if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp, 2670 - timings->hbp, timings->vsw, 2671 - timings->vfp, timings->vbp)) 2350 + DSSDBG("channel %d xres %u yres %u\n", channel, t.x_res, t.y_res); 2351 + 2352 + if (!dispc_mgr_timings_ok(channel, &t)) { 2672 2353 BUG(); 2354 + return; 2355 + } 2673 2356 2674 - _dispc_mgr_set_lcd_timings(channel, timings->hsw, timings->hfp, 2675 - timings->hbp, timings->vsw, timings->vfp, 2676 - timings->vbp); 2357 + if (dispc_mgr_is_lcd(channel)) { 2358 + _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw, 2359 + t.vfp, t.vbp); 2677 2360 2678 - dispc_mgr_set_lcd_size(channel, timings->x_res, timings->y_res); 2361 + xtot = t.x_res + t.hfp + t.hsw + t.hbp; 2362 + ytot = t.y_res + t.vfp + t.vsw + t.vbp; 2679 2363 2680 - xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp; 2681 - ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp; 2364 + ht = (timings->pixel_clock * 1000) / xtot; 2365 + vt = (timings->pixel_clock * 1000) / xtot / ytot; 2682 2366 2683 - ht = (timings->pixel_clock * 1000) / xtot; 2684 - vt = (timings->pixel_clock * 1000) / xtot / ytot; 2367 + DSSDBG("pck %u\n", timings->pixel_clock); 2368 + DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", 2369 + t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp); 2685 2370 2686 - DSSDBG("channel %d xres %u yres %u\n", channel, timings->x_res, 2687 - timings->y_res); 2688 - DSSDBG("pck %u\n", timings->pixel_clock); 2689 - DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", 2690 - timings->hsw, timings->hfp, timings->hbp, 2691 - timings->vsw, timings->vfp, timings->vbp); 2371 + DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 2372 + } else { 2373 + enum dss_hdmi_venc_clk_source_select source; 2692 2374 2693 - DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 2375 + source = dss_get_hdmi_venc_clk_source(); 2376 + 2377 + if (source == DSS_VENC_TV_CLK) 2378 + t.y_res /= 2; 2379 + } 2380 + 2381 + dispc_mgr_set_size(channel, t.x_res, t.y_res); 2694 2382 } 2695 2383 2696 2384 static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div, ··· 2739 2411 break; 2740 2412 default: 2741 2413 BUG(); 2414 + return 0; 2742 2415 } 2743 2416 2744 2417 return r; ··· 2770 2441 break; 2771 2442 default: 2772 2443 BUG(); 2444 + return 0; 2773 2445 } 2774 2446 2775 2447 return r / lcd; ··· 2792 2462 2793 2463 return r / pcd; 2794 2464 } else { 2795 - struct omap_dss_device *dssdev = 2796 - dispc_mgr_get_device(channel); 2465 + enum dss_hdmi_venc_clk_source_select source; 2797 2466 2798 - switch (dssdev->type) { 2799 - case OMAP_DISPLAY_TYPE_VENC: 2467 + source = dss_get_hdmi_venc_clk_source(); 2468 + 2469 + switch (source) { 2470 + case DSS_VENC_TV_CLK: 2800 2471 return venc_get_pixel_clock(); 2801 - case OMAP_DISPLAY_TYPE_HDMI: 2472 + case DSS_HDMI_M_PCLK: 2802 2473 return hdmi_get_pixel_clock(); 2803 2474 default: 2804 2475 BUG(); 2476 + return 0; 2805 2477 } 2806 2478 } 2479 + } 2480 + 2481 + unsigned long dispc_core_clk_rate(void) 2482 + { 2483 + int lcd; 2484 + unsigned long fclk = dispc_fclk_rate(); 2485 + 2486 + if (dss_has_feature(FEAT_CORE_CLK_DIV)) 2487 + lcd = REG_GET(DISPC_DIVISOR, 23, 16); 2488 + else 2489 + lcd = REG_GET(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD), 23, 16); 2490 + 2491 + return fclk / lcd; 2807 2492 } 2808 2493 2809 2494 void dispc_dump_clocks(struct seq_file *s) ··· 2933 2588 } 2934 2589 #endif 2935 2590 2936 - void dispc_dump_regs(struct seq_file *s) 2591 + static void dispc_dump_regs(struct seq_file *s) 2937 2592 { 2938 2593 int i, j; 2939 2594 const char *mgr_names[] = { ··· 3592 3247 return 0; 3593 3248 } 3594 3249 3595 - #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC 3596 - void dispc_fake_vsync_irq(void) 3597 - { 3598 - u32 irqstatus = DISPC_IRQ_VSYNC; 3599 - int i; 3600 - 3601 - WARN_ON(!in_interrupt()); 3602 - 3603 - for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { 3604 - struct omap_dispc_isr_data *isr_data; 3605 - isr_data = &dispc.registered_isr[i]; 3606 - 3607 - if (!isr_data->isr) 3608 - continue; 3609 - 3610 - if (isr_data->mask & irqstatus) 3611 - isr_data->isr(isr_data->arg, irqstatus); 3612 - } 3613 - } 3614 - #endif 3615 - 3616 3250 static void _omap_dispc_initialize_irq(void) 3617 3251 { 3618 3252 unsigned long flags; ··· 3654 3330 } 3655 3331 3656 3332 /* DISPC HW IP initialisation */ 3657 - static int omap_dispchw_probe(struct platform_device *pdev) 3333 + static int __init omap_dispchw_probe(struct platform_device *pdev) 3658 3334 { 3659 3335 u32 rev; 3660 3336 int r = 0; ··· 3723 3399 3724 3400 dispc_runtime_put(); 3725 3401 3402 + dss_debugfs_create_file("dispc", dispc_dump_regs); 3403 + 3404 + #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 3405 + dss_debugfs_create_file("dispc_irq", dispc_dump_irqs); 3406 + #endif 3726 3407 return 0; 3727 3408 3728 3409 err_runtime_get: ··· 3736 3407 return r; 3737 3408 } 3738 3409 3739 - static int omap_dispchw_remove(struct platform_device *pdev) 3410 + static int __exit omap_dispchw_remove(struct platform_device *pdev) 3740 3411 { 3741 3412 pm_runtime_disable(&pdev->dev); 3742 3413 ··· 3748 3419 static int dispc_runtime_suspend(struct device *dev) 3749 3420 { 3750 3421 dispc_save_context(); 3751 - dss_runtime_put(); 3752 3422 3753 3423 return 0; 3754 3424 } 3755 3425 3756 3426 static int dispc_runtime_resume(struct device *dev) 3757 3427 { 3758 - int r; 3759 - 3760 - r = dss_runtime_get(); 3761 - if (r < 0) 3762 - return r; 3763 - 3764 3428 dispc_restore_context(); 3765 3429 3766 3430 return 0; ··· 3765 3443 }; 3766 3444 3767 3445 static struct platform_driver omap_dispchw_driver = { 3768 - .probe = omap_dispchw_probe, 3769 - .remove = omap_dispchw_remove, 3446 + .remove = __exit_p(omap_dispchw_remove), 3770 3447 .driver = { 3771 3448 .name = "omapdss_dispc", 3772 3449 .owner = THIS_MODULE, ··· 3773 3452 }, 3774 3453 }; 3775 3454 3776 - int dispc_init_platform_driver(void) 3455 + int __init dispc_init_platform_driver(void) 3777 3456 { 3778 - return platform_driver_register(&omap_dispchw_driver); 3457 + return platform_driver_probe(&omap_dispchw_driver, omap_dispchw_probe); 3779 3458 } 3780 3459 3781 - void dispc_uninit_platform_driver(void) 3460 + void __exit dispc_uninit_platform_driver(void) 3782 3461 { 3783 - return platform_driver_unregister(&omap_dispchw_driver); 3462 + platform_driver_unregister(&omap_dispchw_driver); 3784 3463 }
+72
drivers/video/omap2/dss/dispc.h
··· 120 120 return 0x03AC; 121 121 default: 122 122 BUG(); 123 + return 0; 123 124 } 124 125 } 125 126 ··· 135 134 return 0x03B0; 136 135 default: 137 136 BUG(); 137 + return 0; 138 138 } 139 139 } 140 140 ··· 146 144 return 0x0064; 147 145 case OMAP_DSS_CHANNEL_DIGIT: 148 146 BUG(); 147 + return 0; 149 148 case OMAP_DSS_CHANNEL_LCD2: 150 149 return 0x0400; 151 150 default: 152 151 BUG(); 152 + return 0; 153 153 } 154 154 } 155 155 ··· 162 158 return 0x0068; 163 159 case OMAP_DSS_CHANNEL_DIGIT: 164 160 BUG(); 161 + return 0; 165 162 case OMAP_DSS_CHANNEL_LCD2: 166 163 return 0x0404; 167 164 default: 168 165 BUG(); 166 + return 0; 169 167 } 170 168 } 171 169 ··· 178 172 return 0x006C; 179 173 case OMAP_DSS_CHANNEL_DIGIT: 180 174 BUG(); 175 + return 0; 181 176 case OMAP_DSS_CHANNEL_LCD2: 182 177 return 0x0408; 183 178 default: 184 179 BUG(); 180 + return 0; 185 181 } 186 182 } 187 183 ··· 194 186 return 0x0070; 195 187 case OMAP_DSS_CHANNEL_DIGIT: 196 188 BUG(); 189 + return 0; 197 190 case OMAP_DSS_CHANNEL_LCD2: 198 191 return 0x040C; 199 192 default: 200 193 BUG(); 194 + return 0; 201 195 } 202 196 } 203 197 ··· 215 205 return 0x03CC; 216 206 default: 217 207 BUG(); 208 + return 0; 218 209 } 219 210 } 220 211 ··· 226 215 return 0x01D4; 227 216 case OMAP_DSS_CHANNEL_DIGIT: 228 217 BUG(); 218 + return 0; 229 219 case OMAP_DSS_CHANNEL_LCD2: 230 220 return 0x03C0; 231 221 default: 232 222 BUG(); 223 + return 0; 233 224 } 234 225 } 235 226 ··· 242 229 return 0x01D8; 243 230 case OMAP_DSS_CHANNEL_DIGIT: 244 231 BUG(); 232 + return 0; 245 233 case OMAP_DSS_CHANNEL_LCD2: 246 234 return 0x03C4; 247 235 default: 248 236 BUG(); 237 + return 0; 249 238 } 250 239 } 251 240 ··· 258 243 return 0x01DC; 259 244 case OMAP_DSS_CHANNEL_DIGIT: 260 245 BUG(); 246 + return 0; 261 247 case OMAP_DSS_CHANNEL_LCD2: 262 248 return 0x03C8; 263 249 default: 264 250 BUG(); 251 + return 0; 265 252 } 266 253 } 267 254 ··· 274 257 return 0x0220; 275 258 case OMAP_DSS_CHANNEL_DIGIT: 276 259 BUG(); 260 + return 0; 277 261 case OMAP_DSS_CHANNEL_LCD2: 278 262 return 0x03BC; 279 263 default: 280 264 BUG(); 265 + return 0; 281 266 } 282 267 } 283 268 ··· 290 271 return 0x0224; 291 272 case OMAP_DSS_CHANNEL_DIGIT: 292 273 BUG(); 274 + return 0; 293 275 case OMAP_DSS_CHANNEL_LCD2: 294 276 return 0x03B8; 295 277 default: 296 278 BUG(); 279 + return 0; 297 280 } 298 281 } 299 282 ··· 306 285 return 0x0228; 307 286 case OMAP_DSS_CHANNEL_DIGIT: 308 287 BUG(); 288 + return 0; 309 289 case OMAP_DSS_CHANNEL_LCD2: 310 290 return 0x03B4; 311 291 default: 312 292 BUG(); 293 + return 0; 313 294 } 314 295 } 315 296 ··· 329 306 return 0x0300; 330 307 default: 331 308 BUG(); 309 + return 0; 332 310 } 333 311 } 334 312 ··· 345 321 return 0x0008; 346 322 default: 347 323 BUG(); 324 + return 0; 348 325 } 349 326 } 350 327 ··· 360 335 return 0x000C; 361 336 default: 362 337 BUG(); 338 + return 0; 363 339 } 364 340 } 365 341 ··· 369 343 switch (plane) { 370 344 case OMAP_DSS_GFX: 371 345 BUG(); 346 + return 0; 372 347 case OMAP_DSS_VIDEO1: 373 348 return 0x0544; 374 349 case OMAP_DSS_VIDEO2: ··· 378 351 return 0x0310; 379 352 default: 380 353 BUG(); 354 + return 0; 381 355 } 382 356 } 383 357 ··· 387 359 switch (plane) { 388 360 case OMAP_DSS_GFX: 389 361 BUG(); 362 + return 0; 390 363 case OMAP_DSS_VIDEO1: 391 364 return 0x0548; 392 365 case OMAP_DSS_VIDEO2: ··· 396 367 return 0x0314; 397 368 default: 398 369 BUG(); 370 + return 0; 399 371 } 400 372 } 401 373 ··· 411 381 return 0x009C; 412 382 default: 413 383 BUG(); 384 + return 0; 414 385 } 415 386 } 416 387 ··· 426 395 return 0x00A8; 427 396 default: 428 397 BUG(); 398 + return 0; 429 399 } 430 400 } 431 401 ··· 442 410 return 0x0070; 443 411 default: 444 412 BUG(); 413 + return 0; 445 414 } 446 415 } 447 416 ··· 451 418 switch (plane) { 452 419 case OMAP_DSS_GFX: 453 420 BUG(); 421 + return 0; 454 422 case OMAP_DSS_VIDEO1: 455 423 return 0x0568; 456 424 case OMAP_DSS_VIDEO2: ··· 460 426 return 0x032C; 461 427 default: 462 428 BUG(); 429 + return 0; 463 430 } 464 431 } 465 432 ··· 476 441 return 0x008C; 477 442 default: 478 443 BUG(); 444 + return 0; 479 445 } 480 446 } 481 447 ··· 492 456 return 0x0088; 493 457 default: 494 458 BUG(); 459 + return 0; 495 460 } 496 461 } 497 462 ··· 508 471 return 0x00A4; 509 472 default: 510 473 BUG(); 474 + return 0; 511 475 } 512 476 } 513 477 ··· 524 486 return 0x0098; 525 487 default: 526 488 BUG(); 489 + return 0; 527 490 } 528 491 } 529 492 ··· 537 498 case OMAP_DSS_VIDEO2: 538 499 case OMAP_DSS_VIDEO3: 539 500 BUG(); 501 + return 0; 540 502 default: 541 503 BUG(); 504 + return 0; 542 505 } 543 506 } 544 507 ··· 553 512 case OMAP_DSS_VIDEO2: 554 513 case OMAP_DSS_VIDEO3: 555 514 BUG(); 515 + return 0; 556 516 default: 557 517 BUG(); 518 + return 0; 558 519 } 559 520 } 560 521 ··· 565 522 switch (plane) { 566 523 case OMAP_DSS_GFX: 567 524 BUG(); 525 + return 0; 568 526 case OMAP_DSS_VIDEO1: 569 527 case OMAP_DSS_VIDEO2: 570 528 return 0x0024; ··· 573 529 return 0x0090; 574 530 default: 575 531 BUG(); 532 + return 0; 576 533 } 577 534 } 578 535 ··· 582 537 switch (plane) { 583 538 case OMAP_DSS_GFX: 584 539 BUG(); 540 + return 0; 585 541 case OMAP_DSS_VIDEO1: 586 542 return 0x0580; 587 543 case OMAP_DSS_VIDEO2: ··· 591 545 return 0x0424; 592 546 default: 593 547 BUG(); 548 + return 0; 594 549 } 595 550 } 596 551 ··· 600 553 switch (plane) { 601 554 case OMAP_DSS_GFX: 602 555 BUG(); 556 + return 0; 603 557 case OMAP_DSS_VIDEO1: 604 558 case OMAP_DSS_VIDEO2: 605 559 return 0x0028; ··· 608 560 return 0x0094; 609 561 default: 610 562 BUG(); 563 + return 0; 611 564 } 612 565 } 613 566 ··· 618 569 switch (plane) { 619 570 case OMAP_DSS_GFX: 620 571 BUG(); 572 + return 0; 621 573 case OMAP_DSS_VIDEO1: 622 574 case OMAP_DSS_VIDEO2: 623 575 return 0x002C; ··· 626 576 return 0x0000; 627 577 default: 628 578 BUG(); 579 + return 0; 629 580 } 630 581 } 631 582 ··· 635 584 switch (plane) { 636 585 case OMAP_DSS_GFX: 637 586 BUG(); 587 + return 0; 638 588 case OMAP_DSS_VIDEO1: 639 589 return 0x0584; 640 590 case OMAP_DSS_VIDEO2: ··· 644 592 return 0x0428; 645 593 default: 646 594 BUG(); 595 + return 0; 647 596 } 648 597 } 649 598 ··· 653 600 switch (plane) { 654 601 case OMAP_DSS_GFX: 655 602 BUG(); 603 + return 0; 656 604 case OMAP_DSS_VIDEO1: 657 605 case OMAP_DSS_VIDEO2: 658 606 return 0x0030; ··· 661 607 return 0x0004; 662 608 default: 663 609 BUG(); 610 + return 0; 664 611 } 665 612 } 666 613 ··· 670 615 switch (plane) { 671 616 case OMAP_DSS_GFX: 672 617 BUG(); 618 + return 0; 673 619 case OMAP_DSS_VIDEO1: 674 620 return 0x0588; 675 621 case OMAP_DSS_VIDEO2: ··· 679 623 return 0x042C; 680 624 default: 681 625 BUG(); 626 + return 0; 682 627 } 683 628 } 684 629 ··· 689 632 switch (plane) { 690 633 case OMAP_DSS_GFX: 691 634 BUG(); 635 + return 0; 692 636 case OMAP_DSS_VIDEO1: 693 637 case OMAP_DSS_VIDEO2: 694 638 return 0x0034 + i * 0x8; ··· 697 639 return 0x0010 + i * 0x8; 698 640 default: 699 641 BUG(); 642 + return 0; 700 643 } 701 644 } 702 645 ··· 707 648 switch (plane) { 708 649 case OMAP_DSS_GFX: 709 650 BUG(); 651 + return 0; 710 652 case OMAP_DSS_VIDEO1: 711 653 return 0x058C + i * 0x8; 712 654 case OMAP_DSS_VIDEO2: ··· 716 656 return 0x0430 + i * 0x8; 717 657 default: 718 658 BUG(); 659 + return 0; 719 660 } 720 661 } 721 662 ··· 726 665 switch (plane) { 727 666 case OMAP_DSS_GFX: 728 667 BUG(); 668 + return 0; 729 669 case OMAP_DSS_VIDEO1: 730 670 case OMAP_DSS_VIDEO2: 731 671 return 0x0038 + i * 0x8; ··· 734 672 return 0x0014 + i * 0x8; 735 673 default: 736 674 BUG(); 675 + return 0; 737 676 } 738 677 } 739 678 ··· 744 681 switch (plane) { 745 682 case OMAP_DSS_GFX: 746 683 BUG(); 684 + return 0; 747 685 case OMAP_DSS_VIDEO1: 748 686 return 0x0590 + i * 8; 749 687 case OMAP_DSS_VIDEO2: ··· 753 689 return 0x0434 + i * 0x8; 754 690 default: 755 691 BUG(); 692 + return 0; 756 693 } 757 694 } 758 695 ··· 763 698 switch (plane) { 764 699 case OMAP_DSS_GFX: 765 700 BUG(); 701 + return 0; 766 702 case OMAP_DSS_VIDEO1: 767 703 case OMAP_DSS_VIDEO2: 768 704 case OMAP_DSS_VIDEO3: 769 705 return 0x0074 + i * 0x4; 770 706 default: 771 707 BUG(); 708 + return 0; 772 709 } 773 710 } 774 711 ··· 780 713 switch (plane) { 781 714 case OMAP_DSS_GFX: 782 715 BUG(); 716 + return 0; 783 717 case OMAP_DSS_VIDEO1: 784 718 return 0x0124 + i * 0x4; 785 719 case OMAP_DSS_VIDEO2: ··· 789 721 return 0x0050 + i * 0x4; 790 722 default: 791 723 BUG(); 724 + return 0; 792 725 } 793 726 } 794 727 ··· 799 730 switch (plane) { 800 731 case OMAP_DSS_GFX: 801 732 BUG(); 733 + return 0; 802 734 case OMAP_DSS_VIDEO1: 803 735 return 0x05CC + i * 0x4; 804 736 case OMAP_DSS_VIDEO2: ··· 808 738 return 0x0470 + i * 0x4; 809 739 default: 810 740 BUG(); 741 + return 0; 811 742 } 812 743 } 813 744 ··· 825 754 return 0x00A0; 826 755 default: 827 756 BUG(); 757 + return 0; 828 758 } 829 759 } 830 760 #endif
+9 -40
drivers/video/omap2/dss/display.c
··· 304 304 return 24; 305 305 default: 306 306 BUG(); 307 + return 0; 307 308 } 308 309 } 309 310 EXPORT_SYMBOL(omapdss_default_get_recommended_bpp); 311 + 312 + void omapdss_default_get_timings(struct omap_dss_device *dssdev, 313 + struct omap_video_timings *timings) 314 + { 315 + *timings = dssdev->panel.timings; 316 + } 317 + EXPORT_SYMBOL(omapdss_default_get_timings); 310 318 311 319 /* Checks if replication logic should be used. Only use for active matrix, 312 320 * when overlay is in RGB12U or RGB16 mode, and LCD interface is ··· 348 340 break; 349 341 default: 350 342 BUG(); 343 + return false; 351 344 } 352 345 353 346 return bpp > 16; ··· 360 351 struct device_attribute *attr; 361 352 int i; 362 353 int r; 363 - 364 - switch (dssdev->type) { 365 - #ifdef CONFIG_OMAP2_DSS_DPI 366 - case OMAP_DISPLAY_TYPE_DPI: 367 - r = dpi_init_display(dssdev); 368 - break; 369 - #endif 370 - #ifdef CONFIG_OMAP2_DSS_RFBI 371 - case OMAP_DISPLAY_TYPE_DBI: 372 - r = rfbi_init_display(dssdev); 373 - break; 374 - #endif 375 - #ifdef CONFIG_OMAP2_DSS_VENC 376 - case OMAP_DISPLAY_TYPE_VENC: 377 - r = venc_init_display(dssdev); 378 - break; 379 - #endif 380 - #ifdef CONFIG_OMAP2_DSS_SDI 381 - case OMAP_DISPLAY_TYPE_SDI: 382 - r = sdi_init_display(dssdev); 383 - break; 384 - #endif 385 - #ifdef CONFIG_OMAP2_DSS_DSI 386 - case OMAP_DISPLAY_TYPE_DSI: 387 - r = dsi_init_display(dssdev); 388 - break; 389 - #endif 390 - case OMAP_DISPLAY_TYPE_HDMI: 391 - r = hdmi_init_display(dssdev); 392 - break; 393 - default: 394 - DSSERR("Support for display '%s' not compiled in.\n", 395 - dssdev->name); 396 - return; 397 - } 398 - 399 - if (r) { 400 - DSSERR("failed to init display %s\n", dssdev->name); 401 - return; 402 - } 403 354 404 355 /* create device sysfs files */ 405 356 i = 0;
+54 -21
drivers/video/omap2/dss/dpi.c
··· 156 156 t->pixel_clock = pck; 157 157 } 158 158 159 - dispc_mgr_set_lcd_timings(dssdev->manager->id, t); 159 + dss_mgr_set_timings(dssdev->manager, t); 160 160 161 161 return 0; 162 162 } ··· 202 202 goto err_reg_enable; 203 203 } 204 204 205 - r = dss_runtime_get(); 206 - if (r) 207 - goto err_get_dss; 208 - 209 205 r = dispc_runtime_get(); 210 206 if (r) 211 207 goto err_get_dispc; ··· 240 244 err_get_dsi: 241 245 dispc_runtime_put(); 242 246 err_get_dispc: 243 - dss_runtime_put(); 244 - err_get_dss: 245 247 if (cpu_is_omap34xx()) 246 248 regulator_disable(dpi.vdds_dsi_reg); 247 249 err_reg_enable: ··· 260 266 } 261 267 262 268 dispc_runtime_put(); 263 - dss_runtime_put(); 264 269 265 270 if (cpu_is_omap34xx()) 266 271 regulator_disable(dpi.vdds_dsi_reg); ··· 276 283 DSSDBG("dpi_set_timings\n"); 277 284 dssdev->panel.timings = *timings; 278 285 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 279 - r = dss_runtime_get(); 286 + r = dispc_runtime_get(); 280 287 if (r) 281 288 return; 282 289 283 - r = dispc_runtime_get(); 284 - if (r) { 285 - dss_runtime_put(); 286 - return; 287 - } 288 - 289 290 dpi_set_mode(dssdev); 290 - dispc_mgr_go(dssdev->manager->id); 291 291 292 292 dispc_runtime_put(); 293 - dss_runtime_put(); 293 + } else { 294 + dss_mgr_set_timings(dssdev->manager, timings); 294 295 } 295 296 } 296 297 EXPORT_SYMBOL(dpi_set_timings); ··· 299 312 unsigned long pck; 300 313 struct dispc_clock_info dispc_cinfo; 301 314 302 - if (!dispc_lcd_timings_ok(timings)) 315 + if (dss_mgr_check_timings(dssdev->manager, timings)) 303 316 return -EINVAL; 304 317 305 318 if (timings->pixel_clock == 0) ··· 339 352 } 340 353 EXPORT_SYMBOL(dpi_check_timings); 341 354 342 - int dpi_init_display(struct omap_dss_device *dssdev) 355 + static int __init dpi_init_display(struct omap_dss_device *dssdev) 343 356 { 344 357 DSSDBG("init_display\n"); 345 358 ··· 365 378 return 0; 366 379 } 367 380 368 - int dpi_init(void) 381 + static void __init dpi_probe_pdata(struct platform_device *pdev) 369 382 { 383 + struct omap_dss_board_info *pdata = pdev->dev.platform_data; 384 + int i, r; 385 + 386 + for (i = 0; i < pdata->num_devices; ++i) { 387 + struct omap_dss_device *dssdev = pdata->devices[i]; 388 + 389 + if (dssdev->type != OMAP_DISPLAY_TYPE_DPI) 390 + continue; 391 + 392 + r = dpi_init_display(dssdev); 393 + if (r) { 394 + DSSERR("device %s init failed: %d\n", dssdev->name, r); 395 + continue; 396 + } 397 + 398 + r = omap_dss_register_device(dssdev, &pdev->dev, i); 399 + if (r) 400 + DSSERR("device %s register failed: %d\n", 401 + dssdev->name, r); 402 + } 403 + } 404 + 405 + static int __init omap_dpi_probe(struct platform_device *pdev) 406 + { 407 + dpi_probe_pdata(pdev); 408 + 370 409 return 0; 371 410 } 372 411 373 - void dpi_exit(void) 412 + static int __exit omap_dpi_remove(struct platform_device *pdev) 374 413 { 414 + omap_dss_unregister_child_devices(&pdev->dev); 415 + 416 + return 0; 375 417 } 376 418 419 + static struct platform_driver omap_dpi_driver = { 420 + .remove = __exit_p(omap_dpi_remove), 421 + .driver = { 422 + .name = "omapdss_dpi", 423 + .owner = THIS_MODULE, 424 + }, 425 + }; 426 + 427 + int __init dpi_init_platform_driver(void) 428 + { 429 + return platform_driver_probe(&omap_dpi_driver, omap_dpi_probe); 430 + } 431 + 432 + void __exit dpi_uninit_platform_driver(void) 433 + { 434 + platform_driver_unregister(&omap_dpi_driver); 435 + }
+271 -135
drivers/video/omap2/dss/dsi.c
··· 256 256 struct platform_device *pdev; 257 257 void __iomem *base; 258 258 259 + int module_id; 260 + 259 261 int irq; 260 262 261 263 struct clk *dss_clk; 262 264 struct clk *sys_clk; 263 - 264 - int (*enable_pads)(int dsi_id, unsigned lane_mask); 265 - void (*disable_pads)(int dsi_id, unsigned lane_mask); 266 265 267 266 struct dsi_clock_info current_cinfo; 268 267 ··· 360 361 return dsi_pdev_map[module]; 361 362 } 362 363 363 - static inline int dsi_get_dsidev_id(struct platform_device *dsidev) 364 - { 365 - return dsidev->id; 366 - } 367 - 368 364 static inline void dsi_write_reg(struct platform_device *dsidev, 369 365 const struct dsi_reg idx, u32 val) 370 366 { ··· 446 452 return 16; 447 453 default: 448 454 BUG(); 455 + return 0; 449 456 } 450 457 } 451 458 ··· 1179 1184 static unsigned long dsi_fclk_rate(struct platform_device *dsidev) 1180 1185 { 1181 1186 unsigned long r; 1182 - int dsi_module = dsi_get_dsidev_id(dsidev); 1183 1187 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1184 1188 1185 - if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) { 1189 + if (dss_get_dsi_clk_source(dsi->module_id) == OMAP_DSS_CLK_SRC_FCK) { 1186 1190 /* DSI FCLK source is DSS_CLK_FCK */ 1187 1191 r = clk_get_rate(dsi->dss_clk); 1188 1192 } else { ··· 1273 1279 } 1274 1280 1275 1281 /* calculate clock rates using dividers in cinfo */ 1276 - static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, 1282 + static int dsi_calc_clock_rates(struct platform_device *dsidev, 1277 1283 struct dsi_clock_info *cinfo) 1278 1284 { 1279 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 1280 1285 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1281 1286 1282 1287 if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max) ··· 1290 1297 if (cinfo->regm_dsi > dsi->regm_dsi_max) 1291 1298 return -EINVAL; 1292 1299 1293 - if (cinfo->use_sys_clk) { 1294 - cinfo->clkin = clk_get_rate(dsi->sys_clk); 1295 - /* XXX it is unclear if highfreq should be used 1296 - * with DSS_SYS_CLK source also */ 1297 - cinfo->highfreq = 0; 1298 - } else { 1299 - cinfo->clkin = dispc_mgr_pclk_rate(dssdev->manager->id); 1300 - 1301 - if (cinfo->clkin < 32000000) 1302 - cinfo->highfreq = 0; 1303 - else 1304 - cinfo->highfreq = 1; 1305 - } 1306 - 1307 - cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); 1300 + cinfo->clkin = clk_get_rate(dsi->sys_clk); 1301 + cinfo->fint = cinfo->clkin / cinfo->regn; 1308 1302 1309 1303 if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min) 1310 1304 return -EINVAL; ··· 1358 1378 1359 1379 memset(&cur, 0, sizeof(cur)); 1360 1380 cur.clkin = dss_sys_clk; 1361 - cur.use_sys_clk = 1; 1362 - cur.highfreq = 0; 1363 1381 1364 - /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ 1365 - /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ 1382 + /* 0.75MHz < Fint = clkin / regn < 2.1MHz */ 1366 1383 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ 1367 1384 for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { 1368 - if (cur.highfreq == 0) 1369 - cur.fint = cur.clkin / cur.regn; 1370 - else 1371 - cur.fint = cur.clkin / (2 * cur.regn); 1385 + cur.fint = cur.clkin / cur.regn; 1372 1386 1373 1387 if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min) 1374 1388 continue; 1375 1389 1376 - /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ 1390 + /* DSIPHY(MHz) = (2 * regm / regn) * clkin */ 1377 1391 for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) { 1378 1392 unsigned long a, b; 1379 1393 1380 1394 a = 2 * cur.regm * (cur.clkin/1000); 1381 - b = cur.regn * (cur.highfreq + 1); 1395 + b = cur.regn; 1382 1396 cur.clkin4ddr = a / b * 1000; 1383 1397 1384 1398 if (cur.clkin4ddr > 1800 * 1000 * 1000) ··· 1460 1486 1461 1487 DSSDBGF(); 1462 1488 1463 - dsi->current_cinfo.use_sys_clk = cinfo->use_sys_clk; 1464 - dsi->current_cinfo.highfreq = cinfo->highfreq; 1465 - 1489 + dsi->current_cinfo.clkin = cinfo->clkin; 1466 1490 dsi->current_cinfo.fint = cinfo->fint; 1467 1491 dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr; 1468 1492 dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk = ··· 1475 1503 1476 1504 DSSDBG("DSI Fint %ld\n", cinfo->fint); 1477 1505 1478 - DSSDBG("clkin (%s) rate %ld, highfreq %d\n", 1479 - cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree", 1480 - cinfo->clkin, 1481 - cinfo->highfreq); 1506 + DSSDBG("clkin rate %ld\n", cinfo->clkin); 1482 1507 1483 1508 /* DSIPHY == CLKIN4DDR */ 1484 - DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu / %d = %lu\n", 1509 + DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu = %lu\n", 1485 1510 cinfo->regm, 1486 1511 cinfo->regn, 1487 1512 cinfo->clkin, 1488 - cinfo->highfreq + 1, 1489 1513 cinfo->clkin4ddr); 1490 1514 1491 1515 DSSDBG("Data rate on 1 DSI lane %ld Mbps\n", ··· 1536 1568 1537 1569 if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) 1538 1570 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ 1539 - l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1, 1540 - 11, 11); /* DSI_PLL_CLKSEL */ 1541 - l = FLD_MOD(l, cinfo->highfreq, 1542 - 12, 12); /* DSI_PLL_HIGHFREQ */ 1543 1571 l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ 1544 1572 l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ 1545 1573 l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ ··· 1680 1716 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1681 1717 struct dsi_clock_info *cinfo = &dsi->current_cinfo; 1682 1718 enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; 1683 - int dsi_module = dsi_get_dsidev_id(dsidev); 1719 + int dsi_module = dsi->module_id; 1684 1720 1685 1721 dispc_clk_src = dss_get_dispc_clk_source(); 1686 1722 dsi_clk_src = dss_get_dsi_clk_source(dsi_module); ··· 1690 1726 1691 1727 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); 1692 1728 1693 - seq_printf(s, "dsi pll source = %s\n", 1694 - cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree"); 1729 + seq_printf(s, "dsi pll clkin\t%lu\n", cinfo->clkin); 1695 1730 1696 1731 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); 1697 1732 ··· 1752 1789 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1753 1790 unsigned long flags; 1754 1791 struct dsi_irq_stats stats; 1755 - int dsi_module = dsi_get_dsidev_id(dsidev); 1756 1792 1757 1793 spin_lock_irqsave(&dsi->irq_stats_lock, flags); 1758 1794 ··· 1768 1806 #define PIS(x) \ 1769 1807 seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); 1770 1808 1771 - seq_printf(s, "-- DSI%d interrupts --\n", dsi_module + 1); 1809 + seq_printf(s, "-- DSI%d interrupts --\n", dsi->module_id + 1); 1772 1810 PIS(VC0); 1773 1811 PIS(VC1); 1774 1812 PIS(VC2); ··· 1847 1885 struct platform_device *dsidev = dsi_get_dsidev_from_id(1); 1848 1886 1849 1887 dsi_dump_dsidev_irqs(dsidev, s); 1850 - } 1851 - 1852 - void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir, 1853 - const struct file_operations *debug_fops) 1854 - { 1855 - struct platform_device *dsidev; 1856 - 1857 - dsidev = dsi_get_dsidev_from_id(0); 1858 - if (dsidev) 1859 - debugfs_create_file("dsi1_irqs", S_IRUGO, debugfs_dir, 1860 - &dsi1_dump_irqs, debug_fops); 1861 - 1862 - dsidev = dsi_get_dsidev_from_id(1); 1863 - if (dsidev) 1864 - debugfs_create_file("dsi2_irqs", S_IRUGO, debugfs_dir, 1865 - &dsi2_dump_irqs, debug_fops); 1866 1888 } 1867 1889 #endif 1868 1890 ··· 1948 2002 dsi_dump_dsidev_regs(dsidev, s); 1949 2003 } 1950 2004 1951 - void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir, 1952 - const struct file_operations *debug_fops) 1953 - { 1954 - struct platform_device *dsidev; 1955 - 1956 - dsidev = dsi_get_dsidev_from_id(0); 1957 - if (dsidev) 1958 - debugfs_create_file("dsi1_regs", S_IRUGO, debugfs_dir, 1959 - &dsi1_dump_regs, debug_fops); 1960 - 1961 - dsidev = dsi_get_dsidev_from_id(1); 1962 - if (dsidev) 1963 - debugfs_create_file("dsi2_regs", S_IRUGO, debugfs_dir, 1964 - &dsi2_dump_regs, debug_fops); 1965 - } 1966 2005 enum dsi_cio_power_state { 1967 2006 DSI_COMPLEXIO_POWER_OFF = 0x0, 1968 2007 DSI_COMPLEXIO_POWER_ON = 0x1, ··· 2004 2073 return 1365 * 3; /* 1365x24 bits */ 2005 2074 default: 2006 2075 BUG(); 2076 + return 0; 2007 2077 } 2008 2078 } 2009 2079 ··· 2269 2337 2270 2338 DSSDBGF(); 2271 2339 2272 - r = dsi->enable_pads(dsidev->id, dsi_get_lane_mask(dssdev)); 2340 + r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); 2273 2341 if (r) 2274 2342 return r; 2275 2343 ··· 2379 2447 dsi_cio_disable_lane_override(dsidev); 2380 2448 err_scp_clk_dom: 2381 2449 dsi_disable_scp_clk(dsidev); 2382 - dsi->disable_pads(dsidev->id, dsi_get_lane_mask(dssdev)); 2450 + dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); 2383 2451 return r; 2384 2452 } 2385 2453 ··· 2393 2461 2394 2462 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); 2395 2463 dsi_disable_scp_clk(dsidev); 2396 - dsi->disable_pads(dsidev->id, dsi_get_lane_mask(dssdev)); 2464 + dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); 2397 2465 } 2398 2466 2399 2467 static void dsi_config_tx_fifo(struct platform_device *dsidev, ··· 2417 2485 if (add + size > 4) { 2418 2486 DSSERR("Illegal FIFO configuration\n"); 2419 2487 BUG(); 2488 + return; 2420 2489 } 2421 2490 2422 2491 v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4); ··· 2450 2517 if (add + size > 4) { 2451 2518 DSSERR("Illegal FIFO configuration\n"); 2452 2519 BUG(); 2520 + return; 2453 2521 } 2454 2522 2455 2523 v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4); ··· 2592 2658 return dsi_sync_vc_l4(dsidev, channel); 2593 2659 default: 2594 2660 BUG(); 2661 + return -EINVAL; 2595 2662 } 2596 2663 } 2597 2664 ··· 3161 3226 data = reqdata[0] | (reqdata[1] << 8); 3162 3227 } else { 3163 3228 BUG(); 3229 + return -EINVAL; 3164 3230 } 3165 3231 3166 3232 r = dsi_vc_send_short(dsidev, channel, data_type, data, 0); ··· 3276 3340 goto err; 3277 3341 } 3278 3342 3279 - BUG(); 3280 3343 err: 3281 3344 DSSERR("dsi_vc_read_rx_fifo(ch %d type %s) failed\n", channel, 3282 3345 type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" : "DCS"); ··· 3670 3735 dsi_write_reg(dsidev, DSI_CTRL, r); 3671 3736 } 3672 3737 3738 + /* 3739 + * According to section 'HS Command Mode Interleaving' in OMAP TRM, Scenario 3 3740 + * results in maximum transition time for data and clock lanes to enter and 3741 + * exit HS mode. Hence, this is the scenario where the least amount of command 3742 + * mode data can be interleaved. We program the minimum amount of TXBYTECLKHS 3743 + * clock cycles that can be used to interleave command mode data in HS so that 3744 + * all scenarios are satisfied. 3745 + */ 3746 + static int dsi_compute_interleave_hs(int blank, bool ddr_alwon, int enter_hs, 3747 + int exit_hs, int exiths_clk, int ddr_pre, int ddr_post) 3748 + { 3749 + int transition; 3750 + 3751 + /* 3752 + * If DDR_CLK_ALWAYS_ON is set, we need to consider HS mode transition 3753 + * time of data lanes only, if it isn't set, we need to consider HS 3754 + * transition time of both data and clock lanes. HS transition time 3755 + * of Scenario 3 is considered. 3756 + */ 3757 + if (ddr_alwon) { 3758 + transition = enter_hs + exit_hs + max(enter_hs, 2) + 1; 3759 + } else { 3760 + int trans1, trans2; 3761 + trans1 = ddr_pre + enter_hs + exit_hs + max(enter_hs, 2) + 1; 3762 + trans2 = ddr_pre + enter_hs + exiths_clk + ddr_post + ddr_pre + 3763 + enter_hs + 1; 3764 + transition = max(trans1, trans2); 3765 + } 3766 + 3767 + return blank > transition ? blank - transition : 0; 3768 + } 3769 + 3770 + /* 3771 + * According to section 'LP Command Mode Interleaving' in OMAP TRM, Scenario 1 3772 + * results in maximum transition time for data lanes to enter and exit LP mode. 3773 + * Hence, this is the scenario where the least amount of command mode data can 3774 + * be interleaved. We program the minimum amount of bytes that can be 3775 + * interleaved in LP so that all scenarios are satisfied. 3776 + */ 3777 + static int dsi_compute_interleave_lp(int blank, int enter_hs, int exit_hs, 3778 + int lp_clk_div, int tdsi_fclk) 3779 + { 3780 + int trans_lp; /* time required for a LP transition, in TXBYTECLKHS */ 3781 + int tlp_avail; /* time left for interleaving commands, in CLKIN4DDR */ 3782 + int ttxclkesc; /* period of LP transmit escape clock, in CLKIN4DDR */ 3783 + int thsbyte_clk = 16; /* Period of TXBYTECLKHS clock, in CLKIN4DDR */ 3784 + int lp_inter; /* cmd mode data that can be interleaved, in bytes */ 3785 + 3786 + /* maximum LP transition time according to Scenario 1 */ 3787 + trans_lp = exit_hs + max(enter_hs, 2) + 1; 3788 + 3789 + /* CLKIN4DDR = 16 * TXBYTECLKHS */ 3790 + tlp_avail = thsbyte_clk * (blank - trans_lp); 3791 + 3792 + ttxclkesc = tdsi_fclk / lp_clk_div; 3793 + 3794 + lp_inter = ((tlp_avail - 8 * thsbyte_clk - 5 * tdsi_fclk) / ttxclkesc - 3795 + 26) / 16; 3796 + 3797 + return max(lp_inter, 0); 3798 + } 3799 + 3800 + static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev) 3801 + { 3802 + struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3803 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3804 + int blanking_mode; 3805 + int hfp_blanking_mode, hbp_blanking_mode, hsa_blanking_mode; 3806 + int hsa, hfp, hbp, width_bytes, bllp, lp_clk_div; 3807 + int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat; 3808 + int tclk_trail, ths_exit, exiths_clk; 3809 + bool ddr_alwon; 3810 + struct omap_video_timings *timings = &dssdev->panel.timings; 3811 + int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); 3812 + int ndl = dsi->num_lanes_used - 1; 3813 + int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1; 3814 + int hsa_interleave_hs = 0, hsa_interleave_lp = 0; 3815 + int hfp_interleave_hs = 0, hfp_interleave_lp = 0; 3816 + int hbp_interleave_hs = 0, hbp_interleave_lp = 0; 3817 + int bl_interleave_hs = 0, bl_interleave_lp = 0; 3818 + u32 r; 3819 + 3820 + r = dsi_read_reg(dsidev, DSI_CTRL); 3821 + blanking_mode = FLD_GET(r, 20, 20); 3822 + hfp_blanking_mode = FLD_GET(r, 21, 21); 3823 + hbp_blanking_mode = FLD_GET(r, 22, 22); 3824 + hsa_blanking_mode = FLD_GET(r, 23, 23); 3825 + 3826 + r = dsi_read_reg(dsidev, DSI_VM_TIMING1); 3827 + hbp = FLD_GET(r, 11, 0); 3828 + hfp = FLD_GET(r, 23, 12); 3829 + hsa = FLD_GET(r, 31, 24); 3830 + 3831 + r = dsi_read_reg(dsidev, DSI_CLK_TIMING); 3832 + ddr_clk_post = FLD_GET(r, 7, 0); 3833 + ddr_clk_pre = FLD_GET(r, 15, 8); 3834 + 3835 + r = dsi_read_reg(dsidev, DSI_VM_TIMING7); 3836 + exit_hs_mode_lat = FLD_GET(r, 15, 0); 3837 + enter_hs_mode_lat = FLD_GET(r, 31, 16); 3838 + 3839 + r = dsi_read_reg(dsidev, DSI_CLK_CTRL); 3840 + lp_clk_div = FLD_GET(r, 12, 0); 3841 + ddr_alwon = FLD_GET(r, 13, 13); 3842 + 3843 + r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0); 3844 + ths_exit = FLD_GET(r, 7, 0); 3845 + 3846 + r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); 3847 + tclk_trail = FLD_GET(r, 15, 8); 3848 + 3849 + exiths_clk = ths_exit + tclk_trail; 3850 + 3851 + width_bytes = DIV_ROUND_UP(timings->x_res * bpp, 8); 3852 + bllp = hbp + hfp + hsa + DIV_ROUND_UP(width_bytes + 6, ndl); 3853 + 3854 + if (!hsa_blanking_mode) { 3855 + hsa_interleave_hs = dsi_compute_interleave_hs(hsa, ddr_alwon, 3856 + enter_hs_mode_lat, exit_hs_mode_lat, 3857 + exiths_clk, ddr_clk_pre, ddr_clk_post); 3858 + hsa_interleave_lp = dsi_compute_interleave_lp(hsa, 3859 + enter_hs_mode_lat, exit_hs_mode_lat, 3860 + lp_clk_div, dsi_fclk_hsdiv); 3861 + } 3862 + 3863 + if (!hfp_blanking_mode) { 3864 + hfp_interleave_hs = dsi_compute_interleave_hs(hfp, ddr_alwon, 3865 + enter_hs_mode_lat, exit_hs_mode_lat, 3866 + exiths_clk, ddr_clk_pre, ddr_clk_post); 3867 + hfp_interleave_lp = dsi_compute_interleave_lp(hfp, 3868 + enter_hs_mode_lat, exit_hs_mode_lat, 3869 + lp_clk_div, dsi_fclk_hsdiv); 3870 + } 3871 + 3872 + if (!hbp_blanking_mode) { 3873 + hbp_interleave_hs = dsi_compute_interleave_hs(hbp, ddr_alwon, 3874 + enter_hs_mode_lat, exit_hs_mode_lat, 3875 + exiths_clk, ddr_clk_pre, ddr_clk_post); 3876 + 3877 + hbp_interleave_lp = dsi_compute_interleave_lp(hbp, 3878 + enter_hs_mode_lat, exit_hs_mode_lat, 3879 + lp_clk_div, dsi_fclk_hsdiv); 3880 + } 3881 + 3882 + if (!blanking_mode) { 3883 + bl_interleave_hs = dsi_compute_interleave_hs(bllp, ddr_alwon, 3884 + enter_hs_mode_lat, exit_hs_mode_lat, 3885 + exiths_clk, ddr_clk_pre, ddr_clk_post); 3886 + 3887 + bl_interleave_lp = dsi_compute_interleave_lp(bllp, 3888 + enter_hs_mode_lat, exit_hs_mode_lat, 3889 + lp_clk_div, dsi_fclk_hsdiv); 3890 + } 3891 + 3892 + DSSDBG("DSI HS interleaving(TXBYTECLKHS) HSA %d, HFP %d, HBP %d, BLLP %d\n", 3893 + hsa_interleave_hs, hfp_interleave_hs, hbp_interleave_hs, 3894 + bl_interleave_hs); 3895 + 3896 + DSSDBG("DSI LP interleaving(bytes) HSA %d, HFP %d, HBP %d, BLLP %d\n", 3897 + hsa_interleave_lp, hfp_interleave_lp, hbp_interleave_lp, 3898 + bl_interleave_lp); 3899 + 3900 + r = dsi_read_reg(dsidev, DSI_VM_TIMING4); 3901 + r = FLD_MOD(r, hsa_interleave_hs, 23, 16); 3902 + r = FLD_MOD(r, hfp_interleave_hs, 15, 8); 3903 + r = FLD_MOD(r, hbp_interleave_hs, 7, 0); 3904 + dsi_write_reg(dsidev, DSI_VM_TIMING4, r); 3905 + 3906 + r = dsi_read_reg(dsidev, DSI_VM_TIMING5); 3907 + r = FLD_MOD(r, hsa_interleave_lp, 23, 16); 3908 + r = FLD_MOD(r, hfp_interleave_lp, 15, 8); 3909 + r = FLD_MOD(r, hbp_interleave_lp, 7, 0); 3910 + dsi_write_reg(dsidev, DSI_VM_TIMING5, r); 3911 + 3912 + r = dsi_read_reg(dsidev, DSI_VM_TIMING6); 3913 + r = FLD_MOD(r, bl_interleave_hs, 31, 15); 3914 + r = FLD_MOD(r, bl_interleave_lp, 16, 0); 3915 + dsi_write_reg(dsidev, DSI_VM_TIMING6, r); 3916 + } 3917 + 3673 3918 static int dsi_proto_config(struct omap_dss_device *dssdev) 3674 3919 { 3675 3920 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); ··· 3884 3769 break; 3885 3770 default: 3886 3771 BUG(); 3772 + return -EINVAL; 3887 3773 } 3888 3774 3889 3775 r = dsi_read_reg(dsidev, DSI_CTRL); ··· 3909 3793 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { 3910 3794 dsi_config_vp_sync_events(dssdev); 3911 3795 dsi_config_blanking_modes(dssdev); 3796 + dsi_config_cmd_mode_interleaving(dssdev); 3912 3797 } 3913 3798 3914 3799 dsi_vc_initial_config(dsidev, 0); ··· 4125 4008 break; 4126 4009 default: 4127 4010 BUG(); 4011 + return -EINVAL; 4128 4012 }; 4129 4013 4130 4014 dsi_if_enable(dsidev, false); ··· 4310 4192 __cancel_delayed_work(&dsi->framedone_timeout_work); 4311 4193 4312 4194 dsi_handle_framedone(dsidev, 0); 4313 - 4314 - #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC 4315 - dispc_fake_vsync_irq(); 4316 - #endif 4317 4195 } 4318 4196 4319 4197 int omap_dsi_update(struct omap_dss_device *dssdev, int channel, ··· 4373 4259 dispc_mgr_enable_stallmode(dssdev->manager->id, true); 4374 4260 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1); 4375 4261 4376 - dispc_mgr_set_lcd_timings(dssdev->manager->id, &timings); 4262 + dss_mgr_set_timings(dssdev->manager, &timings); 4377 4263 } else { 4378 4264 dispc_mgr_enable_stallmode(dssdev->manager->id, false); 4379 4265 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0); 4380 4266 4381 - dispc_mgr_set_lcd_timings(dssdev->manager->id, 4382 - &dssdev->panel.timings); 4267 + dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); 4383 4268 } 4384 4269 4385 4270 dispc_mgr_set_lcd_display_type(dssdev->manager->id, ··· 4407 4294 struct dsi_clock_info cinfo; 4408 4295 int r; 4409 4296 4410 - /* we always use DSS_CLK_SYSCK as input clock */ 4411 - cinfo.use_sys_clk = true; 4412 4297 cinfo.regn = dssdev->clocks.dsi.regn; 4413 4298 cinfo.regm = dssdev->clocks.dsi.regm; 4414 4299 cinfo.regm_dispc = dssdev->clocks.dsi.regm_dispc; 4415 4300 cinfo.regm_dsi = dssdev->clocks.dsi.regm_dsi; 4416 - r = dsi_calc_clock_rates(dssdev, &cinfo); 4301 + r = dsi_calc_clock_rates(dsidev, &cinfo); 4417 4302 if (r) { 4418 4303 DSSERR("Failed to calc dsi clocks\n"); 4419 4304 return r; ··· 4456 4345 static int dsi_display_init_dsi(struct omap_dss_device *dssdev) 4457 4346 { 4458 4347 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4459 - int dsi_module = dsi_get_dsidev_id(dsidev); 4348 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4460 4349 int r; 4461 4350 4462 4351 r = dsi_pll_init(dsidev, true, true); ··· 4468 4357 goto err1; 4469 4358 4470 4359 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); 4471 - dss_select_dsi_clk_source(dsi_module, dssdev->clocks.dsi.dsi_fclk_src); 4360 + dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); 4472 4361 dss_select_lcd_clk_source(dssdev->manager->id, 4473 4362 dssdev->clocks.dispc.channel.lcd_clk_src); 4474 4363 ··· 4507 4396 dsi_cio_uninit(dssdev); 4508 4397 err2: 4509 4398 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 4510 - dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK); 4399 + dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4511 4400 dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); 4512 4401 4513 4402 err1: ··· 4521 4410 { 4522 4411 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4523 4412 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4524 - int dsi_module = dsi_get_dsidev_id(dsidev); 4525 4413 4526 4414 if (enter_ulps && !dsi->ulps_enabled) 4527 4415 dsi_enter_ulps(dsidev); ··· 4533 4423 dsi_vc_enable(dsidev, 3, 0); 4534 4424 4535 4425 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 4536 - dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK); 4426 + dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4537 4427 dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); 4538 4428 dsi_cio_uninit(dssdev); 4539 4429 dsi_pll_uninit(dsidev, disconnect_lanes); ··· 4637 4527 } 4638 4528 EXPORT_SYMBOL(omapdss_dsi_enable_te); 4639 4529 4640 - int dsi_init_display(struct omap_dss_device *dssdev) 4530 + static int __init dsi_init_display(struct omap_dss_device *dssdev) 4641 4531 { 4642 4532 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4643 4533 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); ··· 4790 4680 clk_put(dsi->sys_clk); 4791 4681 } 4792 4682 4793 - /* DSI1 HW IP initialisation */ 4794 - static int omap_dsihw_probe(struct platform_device *dsidev) 4683 + static void __init dsi_probe_pdata(struct platform_device *dsidev) 4795 4684 { 4796 - struct omap_display_platform_data *dss_plat_data; 4797 - struct omap_dss_board_info *board_info; 4685 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4686 + struct omap_dss_board_info *pdata = dsidev->dev.platform_data; 4687 + int i, r; 4688 + 4689 + for (i = 0; i < pdata->num_devices; ++i) { 4690 + struct omap_dss_device *dssdev = pdata->devices[i]; 4691 + 4692 + if (dssdev->type != OMAP_DISPLAY_TYPE_DSI) 4693 + continue; 4694 + 4695 + if (dssdev->phy.dsi.module != dsi->module_id) 4696 + continue; 4697 + 4698 + r = dsi_init_display(dssdev); 4699 + if (r) { 4700 + DSSERR("device %s init failed: %d\n", dssdev->name, r); 4701 + continue; 4702 + } 4703 + 4704 + r = omap_dss_register_device(dssdev, &dsidev->dev, i); 4705 + if (r) 4706 + DSSERR("device %s register failed: %d\n", 4707 + dssdev->name, r); 4708 + } 4709 + } 4710 + 4711 + /* DSI1 HW IP initialisation */ 4712 + static int __init omap_dsihw_probe(struct platform_device *dsidev) 4713 + { 4798 4714 u32 rev; 4799 - int r, i, dsi_module = dsi_get_dsidev_id(dsidev); 4715 + int r, i; 4800 4716 struct resource *dsi_mem; 4801 4717 struct dsi_data *dsi; 4802 4718 ··· 4830 4694 if (!dsi) 4831 4695 return -ENOMEM; 4832 4696 4697 + dsi->module_id = dsidev->id; 4833 4698 dsi->pdev = dsidev; 4834 - dsi_pdev_map[dsi_module] = dsidev; 4699 + dsi_pdev_map[dsi->module_id] = dsidev; 4835 4700 dev_set_drvdata(&dsidev->dev, dsi); 4836 - 4837 - dss_plat_data = dsidev->dev.platform_data; 4838 - board_info = dss_plat_data->board_data; 4839 - dsi->enable_pads = board_info->dsi_enable_pads; 4840 - dsi->disable_pads = board_info->dsi_disable_pads; 4841 4701 4842 4702 spin_lock_init(&dsi->irq_lock); 4843 4703 spin_lock_init(&dsi->errors_lock); ··· 4912 4780 else 4913 4781 dsi->num_lanes_supported = 3; 4914 4782 4783 + dsi_probe_pdata(dsidev); 4784 + 4915 4785 dsi_runtime_put(dsidev); 4916 4786 4787 + if (dsi->module_id == 0) 4788 + dss_debugfs_create_file("dsi1_regs", dsi1_dump_regs); 4789 + else if (dsi->module_id == 1) 4790 + dss_debugfs_create_file("dsi2_regs", dsi2_dump_regs); 4791 + 4792 + #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 4793 + if (dsi->module_id == 0) 4794 + dss_debugfs_create_file("dsi1_irqs", dsi1_dump_irqs); 4795 + else if (dsi->module_id == 1) 4796 + dss_debugfs_create_file("dsi2_irqs", dsi2_dump_irqs); 4797 + #endif 4917 4798 return 0; 4918 4799 4919 4800 err_runtime_get: ··· 4935 4790 return r; 4936 4791 } 4937 4792 4938 - static int omap_dsihw_remove(struct platform_device *dsidev) 4793 + static int __exit omap_dsihw_remove(struct platform_device *dsidev) 4939 4794 { 4940 4795 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4941 4796 4942 4797 WARN_ON(dsi->scp_clk_refcount > 0); 4798 + 4799 + omap_dss_unregister_child_devices(&dsidev->dev); 4943 4800 4944 4801 pm_runtime_disable(&dsidev->dev); 4945 4802 ··· 4963 4816 static int dsi_runtime_suspend(struct device *dev) 4964 4817 { 4965 4818 dispc_runtime_put(); 4966 - dss_runtime_put(); 4967 4819 4968 4820 return 0; 4969 4821 } ··· 4971 4825 { 4972 4826 int r; 4973 4827 4974 - r = dss_runtime_get(); 4975 - if (r) 4976 - goto err_get_dss; 4977 - 4978 4828 r = dispc_runtime_get(); 4979 4829 if (r) 4980 - goto err_get_dispc; 4830 + return r; 4981 4831 4982 4832 return 0; 4983 - 4984 - err_get_dispc: 4985 - dss_runtime_put(); 4986 - err_get_dss: 4987 - return r; 4988 4833 } 4989 4834 4990 4835 static const struct dev_pm_ops dsi_pm_ops = { ··· 4984 4847 }; 4985 4848 4986 4849 static struct platform_driver omap_dsihw_driver = { 4987 - .probe = omap_dsihw_probe, 4988 - .remove = omap_dsihw_remove, 4850 + .remove = __exit_p(omap_dsihw_remove), 4989 4851 .driver = { 4990 4852 .name = "omapdss_dsi", 4991 4853 .owner = THIS_MODULE, ··· 4992 4856 }, 4993 4857 }; 4994 4858 4995 - int dsi_init_platform_driver(void) 4859 + int __init dsi_init_platform_driver(void) 4996 4860 { 4997 - return platform_driver_register(&omap_dsihw_driver); 4861 + return platform_driver_probe(&omap_dsihw_driver, omap_dsihw_probe); 4998 4862 } 4999 4863 5000 - void dsi_uninit_platform_driver(void) 4864 + void __exit dsi_uninit_platform_driver(void) 5001 4865 { 5002 - return platform_driver_unregister(&omap_dsihw_driver); 4866 + platform_driver_unregister(&omap_dsihw_driver); 5003 4867 }
+34 -31
drivers/video/omap2/dss/dss.c
··· 62 62 #define REG_FLD_MOD(idx, val, start, end) \ 63 63 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) 64 64 65 + static int dss_runtime_get(void); 66 + static void dss_runtime_put(void); 67 + 65 68 static struct { 66 69 struct platform_device *pdev; 67 70 void __iomem *base; ··· 280 277 dss_runtime_put(); 281 278 } 282 279 283 - void dss_dump_regs(struct seq_file *s) 280 + static void dss_dump_regs(struct seq_file *s) 284 281 { 285 282 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) 286 283 ··· 325 322 break; 326 323 default: 327 324 BUG(); 325 + return; 328 326 } 329 327 330 328 dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end); ··· 339 335 enum omap_dss_clk_source clk_src) 340 336 { 341 337 struct platform_device *dsidev; 342 - int b; 338 + int b, pos; 343 339 344 340 switch (clk_src) { 345 341 case OMAP_DSS_CLK_SRC_FCK: ··· 359 355 break; 360 356 default: 361 357 BUG(); 358 + return; 362 359 } 363 360 364 - REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ 361 + pos = dsi_module == 0 ? 1 : 10; 362 + REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* DSIx_CLK_SWITCH */ 365 363 366 364 dss.dsi_clk_source[dsi_module] = clk_src; 367 365 } ··· 395 389 break; 396 390 default: 397 391 BUG(); 392 + return; 398 393 } 399 394 400 395 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12; ··· 713 706 clk_put(dss.dss_clk); 714 707 } 715 708 716 - int dss_runtime_get(void) 709 + static int dss_runtime_get(void) 717 710 { 718 711 int r; 719 712 ··· 724 717 return r < 0 ? r : 0; 725 718 } 726 719 727 - void dss_runtime_put(void) 720 + static void dss_runtime_put(void) 728 721 { 729 722 int r; 730 723 ··· 747 740 #endif 748 741 749 742 /* DSS HW IP initialisation */ 750 - static int omap_dsshw_probe(struct platform_device *pdev) 743 + static int __init omap_dsshw_probe(struct platform_device *pdev) 751 744 { 752 745 struct resource *dss_mem; 753 746 u32 rev; ··· 792 785 dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; 793 786 dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; 794 787 795 - r = dpi_init(); 796 - if (r) { 797 - DSSERR("Failed to initialize DPI\n"); 798 - goto err_dpi; 799 - } 800 - 801 - r = sdi_init(); 802 - if (r) { 803 - DSSERR("Failed to initialize SDI\n"); 804 - goto err_sdi; 805 - } 806 - 807 788 rev = dss_read_reg(DSS_REVISION); 808 789 printk(KERN_INFO "OMAP DSS rev %d.%d\n", 809 790 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 810 791 811 792 dss_runtime_put(); 812 793 794 + dss_debugfs_create_file("dss", dss_dump_regs); 795 + 813 796 return 0; 814 - err_sdi: 815 - dpi_exit(); 816 - err_dpi: 817 - dss_runtime_put(); 797 + 818 798 err_runtime_get: 819 799 pm_runtime_disable(&pdev->dev); 820 800 dss_put_clocks(); 821 801 return r; 822 802 } 823 803 824 - static int omap_dsshw_remove(struct platform_device *pdev) 804 + static int __exit omap_dsshw_remove(struct platform_device *pdev) 825 805 { 826 - dpi_exit(); 827 - sdi_exit(); 828 - 829 806 pm_runtime_disable(&pdev->dev); 830 807 831 808 dss_put_clocks(); ··· 820 829 static int dss_runtime_suspend(struct device *dev) 821 830 { 822 831 dss_save_context(); 832 + dss_set_min_bus_tput(dev, 0); 823 833 return 0; 824 834 } 825 835 826 836 static int dss_runtime_resume(struct device *dev) 827 837 { 838 + int r; 839 + /* 840 + * Set an arbitrarily high tput request to ensure OPP100. 841 + * What we should really do is to make a request to stay in OPP100, 842 + * without any tput requirements, but that is not currently possible 843 + * via the PM layer. 844 + */ 845 + 846 + r = dss_set_min_bus_tput(dev, 1000000000); 847 + if (r) 848 + return r; 849 + 828 850 dss_restore_context(); 829 851 return 0; 830 852 } ··· 848 844 }; 849 845 850 846 static struct platform_driver omap_dsshw_driver = { 851 - .probe = omap_dsshw_probe, 852 - .remove = omap_dsshw_remove, 847 + .remove = __exit_p(omap_dsshw_remove), 853 848 .driver = { 854 849 .name = "omapdss_dss", 855 850 .owner = THIS_MODULE, ··· 856 853 }, 857 854 }; 858 855 859 - int dss_init_platform_driver(void) 856 + int __init dss_init_platform_driver(void) 860 857 { 861 - return platform_driver_register(&omap_dsshw_driver); 858 + return platform_driver_probe(&omap_dsshw_driver, omap_dsshw_probe); 862 859 } 863 860 864 861 void dss_uninit_platform_driver(void) 865 862 { 866 - return platform_driver_unregister(&omap_dsshw_driver); 863 + platform_driver_unregister(&omap_dsshw_driver); 867 864 }
+49 -102
drivers/video/omap2/dss/dss.h
··· 150 150 u16 regm_dsi; /* OMAP3: REGM4 151 151 * OMAP4: REGM5 */ 152 152 u16 lp_clk_div; 153 - 154 - u8 highfreq; 155 - bool use_sys_clk; 156 153 }; 157 154 158 155 struct seq_file; ··· 159 162 struct bus_type *dss_get_bus(void); 160 163 struct regulator *dss_get_vdds_dsi(void); 161 164 struct regulator *dss_get_vdds_sdi(void); 165 + int dss_get_ctx_loss_count(struct device *dev); 166 + int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask); 167 + void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); 168 + int dss_set_min_bus_tput(struct device *dev, unsigned long tput); 169 + int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); 170 + 171 + int omap_dss_register_device(struct omap_dss_device *dssdev, 172 + struct device *parent, int disp_num); 173 + void omap_dss_unregister_device(struct omap_dss_device *dssdev); 174 + void omap_dss_unregister_child_devices(struct device *parent); 162 175 163 176 /* apply */ 164 177 void dss_apply_init(void); ··· 186 179 int dss_mgr_set_device(struct omap_overlay_manager *mgr, 187 180 struct omap_dss_device *dssdev); 188 181 int dss_mgr_unset_device(struct omap_overlay_manager *mgr); 182 + void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 183 + struct omap_video_timings *timings); 184 + const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); 189 185 190 186 bool dss_ovl_is_enabled(struct omap_overlay *ovl); 191 187 int dss_ovl_enable(struct omap_overlay *ovl); ··· 218 208 void dss_uninit_overlay_managers(struct platform_device *pdev); 219 209 int dss_mgr_simple_check(struct omap_overlay_manager *mgr, 220 210 const struct omap_overlay_manager_info *info); 211 + int dss_mgr_check_timings(struct omap_overlay_manager *mgr, 212 + const struct omap_video_timings *timings); 221 213 int dss_mgr_check(struct omap_overlay_manager *mgr, 222 - struct omap_dss_device *dssdev, 223 214 struct omap_overlay_manager_info *info, 215 + const struct omap_video_timings *mgr_timings, 224 216 struct omap_overlay_info **overlay_infos); 225 217 226 218 /* overlay */ ··· 232 220 void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); 233 221 int dss_ovl_simple_check(struct omap_overlay *ovl, 234 222 const struct omap_overlay_info *info); 235 - int dss_ovl_check(struct omap_overlay *ovl, 236 - struct omap_overlay_info *info, struct omap_dss_device *dssdev); 223 + int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, 224 + const struct omap_video_timings *mgr_timings); 237 225 238 226 /* DSS */ 239 - int dss_init_platform_driver(void); 227 + int dss_init_platform_driver(void) __init; 240 228 void dss_uninit_platform_driver(void); 241 - 242 - int dss_runtime_get(void); 243 - void dss_runtime_put(void); 244 229 245 230 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 246 231 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); 247 232 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 248 233 void dss_dump_clocks(struct seq_file *s); 249 234 250 - void dss_dump_regs(struct seq_file *s); 251 235 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 252 236 void dss_debug_dump_clocks(struct seq_file *s); 253 237 #endif ··· 273 265 struct dispc_clock_info *dispc_cinfo); 274 266 275 267 /* SDI */ 276 - #ifdef CONFIG_OMAP2_DSS_SDI 277 - int sdi_init(void); 278 - void sdi_exit(void); 279 - int sdi_init_display(struct omap_dss_device *display); 280 - #else 281 - static inline int sdi_init(void) 282 - { 283 - return 0; 284 - } 285 - static inline void sdi_exit(void) 286 - { 287 - } 288 - #endif 268 + int sdi_init_platform_driver(void) __init; 269 + void sdi_uninit_platform_driver(void) __exit; 289 270 290 271 /* DSI */ 291 272 #ifdef CONFIG_OMAP2_DSS_DSI ··· 282 285 struct dentry; 283 286 struct file_operations; 284 287 285 - int dsi_init_platform_driver(void); 286 - void dsi_uninit_platform_driver(void); 288 + int dsi_init_platform_driver(void) __init; 289 + void dsi_uninit_platform_driver(void) __exit; 287 290 288 291 int dsi_runtime_get(struct platform_device *dsidev); 289 292 void dsi_runtime_put(struct platform_device *dsidev); 290 293 291 294 void dsi_dump_clocks(struct seq_file *s); 292 - void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir, 293 - const struct file_operations *debug_fops); 294 - void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir, 295 - const struct file_operations *debug_fops); 296 295 297 - int dsi_init_display(struct omap_dss_device *display); 298 296 void dsi_irq_handler(void); 299 297 u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); 300 298 ··· 306 314 void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); 307 315 struct platform_device *dsi_get_dsidev_from_id(int module); 308 316 #else 309 - static inline int dsi_init_platform_driver(void) 310 - { 311 - return 0; 312 - } 313 - static inline void dsi_uninit_platform_driver(void) 314 - { 315 - } 316 317 static inline int dsi_runtime_get(struct platform_device *dsidev) 317 318 { 318 319 return 0; ··· 362 377 #endif 363 378 364 379 /* DPI */ 365 - #ifdef CONFIG_OMAP2_DSS_DPI 366 - int dpi_init(void); 367 - void dpi_exit(void); 368 - int dpi_init_display(struct omap_dss_device *dssdev); 369 - #else 370 - static inline int dpi_init(void) 371 - { 372 - return 0; 373 - } 374 - static inline void dpi_exit(void) 375 - { 376 - } 377 - #endif 380 + int dpi_init_platform_driver(void) __init; 381 + void dpi_uninit_platform_driver(void) __exit; 378 382 379 383 /* DISPC */ 380 - int dispc_init_platform_driver(void); 381 - void dispc_uninit_platform_driver(void); 384 + int dispc_init_platform_driver(void) __init; 385 + void dispc_uninit_platform_driver(void) __exit; 382 386 void dispc_dump_clocks(struct seq_file *s); 383 - void dispc_dump_irqs(struct seq_file *s); 384 - void dispc_dump_regs(struct seq_file *s); 385 387 void dispc_irq_handler(void); 386 - void dispc_fake_vsync_irq(void); 387 388 388 389 int dispc_runtime_get(void); 389 390 void dispc_runtime_put(void); ··· 380 409 void dispc_lcd_enable_signal_polarity(bool act_high); 381 410 void dispc_lcd_enable_signal(bool enable); 382 411 void dispc_pck_free_enable(bool enable); 383 - void dispc_set_digit_size(u16 width, u16 height); 384 412 void dispc_enable_fifomerge(bool enable); 385 413 void dispc_enable_gamma_table(bool enable); 386 414 void dispc_set_loadmode(enum omap_dss_load_mode mode); 387 415 388 - bool dispc_lcd_timings_ok(struct omap_video_timings *timings); 416 + bool dispc_mgr_timings_ok(enum omap_channel channel, 417 + const struct omap_video_timings *timings); 389 418 unsigned long dispc_fclk_rate(void); 390 419 void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 391 420 struct dispc_clock_info *cinfo); ··· 395 424 396 425 void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); 397 426 void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, 398 - u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); 427 + u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, 428 + bool manual_update); 399 429 int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 400 - bool ilace, bool replication); 430 + bool ilace, bool replication, 431 + const struct omap_video_timings *mgr_timings); 401 432 int dispc_ovl_enable(enum omap_plane plane, bool enable); 402 433 void dispc_ovl_set_channel_out(enum omap_plane plane, 403 434 enum omap_channel channel); 404 435 405 436 void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable); 406 - void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height); 407 437 u32 dispc_mgr_get_vsync_irq(enum omap_channel channel); 408 438 u32 dispc_mgr_get_framedone_irq(enum omap_channel channel); 409 439 bool dispc_mgr_go_busy(enum omap_channel channel); ··· 417 445 void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); 418 446 void dispc_mgr_set_lcd_display_type(enum omap_channel channel, 419 447 enum omap_lcd_display_type type); 420 - void dispc_mgr_set_lcd_timings(enum omap_channel channel, 448 + void dispc_mgr_set_timings(enum omap_channel channel, 421 449 struct omap_video_timings *timings); 422 450 void dispc_mgr_set_pol_freq(enum omap_channel channel, 423 451 enum omap_panel_config config, u8 acbi, u8 acb); 424 452 unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); 425 453 unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); 454 + unsigned long dispc_core_clk_rate(void); 426 455 int dispc_mgr_set_clock_div(enum omap_channel channel, 427 456 struct dispc_clock_info *cinfo); 428 457 int dispc_mgr_get_clock_div(enum omap_channel channel, ··· 433 460 434 461 /* VENC */ 435 462 #ifdef CONFIG_OMAP2_DSS_VENC 436 - int venc_init_platform_driver(void); 437 - void venc_uninit_platform_driver(void); 438 - void venc_dump_regs(struct seq_file *s); 439 - int venc_init_display(struct omap_dss_device *display); 463 + int venc_init_platform_driver(void) __init; 464 + void venc_uninit_platform_driver(void) __exit; 440 465 unsigned long venc_get_pixel_clock(void); 441 466 #else 442 - static inline int venc_init_platform_driver(void) 443 - { 444 - return 0; 445 - } 446 - static inline void venc_uninit_platform_driver(void) 447 - { 448 - } 449 467 static inline unsigned long venc_get_pixel_clock(void) 450 468 { 451 469 WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__); ··· 446 482 447 483 /* HDMI */ 448 484 #ifdef CONFIG_OMAP4_DSS_HDMI 449 - int hdmi_init_platform_driver(void); 450 - void hdmi_uninit_platform_driver(void); 451 - int hdmi_init_display(struct omap_dss_device *dssdev); 485 + int hdmi_init_platform_driver(void) __init; 486 + void hdmi_uninit_platform_driver(void) __exit; 452 487 unsigned long hdmi_get_pixel_clock(void); 453 - void hdmi_dump_regs(struct seq_file *s); 454 488 #else 455 - static inline int hdmi_init_display(struct omap_dss_device *dssdev) 456 - { 457 - return 0; 458 - } 459 - static inline int hdmi_init_platform_driver(void) 460 - { 461 - return 0; 462 - } 463 - static inline void hdmi_uninit_platform_driver(void) 464 - { 465 - } 466 489 static inline unsigned long hdmi_get_pixel_clock(void) 467 490 { 468 491 WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__); ··· 465 514 bool omapdss_hdmi_detect(void); 466 515 int hdmi_panel_init(void); 467 516 void hdmi_panel_exit(void); 517 + #ifdef CONFIG_OMAP4_DSS_HDMI_AUDIO 518 + int hdmi_audio_enable(void); 519 + void hdmi_audio_disable(void); 520 + int hdmi_audio_start(void); 521 + void hdmi_audio_stop(void); 522 + bool hdmi_mode_has_audio(void); 523 + int hdmi_audio_config(struct omap_dss_audio *audio); 524 + #endif 468 525 469 526 /* RFBI */ 470 - #ifdef CONFIG_OMAP2_DSS_RFBI 471 - int rfbi_init_platform_driver(void); 472 - void rfbi_uninit_platform_driver(void); 473 - void rfbi_dump_regs(struct seq_file *s); 474 - int rfbi_init_display(struct omap_dss_device *display); 475 - #else 476 - static inline int rfbi_init_platform_driver(void) 477 - { 478 - return 0; 479 - } 480 - static inline void rfbi_uninit_platform_driver(void) 481 - { 482 - } 483 - #endif 527 + int rfbi_init_platform_driver(void) __init; 528 + void rfbi_uninit_platform_driver(void) __exit; 484 529 485 530 486 531 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+28 -2
drivers/video/omap2/dss/dss_features.c
··· 52 52 const char * const *clksrc_names; 53 53 const struct dss_param_range *dss_params; 54 54 55 + const enum omap_dss_rotation_type supported_rotation_types; 56 + 55 57 const u32 buffer_size_unit; 56 58 const u32 burst_size_unit; 57 59 }; ··· 313 311 * scaler cannot scale a image with width more than 768. 314 312 */ 315 313 [FEAT_PARAM_LINEWIDTH] = { 1, 768 }, 314 + [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, 315 + [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, 316 316 }; 317 317 318 318 static const struct dss_param_range omap3_dss_param_range[] = { ··· 328 324 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, 329 325 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 330 326 [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, 327 + [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, 328 + [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, 331 329 }; 332 330 333 331 static const struct dss_param_range omap4_dss_param_range[] = { ··· 343 337 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 344 338 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 345 339 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 340 + [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, 341 + [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, 346 342 }; 347 343 348 344 static const enum dss_feat_id omap2_dss_feat_list[] = { ··· 407 399 FEAT_FIR_COEF_V, 408 400 FEAT_ALPHA_FREE_ZORDER, 409 401 FEAT_FIFO_MERGE, 402 + FEAT_BURST_2D, 410 403 }; 411 404 412 405 static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = { ··· 425 416 FEAT_FIR_COEF_V, 426 417 FEAT_ALPHA_FREE_ZORDER, 427 418 FEAT_FIFO_MERGE, 419 + FEAT_BURST_2D, 428 420 }; 429 421 430 422 static const enum dss_feat_id omap4_dss_feat_list[] = { ··· 444 434 FEAT_FIR_COEF_V, 445 435 FEAT_ALPHA_FREE_ZORDER, 446 436 FEAT_FIFO_MERGE, 437 + FEAT_BURST_2D, 447 438 }; 448 439 449 440 /* OMAP2 DSS Features */ ··· 462 451 .overlay_caps = omap2_dss_overlay_caps, 463 452 .clksrc_names = omap2_dss_clk_source_names, 464 453 .dss_params = omap2_dss_param_range, 454 + .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 465 455 .buffer_size_unit = 1, 466 456 .burst_size_unit = 8, 467 457 }; ··· 482 470 .overlay_caps = omap3430_dss_overlay_caps, 483 471 .clksrc_names = omap3_dss_clk_source_names, 484 472 .dss_params = omap3_dss_param_range, 473 + .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 485 474 .buffer_size_unit = 1, 486 475 .burst_size_unit = 8, 487 476 }; ··· 501 488 .overlay_caps = omap3630_dss_overlay_caps, 502 489 .clksrc_names = omap3_dss_clk_source_names, 503 490 .dss_params = omap3_dss_param_range, 491 + .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 504 492 .buffer_size_unit = 1, 505 493 .burst_size_unit = 8, 506 494 }; ··· 522 508 .overlay_caps = omap4_dss_overlay_caps, 523 509 .clksrc_names = omap4_dss_clk_source_names, 524 510 .dss_params = omap4_dss_param_range, 511 + .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 525 512 .buffer_size_unit = 16, 526 513 .burst_size_unit = 16, 527 514 }; ··· 542 527 .overlay_caps = omap4_dss_overlay_caps, 543 528 .clksrc_names = omap4_dss_clk_source_names, 544 529 .dss_params = omap4_dss_param_range, 530 + .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 545 531 .buffer_size_unit = 16, 546 532 .burst_size_unit = 16, 547 533 }; ··· 562 546 .overlay_caps = omap4_dss_overlay_caps, 563 547 .clksrc_names = omap4_dss_clk_source_names, 564 548 .dss_params = omap4_dss_param_range, 549 + .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 565 550 .buffer_size_unit = 16, 566 551 .burst_size_unit = 16, 567 552 }; ··· 579 562 .pll_enable = ti_hdmi_4xxx_pll_enable, 580 563 .pll_disable = ti_hdmi_4xxx_pll_disable, 581 564 .video_enable = ti_hdmi_4xxx_wp_video_start, 565 + .video_disable = ti_hdmi_4xxx_wp_video_stop, 582 566 .dump_wrapper = ti_hdmi_4xxx_wp_dump, 583 567 .dump_core = ti_hdmi_4xxx_core_dump, 584 568 .dump_pll = ti_hdmi_4xxx_pll_dump, 585 569 .dump_phy = ti_hdmi_4xxx_phy_dump, 586 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 587 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 570 + #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 588 571 .audio_enable = ti_hdmi_4xxx_wp_audio_enable, 572 + .audio_disable = ti_hdmi_4xxx_wp_audio_disable, 573 + .audio_start = ti_hdmi_4xxx_audio_start, 574 + .audio_stop = ti_hdmi_4xxx_audio_stop, 575 + .audio_config = ti_hdmi_4xxx_audio_config, 589 576 #endif 590 577 591 578 }; ··· 681 660 682 661 *start = omap_current_dss_features->reg_fields[id].start; 683 662 *end = omap_current_dss_features->reg_fields[id].end; 663 + } 664 + 665 + bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type) 666 + { 667 + return omap_current_dss_features->supported_rotation_types & rot_type; 684 668 } 685 669 686 670 void dss_features_init(void)
+5
drivers/video/omap2/dss/dss_features.h
··· 62 62 FEAT_FIFO_MERGE, 63 63 /* An unknown HW bug causing the normal FIFO thresholds not to work */ 64 64 FEAT_OMAP3_DSI_FIFO_BUG, 65 + FEAT_BURST_2D, 65 66 }; 66 67 67 68 /* DSS register field id */ ··· 92 91 FEAT_PARAM_DSIPLL_LPDIV, 93 92 FEAT_PARAM_DOWNSCALE, 94 93 FEAT_PARAM_LINEWIDTH, 94 + FEAT_PARAM_MGR_WIDTH, 95 + FEAT_PARAM_MGR_HEIGHT, 95 96 }; 96 97 97 98 /* DSS Feature Functions */ ··· 110 107 111 108 u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ 112 109 u32 dss_feat_get_burst_size_unit(void); /* in bytes */ 110 + 111 + bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type); 113 112 114 113 bool dss_has_feature(enum dss_feat_id id); 115 114 void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
+194 -285
drivers/video/omap2/dss/hdmi.c
··· 33 33 #include <linux/pm_runtime.h> 34 34 #include <linux/clk.h> 35 35 #include <video/omapdss.h> 36 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 37 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 38 - #include <sound/soc.h> 39 - #include <sound/pcm_params.h> 40 - #include "ti_hdmi_4xxx_ip.h" 41 - #endif 42 36 43 37 #include "ti_hdmi.h" 44 38 #include "dss.h" ··· 57 63 58 64 static struct { 59 65 struct mutex lock; 60 - struct omap_display_platform_data *pdata; 61 66 struct platform_device *pdev; 62 67 struct hdmi_ip_data ip_data; 63 68 ··· 123 130 124 131 DSSDBG("hdmi_runtime_get\n"); 125 132 126 - /* 127 - * HACK: Add dss_runtime_get() to ensure DSS clock domain is enabled. 128 - * This should be removed later. 129 - */ 130 - r = dss_runtime_get(); 131 - if (r < 0) 132 - goto err_get_dss; 133 - 134 133 r = pm_runtime_get_sync(&hdmi.pdev->dev); 135 134 WARN_ON(r < 0); 136 135 if (r < 0) 137 - goto err_get_hdmi; 136 + return r; 138 137 139 138 return 0; 140 - 141 - err_get_hdmi: 142 - dss_runtime_put(); 143 - err_get_dss: 144 - return r; 145 139 } 146 140 147 141 static void hdmi_runtime_put(void) ··· 139 159 140 160 r = pm_runtime_put_sync(&hdmi.pdev->dev); 141 161 WARN_ON(r < 0); 142 - 143 - /* 144 - * HACK: This is added to complement the dss_runtime_get() call in 145 - * hdmi_runtime_get(). This should be removed later. 146 - */ 147 - dss_runtime_put(); 148 162 } 149 163 150 - int hdmi_init_display(struct omap_dss_device *dssdev) 164 + static int __init hdmi_init_display(struct omap_dss_device *dssdev) 151 165 { 152 166 DSSDBG("init_display\n"); 153 167 ··· 318 344 319 345 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); 320 346 321 - hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); 347 + hdmi.ip_data.ops->video_disable(&hdmi.ip_data); 322 348 323 349 /* config the PLL and PHY hdmi_set_pll_pwrfirst */ 324 350 r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); ··· 350 376 dispc_enable_gamma_table(0); 351 377 352 378 /* tv size */ 353 - dispc_set_digit_size(dssdev->panel.timings.x_res, 354 - dssdev->panel.timings.y_res); 379 + dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); 355 380 356 - hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1); 381 + r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); 382 + if (r) 383 + goto err_vid_enable; 357 384 358 385 r = dss_mgr_enable(dssdev->manager); 359 386 if (r) ··· 363 388 return 0; 364 389 365 390 err_mgr_enable: 366 - hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); 391 + hdmi.ip_data.ops->video_disable(&hdmi.ip_data); 392 + err_vid_enable: 367 393 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 368 394 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 369 395 err: ··· 376 400 { 377 401 dss_mgr_disable(dssdev->manager); 378 402 379 - hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); 403 + hdmi.ip_data.ops->video_disable(&hdmi.ip_data); 380 404 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 381 405 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 382 406 hdmi_runtime_put(); ··· 412 436 r = hdmi_power_on(dssdev); 413 437 if (r) 414 438 DSSERR("failed to power on device\n"); 439 + } else { 440 + dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); 415 441 } 416 442 } 417 443 418 - void hdmi_dump_regs(struct seq_file *s) 444 + static void hdmi_dump_regs(struct seq_file *s) 419 445 { 420 446 mutex_lock(&hdmi.lock); 421 447 ··· 533 555 mutex_unlock(&hdmi.lock); 534 556 } 535 557 536 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 537 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 538 - 539 - static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd, 540 - struct snd_soc_dai *dai) 541 - { 542 - struct snd_soc_pcm_runtime *rtd = substream->private_data; 543 - struct snd_soc_codec *codec = rtd->codec; 544 - struct platform_device *pdev = to_platform_device(codec->dev); 545 - struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec); 546 - int err = 0; 547 - 548 - if (!(ip_data->ops) && !(ip_data->ops->audio_enable)) { 549 - dev_err(&pdev->dev, "Cannot enable/disable audio\n"); 550 - return -ENODEV; 551 - } 552 - 553 - switch (cmd) { 554 - case SNDRV_PCM_TRIGGER_START: 555 - case SNDRV_PCM_TRIGGER_RESUME: 556 - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 557 - ip_data->ops->audio_enable(ip_data, true); 558 - break; 559 - case SNDRV_PCM_TRIGGER_STOP: 560 - case SNDRV_PCM_TRIGGER_SUSPEND: 561 - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 562 - ip_data->ops->audio_enable(ip_data, false); 563 - break; 564 - default: 565 - err = -EINVAL; 566 - } 567 - return err; 568 - } 569 - 570 - static int hdmi_audio_hw_params(struct snd_pcm_substream *substream, 571 - struct snd_pcm_hw_params *params, 572 - struct snd_soc_dai *dai) 573 - { 574 - struct snd_soc_pcm_runtime *rtd = substream->private_data; 575 - struct snd_soc_codec *codec = rtd->codec; 576 - struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec); 577 - struct hdmi_audio_format audio_format; 578 - struct hdmi_audio_dma audio_dma; 579 - struct hdmi_core_audio_config core_cfg; 580 - struct hdmi_core_infoframe_audio aud_if_cfg; 581 - int err, n, cts; 582 - enum hdmi_core_audio_sample_freq sample_freq; 583 - 584 - switch (params_format(params)) { 585 - case SNDRV_PCM_FORMAT_S16_LE: 586 - core_cfg.i2s_cfg.word_max_length = 587 - HDMI_AUDIO_I2S_MAX_WORD_20BITS; 588 - core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_16_BITS; 589 - core_cfg.i2s_cfg.in_length_bits = 590 - HDMI_AUDIO_I2S_INPUT_LENGTH_16; 591 - core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT; 592 - audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; 593 - audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; 594 - audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; 595 - audio_dma.transfer_size = 0x10; 596 - break; 597 - case SNDRV_PCM_FORMAT_S24_LE: 598 - core_cfg.i2s_cfg.word_max_length = 599 - HDMI_AUDIO_I2S_MAX_WORD_24BITS; 600 - core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_24_BITS; 601 - core_cfg.i2s_cfg.in_length_bits = 602 - HDMI_AUDIO_I2S_INPUT_LENGTH_24; 603 - audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE; 604 - audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS; 605 - audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT; 606 - core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; 607 - audio_dma.transfer_size = 0x20; 608 - break; 609 - default: 610 - return -EINVAL; 611 - } 612 - 613 - switch (params_rate(params)) { 614 - case 32000: 615 - sample_freq = HDMI_AUDIO_FS_32000; 616 - break; 617 - case 44100: 618 - sample_freq = HDMI_AUDIO_FS_44100; 619 - break; 620 - case 48000: 621 - sample_freq = HDMI_AUDIO_FS_48000; 622 - break; 623 - default: 624 - return -EINVAL; 625 - } 626 - 627 - err = hdmi_config_audio_acr(ip_data, params_rate(params), &n, &cts); 628 - if (err < 0) 629 - return err; 630 - 631 - /* Audio wrapper config */ 632 - audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; 633 - audio_format.active_chnnls_msk = 0x03; 634 - audio_format.type = HDMI_AUDIO_TYPE_LPCM; 635 - audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST; 636 - /* Disable start/stop signals of IEC 60958 blocks */ 637 - audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF; 638 - 639 - audio_dma.block_size = 0xC0; 640 - audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; 641 - audio_dma.fifo_threshold = 0x20; /* in number of samples */ 642 - 643 - hdmi_wp_audio_config_dma(ip_data, &audio_dma); 644 - hdmi_wp_audio_config_format(ip_data, &audio_format); 645 - 646 - /* 647 - * I2S config 648 - */ 649 - core_cfg.i2s_cfg.en_high_bitrate_aud = false; 650 - /* Only used with high bitrate audio */ 651 - core_cfg.i2s_cfg.cbit_order = false; 652 - /* Serial data and word select should change on sck rising edge */ 653 - core_cfg.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; 654 - core_cfg.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; 655 - /* Set I2S word select polarity */ 656 - core_cfg.i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT; 657 - core_cfg.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; 658 - /* Set serial data to word select shift. See Phillips spec. */ 659 - core_cfg.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT; 660 - /* Enable one of the four available serial data channels */ 661 - core_cfg.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; 662 - 663 - /* Core audio config */ 664 - core_cfg.freq_sample = sample_freq; 665 - core_cfg.n = n; 666 - core_cfg.cts = cts; 667 - if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { 668 - core_cfg.aud_par_busclk = 0; 669 - core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW; 670 - core_cfg.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK); 671 - } else { 672 - core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8); 673 - core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW; 674 - core_cfg.use_mclk = true; 675 - } 676 - 677 - if (core_cfg.use_mclk) 678 - core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS; 679 - core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH; 680 - core_cfg.en_spdif = false; 681 - /* Use sample frequency from channel status word */ 682 - core_cfg.fs_override = true; 683 - /* Enable ACR packets */ 684 - core_cfg.en_acr_pkt = true; 685 - /* Disable direct streaming digital audio */ 686 - core_cfg.en_dsd_audio = false; 687 - /* Use parallel audio interface */ 688 - core_cfg.en_parallel_aud_input = true; 689 - 690 - hdmi_core_audio_config(ip_data, &core_cfg); 691 - 692 - /* 693 - * Configure packet 694 - * info frame audio see doc CEA861-D page 74 695 - */ 696 - aud_if_cfg.db1_coding_type = HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM; 697 - aud_if_cfg.db1_channel_count = 2; 698 - aud_if_cfg.db2_sample_freq = HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM; 699 - aud_if_cfg.db2_sample_size = HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM; 700 - aud_if_cfg.db4_channel_alloc = 0x00; 701 - aud_if_cfg.db5_downmix_inh = false; 702 - aud_if_cfg.db5_lsv = 0; 703 - 704 - hdmi_core_audio_infoframe_config(ip_data, &aud_if_cfg); 705 - return 0; 706 - } 707 - 708 - static int hdmi_audio_startup(struct snd_pcm_substream *substream, 709 - struct snd_soc_dai *dai) 710 - { 711 - if (!hdmi.ip_data.cfg.cm.mode) { 712 - pr_err("Current video settings do not support audio.\n"); 713 - return -EIO; 714 - } 715 - return 0; 716 - } 717 - 718 - static int hdmi_audio_codec_probe(struct snd_soc_codec *codec) 719 - { 720 - struct hdmi_ip_data *priv = &hdmi.ip_data; 721 - 722 - snd_soc_codec_set_drvdata(codec, priv); 723 - return 0; 724 - } 725 - 726 - static struct snd_soc_codec_driver hdmi_audio_codec_drv = { 727 - .probe = hdmi_audio_codec_probe, 728 - }; 729 - 730 - static struct snd_soc_dai_ops hdmi_audio_codec_ops = { 731 - .hw_params = hdmi_audio_hw_params, 732 - .trigger = hdmi_audio_trigger, 733 - .startup = hdmi_audio_startup, 734 - }; 735 - 736 - static struct snd_soc_dai_driver hdmi_codec_dai_drv = { 737 - .name = "hdmi-audio-codec", 738 - .playback = { 739 - .channels_min = 2, 740 - .channels_max = 2, 741 - .rates = SNDRV_PCM_RATE_32000 | 742 - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, 743 - .formats = SNDRV_PCM_FMTBIT_S16_LE | 744 - SNDRV_PCM_FMTBIT_S24_LE, 745 - }, 746 - .ops = &hdmi_audio_codec_ops, 747 - }; 748 - #endif 749 - 750 558 static int hdmi_get_clocks(struct platform_device *pdev) 751 559 { 752 560 struct clk *clk; ··· 554 790 clk_put(hdmi.sys_clk); 555 791 } 556 792 793 + #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 794 + int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts) 795 + { 796 + u32 deep_color; 797 + bool deep_color_correct = false; 798 + u32 pclk = hdmi.ip_data.cfg.timings.pixel_clock; 799 + 800 + if (n == NULL || cts == NULL) 801 + return -EINVAL; 802 + 803 + /* TODO: When implemented, query deep color mode here. */ 804 + deep_color = 100; 805 + 806 + /* 807 + * When using deep color, the default N value (as in the HDMI 808 + * specification) yields to an non-integer CTS. Hence, we 809 + * modify it while keeping the restrictions described in 810 + * section 7.2.1 of the HDMI 1.4a specification. 811 + */ 812 + switch (sample_freq) { 813 + case 32000: 814 + case 48000: 815 + case 96000: 816 + case 192000: 817 + if (deep_color == 125) 818 + if (pclk == 27027 || pclk == 74250) 819 + deep_color_correct = true; 820 + if (deep_color == 150) 821 + if (pclk == 27027) 822 + deep_color_correct = true; 823 + break; 824 + case 44100: 825 + case 88200: 826 + case 176400: 827 + if (deep_color == 125) 828 + if (pclk == 27027) 829 + deep_color_correct = true; 830 + break; 831 + default: 832 + return -EINVAL; 833 + } 834 + 835 + if (deep_color_correct) { 836 + switch (sample_freq) { 837 + case 32000: 838 + *n = 8192; 839 + break; 840 + case 44100: 841 + *n = 12544; 842 + break; 843 + case 48000: 844 + *n = 8192; 845 + break; 846 + case 88200: 847 + *n = 25088; 848 + break; 849 + case 96000: 850 + *n = 16384; 851 + break; 852 + case 176400: 853 + *n = 50176; 854 + break; 855 + case 192000: 856 + *n = 32768; 857 + break; 858 + default: 859 + return -EINVAL; 860 + } 861 + } else { 862 + switch (sample_freq) { 863 + case 32000: 864 + *n = 4096; 865 + break; 866 + case 44100: 867 + *n = 6272; 868 + break; 869 + case 48000: 870 + *n = 6144; 871 + break; 872 + case 88200: 873 + *n = 12544; 874 + break; 875 + case 96000: 876 + *n = 12288; 877 + break; 878 + case 176400: 879 + *n = 25088; 880 + break; 881 + case 192000: 882 + *n = 24576; 883 + break; 884 + default: 885 + return -EINVAL; 886 + } 887 + } 888 + /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ 889 + *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); 890 + 891 + return 0; 892 + } 893 + 894 + int hdmi_audio_enable(void) 895 + { 896 + DSSDBG("audio_enable\n"); 897 + 898 + return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data); 899 + } 900 + 901 + void hdmi_audio_disable(void) 902 + { 903 + DSSDBG("audio_disable\n"); 904 + 905 + hdmi.ip_data.ops->audio_disable(&hdmi.ip_data); 906 + } 907 + 908 + int hdmi_audio_start(void) 909 + { 910 + DSSDBG("audio_start\n"); 911 + 912 + return hdmi.ip_data.ops->audio_start(&hdmi.ip_data); 913 + } 914 + 915 + void hdmi_audio_stop(void) 916 + { 917 + DSSDBG("audio_stop\n"); 918 + 919 + hdmi.ip_data.ops->audio_stop(&hdmi.ip_data); 920 + } 921 + 922 + bool hdmi_mode_has_audio(void) 923 + { 924 + if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI) 925 + return true; 926 + else 927 + return false; 928 + } 929 + 930 + int hdmi_audio_config(struct omap_dss_audio *audio) 931 + { 932 + return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio); 933 + } 934 + 935 + #endif 936 + 937 + static void __init hdmi_probe_pdata(struct platform_device *pdev) 938 + { 939 + struct omap_dss_board_info *pdata = pdev->dev.platform_data; 940 + int r, i; 941 + 942 + for (i = 0; i < pdata->num_devices; ++i) { 943 + struct omap_dss_device *dssdev = pdata->devices[i]; 944 + 945 + if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) 946 + continue; 947 + 948 + r = hdmi_init_display(dssdev); 949 + if (r) { 950 + DSSERR("device %s init failed: %d\n", dssdev->name, r); 951 + continue; 952 + } 953 + 954 + r = omap_dss_register_device(dssdev, &pdev->dev, i); 955 + if (r) 956 + DSSERR("device %s register failed: %d\n", 957 + dssdev->name, r); 958 + } 959 + } 960 + 557 961 /* HDMI HW IP initialisation */ 558 - static int omapdss_hdmihw_probe(struct platform_device *pdev) 962 + static int __init omapdss_hdmihw_probe(struct platform_device *pdev) 559 963 { 560 964 struct resource *hdmi_mem; 561 965 int r; 562 966 563 - hdmi.pdata = pdev->dev.platform_data; 564 967 hdmi.pdev = pdev; 565 968 566 969 mutex_init(&hdmi.lock); ··· 761 830 762 831 hdmi_panel_init(); 763 832 764 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 765 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 833 + dss_debugfs_create_file("hdmi", hdmi_dump_regs); 766 834 767 - /* Register ASoC codec DAI */ 768 - r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv, 769 - &hdmi_codec_dai_drv, 1); 770 - if (r) { 771 - DSSERR("can't register ASoC HDMI audio codec\n"); 772 - return r; 773 - } 774 - #endif 835 + hdmi_probe_pdata(pdev); 836 + 775 837 return 0; 776 838 } 777 839 778 - static int omapdss_hdmihw_remove(struct platform_device *pdev) 840 + static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 779 841 { 780 - hdmi_panel_exit(); 842 + omap_dss_unregister_child_devices(&pdev->dev); 781 843 782 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 783 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 784 - snd_soc_unregister_codec(&pdev->dev); 785 - #endif 844 + hdmi_panel_exit(); 786 845 787 846 pm_runtime_disable(&pdev->dev); 788 847 ··· 788 867 clk_disable(hdmi.sys_clk); 789 868 790 869 dispc_runtime_put(); 791 - dss_runtime_put(); 792 870 793 871 return 0; 794 872 } ··· 796 876 { 797 877 int r; 798 878 799 - r = dss_runtime_get(); 800 - if (r < 0) 801 - goto err_get_dss; 802 - 803 879 r = dispc_runtime_get(); 804 880 if (r < 0) 805 - goto err_get_dispc; 806 - 881 + return r; 807 882 808 883 clk_enable(hdmi.sys_clk); 809 884 810 885 return 0; 811 - 812 - err_get_dispc: 813 - dss_runtime_put(); 814 - err_get_dss: 815 - return r; 816 886 } 817 887 818 888 static const struct dev_pm_ops hdmi_pm_ops = { ··· 811 901 }; 812 902 813 903 static struct platform_driver omapdss_hdmihw_driver = { 814 - .probe = omapdss_hdmihw_probe, 815 - .remove = omapdss_hdmihw_remove, 904 + .remove = __exit_p(omapdss_hdmihw_remove), 816 905 .driver = { 817 906 .name = "omapdss_hdmi", 818 907 .owner = THIS_MODULE, ··· 819 910 }, 820 911 }; 821 912 822 - int hdmi_init_platform_driver(void) 913 + int __init hdmi_init_platform_driver(void) 823 914 { 824 - return platform_driver_register(&omapdss_hdmihw_driver); 915 + return platform_driver_probe(&omapdss_hdmihw_driver, omapdss_hdmihw_probe); 825 916 } 826 917 827 - void hdmi_uninit_platform_driver(void) 918 + void __exit hdmi_uninit_platform_driver(void) 828 919 { 829 - return platform_driver_unregister(&omapdss_hdmihw_driver); 920 + platform_driver_unregister(&omapdss_hdmihw_driver); 830 921 }
+212 -22
drivers/video/omap2/dss/hdmi_panel.c
··· 30 30 #include "dss.h" 31 31 32 32 static struct { 33 - struct mutex hdmi_lock; 33 + /* This protects the panel ops, mainly when accessing the HDMI IP. */ 34 + struct mutex lock; 35 + #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 36 + /* This protects the audio ops, specifically. */ 37 + spinlock_t audio_lock; 38 + #endif 34 39 } hdmi; 35 40 36 41 ··· 59 54 60 55 } 61 56 57 + #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 58 + static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev) 59 + { 60 + unsigned long flags; 61 + int r; 62 + 63 + mutex_lock(&hdmi.lock); 64 + spin_lock_irqsave(&hdmi.audio_lock, flags); 65 + 66 + /* enable audio only if the display is active and supports audio */ 67 + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || 68 + !hdmi_mode_has_audio()) { 69 + DSSERR("audio not supported or display is off\n"); 70 + r = -EPERM; 71 + goto err; 72 + } 73 + 74 + r = hdmi_audio_enable(); 75 + 76 + if (!r) 77 + dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; 78 + 79 + err: 80 + spin_unlock_irqrestore(&hdmi.audio_lock, flags); 81 + mutex_unlock(&hdmi.lock); 82 + return r; 83 + } 84 + 85 + static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev) 86 + { 87 + unsigned long flags; 88 + 89 + spin_lock_irqsave(&hdmi.audio_lock, flags); 90 + 91 + hdmi_audio_disable(); 92 + 93 + dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED; 94 + 95 + spin_unlock_irqrestore(&hdmi.audio_lock, flags); 96 + } 97 + 98 + static int hdmi_panel_audio_start(struct omap_dss_device *dssdev) 99 + { 100 + unsigned long flags; 101 + int r; 102 + 103 + spin_lock_irqsave(&hdmi.audio_lock, flags); 104 + /* 105 + * No need to check the panel state. It was checked when trasitioning 106 + * to AUDIO_ENABLED. 107 + */ 108 + if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED) { 109 + DSSERR("audio start from invalid state\n"); 110 + r = -EPERM; 111 + goto err; 112 + } 113 + 114 + r = hdmi_audio_start(); 115 + 116 + if (!r) 117 + dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING; 118 + 119 + err: 120 + spin_unlock_irqrestore(&hdmi.audio_lock, flags); 121 + return r; 122 + } 123 + 124 + static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev) 125 + { 126 + unsigned long flags; 127 + 128 + spin_lock_irqsave(&hdmi.audio_lock, flags); 129 + 130 + hdmi_audio_stop(); 131 + dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; 132 + 133 + spin_unlock_irqrestore(&hdmi.audio_lock, flags); 134 + } 135 + 136 + static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev) 137 + { 138 + bool r = false; 139 + 140 + mutex_lock(&hdmi.lock); 141 + 142 + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 143 + goto err; 144 + 145 + if (!hdmi_mode_has_audio()) 146 + goto err; 147 + 148 + r = true; 149 + err: 150 + mutex_unlock(&hdmi.lock); 151 + return r; 152 + } 153 + 154 + static int hdmi_panel_audio_config(struct omap_dss_device *dssdev, 155 + struct omap_dss_audio *audio) 156 + { 157 + unsigned long flags; 158 + int r; 159 + 160 + mutex_lock(&hdmi.lock); 161 + spin_lock_irqsave(&hdmi.audio_lock, flags); 162 + 163 + /* config audio only if the display is active and supports audio */ 164 + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || 165 + !hdmi_mode_has_audio()) { 166 + DSSERR("audio not supported or display is off\n"); 167 + r = -EPERM; 168 + goto err; 169 + } 170 + 171 + r = hdmi_audio_config(audio); 172 + 173 + if (!r) 174 + dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED; 175 + 176 + err: 177 + spin_unlock_irqrestore(&hdmi.audio_lock, flags); 178 + mutex_unlock(&hdmi.lock); 179 + return r; 180 + } 181 + 182 + #else 183 + static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev) 184 + { 185 + return -EPERM; 186 + } 187 + 188 + static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev) 189 + { 190 + } 191 + 192 + static int hdmi_panel_audio_start(struct omap_dss_device *dssdev) 193 + { 194 + return -EPERM; 195 + } 196 + 197 + static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev) 198 + { 199 + } 200 + 201 + static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev) 202 + { 203 + return false; 204 + } 205 + 206 + static int hdmi_panel_audio_config(struct omap_dss_device *dssdev, 207 + struct omap_dss_audio *audio) 208 + { 209 + return -EPERM; 210 + } 211 + #endif 212 + 62 213 static int hdmi_panel_enable(struct omap_dss_device *dssdev) 63 214 { 64 215 int r = 0; 65 216 DSSDBG("ENTER hdmi_panel_enable\n"); 66 217 67 - mutex_lock(&hdmi.hdmi_lock); 218 + mutex_lock(&hdmi.lock); 68 219 69 220 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 70 221 r = -EINVAL; ··· 236 75 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 237 76 238 77 err: 239 - mutex_unlock(&hdmi.hdmi_lock); 78 + mutex_unlock(&hdmi.lock); 240 79 241 80 return r; 242 81 } 243 82 244 83 static void hdmi_panel_disable(struct omap_dss_device *dssdev) 245 84 { 246 - mutex_lock(&hdmi.hdmi_lock); 85 + mutex_lock(&hdmi.lock); 247 86 248 - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 87 + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 88 + /* 89 + * TODO: notify audio users that the display was disabled. For 90 + * now, disable audio locally to not break our audio state 91 + * machine. 92 + */ 93 + hdmi_panel_audio_disable(dssdev); 249 94 omapdss_hdmi_display_disable(dssdev); 95 + } 250 96 251 97 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 252 98 253 - mutex_unlock(&hdmi.hdmi_lock); 99 + mutex_unlock(&hdmi.lock); 254 100 } 255 101 256 102 static int hdmi_panel_suspend(struct omap_dss_device *dssdev) 257 103 { 258 104 int r = 0; 259 105 260 - mutex_lock(&hdmi.hdmi_lock); 106 + mutex_lock(&hdmi.lock); 261 107 262 108 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { 263 109 r = -EINVAL; 264 110 goto err; 265 111 } 266 112 267 - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 113 + /* 114 + * TODO: notify audio users that the display was suspended. For now, 115 + * disable audio locally to not break our audio state machine. 116 + */ 117 + hdmi_panel_audio_disable(dssdev); 268 118 119 + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 269 120 omapdss_hdmi_display_disable(dssdev); 270 121 271 122 err: 272 - mutex_unlock(&hdmi.hdmi_lock); 123 + mutex_unlock(&hdmi.lock); 273 124 274 125 return r; 275 126 } ··· 290 117 { 291 118 int r = 0; 292 119 293 - mutex_lock(&hdmi.hdmi_lock); 120 + mutex_lock(&hdmi.lock); 294 121 295 122 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { 296 123 r = -EINVAL; ··· 302 129 DSSERR("failed to power on\n"); 303 130 goto err; 304 131 } 132 + /* TODO: notify audio users that the panel resumed. */ 305 133 306 134 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 307 135 308 136 err: 309 - mutex_unlock(&hdmi.hdmi_lock); 137 + mutex_unlock(&hdmi.lock); 310 138 311 139 return r; 312 140 } ··· 315 141 static void hdmi_get_timings(struct omap_dss_device *dssdev, 316 142 struct omap_video_timings *timings) 317 143 { 318 - mutex_lock(&hdmi.hdmi_lock); 144 + mutex_lock(&hdmi.lock); 319 145 320 146 *timings = dssdev->panel.timings; 321 147 322 - mutex_unlock(&hdmi.hdmi_lock); 148 + mutex_unlock(&hdmi.lock); 323 149 } 324 150 325 151 static void hdmi_set_timings(struct omap_dss_device *dssdev, ··· 327 153 { 328 154 DSSDBG("hdmi_set_timings\n"); 329 155 330 - mutex_lock(&hdmi.hdmi_lock); 156 + mutex_lock(&hdmi.lock); 157 + 158 + /* 159 + * TODO: notify audio users that there was a timings change. For 160 + * now, disable audio locally to not break our audio state machine. 161 + */ 162 + hdmi_panel_audio_disable(dssdev); 331 163 332 164 dssdev->panel.timings = *timings; 333 165 omapdss_hdmi_display_set_timing(dssdev); 334 166 335 - mutex_unlock(&hdmi.hdmi_lock); 167 + mutex_unlock(&hdmi.lock); 336 168 } 337 169 338 170 static int hdmi_check_timings(struct omap_dss_device *dssdev, ··· 348 168 349 169 DSSDBG("hdmi_check_timings\n"); 350 170 351 - mutex_lock(&hdmi.hdmi_lock); 171 + mutex_lock(&hdmi.lock); 352 172 353 173 r = omapdss_hdmi_display_check_timing(dssdev, timings); 354 174 355 - mutex_unlock(&hdmi.hdmi_lock); 175 + mutex_unlock(&hdmi.lock); 356 176 return r; 357 177 } 358 178 ··· 360 180 { 361 181 int r; 362 182 363 - mutex_lock(&hdmi.hdmi_lock); 183 + mutex_lock(&hdmi.lock); 364 184 365 185 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { 366 186 r = omapdss_hdmi_display_enable(dssdev); ··· 374 194 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) 375 195 omapdss_hdmi_display_disable(dssdev); 376 196 err: 377 - mutex_unlock(&hdmi.hdmi_lock); 197 + mutex_unlock(&hdmi.lock); 378 198 379 199 return r; 380 200 } ··· 383 203 { 384 204 int r; 385 205 386 - mutex_lock(&hdmi.hdmi_lock); 206 + mutex_lock(&hdmi.lock); 387 207 388 208 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { 389 209 r = omapdss_hdmi_display_enable(dssdev); ··· 397 217 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) 398 218 omapdss_hdmi_display_disable(dssdev); 399 219 err: 400 - mutex_unlock(&hdmi.hdmi_lock); 220 + mutex_unlock(&hdmi.lock); 401 221 402 222 return r; 403 223 } ··· 414 234 .check_timings = hdmi_check_timings, 415 235 .read_edid = hdmi_read_edid, 416 236 .detect = hdmi_detect, 237 + .audio_enable = hdmi_panel_audio_enable, 238 + .audio_disable = hdmi_panel_audio_disable, 239 + .audio_start = hdmi_panel_audio_start, 240 + .audio_stop = hdmi_panel_audio_stop, 241 + .audio_supported = hdmi_panel_audio_supported, 242 + .audio_config = hdmi_panel_audio_config, 417 243 .driver = { 418 244 .name = "hdmi_panel", 419 245 .owner = THIS_MODULE, ··· 428 242 429 243 int hdmi_panel_init(void) 430 244 { 431 - mutex_init(&hdmi.hdmi_lock); 245 + mutex_init(&hdmi.lock); 246 + 247 + #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 248 + spin_lock_init(&hdmi.audio_lock); 249 + #endif 432 250 433 251 omap_dss_register_driver(&hdmi_driver); 434 252
+17 -2
drivers/video/omap2/dss/manager.c
··· 654 654 return 0; 655 655 } 656 656 657 + int dss_mgr_check_timings(struct omap_overlay_manager *mgr, 658 + const struct omap_video_timings *timings) 659 + { 660 + if (!dispc_mgr_timings_ok(mgr->id, timings)) { 661 + DSSERR("check_manager: invalid timings\n"); 662 + return -EINVAL; 663 + } 664 + 665 + return 0; 666 + } 667 + 657 668 int dss_mgr_check(struct omap_overlay_manager *mgr, 658 - struct omap_dss_device *dssdev, 659 669 struct omap_overlay_manager_info *info, 670 + const struct omap_video_timings *mgr_timings, 660 671 struct omap_overlay_info **overlay_infos) 661 672 { 662 673 struct omap_overlay *ovl; ··· 679 668 return r; 680 669 } 681 670 671 + r = dss_mgr_check_timings(mgr, mgr_timings); 672 + if (r) 673 + return r; 674 + 682 675 list_for_each_entry(ovl, &mgr->overlays, list) { 683 676 struct omap_overlay_info *oi; 684 677 int r; ··· 692 677 if (oi == NULL) 693 678 continue; 694 679 695 - r = dss_ovl_check(ovl, oi, dssdev); 680 + r = dss_ovl_check(ovl, oi, mgr_timings); 696 681 if (r) 697 682 return r; 698 683 }
+10 -6
drivers/video/omap2/dss/overlay.c
··· 628 628 return -EINVAL; 629 629 } 630 630 631 + if (dss_feat_rotation_type_supported(info->rotation_type) == 0) { 632 + DSSERR("check_overlay: rotation type %d not supported\n", 633 + info->rotation_type); 634 + return -EINVAL; 635 + } 636 + 631 637 return 0; 632 638 } 633 639 634 - int dss_ovl_check(struct omap_overlay *ovl, 635 - struct omap_overlay_info *info, struct omap_dss_device *dssdev) 640 + int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, 641 + const struct omap_video_timings *mgr_timings) 636 642 { 637 643 u16 outw, outh; 638 644 u16 dw, dh; 639 645 640 - if (dssdev == NULL) 641 - return 0; 642 - 643 - dssdev->driver->get_resolution(dssdev, &dw, &dh); 646 + dw = mgr_timings->x_res; 647 + dh = mgr_timings->y_res; 644 648 645 649 if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { 646 650 outw = info->width;
+61 -23
drivers/video/omap2/dss/rfbi.c
··· 304 304 u16 height, void (*callback)(void *data), void *data) 305 305 { 306 306 u32 l; 307 + struct omap_video_timings timings = { 308 + .hsw = 1, 309 + .hfp = 1, 310 + .hbp = 1, 311 + .vsw = 1, 312 + .vfp = 0, 313 + .vbp = 0, 314 + .x_res = width, 315 + .y_res = height, 316 + }; 307 317 308 318 /*BUG_ON(callback == 0);*/ 309 319 BUG_ON(rfbi.framedone_callback != NULL); 310 320 311 321 DSSDBG("rfbi_transfer_area %dx%d\n", width, height); 312 322 313 - dispc_mgr_set_lcd_size(dssdev->manager->id, width, height); 323 + dss_mgr_set_timings(dssdev->manager, &timings); 314 324 315 325 dispc_mgr_enable(dssdev->manager->id, true); 316 326 ··· 776 766 u16 *x, u16 *y, u16 *w, u16 *h) 777 767 { 778 768 u16 dw, dh; 769 + struct omap_video_timings timings = { 770 + .hsw = 1, 771 + .hfp = 1, 772 + .hbp = 1, 773 + .vsw = 1, 774 + .vfp = 0, 775 + .vbp = 0, 776 + .x_res = *w, 777 + .y_res = *h, 778 + }; 779 779 780 780 dssdev->driver->get_resolution(dssdev, &dw, &dh); 781 781 ··· 804 784 if (*w == 0 || *h == 0) 805 785 return -EINVAL; 806 786 807 - dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h); 787 + dss_mgr_set_timings(dssdev->manager, &timings); 808 788 809 789 return 0; 810 790 } ··· 819 799 } 820 800 EXPORT_SYMBOL(omap_rfbi_update); 821 801 822 - void rfbi_dump_regs(struct seq_file *s) 802 + static void rfbi_dump_regs(struct seq_file *s) 823 803 { 824 804 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) 825 805 ··· 920 900 } 921 901 EXPORT_SYMBOL(omapdss_rfbi_display_disable); 922 902 923 - int rfbi_init_display(struct omap_dss_device *dssdev) 903 + static int __init rfbi_init_display(struct omap_dss_device *dssdev) 924 904 { 925 905 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; 926 906 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 927 907 return 0; 928 908 } 929 909 910 + static void __init rfbi_probe_pdata(struct platform_device *pdev) 911 + { 912 + struct omap_dss_board_info *pdata = pdev->dev.platform_data; 913 + int i, r; 914 + 915 + for (i = 0; i < pdata->num_devices; ++i) { 916 + struct omap_dss_device *dssdev = pdata->devices[i]; 917 + 918 + if (dssdev->type != OMAP_DISPLAY_TYPE_DBI) 919 + continue; 920 + 921 + r = rfbi_init_display(dssdev); 922 + if (r) { 923 + DSSERR("device %s init failed: %d\n", dssdev->name, r); 924 + continue; 925 + } 926 + 927 + r = omap_dss_register_device(dssdev, &pdev->dev, i); 928 + if (r) 929 + DSSERR("device %s register failed: %d\n", 930 + dssdev->name, r); 931 + } 932 + } 933 + 930 934 /* RFBI HW IP initialisation */ 931 - static int omap_rfbihw_probe(struct platform_device *pdev) 935 + static int __init omap_rfbihw_probe(struct platform_device *pdev) 932 936 { 933 937 u32 rev; 934 938 struct resource *rfbi_mem; ··· 1000 956 1001 957 rfbi_runtime_put(); 1002 958 959 + dss_debugfs_create_file("rfbi", rfbi_dump_regs); 960 + 961 + rfbi_probe_pdata(pdev); 962 + 1003 963 return 0; 1004 964 1005 965 err_runtime_get: ··· 1011 963 return r; 1012 964 } 1013 965 1014 - static int omap_rfbihw_remove(struct platform_device *pdev) 966 + static int __exit omap_rfbihw_remove(struct platform_device *pdev) 1015 967 { 968 + omap_dss_unregister_child_devices(&pdev->dev); 1016 969 pm_runtime_disable(&pdev->dev); 1017 970 return 0; 1018 971 } ··· 1021 972 static int rfbi_runtime_suspend(struct device *dev) 1022 973 { 1023 974 dispc_runtime_put(); 1024 - dss_runtime_put(); 1025 975 1026 976 return 0; 1027 977 } ··· 1029 981 { 1030 982 int r; 1031 983 1032 - r = dss_runtime_get(); 1033 - if (r < 0) 1034 - goto err_get_dss; 1035 - 1036 984 r = dispc_runtime_get(); 1037 985 if (r < 0) 1038 - goto err_get_dispc; 986 + return r; 1039 987 1040 988 return 0; 1041 - 1042 - err_get_dispc: 1043 - dss_runtime_put(); 1044 - err_get_dss: 1045 - return r; 1046 989 } 1047 990 1048 991 static const struct dev_pm_ops rfbi_pm_ops = { ··· 1042 1003 }; 1043 1004 1044 1005 static struct platform_driver omap_rfbihw_driver = { 1045 - .probe = omap_rfbihw_probe, 1046 - .remove = omap_rfbihw_remove, 1006 + .remove = __exit_p(omap_rfbihw_remove), 1047 1007 .driver = { 1048 1008 .name = "omapdss_rfbi", 1049 1009 .owner = THIS_MODULE, ··· 1050 1012 }, 1051 1013 }; 1052 1014 1053 - int rfbi_init_platform_driver(void) 1015 + int __init rfbi_init_platform_driver(void) 1054 1016 { 1055 - return platform_driver_register(&omap_rfbihw_driver); 1017 + return platform_driver_probe(&omap_rfbihw_driver, omap_rfbihw_probe); 1056 1018 } 1057 1019 1058 - void rfbi_uninit_platform_driver(void) 1020 + void __exit rfbi_uninit_platform_driver(void) 1059 1021 { 1060 - return platform_driver_unregister(&omap_rfbihw_driver); 1022 + platform_driver_unregister(&omap_rfbihw_driver); 1061 1023 }
+52 -11
drivers/video/omap2/dss/sdi.c
··· 24 24 #include <linux/err.h> 25 25 #include <linux/regulator/consumer.h> 26 26 #include <linux/export.h> 27 + #include <linux/platform_device.h> 27 28 28 29 #include <video/omapdss.h> 29 30 #include "dss.h" ··· 72 71 if (r) 73 72 goto err_reg_enable; 74 73 75 - r = dss_runtime_get(); 76 - if (r) 77 - goto err_get_dss; 78 - 79 74 r = dispc_runtime_get(); 80 75 if (r) 81 76 goto err_get_dispc; ··· 104 107 } 105 108 106 109 107 - dispc_mgr_set_lcd_timings(dssdev->manager->id, t); 110 + dss_mgr_set_timings(dssdev->manager, t); 108 111 109 112 r = dss_set_clock_div(&dss_cinfo); 110 113 if (r) ··· 134 137 err_calc_clock_div: 135 138 dispc_runtime_put(); 136 139 err_get_dispc: 137 - dss_runtime_put(); 138 - err_get_dss: 139 140 regulator_disable(sdi.vdds_sdi_reg); 140 141 err_reg_enable: 141 142 omap_dss_stop_device(dssdev); ··· 149 154 dss_sdi_disable(); 150 155 151 156 dispc_runtime_put(); 152 - dss_runtime_put(); 153 157 154 158 regulator_disable(sdi.vdds_sdi_reg); 155 159 ··· 156 162 } 157 163 EXPORT_SYMBOL(omapdss_sdi_display_disable); 158 164 159 - int sdi_init_display(struct omap_dss_device *dssdev) 165 + static int __init sdi_init_display(struct omap_dss_device *dssdev) 160 166 { 161 167 DSSDBG("SDI init\n"); 162 168 ··· 176 182 return 0; 177 183 } 178 184 179 - int sdi_init(void) 185 + static void __init sdi_probe_pdata(struct platform_device *pdev) 180 186 { 187 + struct omap_dss_board_info *pdata = pdev->dev.platform_data; 188 + int i, r; 189 + 190 + for (i = 0; i < pdata->num_devices; ++i) { 191 + struct omap_dss_device *dssdev = pdata->devices[i]; 192 + 193 + if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) 194 + continue; 195 + 196 + r = sdi_init_display(dssdev); 197 + if (r) { 198 + DSSERR("device %s init failed: %d\n", dssdev->name, r); 199 + continue; 200 + } 201 + 202 + r = omap_dss_register_device(dssdev, &pdev->dev, i); 203 + if (r) 204 + DSSERR("device %s register failed: %d\n", 205 + dssdev->name, r); 206 + } 207 + } 208 + 209 + static int __init omap_sdi_probe(struct platform_device *pdev) 210 + { 211 + sdi_probe_pdata(pdev); 212 + 181 213 return 0; 182 214 } 183 215 184 - void sdi_exit(void) 216 + static int __exit omap_sdi_remove(struct platform_device *pdev) 185 217 { 218 + omap_dss_unregister_child_devices(&pdev->dev); 219 + 220 + return 0; 221 + } 222 + 223 + static struct platform_driver omap_sdi_driver = { 224 + .remove = __exit_p(omap_sdi_remove), 225 + .driver = { 226 + .name = "omapdss_sdi", 227 + .owner = THIS_MODULE, 228 + }, 229 + }; 230 + 231 + int __init sdi_init_platform_driver(void) 232 + { 233 + return platform_driver_probe(&omap_sdi_driver, omap_sdi_probe); 234 + } 235 + 236 + void __exit sdi_uninit_platform_driver(void) 237 + { 238 + platform_driver_unregister(&omap_sdi_driver); 186 239 }
+24 -8
drivers/video/omap2/dss/ti_hdmi.h
··· 96 96 97 97 void (*pll_disable)(struct hdmi_ip_data *ip_data); 98 98 99 - void (*video_enable)(struct hdmi_ip_data *ip_data, bool start); 99 + int (*video_enable)(struct hdmi_ip_data *ip_data); 100 + 101 + void (*video_disable)(struct hdmi_ip_data *ip_data); 100 102 101 103 void (*dump_wrapper)(struct hdmi_ip_data *ip_data, struct seq_file *s); 102 104 ··· 108 106 109 107 void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s); 110 108 111 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 112 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 113 - void (*audio_enable)(struct hdmi_ip_data *ip_data, bool start); 109 + #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 110 + int (*audio_enable)(struct hdmi_ip_data *ip_data); 111 + 112 + void (*audio_disable)(struct hdmi_ip_data *ip_data); 113 + 114 + int (*audio_start)(struct hdmi_ip_data *ip_data); 115 + 116 + void (*audio_stop)(struct hdmi_ip_data *ip_data); 117 + 118 + int (*audio_config)(struct hdmi_ip_data *ip_data, 119 + struct omap_dss_audio *audio); 114 120 #endif 115 121 116 122 }; ··· 183 173 void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); 184 174 int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); 185 175 bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data); 186 - void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start); 176 + int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data); 177 + void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data); 187 178 int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); 188 179 void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data); 189 180 void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); ··· 192 181 void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); 193 182 void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); 194 183 void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); 195 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 196 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 197 - void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable); 184 + #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 185 + int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts); 186 + int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data); 187 + void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data); 188 + int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data); 189 + void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data); 190 + int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, 191 + struct omap_dss_audio *audio); 198 192 #endif 199 193 #endif
+318 -156
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
··· 29 29 #include <linux/string.h> 30 30 #include <linux/seq_file.h> 31 31 #include <linux/gpio.h> 32 + #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 33 + #include <sound/asound.h> 34 + #include <sound/asoundef.h> 35 + #endif 32 36 33 37 #include "ti_hdmi_4xxx_ip.h" 34 38 #include "dss.h" 39 + #include "dss_features.h" 35 40 36 41 static inline void hdmi_write_reg(void __iomem *base_addr, 37 42 const u16 idx, u32 val) ··· 303 298 REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); 304 299 305 300 r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio), 306 - NULL, hpd_irq_handler, 307 - IRQF_DISABLED | IRQF_TRIGGER_RISING | 308 - IRQF_TRIGGER_FALLING, "hpd", ip_data); 301 + NULL, hpd_irq_handler, 302 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | 303 + IRQF_ONESHOT, "hpd", ip_data); 309 304 if (r) { 310 305 DSSERR("HPD IRQ request failed\n"); 311 306 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); ··· 704 699 705 700 } 706 701 707 - void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start) 702 + int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data) 708 703 { 709 - REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, start, 31, 31); 704 + REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, true, 31, 31); 705 + return 0; 706 + } 707 + 708 + void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data) 709 + { 710 + REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, false, 31, 31); 710 711 } 711 712 712 713 static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, ··· 897 886 898 887 #define CORE_REG(i, name) name(i) 899 888 #define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ 900 - hdmi_read_reg(hdmi_pll_base(ip_data), r)) 901 - #define DUMPCOREAV(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \ 889 + hdmi_read_reg(hdmi_core_sys_base(ip_data), r)) 890 + #define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\ 891 + hdmi_read_reg(hdmi_av_base(ip_data), r)) 892 + #define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \ 902 893 (i < 10) ? 32 - strlen(#r) : 31 - strlen(#r), " ", \ 903 - hdmi_read_reg(hdmi_pll_base(ip_data), CORE_REG(i, r))) 894 + hdmi_read_reg(hdmi_av_base(ip_data), CORE_REG(i, r))) 904 895 905 896 DUMPCORE(HDMI_CORE_SYS_VND_IDL); 906 897 DUMPCORE(HDMI_CORE_SYS_DEV_IDL); ··· 911 898 DUMPCORE(HDMI_CORE_SYS_SRST); 912 899 DUMPCORE(HDMI_CORE_CTRL1); 913 900 DUMPCORE(HDMI_CORE_SYS_SYS_STAT); 901 + DUMPCORE(HDMI_CORE_SYS_DE_DLY); 902 + DUMPCORE(HDMI_CORE_SYS_DE_CTRL); 903 + DUMPCORE(HDMI_CORE_SYS_DE_TOP); 904 + DUMPCORE(HDMI_CORE_SYS_DE_CNTL); 905 + DUMPCORE(HDMI_CORE_SYS_DE_CNTH); 906 + DUMPCORE(HDMI_CORE_SYS_DE_LINL); 907 + DUMPCORE(HDMI_CORE_SYS_DE_LINH_1); 914 908 DUMPCORE(HDMI_CORE_SYS_VID_ACEN); 915 909 DUMPCORE(HDMI_CORE_SYS_VID_MODE); 916 910 DUMPCORE(HDMI_CORE_SYS_INTR_STATE); ··· 927 907 DUMPCORE(HDMI_CORE_SYS_INTR4); 928 908 DUMPCORE(HDMI_CORE_SYS_UMASK1); 929 909 DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL); 930 - DUMPCORE(HDMI_CORE_SYS_DE_DLY); 931 - DUMPCORE(HDMI_CORE_SYS_DE_CTRL); 932 - DUMPCORE(HDMI_CORE_SYS_DE_TOP); 933 - DUMPCORE(HDMI_CORE_SYS_DE_CNTL); 934 - DUMPCORE(HDMI_CORE_SYS_DE_CNTH); 935 - DUMPCORE(HDMI_CORE_SYS_DE_LINL); 936 - DUMPCORE(HDMI_CORE_SYS_DE_LINH_1); 937 910 938 - DUMPCORE(HDMI_CORE_DDC_CMD); 939 - DUMPCORE(HDMI_CORE_DDC_STATUS); 940 911 DUMPCORE(HDMI_CORE_DDC_ADDR); 912 + DUMPCORE(HDMI_CORE_DDC_SEGM); 941 913 DUMPCORE(HDMI_CORE_DDC_OFFSET); 942 914 DUMPCORE(HDMI_CORE_DDC_COUNT1); 943 915 DUMPCORE(HDMI_CORE_DDC_COUNT2); 916 + DUMPCORE(HDMI_CORE_DDC_STATUS); 917 + DUMPCORE(HDMI_CORE_DDC_CMD); 944 918 DUMPCORE(HDMI_CORE_DDC_DATA); 945 - DUMPCORE(HDMI_CORE_DDC_SEGM); 946 919 947 - DUMPCORE(HDMI_CORE_AV_HDMI_CTRL); 948 - DUMPCORE(HDMI_CORE_AV_DPD); 949 - DUMPCORE(HDMI_CORE_AV_PB_CTRL1); 950 - DUMPCORE(HDMI_CORE_AV_PB_CTRL2); 951 - DUMPCORE(HDMI_CORE_AV_AVI_TYPE); 952 - DUMPCORE(HDMI_CORE_AV_AVI_VERS); 953 - DUMPCORE(HDMI_CORE_AV_AVI_LEN); 954 - DUMPCORE(HDMI_CORE_AV_AVI_CHSUM); 920 + DUMPCOREAV(HDMI_CORE_AV_ACR_CTRL); 921 + DUMPCOREAV(HDMI_CORE_AV_FREQ_SVAL); 922 + DUMPCOREAV(HDMI_CORE_AV_N_SVAL1); 923 + DUMPCOREAV(HDMI_CORE_AV_N_SVAL2); 924 + DUMPCOREAV(HDMI_CORE_AV_N_SVAL3); 925 + DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL1); 926 + DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL2); 927 + DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL3); 928 + DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL1); 929 + DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL2); 930 + DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL3); 931 + DUMPCOREAV(HDMI_CORE_AV_AUD_MODE); 932 + DUMPCOREAV(HDMI_CORE_AV_SPDIF_CTRL); 933 + DUMPCOREAV(HDMI_CORE_AV_HW_SPDIF_FS); 934 + DUMPCOREAV(HDMI_CORE_AV_SWAP_I2S); 935 + DUMPCOREAV(HDMI_CORE_AV_SPDIF_ERTH); 936 + DUMPCOREAV(HDMI_CORE_AV_I2S_IN_MAP); 937 + DUMPCOREAV(HDMI_CORE_AV_I2S_IN_CTRL); 938 + DUMPCOREAV(HDMI_CORE_AV_I2S_CHST0); 939 + DUMPCOREAV(HDMI_CORE_AV_I2S_CHST1); 940 + DUMPCOREAV(HDMI_CORE_AV_I2S_CHST2); 941 + DUMPCOREAV(HDMI_CORE_AV_I2S_CHST4); 942 + DUMPCOREAV(HDMI_CORE_AV_I2S_CHST5); 943 + DUMPCOREAV(HDMI_CORE_AV_ASRC); 944 + DUMPCOREAV(HDMI_CORE_AV_I2S_IN_LEN); 945 + DUMPCOREAV(HDMI_CORE_AV_HDMI_CTRL); 946 + DUMPCOREAV(HDMI_CORE_AV_AUDO_TXSTAT); 947 + DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_1); 948 + DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_2); 949 + DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_3); 950 + DUMPCOREAV(HDMI_CORE_AV_TEST_TXCTRL); 951 + DUMPCOREAV(HDMI_CORE_AV_DPD); 952 + DUMPCOREAV(HDMI_CORE_AV_PB_CTRL1); 953 + DUMPCOREAV(HDMI_CORE_AV_PB_CTRL2); 954 + DUMPCOREAV(HDMI_CORE_AV_AVI_TYPE); 955 + DUMPCOREAV(HDMI_CORE_AV_AVI_VERS); 956 + DUMPCOREAV(HDMI_CORE_AV_AVI_LEN); 957 + DUMPCOREAV(HDMI_CORE_AV_AVI_CHSUM); 955 958 956 959 for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++) 957 - DUMPCOREAV(i, HDMI_CORE_AV_AVI_DBYTE); 960 + DUMPCOREAV2(i, HDMI_CORE_AV_AVI_DBYTE); 961 + 962 + DUMPCOREAV(HDMI_CORE_AV_SPD_TYPE); 963 + DUMPCOREAV(HDMI_CORE_AV_SPD_VERS); 964 + DUMPCOREAV(HDMI_CORE_AV_SPD_LEN); 965 + DUMPCOREAV(HDMI_CORE_AV_SPD_CHSUM); 958 966 959 967 for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++) 960 - DUMPCOREAV(i, HDMI_CORE_AV_SPD_DBYTE); 968 + DUMPCOREAV2(i, HDMI_CORE_AV_SPD_DBYTE); 969 + 970 + DUMPCOREAV(HDMI_CORE_AV_AUDIO_TYPE); 971 + DUMPCOREAV(HDMI_CORE_AV_AUDIO_VERS); 972 + DUMPCOREAV(HDMI_CORE_AV_AUDIO_LEN); 973 + DUMPCOREAV(HDMI_CORE_AV_AUDIO_CHSUM); 961 974 962 975 for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++) 963 - DUMPCOREAV(i, HDMI_CORE_AV_AUD_DBYTE); 976 + DUMPCOREAV2(i, HDMI_CORE_AV_AUD_DBYTE); 977 + 978 + DUMPCOREAV(HDMI_CORE_AV_MPEG_TYPE); 979 + DUMPCOREAV(HDMI_CORE_AV_MPEG_VERS); 980 + DUMPCOREAV(HDMI_CORE_AV_MPEG_LEN); 981 + DUMPCOREAV(HDMI_CORE_AV_MPEG_CHSUM); 964 982 965 983 for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++) 966 - DUMPCOREAV(i, HDMI_CORE_AV_MPEG_DBYTE); 984 + DUMPCOREAV2(i, HDMI_CORE_AV_MPEG_DBYTE); 967 985 968 986 for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++) 969 - DUMPCOREAV(i, HDMI_CORE_AV_GEN_DBYTE); 987 + DUMPCOREAV2(i, HDMI_CORE_AV_GEN_DBYTE); 988 + 989 + DUMPCOREAV(HDMI_CORE_AV_CP_BYTE1); 970 990 971 991 for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++) 972 - DUMPCOREAV(i, HDMI_CORE_AV_GEN2_DBYTE); 992 + DUMPCOREAV2(i, HDMI_CORE_AV_GEN2_DBYTE); 973 993 974 - DUMPCORE(HDMI_CORE_AV_ACR_CTRL); 975 - DUMPCORE(HDMI_CORE_AV_FREQ_SVAL); 976 - DUMPCORE(HDMI_CORE_AV_N_SVAL1); 977 - DUMPCORE(HDMI_CORE_AV_N_SVAL2); 978 - DUMPCORE(HDMI_CORE_AV_N_SVAL3); 979 - DUMPCORE(HDMI_CORE_AV_CTS_SVAL1); 980 - DUMPCORE(HDMI_CORE_AV_CTS_SVAL2); 981 - DUMPCORE(HDMI_CORE_AV_CTS_SVAL3); 982 - DUMPCORE(HDMI_CORE_AV_CTS_HVAL1); 983 - DUMPCORE(HDMI_CORE_AV_CTS_HVAL2); 984 - DUMPCORE(HDMI_CORE_AV_CTS_HVAL3); 985 - DUMPCORE(HDMI_CORE_AV_AUD_MODE); 986 - DUMPCORE(HDMI_CORE_AV_SPDIF_CTRL); 987 - DUMPCORE(HDMI_CORE_AV_HW_SPDIF_FS); 988 - DUMPCORE(HDMI_CORE_AV_SWAP_I2S); 989 - DUMPCORE(HDMI_CORE_AV_SPDIF_ERTH); 990 - DUMPCORE(HDMI_CORE_AV_I2S_IN_MAP); 991 - DUMPCORE(HDMI_CORE_AV_I2S_IN_CTRL); 992 - DUMPCORE(HDMI_CORE_AV_I2S_CHST0); 993 - DUMPCORE(HDMI_CORE_AV_I2S_CHST1); 994 - DUMPCORE(HDMI_CORE_AV_I2S_CHST2); 995 - DUMPCORE(HDMI_CORE_AV_I2S_CHST4); 996 - DUMPCORE(HDMI_CORE_AV_I2S_CHST5); 997 - DUMPCORE(HDMI_CORE_AV_ASRC); 998 - DUMPCORE(HDMI_CORE_AV_I2S_IN_LEN); 999 - DUMPCORE(HDMI_CORE_AV_HDMI_CTRL); 1000 - DUMPCORE(HDMI_CORE_AV_AUDO_TXSTAT); 1001 - DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_1); 1002 - DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_2); 1003 - DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_3); 1004 - DUMPCORE(HDMI_CORE_AV_TEST_TXCTRL); 1005 - DUMPCORE(HDMI_CORE_AV_DPD); 1006 - DUMPCORE(HDMI_CORE_AV_PB_CTRL1); 1007 - DUMPCORE(HDMI_CORE_AV_PB_CTRL2); 1008 - DUMPCORE(HDMI_CORE_AV_AVI_TYPE); 1009 - DUMPCORE(HDMI_CORE_AV_AVI_VERS); 1010 - DUMPCORE(HDMI_CORE_AV_AVI_LEN); 1011 - DUMPCORE(HDMI_CORE_AV_AVI_CHSUM); 1012 - DUMPCORE(HDMI_CORE_AV_SPD_TYPE); 1013 - DUMPCORE(HDMI_CORE_AV_SPD_VERS); 1014 - DUMPCORE(HDMI_CORE_AV_SPD_LEN); 1015 - DUMPCORE(HDMI_CORE_AV_SPD_CHSUM); 1016 - DUMPCORE(HDMI_CORE_AV_AUDIO_TYPE); 1017 - DUMPCORE(HDMI_CORE_AV_AUDIO_VERS); 1018 - DUMPCORE(HDMI_CORE_AV_AUDIO_LEN); 1019 - DUMPCORE(HDMI_CORE_AV_AUDIO_CHSUM); 1020 - DUMPCORE(HDMI_CORE_AV_MPEG_TYPE); 1021 - DUMPCORE(HDMI_CORE_AV_MPEG_VERS); 1022 - DUMPCORE(HDMI_CORE_AV_MPEG_LEN); 1023 - DUMPCORE(HDMI_CORE_AV_MPEG_CHSUM); 1024 - DUMPCORE(HDMI_CORE_AV_CP_BYTE1); 1025 - DUMPCORE(HDMI_CORE_AV_CEC_ADDR_ID); 994 + DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID); 1026 995 } 1027 996 1028 997 void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) ··· 1025 1016 DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); 1026 1017 } 1027 1018 1028 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 1029 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 1030 - void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data, 1019 + #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 1020 + static void ti_hdmi_4xxx_wp_audio_config_format(struct hdmi_ip_data *ip_data, 1031 1021 struct hdmi_audio_format *aud_fmt) 1032 1022 { 1033 1023 u32 r; ··· 1045 1037 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r); 1046 1038 } 1047 1039 1048 - void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, 1040 + static void ti_hdmi_4xxx_wp_audio_config_dma(struct hdmi_ip_data *ip_data, 1049 1041 struct hdmi_audio_dma *aud_dma) 1050 1042 { 1051 1043 u32 r; ··· 1063 1055 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r); 1064 1056 } 1065 1057 1066 - void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, 1058 + static void ti_hdmi_4xxx_core_audio_config(struct hdmi_ip_data *ip_data, 1067 1059 struct hdmi_core_audio_config *cfg) 1068 1060 { 1069 1061 u32 r; ··· 1114 1106 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, 1115 1107 cfg->fs_override, 1, 1); 1116 1108 1117 - /* I2S parameters */ 1118 - REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_CHST4, 1119 - cfg->freq_sample, 3, 0); 1109 + /* 1110 + * Set IEC-60958-3 channel status word. It is passed to the IP 1111 + * just as it is received. The user of the driver is responsible 1112 + * for its contents. 1113 + */ 1114 + hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST0, 1115 + cfg->iec60958_cfg->status[0]); 1116 + hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST1, 1117 + cfg->iec60958_cfg->status[1]); 1118 + hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST2, 1119 + cfg->iec60958_cfg->status[2]); 1120 + /* yes, this is correct: status[3] goes to CHST4 register */ 1121 + hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST4, 1122 + cfg->iec60958_cfg->status[3]); 1123 + /* yes, this is correct: status[4] goes to CHST5 register */ 1124 + hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, 1125 + cfg->iec60958_cfg->status[4]); 1120 1126 1127 + /* set I2S parameters */ 1121 1128 r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL); 1122 - r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7); 1123 1129 r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6); 1124 - r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5); 1125 1130 r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4); 1126 - r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3); 1127 1131 r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2); 1128 1132 r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1); 1129 1133 r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0); 1130 1134 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r); 1131 - 1132 - r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_CHST5); 1133 - r = FLD_MOD(r, cfg->freq_sample, 7, 4); 1134 - r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1); 1135 - r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0); 1136 - hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, r); 1137 1135 1138 1136 REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN, 1139 1137 cfg->i2s_cfg.in_length_bits, 3, 0); ··· 1152 1138 r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2); 1153 1139 r = FLD_MOD(r, cfg->en_spdif, 1, 1); 1154 1140 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r); 1141 + 1142 + /* Audio channel mappings */ 1143 + /* TODO: Make channel mapping dynamic. For now, map channels 1144 + * in the ALSA order: FL/FR/RL/RR/C/LFE/SL/SR. Remapping is needed as 1145 + * HDMI speaker order is different. See CEA-861 Section 6.6.2. 1146 + */ 1147 + hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_MAP, 0x78); 1148 + REG_FLD_MOD(av_base, HDMI_CORE_AV_SWAP_I2S, 1, 5, 5); 1155 1149 } 1156 1150 1157 - void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, 1158 - struct hdmi_core_infoframe_audio *info_aud) 1151 + static void ti_hdmi_4xxx_core_audio_infoframe_cfg(struct hdmi_ip_data *ip_data, 1152 + struct snd_cea_861_aud_if *info_aud) 1159 1153 { 1160 - u8 val; 1161 1154 u8 sum = 0, checksum = 0; 1162 1155 void __iomem *av_base = hdmi_av_base(ip_data); 1163 1156 ··· 1178 1157 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a); 1179 1158 sum += 0x84 + 0x001 + 0x00a; 1180 1159 1181 - val = (info_aud->db1_coding_type << 4) 1182 - | (info_aud->db1_channel_count - 1); 1183 - hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), val); 1184 - sum += val; 1160 + hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), 1161 + info_aud->db1_ct_cc); 1162 + sum += info_aud->db1_ct_cc; 1185 1163 1186 - val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size; 1187 - hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), val); 1188 - sum += val; 1164 + hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), 1165 + info_aud->db2_sf_ss); 1166 + sum += info_aud->db2_sf_ss; 1189 1167 1190 - hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), 0x00); 1168 + hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3); 1169 + sum += info_aud->db3; 1191 1170 1192 - val = info_aud->db4_channel_alloc; 1193 - hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), val); 1194 - sum += val; 1171 + hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca); 1172 + sum += info_aud->db4_ca; 1195 1173 1196 - val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3); 1197 - hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), val); 1198 - sum += val; 1174 + hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), 1175 + info_aud->db5_dminh_lsv); 1176 + sum += info_aud->db5_dminh_lsv; 1199 1177 1200 1178 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00); 1201 1179 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00); ··· 1212 1192 */ 1213 1193 } 1214 1194 1215 - int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, 1216 - u32 sample_freq, u32 *n, u32 *cts) 1195 + int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, 1196 + struct omap_dss_audio *audio) 1217 1197 { 1218 - u32 r; 1219 - u32 deep_color = 0; 1220 - u32 pclk = ip_data->cfg.timings.pixel_clock; 1198 + struct hdmi_audio_format audio_format; 1199 + struct hdmi_audio_dma audio_dma; 1200 + struct hdmi_core_audio_config core; 1201 + int err, n, cts, channel_count; 1202 + unsigned int fs_nr; 1203 + bool word_length_16b = false; 1221 1204 1222 - if (n == NULL || cts == NULL) 1205 + if (!audio || !audio->iec || !audio->cea || !ip_data) 1223 1206 return -EINVAL; 1207 + 1208 + core.iec60958_cfg = audio->iec; 1224 1209 /* 1225 - * Obtain current deep color configuration. This needed 1226 - * to calculate the TMDS clock based on the pixel clock. 1210 + * In the IEC-60958 status word, check if the audio sample word length 1211 + * is 16-bit as several optimizations can be performed in such case. 1227 1212 */ 1228 - r = REG_GET(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, 1, 0); 1229 - switch (r) { 1230 - case 1: /* No deep color selected */ 1231 - deep_color = 100; 1213 + if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24)) 1214 + if (audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16) 1215 + word_length_16b = true; 1216 + 1217 + /* I2S configuration. See Phillips' specification */ 1218 + if (word_length_16b) 1219 + core.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT; 1220 + else 1221 + core.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; 1222 + /* 1223 + * The I2S input word length is twice the lenght given in the IEC-60958 1224 + * status word. If the word size is greater than 1225 + * 20 bits, increment by one. 1226 + */ 1227 + core.i2s_cfg.in_length_bits = audio->iec->status[4] 1228 + & IEC958_AES4_CON_WORDLEN; 1229 + if (audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24) 1230 + core.i2s_cfg.in_length_bits++; 1231 + core.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; 1232 + core.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; 1233 + core.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; 1234 + core.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT; 1235 + 1236 + /* convert sample frequency to a number */ 1237 + switch (audio->iec->status[3] & IEC958_AES3_CON_FS) { 1238 + case IEC958_AES3_CON_FS_32000: 1239 + fs_nr = 32000; 1232 1240 break; 1233 - case 2: /* 10-bit deep color selected */ 1234 - deep_color = 125; 1241 + case IEC958_AES3_CON_FS_44100: 1242 + fs_nr = 44100; 1235 1243 break; 1236 - case 3: /* 12-bit deep color selected */ 1237 - deep_color = 150; 1244 + case IEC958_AES3_CON_FS_48000: 1245 + fs_nr = 48000; 1246 + break; 1247 + case IEC958_AES3_CON_FS_88200: 1248 + fs_nr = 88200; 1249 + break; 1250 + case IEC958_AES3_CON_FS_96000: 1251 + fs_nr = 96000; 1252 + break; 1253 + case IEC958_AES3_CON_FS_176400: 1254 + fs_nr = 176400; 1255 + break; 1256 + case IEC958_AES3_CON_FS_192000: 1257 + fs_nr = 192000; 1238 1258 break; 1239 1259 default: 1240 1260 return -EINVAL; 1241 1261 } 1242 1262 1243 - switch (sample_freq) { 1244 - case 32000: 1245 - if ((deep_color == 125) && ((pclk == 54054) 1246 - || (pclk == 74250))) 1247 - *n = 8192; 1248 - else 1249 - *n = 4096; 1263 + err = hdmi_compute_acr(fs_nr, &n, &cts); 1264 + 1265 + /* Audio clock regeneration settings */ 1266 + core.n = n; 1267 + core.cts = cts; 1268 + if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { 1269 + core.aud_par_busclk = 0; 1270 + core.cts_mode = HDMI_AUDIO_CTS_MODE_SW; 1271 + core.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK); 1272 + } else { 1273 + core.aud_par_busclk = (((128 * 31) - 1) << 8); 1274 + core.cts_mode = HDMI_AUDIO_CTS_MODE_HW; 1275 + core.use_mclk = true; 1276 + } 1277 + 1278 + if (core.use_mclk) 1279 + core.mclk_mode = HDMI_AUDIO_MCLK_128FS; 1280 + 1281 + /* Audio channels settings */ 1282 + channel_count = (audio->cea->db1_ct_cc & 1283 + CEA861_AUDIO_INFOFRAME_DB1CC) + 1; 1284 + 1285 + switch (channel_count) { 1286 + case 2: 1287 + audio_format.active_chnnls_msk = 0x03; 1250 1288 break; 1251 - case 44100: 1252 - *n = 6272; 1289 + case 3: 1290 + audio_format.active_chnnls_msk = 0x07; 1253 1291 break; 1254 - case 48000: 1255 - if ((deep_color == 125) && ((pclk == 54054) 1256 - || (pclk == 74250))) 1257 - *n = 8192; 1258 - else 1259 - *n = 6144; 1292 + case 4: 1293 + audio_format.active_chnnls_msk = 0x0f; 1294 + break; 1295 + case 5: 1296 + audio_format.active_chnnls_msk = 0x1f; 1297 + break; 1298 + case 6: 1299 + audio_format.active_chnnls_msk = 0x3f; 1300 + break; 1301 + case 7: 1302 + audio_format.active_chnnls_msk = 0x7f; 1303 + break; 1304 + case 8: 1305 + audio_format.active_chnnls_msk = 0xff; 1260 1306 break; 1261 1307 default: 1262 - *n = 0; 1263 1308 return -EINVAL; 1264 1309 } 1265 1310 1266 - /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ 1267 - *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); 1311 + /* 1312 + * the HDMI IP needs to enable four stereo channels when transmitting 1313 + * more than 2 audio channels 1314 + */ 1315 + if (channel_count == 2) { 1316 + audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; 1317 + core.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; 1318 + core.layout = HDMI_AUDIO_LAYOUT_2CH; 1319 + } else { 1320 + audio_format.stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS; 1321 + core.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN | 1322 + HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN | 1323 + HDMI_AUDIO_I2S_SD3_EN; 1324 + core.layout = HDMI_AUDIO_LAYOUT_8CH; 1325 + } 1326 + 1327 + core.en_spdif = false; 1328 + /* use sample frequency from channel status word */ 1329 + core.fs_override = true; 1330 + /* enable ACR packets */ 1331 + core.en_acr_pkt = true; 1332 + /* disable direct streaming digital audio */ 1333 + core.en_dsd_audio = false; 1334 + /* use parallel audio interface */ 1335 + core.en_parallel_aud_input = true; 1336 + 1337 + /* DMA settings */ 1338 + if (word_length_16b) 1339 + audio_dma.transfer_size = 0x10; 1340 + else 1341 + audio_dma.transfer_size = 0x20; 1342 + audio_dma.block_size = 0xC0; 1343 + audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; 1344 + audio_dma.fifo_threshold = 0x20; /* in number of samples */ 1345 + 1346 + /* audio FIFO format settings */ 1347 + if (word_length_16b) { 1348 + audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; 1349 + audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; 1350 + audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; 1351 + } else { 1352 + audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE; 1353 + audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS; 1354 + audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT; 1355 + } 1356 + audio_format.type = HDMI_AUDIO_TYPE_LPCM; 1357 + audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST; 1358 + /* disable start/stop signals of IEC 60958 blocks */ 1359 + audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; 1360 + 1361 + /* configure DMA and audio FIFO format*/ 1362 + ti_hdmi_4xxx_wp_audio_config_dma(ip_data, &audio_dma); 1363 + ti_hdmi_4xxx_wp_audio_config_format(ip_data, &audio_format); 1364 + 1365 + /* configure the core*/ 1366 + ti_hdmi_4xxx_core_audio_config(ip_data, &core); 1367 + 1368 + /* configure CEA 861 audio infoframe*/ 1369 + ti_hdmi_4xxx_core_audio_infoframe_cfg(ip_data, audio->cea); 1268 1370 1269 1371 return 0; 1270 1372 } 1271 1373 1272 - void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable) 1374 + int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data) 1375 + { 1376 + REG_FLD_MOD(hdmi_wp_base(ip_data), 1377 + HDMI_WP_AUDIO_CTRL, true, 31, 31); 1378 + return 0; 1379 + } 1380 + 1381 + void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data) 1382 + { 1383 + REG_FLD_MOD(hdmi_wp_base(ip_data), 1384 + HDMI_WP_AUDIO_CTRL, false, 31, 31); 1385 + } 1386 + 1387 + int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data) 1273 1388 { 1274 1389 REG_FLD_MOD(hdmi_av_base(ip_data), 1275 - HDMI_CORE_AV_AUD_MODE, enable, 0, 0); 1390 + HDMI_CORE_AV_AUD_MODE, true, 0, 0); 1276 1391 REG_FLD_MOD(hdmi_wp_base(ip_data), 1277 - HDMI_WP_AUDIO_CTRL, enable, 31, 31); 1392 + HDMI_WP_AUDIO_CTRL, true, 30, 30); 1393 + return 0; 1394 + } 1395 + 1396 + void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data) 1397 + { 1398 + REG_FLD_MOD(hdmi_av_base(ip_data), 1399 + HDMI_CORE_AV_AUD_MODE, false, 0, 0); 1278 1400 REG_FLD_MOD(hdmi_wp_base(ip_data), 1279 - HDMI_WP_AUDIO_CTRL, enable, 30, 30); 1401 + HDMI_WP_AUDIO_CTRL, false, 30, 30); 1280 1402 } 1281 1403 #endif
+27 -134
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
··· 24 24 #include <linux/string.h> 25 25 #include <video/omapdss.h> 26 26 #include "ti_hdmi.h" 27 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 28 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 29 - #include <sound/soc.h> 30 - #include <sound/pcm_params.h> 31 - #endif 32 27 33 28 /* HDMI Wrapper */ 34 29 ··· 52 57 #define HDMI_CORE_SYS_SRST 0x14 53 58 #define HDMI_CORE_CTRL1 0x20 54 59 #define HDMI_CORE_SYS_SYS_STAT 0x24 60 + #define HDMI_CORE_SYS_DE_DLY 0xC8 61 + #define HDMI_CORE_SYS_DE_CTRL 0xCC 62 + #define HDMI_CORE_SYS_DE_TOP 0xD0 63 + #define HDMI_CORE_SYS_DE_CNTL 0xD8 64 + #define HDMI_CORE_SYS_DE_CNTH 0xDC 65 + #define HDMI_CORE_SYS_DE_LINL 0xE0 66 + #define HDMI_CORE_SYS_DE_LINH_1 0xE4 55 67 #define HDMI_CORE_SYS_VID_ACEN 0x124 56 68 #define HDMI_CORE_SYS_VID_MODE 0x128 57 69 #define HDMI_CORE_SYS_INTR_STATE 0x1C0 ··· 68 66 #define HDMI_CORE_SYS_INTR4 0x1D0 69 67 #define HDMI_CORE_SYS_UMASK1 0x1D4 70 68 #define HDMI_CORE_SYS_TMDS_CTRL 0x208 71 - #define HDMI_CORE_SYS_DE_DLY 0xC8 72 - #define HDMI_CORE_SYS_DE_CTRL 0xCC 73 - #define HDMI_CORE_SYS_DE_TOP 0xD0 74 - #define HDMI_CORE_SYS_DE_CNTL 0xD8 75 - #define HDMI_CORE_SYS_DE_CNTH 0xDC 76 - #define HDMI_CORE_SYS_DE_LINL 0xE0 77 - #define HDMI_CORE_SYS_DE_LINH_1 0xE4 69 + 78 70 #define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1 79 71 #define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1 80 - #define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1 72 + #define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1 81 73 #define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1 82 74 83 75 /* HDMI DDC E-DID */ 84 - #define HDMI_CORE_DDC_CMD 0x3CC 85 - #define HDMI_CORE_DDC_STATUS 0x3C8 86 76 #define HDMI_CORE_DDC_ADDR 0x3B4 77 + #define HDMI_CORE_DDC_SEGM 0x3B8 87 78 #define HDMI_CORE_DDC_OFFSET 0x3BC 88 79 #define HDMI_CORE_DDC_COUNT1 0x3C0 89 80 #define HDMI_CORE_DDC_COUNT2 0x3C4 81 + #define HDMI_CORE_DDC_STATUS 0x3C8 82 + #define HDMI_CORE_DDC_CMD 0x3CC 90 83 #define HDMI_CORE_DDC_DATA 0x3D0 91 - #define HDMI_CORE_DDC_SEGM 0x3B8 92 84 93 85 /* HDMI IP Core Audio Video */ 94 86 95 - #define HDMI_CORE_AV_HDMI_CTRL 0xBC 96 - #define HDMI_CORE_AV_DPD 0xF4 97 - #define HDMI_CORE_AV_PB_CTRL1 0xF8 98 - #define HDMI_CORE_AV_PB_CTRL2 0xFC 99 - #define HDMI_CORE_AV_AVI_TYPE 0x100 100 - #define HDMI_CORE_AV_AVI_VERS 0x104 101 - #define HDMI_CORE_AV_AVI_LEN 0x108 102 - #define HDMI_CORE_AV_AVI_CHSUM 0x10C 103 - #define HDMI_CORE_AV_AVI_DBYTE(n) (n * 4 + 0x110) 104 - #define HDMI_CORE_AV_AVI_DBYTE_NELEMS 15 105 - #define HDMI_CORE_AV_SPD_DBYTE(n) (n * 4 + 0x190) 106 - #define HDMI_CORE_AV_SPD_DBYTE_NELEMS 27 107 - #define HDMI_CORE_AV_AUD_DBYTE(n) (n * 4 + 0x210) 108 - #define HDMI_CORE_AV_AUD_DBYTE_NELEMS 10 109 - #define HDMI_CORE_AV_MPEG_DBYTE(n) (n * 4 + 0x290) 110 - #define HDMI_CORE_AV_MPEG_DBYTE_NELEMS 27 111 - #define HDMI_CORE_AV_GEN_DBYTE(n) (n * 4 + 0x300) 112 - #define HDMI_CORE_AV_GEN_DBYTE_NELEMS 31 113 - #define HDMI_CORE_AV_GEN2_DBYTE(n) (n * 4 + 0x380) 114 - #define HDMI_CORE_AV_GEN2_DBYTE_NELEMS 31 115 87 #define HDMI_CORE_AV_ACR_CTRL 0x4 116 88 #define HDMI_CORE_AV_FREQ_SVAL 0x8 117 89 #define HDMI_CORE_AV_N_SVAL1 0xC ··· 124 148 #define HDMI_CORE_AV_AVI_VERS 0x104 125 149 #define HDMI_CORE_AV_AVI_LEN 0x108 126 150 #define HDMI_CORE_AV_AVI_CHSUM 0x10C 151 + #define HDMI_CORE_AV_AVI_DBYTE(n) (n * 4 + 0x110) 127 152 #define HDMI_CORE_AV_SPD_TYPE 0x180 128 153 #define HDMI_CORE_AV_SPD_VERS 0x184 129 154 #define HDMI_CORE_AV_SPD_LEN 0x188 130 155 #define HDMI_CORE_AV_SPD_CHSUM 0x18C 156 + #define HDMI_CORE_AV_SPD_DBYTE(n) (n * 4 + 0x190) 131 157 #define HDMI_CORE_AV_AUDIO_TYPE 0x200 132 158 #define HDMI_CORE_AV_AUDIO_VERS 0x204 133 159 #define HDMI_CORE_AV_AUDIO_LEN 0x208 134 160 #define HDMI_CORE_AV_AUDIO_CHSUM 0x20C 161 + #define HDMI_CORE_AV_AUD_DBYTE(n) (n * 4 + 0x210) 135 162 #define HDMI_CORE_AV_MPEG_TYPE 0x280 136 163 #define HDMI_CORE_AV_MPEG_VERS 0x284 137 164 #define HDMI_CORE_AV_MPEG_LEN 0x288 138 165 #define HDMI_CORE_AV_MPEG_CHSUM 0x28C 166 + #define HDMI_CORE_AV_MPEG_DBYTE(n) (n * 4 + 0x290) 167 + #define HDMI_CORE_AV_GEN_DBYTE(n) (n * 4 + 0x300) 139 168 #define HDMI_CORE_AV_CP_BYTE1 0x37C 169 + #define HDMI_CORE_AV_GEN2_DBYTE(n) (n * 4 + 0x380) 140 170 #define HDMI_CORE_AV_CEC_ADDR_ID 0x3FC 171 + 141 172 #define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4 142 173 #define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4 143 174 #define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4 144 175 #define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4 176 + 177 + #define HDMI_CORE_AV_AVI_DBYTE_NELEMS 15 178 + #define HDMI_CORE_AV_SPD_DBYTE_NELEMS 27 179 + #define HDMI_CORE_AV_AUD_DBYTE_NELEMS 10 180 + #define HDMI_CORE_AV_MPEG_DBYTE_NELEMS 27 181 + #define HDMI_CORE_AV_GEN_DBYTE_NELEMS 31 182 + #define HDMI_CORE_AV_GEN2_DBYTE_NELEMS 31 145 183 146 184 /* PLL */ 147 185 ··· 274 284 HDMI_INFOFRAME_AVI_DB5PR_8 = 7, 275 285 HDMI_INFOFRAME_AVI_DB5PR_9 = 8, 276 286 HDMI_INFOFRAME_AVI_DB5PR_10 = 9, 277 - HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM = 0, 278 - HDMI_INFOFRAME_AUDIO_DB1CT_IEC60958 = 1, 279 - HDMI_INFOFRAME_AUDIO_DB1CT_AC3 = 2, 280 - HDMI_INFOFRAME_AUDIO_DB1CT_MPEG1 = 3, 281 - HDMI_INFOFRAME_AUDIO_DB1CT_MP3 = 4, 282 - HDMI_INFOFRAME_AUDIO_DB1CT_MPEG2_MULTICH = 5, 283 - HDMI_INFOFRAME_AUDIO_DB1CT_AAC = 6, 284 - HDMI_INFOFRAME_AUDIO_DB1CT_DTS = 7, 285 - HDMI_INFOFRAME_AUDIO_DB1CT_ATRAC = 8, 286 - HDMI_INFOFRAME_AUDIO_DB1CT_ONEBIT = 9, 287 - HDMI_INFOFRAME_AUDIO_DB1CT_DOLBY_DIGITAL_PLUS = 10, 288 - HDMI_INFOFRAME_AUDIO_DB1CT_DTS_HD = 11, 289 - HDMI_INFOFRAME_AUDIO_DB1CT_MAT = 12, 290 - HDMI_INFOFRAME_AUDIO_DB1CT_DST = 13, 291 - HDMI_INFOFRAME_AUDIO_DB1CT_WMA_PRO = 14, 292 - HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM = 0, 293 - HDMI_INFOFRAME_AUDIO_DB2SF_32000 = 1, 294 - HDMI_INFOFRAME_AUDIO_DB2SF_44100 = 2, 295 - HDMI_INFOFRAME_AUDIO_DB2SF_48000 = 3, 296 - HDMI_INFOFRAME_AUDIO_DB2SF_88200 = 4, 297 - HDMI_INFOFRAME_AUDIO_DB2SF_96000 = 5, 298 - HDMI_INFOFRAME_AUDIO_DB2SF_176400 = 6, 299 - HDMI_INFOFRAME_AUDIO_DB2SF_192000 = 7, 300 - HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM = 0, 301 - HDMI_INFOFRAME_AUDIO_DB2SS_16BIT = 1, 302 - HDMI_INFOFRAME_AUDIO_DB2SS_20BIT = 2, 303 - HDMI_INFOFRAME_AUDIO_DB2SS_24BIT = 3, 304 - HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PERMITTED = 0, 305 - HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PROHIBITED = 1 306 287 }; 307 288 308 289 enum hdmi_packing_mode { ··· 281 320 HDMI_PACK_24b_RGB_YUV444_YUV422 = 1, 282 321 HDMI_PACK_20b_YUV422 = 2, 283 322 HDMI_PACK_ALREADYPACKED = 7 284 - }; 285 - 286 - enum hdmi_core_audio_sample_freq { 287 - HDMI_AUDIO_FS_32000 = 0x3, 288 - HDMI_AUDIO_FS_44100 = 0x0, 289 - HDMI_AUDIO_FS_48000 = 0x2, 290 - HDMI_AUDIO_FS_88200 = 0x8, 291 - HDMI_AUDIO_FS_96000 = 0xA, 292 - HDMI_AUDIO_FS_176400 = 0xC, 293 - HDMI_AUDIO_FS_192000 = 0xE, 294 - HDMI_AUDIO_FS_NOT_INDICATED = 0x1 295 323 }; 296 324 297 325 enum hdmi_core_audio_layout { ··· 337 387 }; 338 388 339 389 enum hdmi_audio_i2s_config { 340 - HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT = 0, 341 - HDMI_AUDIO_I2S_WS_POLARIT_YLOW_IS_RIGHT = 1, 342 390 HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0, 343 391 HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1, 344 - HDMI_AUDIO_I2S_MAX_WORD_20BITS = 0, 345 - HDMI_AUDIO_I2S_MAX_WORD_24BITS = 1, 346 - HDMI_AUDIO_I2S_CHST_WORD_NOT_SPECIFIED = 0, 347 - HDMI_AUDIO_I2S_CHST_WORD_16_BITS = 1, 348 - HDMI_AUDIO_I2S_CHST_WORD_17_BITS = 6, 349 - HDMI_AUDIO_I2S_CHST_WORD_18_BITS = 2, 350 - HDMI_AUDIO_I2S_CHST_WORD_19_BITS = 4, 351 - HDMI_AUDIO_I2S_CHST_WORD_20_BITS_20MAX = 5, 352 - HDMI_AUDIO_I2S_CHST_WORD_20_BITS_24MAX = 1, 353 - HDMI_AUDIO_I2S_CHST_WORD_21_BITS = 6, 354 - HDMI_AUDIO_I2S_CHST_WORD_22_BITS = 2, 355 - HDMI_AUDIO_I2S_CHST_WORD_23_BITS = 4, 356 - HDMI_AUDIO_I2S_CHST_WORD_24_BITS = 5, 357 392 HDMI_AUDIO_I2S_SCK_EDGE_FALLING = 0, 358 393 HDMI_AUDIO_I2S_SCK_EDGE_RISING = 1, 359 394 HDMI_AUDIO_I2S_VBIT_FOR_PCM = 0, 360 395 HDMI_AUDIO_I2S_VBIT_FOR_COMPRESSED = 1, 361 - HDMI_AUDIO_I2S_INPUT_LENGTH_NA = 0, 362 - HDMI_AUDIO_I2S_INPUT_LENGTH_16 = 2, 363 - HDMI_AUDIO_I2S_INPUT_LENGTH_17 = 12, 364 - HDMI_AUDIO_I2S_INPUT_LENGTH_18 = 4, 365 - HDMI_AUDIO_I2S_INPUT_LENGTH_19 = 8, 366 - HDMI_AUDIO_I2S_INPUT_LENGTH_20 = 10, 367 - HDMI_AUDIO_I2S_INPUT_LENGTH_21 = 13, 368 - HDMI_AUDIO_I2S_INPUT_LENGTH_22 = 5, 369 - HDMI_AUDIO_I2S_INPUT_LENGTH_23 = 9, 370 - HDMI_AUDIO_I2S_INPUT_LENGTH_24 = 11, 371 396 HDMI_AUDIO_I2S_FIRST_BIT_SHIFT = 0, 372 397 HDMI_AUDIO_I2S_FIRST_BIT_NO_SHIFT = 1, 373 398 HDMI_AUDIO_I2S_SD0_EN = 1, ··· 369 444 enum hdmi_core_packet_mode pkt_mode; 370 445 enum hdmi_core_hdmi_dvi hdmi_dvi; 371 446 enum hdmi_core_tclkselclkmult tclk_sel_clkmult; 372 - }; 373 - 374 - /* 375 - * Refer to section 8.2 in HDMI 1.3 specification for 376 - * details about infoframe databytes 377 - */ 378 - struct hdmi_core_infoframe_audio { 379 - u8 db1_coding_type; 380 - u8 db1_channel_count; 381 - u8 db2_sample_freq; 382 - u8 db2_sample_size; 383 - u8 db4_channel_alloc; 384 - bool db5_downmix_inh; 385 - u8 db5_lsv; /* Level shift values for downmix */ 386 447 }; 387 448 388 449 struct hdmi_core_packet_enable_repeat { ··· 407 496 }; 408 497 409 498 struct hdmi_core_audio_i2s_config { 410 - u8 word_max_length; 411 - u8 word_length; 412 499 u8 in_length_bits; 413 500 u8 justification; 414 - u8 en_high_bitrate_aud; 415 501 u8 sck_edge_mode; 416 - u8 cbit_order; 417 502 u8 vbit; 418 - u8 ws_polarity; 419 503 u8 direction; 420 504 u8 shift; 421 505 u8 active_sds; ··· 418 512 419 513 struct hdmi_core_audio_config { 420 514 struct hdmi_core_audio_i2s_config i2s_cfg; 421 - enum hdmi_core_audio_sample_freq freq_sample; 515 + struct snd_aes_iec958 *iec60958_cfg; 422 516 bool fs_override; 423 517 u32 n; 424 518 u32 cts; ··· 433 527 bool en_spdif; 434 528 }; 435 529 436 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 437 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 438 - int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, 439 - u32 sample_freq, u32 *n, u32 *cts); 440 - void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, 441 - struct hdmi_core_infoframe_audio *info_aud); 442 - void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, 443 - struct hdmi_core_audio_config *cfg); 444 - void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, 445 - struct hdmi_audio_dma *aud_dma); 446 - void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data, 447 - struct hdmi_audio_format *aud_fmt); 448 - #endif 449 530 #endif
+101 -32
drivers/video/omap2/dss/venc.c
··· 415 415 return &venc_config_ntsc_trm; 416 416 417 417 BUG(); 418 + return NULL; 418 419 } 419 420 420 421 static int venc_power_on(struct omap_dss_device *dssdev) ··· 441 440 442 441 venc_write_reg(VENC_OUTPUT_CONTROL, l); 443 442 444 - dispc_set_digit_size(dssdev->panel.timings.x_res, 445 - dssdev->panel.timings.y_res/2); 443 + dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); 446 444 447 - regulator_enable(venc.vdda_dac_reg); 445 + r = regulator_enable(venc.vdda_dac_reg); 446 + if (r) 447 + goto err; 448 448 449 449 if (dssdev->platform_enable) 450 450 dssdev->platform_enable(dssdev); ··· 487 485 return 13500000; 488 486 } 489 487 488 + static ssize_t display_output_type_show(struct device *dev, 489 + struct device_attribute *attr, char *buf) 490 + { 491 + struct omap_dss_device *dssdev = to_dss_device(dev); 492 + const char *ret; 493 + 494 + switch (dssdev->phy.venc.type) { 495 + case OMAP_DSS_VENC_TYPE_COMPOSITE: 496 + ret = "composite"; 497 + break; 498 + case OMAP_DSS_VENC_TYPE_SVIDEO: 499 + ret = "svideo"; 500 + break; 501 + default: 502 + return -EINVAL; 503 + } 504 + 505 + return snprintf(buf, PAGE_SIZE, "%s\n", ret); 506 + } 507 + 508 + static ssize_t display_output_type_store(struct device *dev, 509 + struct device_attribute *attr, const char *buf, size_t size) 510 + { 511 + struct omap_dss_device *dssdev = to_dss_device(dev); 512 + enum omap_dss_venc_type new_type; 513 + 514 + if (sysfs_streq("composite", buf)) 515 + new_type = OMAP_DSS_VENC_TYPE_COMPOSITE; 516 + else if (sysfs_streq("svideo", buf)) 517 + new_type = OMAP_DSS_VENC_TYPE_SVIDEO; 518 + else 519 + return -EINVAL; 520 + 521 + mutex_lock(&venc.venc_lock); 522 + 523 + if (dssdev->phy.venc.type != new_type) { 524 + dssdev->phy.venc.type = new_type; 525 + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 526 + venc_power_off(dssdev); 527 + venc_power_on(dssdev); 528 + } 529 + } 530 + 531 + mutex_unlock(&venc.venc_lock); 532 + 533 + return size; 534 + } 535 + 536 + static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR, 537 + display_output_type_show, display_output_type_store); 538 + 490 539 /* driver */ 491 540 static int venc_panel_probe(struct omap_dss_device *dssdev) 492 541 { 493 542 dssdev->panel.timings = omap_dss_pal_timings; 494 543 495 - return 0; 544 + return device_create_file(&dssdev->dev, &dev_attr_output_type); 496 545 } 497 546 498 547 static void venc_panel_remove(struct omap_dss_device *dssdev) 499 548 { 549 + device_remove_file(&dssdev->dev, &dev_attr_output_type); 500 550 } 501 551 502 552 static int venc_panel_enable(struct omap_dss_device *dssdev) ··· 631 577 return venc_panel_enable(dssdev); 632 578 } 633 579 634 - static void venc_get_timings(struct omap_dss_device *dssdev, 635 - struct omap_video_timings *timings) 636 - { 637 - *timings = dssdev->panel.timings; 638 - } 639 - 640 580 static void venc_set_timings(struct omap_dss_device *dssdev, 641 581 struct omap_video_timings *timings) 642 582 { ··· 645 597 /* turn the venc off and on to get new timings to use */ 646 598 venc_panel_disable(dssdev); 647 599 venc_panel_enable(dssdev); 600 + } else { 601 + dss_mgr_set_timings(dssdev->manager, timings); 648 602 } 649 603 } 650 604 ··· 711 661 .get_resolution = omapdss_default_get_resolution, 712 662 .get_recommended_bpp = omapdss_default_get_recommended_bpp, 713 663 714 - .get_timings = venc_get_timings, 715 664 .set_timings = venc_set_timings, 716 665 .check_timings = venc_check_timings, 717 666 ··· 724 675 }; 725 676 /* driver end */ 726 677 727 - int venc_init_display(struct omap_dss_device *dssdev) 678 + static int __init venc_init_display(struct omap_dss_device *dssdev) 728 679 { 729 680 DSSDBG("init_display\n"); 730 681 ··· 744 695 return 0; 745 696 } 746 697 747 - void venc_dump_regs(struct seq_file *s) 698 + static void venc_dump_regs(struct seq_file *s) 748 699 { 749 700 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) 750 701 ··· 828 779 clk_put(venc.tv_dac_clk); 829 780 } 830 781 782 + static void __init venc_probe_pdata(struct platform_device *pdev) 783 + { 784 + struct omap_dss_board_info *pdata = pdev->dev.platform_data; 785 + int r, i; 786 + 787 + for (i = 0; i < pdata->num_devices; ++i) { 788 + struct omap_dss_device *dssdev = pdata->devices[i]; 789 + 790 + if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) 791 + continue; 792 + 793 + r = venc_init_display(dssdev); 794 + if (r) { 795 + DSSERR("device %s init failed: %d\n", dssdev->name, r); 796 + continue; 797 + } 798 + 799 + r = omap_dss_register_device(dssdev, &pdev->dev, i); 800 + if (r) 801 + DSSERR("device %s register failed: %d\n", 802 + dssdev->name, r); 803 + } 804 + } 805 + 831 806 /* VENC HW IP initialisation */ 832 - static int omap_venchw_probe(struct platform_device *pdev) 807 + static int __init omap_venchw_probe(struct platform_device *pdev) 833 808 { 834 809 u8 rev_id; 835 810 struct resource *venc_mem; ··· 897 824 if (r) 898 825 goto err_reg_panel_driver; 899 826 827 + dss_debugfs_create_file("venc", venc_dump_regs); 828 + 829 + venc_probe_pdata(pdev); 830 + 900 831 return 0; 901 832 902 833 err_reg_panel_driver: ··· 910 833 return r; 911 834 } 912 835 913 - static int omap_venchw_remove(struct platform_device *pdev) 836 + static int __exit omap_venchw_remove(struct platform_device *pdev) 914 837 { 838 + omap_dss_unregister_child_devices(&pdev->dev); 839 + 915 840 if (venc.vdda_dac_reg != NULL) { 916 841 regulator_put(venc.vdda_dac_reg); 917 842 venc.vdda_dac_reg = NULL; 918 843 } 844 + 919 845 omap_dss_unregister_driver(&venc_driver); 920 846 921 847 pm_runtime_disable(&pdev->dev); ··· 933 853 clk_disable(venc.tv_dac_clk); 934 854 935 855 dispc_runtime_put(); 936 - dss_runtime_put(); 937 856 938 857 return 0; 939 858 } ··· 941 862 { 942 863 int r; 943 864 944 - r = dss_runtime_get(); 945 - if (r < 0) 946 - goto err_get_dss; 947 - 948 865 r = dispc_runtime_get(); 949 866 if (r < 0) 950 - goto err_get_dispc; 867 + return r; 951 868 952 869 if (venc.tv_dac_clk) 953 870 clk_enable(venc.tv_dac_clk); 954 871 955 872 return 0; 956 - 957 - err_get_dispc: 958 - dss_runtime_put(); 959 - err_get_dss: 960 - return r; 961 873 } 962 874 963 875 static const struct dev_pm_ops venc_pm_ops = { ··· 957 887 }; 958 888 959 889 static struct platform_driver omap_venchw_driver = { 960 - .probe = omap_venchw_probe, 961 - .remove = omap_venchw_remove, 890 + .remove = __exit_p(omap_venchw_remove), 962 891 .driver = { 963 892 .name = "omapdss_venc", 964 893 .owner = THIS_MODULE, ··· 965 896 }, 966 897 }; 967 898 968 - int venc_init_platform_driver(void) 899 + int __init venc_init_platform_driver(void) 969 900 { 970 901 if (cpu_is_omap44xx()) 971 902 return 0; 972 903 973 - return platform_driver_register(&omap_venchw_driver); 904 + return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe); 974 905 } 975 906 976 - void venc_uninit_platform_driver(void) 907 + void __exit venc_uninit_platform_driver(void) 977 908 { 978 909 if (cpu_is_omap44xx()) 979 910 return; 980 911 981 - return platform_driver_unregister(&omap_venchw_driver); 912 + platform_driver_unregister(&omap_venchw_driver); 982 913 }
+9 -8
drivers/video/omap2/omapfb/omapfb-ioctl.c
··· 70 70 71 71 DBG("omapfb_setup_plane\n"); 72 72 73 - if (ofbi->num_overlays != 1) { 73 + if (ofbi->num_overlays == 0) { 74 74 r = -EINVAL; 75 75 goto out; 76 76 } ··· 185 185 { 186 186 struct omapfb_info *ofbi = FB2OFB(fbi); 187 187 188 - if (ofbi->num_overlays != 1) { 188 + if (ofbi->num_overlays == 0) { 189 189 memset(pi, 0, sizeof(*pi)); 190 190 } else { 191 191 struct omap_overlay *ovl; ··· 225 225 down_write_nested(&rg->lock, rg->id); 226 226 atomic_inc(&rg->lock_count); 227 227 228 + if (rg->size == size && rg->type == mi->type) 229 + goto out; 230 + 228 231 if (atomic_read(&rg->map_count)) { 229 232 r = -EBUSY; 230 233 goto out; ··· 250 247 } 251 248 } 252 249 253 - if (rg->size != size || rg->type != mi->type) { 254 - r = omapfb_realloc_fbmem(fbi, size, mi->type); 255 - if (r) { 256 - dev_err(fbdev->dev, "realloc fbmem failed\n"); 257 - goto out; 258 - } 250 + r = omapfb_realloc_fbmem(fbi, size, mi->type); 251 + if (r) { 252 + dev_err(fbdev->dev, "realloc fbmem failed\n"); 253 + goto out; 259 254 } 260 255 261 256 out:
+6 -6
drivers/video/omap2/omapfb/omapfb-main.c
··· 179 179 break; 180 180 default: 181 181 BUG(); 182 + return 0; 182 183 } 183 184 184 185 offset *= vrfb->bytespp; ··· 1503 1502 1504 1503 fbnum = simple_strtoul(p, &p, 10); 1505 1504 1506 - if (p == param) 1505 + if (p == start) 1507 1506 return -EINVAL; 1508 1507 1509 1508 if (*p != ':') ··· 2308 2307 return 0; 2309 2308 } 2310 2309 2311 - static int omapfb_probe(struct platform_device *pdev) 2310 + static int __init omapfb_probe(struct platform_device *pdev) 2312 2311 { 2313 2312 struct omapfb2_device *fbdev = NULL; 2314 2313 int r = 0; ··· 2449 2448 return r; 2450 2449 } 2451 2450 2452 - static int omapfb_remove(struct platform_device *pdev) 2451 + static int __exit omapfb_remove(struct platform_device *pdev) 2453 2452 { 2454 2453 struct omapfb2_device *fbdev = platform_get_drvdata(pdev); 2455 2454 ··· 2463 2462 } 2464 2463 2465 2464 static struct platform_driver omapfb_driver = { 2466 - .probe = omapfb_probe, 2467 - .remove = omapfb_remove, 2465 + .remove = __exit_p(omapfb_remove), 2468 2466 .driver = { 2469 2467 .name = "omapfb", 2470 2468 .owner = THIS_MODULE, ··· 2474 2474 { 2475 2475 DBG("omapfb_init\n"); 2476 2476 2477 - if (platform_driver_register(&omapfb_driver)) { 2477 + if (platform_driver_probe(&omapfb_driver, omapfb_probe)) { 2478 2478 printk(KERN_ERR "failed to register omapfb driver\n"); 2479 2479 return -ENODEV; 2480 2480 }
+1
drivers/video/omap2/omapfb/omapfb.h
··· 166 166 167 167 /* This should never happen */ 168 168 BUG(); 169 + return NULL; 169 170 } 170 171 171 172 static inline void omapfb_lock(struct omapfb2_device *fbdev)
+3 -1
drivers/video/omap2/vrfb.c
··· 179 179 pixel_size_exp = 2; 180 180 else if (bytespp == 2) 181 181 pixel_size_exp = 1; 182 - else 182 + else { 183 183 BUG(); 184 + return; 185 + } 184 186 185 187 vrfb_width = ALIGN(width * bytespp, VRFB_PAGE_WIDTH) / bytespp; 186 188 vrfb_height = ALIGN(height, VRFB_PAGE_HEIGHT);
+1 -4
drivers/video/pxa3xx-gcu.c
··· 316 316 ret = wait_event_interruptible_timeout(priv->wait_idle, 317 317 !priv->shared->hw_running, HZ*4); 318 318 319 - if (ret < 0) 319 + if (ret != 0) 320 320 break; 321 - 322 - if (ret > 0) 323 - continue; 324 321 325 322 if (gc_readl(priv, REG_GCRBEXHR) == rbexhr && 326 323 priv->shared->num_interrupts == num) {
+76 -72
drivers/video/s3c-fb.c
··· 47 47 #ifdef CONFIG_FB_S3C_DEBUG_REGWRITE 48 48 #undef writel 49 49 #define writel(v, r) do { \ 50 - printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \ 50 + pr_debug("%s: %08x => %p\n", __func__, (unsigned int)v, r); \ 51 51 __raw_writel(v, r); \ 52 52 } while (0) 53 53 #endif /* FB_S3C_DEBUG_REGWRITE */ ··· 495 495 u32 alpha = 0; 496 496 u32 data; 497 497 u32 pagewidth; 498 - int clkdiv; 499 498 500 499 dev_dbg(sfb->dev, "setting framebuffer parameters\n"); 501 500 ··· 531 532 /* disable the window whilst we update it */ 532 533 writel(0, regs + WINCON(win_no)); 533 534 534 - /* use platform specified window as the basis for the lcd timings */ 535 - 536 - if (win_no == sfb->pdata->default_win) { 537 - clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); 538 - 539 - data = sfb->pdata->vidcon0; 540 - data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); 541 - 542 - if (clkdiv > 1) 543 - data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR; 544 - else 545 - data &= ~VIDCON0_CLKDIR; /* 1:1 clock */ 546 - 547 - /* write the timing data to the panel */ 548 - 549 - if (sfb->variant.is_2443) 550 - data |= (1 << 5); 551 - 552 - writel(data, regs + VIDCON0); 553 - 535 + if (!sfb->output_on) 554 536 s3c_fb_enable(sfb, 1); 555 - 556 - data = VIDTCON0_VBPD(var->upper_margin - 1) | 557 - VIDTCON0_VFPD(var->lower_margin - 1) | 558 - VIDTCON0_VSPW(var->vsync_len - 1); 559 - 560 - writel(data, regs + sfb->variant.vidtcon); 561 - 562 - data = VIDTCON1_HBPD(var->left_margin - 1) | 563 - VIDTCON1_HFPD(var->right_margin - 1) | 564 - VIDTCON1_HSPW(var->hsync_len - 1); 565 - 566 - /* VIDTCON1 */ 567 - writel(data, regs + sfb->variant.vidtcon + 4); 568 - 569 - data = VIDTCON2_LINEVAL(var->yres - 1) | 570 - VIDTCON2_HOZVAL(var->xres - 1) | 571 - VIDTCON2_LINEVAL_E(var->yres - 1) | 572 - VIDTCON2_HOZVAL_E(var->xres - 1); 573 - writel(data, regs + sfb->variant.vidtcon + 8); 574 - } 575 537 576 538 /* write the buffer address */ 577 539 ··· 799 839 struct s3c_fb *sfb = win->parent; 800 840 unsigned int index = win->index; 801 841 u32 wincon; 842 + u32 output_on = sfb->output_on; 802 843 803 844 dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); 804 845 ··· 838 877 839 878 shadow_protect_win(win, 1); 840 879 writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4)); 841 - shadow_protect_win(win, 0); 842 880 843 881 /* Check the enabled state to see if we need to be running the 844 882 * main LCD interface, as if there are no active windows then 845 883 * it is highly likely that we also do not need to output 846 884 * anything. 847 885 */ 848 - 849 - /* We could do something like the following code, but the current 850 - * system of using framebuffer events means that we cannot make 851 - * the distinction between just window 0 being inactive and all 852 - * the windows being down. 853 - * 854 - * s3c_fb_enable(sfb, sfb->enabled ? 1 : 0); 855 - */ 856 - 857 - /* we're stuck with this until we can do something about overriding 858 - * the power control using the blanking event for a single fb. 859 - */ 860 - if (index == sfb->pdata->default_win) { 861 - shadow_protect_win(win, 1); 862 - s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0); 863 - shadow_protect_win(win, 0); 864 - } 886 + s3c_fb_enable(sfb, sfb->enabled ? 1 : 0); 887 + shadow_protect_win(win, 0); 865 888 866 889 pm_runtime_put_sync(sfb->dev); 867 890 868 - return 0; 891 + return output_on == sfb->output_on; 869 892 } 870 893 871 894 /** ··· 1056 1111 * 1057 1112 * Calculate the pixel clock when none has been given through platform data. 1058 1113 */ 1059 - static void __devinit s3c_fb_missing_pixclock(struct fb_videomode *mode) 1114 + static void s3c_fb_missing_pixclock(struct fb_videomode *mode) 1060 1115 { 1061 1116 u64 pixclk = 1000000000000ULL; 1062 1117 u32 div; ··· 1089 1144 1090 1145 dev_dbg(sfb->dev, "allocating memory for display\n"); 1091 1146 1092 - real_size = windata->win_mode.xres * windata->win_mode.yres; 1147 + real_size = windata->xres * windata->yres; 1093 1148 virt_size = windata->virtual_x * windata->virtual_y; 1094 1149 1095 1150 dev_dbg(sfb->dev, "real_size=%u (%u.%u), virt_size=%u (%u.%u)\n", 1096 - real_size, windata->win_mode.xres, windata->win_mode.yres, 1151 + real_size, windata->xres, windata->yres, 1097 1152 virt_size, windata->virtual_x, windata->virtual_y); 1098 1153 1099 1154 size = (real_size > virt_size) ? real_size : virt_size; ··· 1175 1230 struct s3c_fb_win **res) 1176 1231 { 1177 1232 struct fb_var_screeninfo *var; 1178 - struct fb_videomode *initmode; 1233 + struct fb_videomode initmode; 1179 1234 struct s3c_fb_pd_win *windata; 1180 1235 struct s3c_fb_win *win; 1181 1236 struct fb_info *fbinfo; ··· 1196 1251 } 1197 1252 1198 1253 windata = sfb->pdata->win[win_no]; 1199 - initmode = &windata->win_mode; 1254 + initmode = *sfb->pdata->vtiming; 1200 1255 1201 1256 WARN_ON(windata->max_bpp == 0); 1202 - WARN_ON(windata->win_mode.xres == 0); 1203 - WARN_ON(windata->win_mode.yres == 0); 1257 + WARN_ON(windata->xres == 0); 1258 + WARN_ON(windata->yres == 0); 1204 1259 1205 1260 win = fbinfo->par; 1206 1261 *res = win; ··· 1239 1294 } 1240 1295 1241 1296 /* setup the initial video mode from the window */ 1242 - fb_videomode_to_var(&fbinfo->var, initmode); 1297 + initmode.xres = windata->xres; 1298 + initmode.yres = windata->yres; 1299 + fb_videomode_to_var(&fbinfo->var, &initmode); 1243 1300 1244 1301 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; 1245 1302 fbinfo->fix.accel = FB_ACCEL_NONE; ··· 1283 1336 dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); 1284 1337 1285 1338 return 0; 1339 + } 1340 + 1341 + /** 1342 + * s3c_fb_set_rgb_timing() - set video timing for rgb interface. 1343 + * @sfb: The base resources for the hardware. 1344 + * 1345 + * Set horizontal and vertical lcd rgb interface timing. 1346 + */ 1347 + static void s3c_fb_set_rgb_timing(struct s3c_fb *sfb) 1348 + { 1349 + struct fb_videomode *vmode = sfb->pdata->vtiming; 1350 + void __iomem *regs = sfb->regs; 1351 + int clkdiv; 1352 + u32 data; 1353 + 1354 + if (!vmode->pixclock) 1355 + s3c_fb_missing_pixclock(vmode); 1356 + 1357 + clkdiv = s3c_fb_calc_pixclk(sfb, vmode->pixclock); 1358 + 1359 + data = sfb->pdata->vidcon0; 1360 + data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); 1361 + 1362 + if (clkdiv > 1) 1363 + data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR; 1364 + else 1365 + data &= ~VIDCON0_CLKDIR; /* 1:1 clock */ 1366 + 1367 + if (sfb->variant.is_2443) 1368 + data |= (1 << 5); 1369 + writel(data, regs + VIDCON0); 1370 + 1371 + data = VIDTCON0_VBPD(vmode->upper_margin - 1) | 1372 + VIDTCON0_VFPD(vmode->lower_margin - 1) | 1373 + VIDTCON0_VSPW(vmode->vsync_len - 1); 1374 + writel(data, regs + sfb->variant.vidtcon); 1375 + 1376 + data = VIDTCON1_HBPD(vmode->left_margin - 1) | 1377 + VIDTCON1_HFPD(vmode->right_margin - 1) | 1378 + VIDTCON1_HSPW(vmode->hsync_len - 1); 1379 + writel(data, regs + sfb->variant.vidtcon + 4); 1380 + 1381 + data = VIDTCON2_LINEVAL(vmode->yres - 1) | 1382 + VIDTCON2_HOZVAL(vmode->xres - 1) | 1383 + VIDTCON2_LINEVAL_E(vmode->yres - 1) | 1384 + VIDTCON2_HOZVAL_E(vmode->xres - 1); 1385 + writel(data, regs + sfb->variant.vidtcon + 8); 1286 1386 } 1287 1387 1288 1388 /** ··· 1475 1481 writel(0xffffff, regs + WKEYCON1); 1476 1482 } 1477 1483 1484 + s3c_fb_set_rgb_timing(sfb); 1485 + 1478 1486 /* we have the register setup, start allocating framebuffers */ 1479 1487 1480 1488 for (win = 0; win < fbdrv->variant.nr_windows; win++) { 1481 1489 if (!pd->win[win]) 1482 1490 continue; 1483 - 1484 - if (!pd->win[win]->win_mode.pixclock) 1485 - s3c_fb_missing_pixclock(&pd->win[win]->win_mode); 1486 1491 1487 1492 ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win], 1488 1493 &sfb->windows[win]); ··· 1557 1564 struct s3c_fb_win *win; 1558 1565 int win_no; 1559 1566 1567 + pm_runtime_get_sync(sfb->dev); 1568 + 1560 1569 for (win_no = S3C_FB_MAX_WIN - 1; win_no >= 0; win_no--) { 1561 1570 win = sfb->windows[win_no]; 1562 1571 if (!win) ··· 1572 1577 clk_disable(sfb->lcd_clk); 1573 1578 1574 1579 clk_disable(sfb->bus_clk); 1580 + 1581 + pm_runtime_put_sync(sfb->dev); 1582 + 1575 1583 return 0; 1576 1584 } 1577 1585 ··· 1586 1588 struct s3c_fb_win *win; 1587 1589 int win_no; 1588 1590 u32 reg; 1591 + 1592 + pm_runtime_get_sync(sfb->dev); 1589 1593 1590 1594 clk_enable(sfb->bus_clk); 1591 1595 ··· 1623 1623 shadow_protect_win(win, 0); 1624 1624 } 1625 1625 1626 + s3c_fb_set_rgb_timing(sfb); 1627 + 1626 1628 /* restore framebuffers */ 1627 1629 for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) { 1628 1630 win = sfb->windows[win_no]; ··· 1634 1632 dev_dbg(&pdev->dev, "resuming window %d\n", win_no); 1635 1633 s3c_fb_set_par(win->fbinfo); 1636 1634 } 1635 + 1636 + pm_runtime_put_sync(sfb->dev); 1637 1637 1638 1638 return 0; 1639 1639 }
+210 -9
drivers/video/sh_mobile_hdmi.c
··· 31 31 32 32 #include "sh_mobile_lcdcfb.h" 33 33 34 + /* HDMI Core Control Register (HTOP0) */ 34 35 #define HDMI_SYSTEM_CTRL 0x00 /* System control */ 35 36 #define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control, 36 37 bits 19..16 of 20-bit N for Audio Clock Regeneration packet */ ··· 202 201 #define HDMI_REVISION_ID 0xF1 /* Revision ID */ 203 202 #define HDMI_TEST_MODE 0xFE /* Test mode */ 204 203 204 + /* HDMI Control Register (HTOP1) */ 205 + #define HDMI_HTOP1_TEST_MODE 0x0000 /* Test mode */ 206 + #define HDMI_HTOP1_VIDEO_INPUT 0x0008 /* VideoInput */ 207 + #define HDMI_HTOP1_CORE_RSTN 0x000C /* CoreResetn */ 208 + #define HDMI_HTOP1_PLLBW 0x0018 /* PLLBW */ 209 + #define HDMI_HTOP1_CLK_TO_PHY 0x001C /* Clk to Phy */ 210 + #define HDMI_HTOP1_VIDEO_INPUT2 0x0020 /* VideoInput2 */ 211 + #define HDMI_HTOP1_TISEMP0_1 0x0024 /* tisemp0-1 */ 212 + #define HDMI_HTOP1_TISEMP2_C 0x0028 /* tisemp2-c */ 213 + #define HDMI_HTOP1_TISIDRV 0x002C /* tisidrv */ 214 + #define HDMI_HTOP1_TISEN 0x0034 /* tisen */ 215 + #define HDMI_HTOP1_TISDREN 0x0038 /* tisdren */ 216 + #define HDMI_HTOP1_CISRANGE 0x003C /* cisrange */ 217 + #define HDMI_HTOP1_ENABLE_SELECTOR 0x0040 /* Enable Selector */ 218 + #define HDMI_HTOP1_MACRO_RESET 0x0044 /* Macro reset */ 219 + #define HDMI_HTOP1_PLL_CALIBRATION 0x0048 /* PLL calibration */ 220 + #define HDMI_HTOP1_RE_CALIBRATION 0x004C /* Re-calibration */ 221 + #define HDMI_HTOP1_CURRENT 0x0050 /* Current */ 222 + #define HDMI_HTOP1_PLL_LOCK_DETECT 0x0054 /* PLL lock detect */ 223 + #define HDMI_HTOP1_PHY_TEST_MODE 0x0058 /* PHY Test Mode */ 224 + #define HDMI_HTOP1_CLK_SET 0x0080 /* Clock Set */ 225 + #define HDMI_HTOP1_DDC_FAIL_SAFE 0x0084 /* DDC fail safe */ 226 + #define HDMI_HTOP1_PRBS 0x0088 /* PRBS */ 227 + #define HDMI_HTOP1_EDID_AINC_CONTROL 0x008C /* EDID ainc Control */ 228 + #define HDMI_HTOP1_HTOP_DCL_MODE 0x00FC /* Deep Coloer Mode */ 229 + #define HDMI_HTOP1_HTOP_DCL_FRC_COEF0 0x0100 /* Deep Color:FRC COEF0 */ 230 + #define HDMI_HTOP1_HTOP_DCL_FRC_COEF1 0x0104 /* Deep Color:FRC COEF1 */ 231 + #define HDMI_HTOP1_HTOP_DCL_FRC_COEF2 0x0108 /* Deep Color:FRC COEF2 */ 232 + #define HDMI_HTOP1_HTOP_DCL_FRC_COEF3 0x010C /* Deep Color:FRC COEF3 */ 233 + #define HDMI_HTOP1_HTOP_DCL_FRC_COEF0_C 0x0110 /* Deep Color:FRC COEF0C */ 234 + #define HDMI_HTOP1_HTOP_DCL_FRC_COEF1_C 0x0114 /* Deep Color:FRC COEF1C */ 235 + #define HDMI_HTOP1_HTOP_DCL_FRC_COEF2_C 0x0118 /* Deep Color:FRC COEF2C */ 236 + #define HDMI_HTOP1_HTOP_DCL_FRC_COEF3_C 0x011C /* Deep Color:FRC COEF3C */ 237 + #define HDMI_HTOP1_HTOP_DCL_FRC_MODE 0x0120 /* Deep Color:FRC Mode */ 238 + #define HDMI_HTOP1_HTOP_DCL_RECT_START1 0x0124 /* Deep Color:Rect Start1 */ 239 + #define HDMI_HTOP1_HTOP_DCL_RECT_SIZE1 0x0128 /* Deep Color:Rect Size1 */ 240 + #define HDMI_HTOP1_HTOP_DCL_RECT_START2 0x012C /* Deep Color:Rect Start2 */ 241 + #define HDMI_HTOP1_HTOP_DCL_RECT_SIZE2 0x0130 /* Deep Color:Rect Size2 */ 242 + #define HDMI_HTOP1_HTOP_DCL_RECT_START3 0x0134 /* Deep Color:Rect Start3 */ 243 + #define HDMI_HTOP1_HTOP_DCL_RECT_SIZE3 0x0138 /* Deep Color:Rect Size3 */ 244 + #define HDMI_HTOP1_HTOP_DCL_RECT_START4 0x013C /* Deep Color:Rect Start4 */ 245 + #define HDMI_HTOP1_HTOP_DCL_RECT_SIZE4 0x0140 /* Deep Color:Rect Size4 */ 246 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y1_1 0x0144 /* Deep Color:Fil Para Y1_1 */ 247 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y1_2 0x0148 /* Deep Color:Fil Para Y1_2 */ 248 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB1_1 0x014C /* Deep Color:Fil Para CB1_1 */ 249 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB1_2 0x0150 /* Deep Color:Fil Para CB1_2 */ 250 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR1_1 0x0154 /* Deep Color:Fil Para CR1_1 */ 251 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR1_2 0x0158 /* Deep Color:Fil Para CR1_2 */ 252 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y2_1 0x015C /* Deep Color:Fil Para Y2_1 */ 253 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y2_2 0x0160 /* Deep Color:Fil Para Y2_2 */ 254 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB2_1 0x0164 /* Deep Color:Fil Para CB2_1 */ 255 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB2_2 0x0168 /* Deep Color:Fil Para CB2_2 */ 256 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR2_1 0x016C /* Deep Color:Fil Para CR2_1 */ 257 + #define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR2_2 0x0170 /* Deep Color:Fil Para CR2_2 */ 258 + #define HDMI_HTOP1_HTOP_DCL_COR_PARA_Y1 0x0174 /* Deep Color:Cor Para Y1 */ 259 + #define HDMI_HTOP1_HTOP_DCL_COR_PARA_CB1 0x0178 /* Deep Color:Cor Para CB1 */ 260 + #define HDMI_HTOP1_HTOP_DCL_COR_PARA_CR1 0x017C /* Deep Color:Cor Para CR1 */ 261 + #define HDMI_HTOP1_HTOP_DCL_COR_PARA_Y2 0x0180 /* Deep Color:Cor Para Y2 */ 262 + #define HDMI_HTOP1_HTOP_DCL_COR_PARA_CB2 0x0184 /* Deep Color:Cor Para CB2 */ 263 + #define HDMI_HTOP1_HTOP_DCL_COR_PARA_CR2 0x0188 /* Deep Color:Cor Para CR2 */ 264 + #define HDMI_HTOP1_EDID_DATA_READ 0x0200 /* EDID Data Read 128Byte:0x03FC */ 265 + 205 266 enum hotplug_state { 206 267 HDMI_HOTPLUG_DISCONNECTED, 207 268 HDMI_HOTPLUG_CONNECTED, ··· 274 211 struct sh_mobile_lcdc_entity entity; 275 212 276 213 void __iomem *base; 214 + void __iomem *htop1; 277 215 enum hotplug_state hp_state; /* hot-plug status */ 278 216 u8 preprogrammed_vic; /* use a pre-programmed VIC or 279 217 the external mode */ ··· 286 222 struct delayed_work edid_work; 287 223 struct fb_videomode mode; 288 224 struct fb_monspecs monspec; 225 + 226 + /* register access functions */ 227 + void (*write)(struct sh_hdmi *hdmi, u8 data, u8 reg); 228 + u8 (*read)(struct sh_hdmi *hdmi, u8 reg); 289 229 }; 290 230 291 231 #define entity_to_sh_hdmi(e) container_of(e, struct sh_hdmi, entity) 292 232 293 - static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) 233 + static void __hdmi_write8(struct sh_hdmi *hdmi, u8 data, u8 reg) 294 234 { 295 235 iowrite8(data, hdmi->base + reg); 296 236 } 297 237 298 - static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg) 238 + static u8 __hdmi_read8(struct sh_hdmi *hdmi, u8 reg) 299 239 { 300 240 return ioread8(hdmi->base + reg); 241 + } 242 + 243 + static void __hdmi_write32(struct sh_hdmi *hdmi, u8 data, u8 reg) 244 + { 245 + iowrite32((u32)data, hdmi->base + (reg * 4)); 246 + udelay(100); 247 + } 248 + 249 + static u8 __hdmi_read32(struct sh_hdmi *hdmi, u8 reg) 250 + { 251 + return (u8)ioread32(hdmi->base + (reg * 4)); 252 + } 253 + 254 + static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) 255 + { 256 + hdmi->write(hdmi, data, reg); 257 + } 258 + 259 + static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg) 260 + { 261 + return hdmi->read(hdmi, reg); 262 + } 263 + 264 + static void hdmi_bit_set(struct sh_hdmi *hdmi, u8 mask, u8 data, u8 reg) 265 + { 266 + u8 val = hdmi_read(hdmi, reg); 267 + 268 + val &= ~mask; 269 + val |= (data & mask); 270 + 271 + hdmi_write(hdmi, val, reg); 272 + } 273 + 274 + static void hdmi_htop1_write(struct sh_hdmi *hdmi, u32 data, u32 reg) 275 + { 276 + iowrite32(data, hdmi->htop1 + reg); 277 + udelay(100); 278 + } 279 + 280 + static u32 hdmi_htop1_read(struct sh_hdmi *hdmi, u32 reg) 281 + { 282 + return ioread32(hdmi->htop1 + reg); 301 283 } 302 284 303 285 /* ··· 803 693 msleep(10); 804 694 805 695 /* PS mode b->d, reset PLLA and PLLB */ 806 - hdmi_write(hdmi, 0x4C, HDMI_SYSTEM_CTRL); 696 + hdmi_bit_set(hdmi, 0xFC, 0x4C, HDMI_SYSTEM_CTRL); 807 697 808 698 udelay(10); 809 699 810 - hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL); 700 + hdmi_bit_set(hdmi, 0xFC, 0x40, HDMI_SYSTEM_CTRL); 811 701 } 812 702 813 703 static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi, ··· 856 746 /* Read EDID */ 857 747 dev_dbg(hdmi->dev, "Read back EDID code:"); 858 748 for (i = 0; i < 128; i++) { 859 - edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW); 749 + edid[i] = (hdmi->htop1) ? 750 + (u8)hdmi_htop1_read(hdmi, HDMI_HTOP1_EDID_DATA_READ + (i * 4)) : 751 + hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW); 860 752 #ifdef DEBUG 861 753 if ((i % 16) == 0) { 862 754 printk(KERN_CONT "\n"); ··· 1029 917 u8 status1, status2, mask1, mask2; 1030 918 1031 919 /* mode_b and PLLA and PLLB reset */ 1032 - hdmi_write(hdmi, 0x2C, HDMI_SYSTEM_CTRL); 920 + hdmi_bit_set(hdmi, 0xFC, 0x2C, HDMI_SYSTEM_CTRL); 1033 921 1034 922 /* How long shall reset be held? */ 1035 923 udelay(10); 1036 924 1037 925 /* mode_b and PLLA and PLLB reset release */ 1038 - hdmi_write(hdmi, 0x20, HDMI_SYSTEM_CTRL); 926 + hdmi_bit_set(hdmi, 0xFC, 0x20, HDMI_SYSTEM_CTRL); 1039 927 1040 928 status1 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_1); 1041 929 status2 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_2); ··· 1113 1001 */ 1114 1002 if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) { 1115 1003 /* PS mode d->e. All functions are active */ 1116 - hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL); 1004 + hdmi_bit_set(hdmi, 0xFC, 0x80, HDMI_SYSTEM_CTRL); 1117 1005 dev_dbg(hdmi->dev, "HDMI running\n"); 1118 1006 } 1119 1007 ··· 1128 1016 1129 1017 dev_dbg(hdmi->dev, "%s(%p)\n", __func__, hdmi); 1130 1018 /* PS mode e->a */ 1131 - hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL); 1019 + hdmi_bit_set(hdmi, 0xFC, 0x10, HDMI_SYSTEM_CTRL); 1132 1020 } 1133 1021 1134 1022 static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = { ··· 1222 1110 dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, hdmi); 1223 1111 } 1224 1112 1113 + static void sh_hdmi_htop1_init(struct sh_hdmi *hdmi) 1114 + { 1115 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_MODE); 1116 + hdmi_htop1_write(hdmi, 0x0000000b, 0x0010); 1117 + hdmi_htop1_write(hdmi, 0x00006710, HDMI_HTOP1_HTOP_DCL_FRC_MODE); 1118 + hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y1_1); 1119 + hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y1_2); 1120 + hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB1_1); 1121 + hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB1_2); 1122 + hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR1_1); 1123 + hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR1_2); 1124 + hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y2_1); 1125 + hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y2_2); 1126 + hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB2_1); 1127 + hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB2_2); 1128 + hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR2_1); 1129 + hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR2_2); 1130 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_Y1); 1131 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_CB1); 1132 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_CR1); 1133 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_Y2); 1134 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_CB2); 1135 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_CR2); 1136 + hdmi_htop1_write(hdmi, 0x00000008, HDMI_HTOP1_CURRENT); 1137 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_TISEMP0_1); 1138 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_TISEMP2_C); 1139 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_PHY_TEST_MODE); 1140 + hdmi_htop1_write(hdmi, 0x00000081, HDMI_HTOP1_TISIDRV); 1141 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_PLLBW); 1142 + hdmi_htop1_write(hdmi, 0x0000000f, HDMI_HTOP1_TISEN); 1143 + hdmi_htop1_write(hdmi, 0x0000000f, HDMI_HTOP1_TISDREN); 1144 + hdmi_htop1_write(hdmi, 0x00000003, HDMI_HTOP1_ENABLE_SELECTOR); 1145 + hdmi_htop1_write(hdmi, 0x00000001, HDMI_HTOP1_MACRO_RESET); 1146 + hdmi_htop1_write(hdmi, 0x00000016, HDMI_HTOP1_CISRANGE); 1147 + msleep(100); 1148 + hdmi_htop1_write(hdmi, 0x00000001, HDMI_HTOP1_ENABLE_SELECTOR); 1149 + msleep(100); 1150 + hdmi_htop1_write(hdmi, 0x00000003, HDMI_HTOP1_ENABLE_SELECTOR); 1151 + hdmi_htop1_write(hdmi, 0x00000001, HDMI_HTOP1_MACRO_RESET); 1152 + hdmi_htop1_write(hdmi, 0x0000000f, HDMI_HTOP1_TISEN); 1153 + hdmi_htop1_write(hdmi, 0x0000000f, HDMI_HTOP1_TISDREN); 1154 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_VIDEO_INPUT); 1155 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_CLK_TO_PHY); 1156 + hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_VIDEO_INPUT2); 1157 + hdmi_htop1_write(hdmi, 0x0000000a, HDMI_HTOP1_CLK_SET); 1158 + } 1159 + 1225 1160 static int __init sh_hdmi_probe(struct platform_device *pdev) 1226 1161 { 1227 1162 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; 1228 1163 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1164 + struct resource *htop1_res; 1229 1165 int irq = platform_get_irq(pdev, 0), ret; 1230 1166 struct sh_hdmi *hdmi; 1231 1167 long rate; 1232 1168 1233 1169 if (!res || !pdata || irq < 0) 1234 1170 return -ENODEV; 1171 + 1172 + htop1_res = NULL; 1173 + if (pdata->flags & HDMI_HAS_HTOP1) { 1174 + htop1_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1175 + if (!htop1_res) { 1176 + dev_err(&pdev->dev, "htop1 needs register base\n"); 1177 + return -EINVAL; 1178 + } 1179 + } 1235 1180 1236 1181 hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL); 1237 1182 if (!hdmi) { ··· 1305 1136 ret = PTR_ERR(hdmi->hdmi_clk); 1306 1137 dev_err(&pdev->dev, "Unable to get clock: %d\n", ret); 1307 1138 goto egetclk; 1139 + } 1140 + 1141 + /* select register access functions */ 1142 + if (pdata->flags & HDMI_32BIT_REG) { 1143 + hdmi->write = __hdmi_write32; 1144 + hdmi->read = __hdmi_read32; 1145 + } else { 1146 + hdmi->write = __hdmi_write8; 1147 + hdmi->read = __hdmi_read8; 1308 1148 } 1309 1149 1310 1150 /* An arbitrary relaxed pixclock just to get things started: from standard 480p */ ··· 1354 1176 pm_runtime_enable(&pdev->dev); 1355 1177 pm_runtime_get_sync(&pdev->dev); 1356 1178 1179 + /* init interrupt polarity */ 1180 + if (pdata->flags & HDMI_OUTPUT_PUSH_PULL) 1181 + hdmi_bit_set(hdmi, 0x02, 0x02, HDMI_SYSTEM_CTRL); 1182 + 1183 + if (pdata->flags & HDMI_OUTPUT_POLARITY_HI) 1184 + hdmi_bit_set(hdmi, 0x01, 0x01, HDMI_SYSTEM_CTRL); 1185 + 1186 + /* enable htop1 register if needed */ 1187 + if (htop1_res) { 1188 + hdmi->htop1 = ioremap(htop1_res->start, resource_size(htop1_res)); 1189 + if (!hdmi->htop1) { 1190 + dev_err(&pdev->dev, "control register region already claimed\n"); 1191 + ret = -ENOMEM; 1192 + goto emap_htop1; 1193 + } 1194 + sh_hdmi_htop1_init(hdmi); 1195 + } 1196 + 1357 1197 /* Product and revision IDs are 0 in sh-mobile version */ 1358 1198 dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n", 1359 1199 hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID)); ··· 1395 1199 ecodec: 1396 1200 free_irq(irq, hdmi); 1397 1201 ereqirq: 1202 + if (hdmi->htop1) 1203 + iounmap(hdmi->htop1); 1204 + emap_htop1: 1398 1205 pm_runtime_put(&pdev->dev); 1399 1206 pm_runtime_disable(&pdev->dev); 1400 1207 iounmap(hdmi->base); ··· 1429 1230 pm_runtime_disable(&pdev->dev); 1430 1231 clk_disable(hdmi->hdmi_clk); 1431 1232 clk_put(hdmi->hdmi_clk); 1233 + if (hdmi->htop1) 1234 + iounmap(hdmi->htop1); 1432 1235 iounmap(hdmi->base); 1433 1236 release_mem_region(res->start, resource_size(res)); 1434 1237 kfree(hdmi);
-45
drivers/video/sis/init.h
··· 105 105 static const unsigned short ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00}; 106 106 static const unsigned short ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e}; 107 107 108 - static const unsigned short SiS_DRAMType[17][5]={ 109 - {0x0C,0x0A,0x02,0x40,0x39}, 110 - {0x0D,0x0A,0x01,0x40,0x48}, 111 - {0x0C,0x09,0x02,0x20,0x35}, 112 - {0x0D,0x09,0x01,0x20,0x44}, 113 - {0x0C,0x08,0x02,0x10,0x31}, 114 - {0x0D,0x08,0x01,0x10,0x40}, 115 - {0x0C,0x0A,0x01,0x20,0x34}, 116 - {0x0C,0x09,0x01,0x08,0x32}, 117 - {0x0B,0x08,0x02,0x08,0x21}, 118 - {0x0C,0x08,0x01,0x08,0x30}, 119 - {0x0A,0x08,0x02,0x04,0x11}, 120 - {0x0B,0x0A,0x01,0x10,0x28}, 121 - {0x09,0x08,0x02,0x02,0x01}, 122 - {0x0B,0x09,0x01,0x08,0x24}, 123 - {0x0B,0x08,0x01,0x04,0x20}, 124 - {0x0A,0x08,0x01,0x02,0x10}, 125 - {0x09,0x08,0x01,0x01,0x00} 126 - }; 127 - 128 - static const unsigned short SiS_SDRDRAM_TYPE[13][5] = 129 - { 130 - { 2,12, 9,64,0x35}, 131 - { 1,13, 9,64,0x44}, 132 - { 2,12, 8,32,0x31}, 133 - { 2,11, 9,32,0x25}, 134 - { 1,12, 9,32,0x34}, 135 - { 1,13, 8,32,0x40}, 136 - { 2,11, 8,16,0x21}, 137 - { 1,12, 8,16,0x30}, 138 - { 1,11, 9,16,0x24}, 139 - { 1,11, 8, 8,0x20}, 140 - { 2, 9, 8, 4,0x01}, 141 - { 1,10, 8, 4,0x10}, 142 - { 1, 9, 8, 2,0x00} 143 - }; 144 - 145 - static const unsigned short SiS_DDRDRAM_TYPE[4][5] = 146 - { 147 - { 2,12, 9,64,0x35}, 148 - { 2,12, 8,32,0x31}, 149 - { 2,11, 8,16,0x21}, 150 - { 2, 9, 8, 4,0x01} 151 - }; 152 - 153 108 static const unsigned char SiS_MDA_DAC[] = 154 109 { 155 110 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+21 -20
drivers/video/sis/sis_main.c
··· 4222 4222 return 1; /* 32bit */ 4223 4223 } 4224 4224 4225 + static const unsigned short __devinitconst SiS_DRAMType[17][5] = { 4226 + {0x0C,0x0A,0x02,0x40,0x39}, 4227 + {0x0D,0x0A,0x01,0x40,0x48}, 4228 + {0x0C,0x09,0x02,0x20,0x35}, 4229 + {0x0D,0x09,0x01,0x20,0x44}, 4230 + {0x0C,0x08,0x02,0x10,0x31}, 4231 + {0x0D,0x08,0x01,0x10,0x40}, 4232 + {0x0C,0x0A,0x01,0x20,0x34}, 4233 + {0x0C,0x09,0x01,0x08,0x32}, 4234 + {0x0B,0x08,0x02,0x08,0x21}, 4235 + {0x0C,0x08,0x01,0x08,0x30}, 4236 + {0x0A,0x08,0x02,0x04,0x11}, 4237 + {0x0B,0x0A,0x01,0x10,0x28}, 4238 + {0x09,0x08,0x02,0x02,0x01}, 4239 + {0x0B,0x09,0x01,0x08,0x24}, 4240 + {0x0B,0x08,0x01,0x04,0x20}, 4241 + {0x0A,0x08,0x01,0x02,0x10}, 4242 + {0x09,0x08,0x01,0x01,0x00} 4243 + }; 4244 + 4225 4245 static int __devinit 4226 4246 sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth, 4227 4247 int PseudoRankCapacity, int PseudoAdrPinCount, ··· 4251 4231 unsigned short sr14; 4252 4232 unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid; 4253 4233 unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage; 4254 - static const unsigned short SiS_DRAMType[17][5] = { 4255 - {0x0C,0x0A,0x02,0x40,0x39}, 4256 - {0x0D,0x0A,0x01,0x40,0x48}, 4257 - {0x0C,0x09,0x02,0x20,0x35}, 4258 - {0x0D,0x09,0x01,0x20,0x44}, 4259 - {0x0C,0x08,0x02,0x10,0x31}, 4260 - {0x0D,0x08,0x01,0x10,0x40}, 4261 - {0x0C,0x0A,0x01,0x20,0x34}, 4262 - {0x0C,0x09,0x01,0x08,0x32}, 4263 - {0x0B,0x08,0x02,0x08,0x21}, 4264 - {0x0C,0x08,0x01,0x08,0x30}, 4265 - {0x0A,0x08,0x02,0x04,0x11}, 4266 - {0x0B,0x0A,0x01,0x10,0x28}, 4267 - {0x09,0x08,0x02,0x02,0x01}, 4268 - {0x0B,0x09,0x01,0x08,0x24}, 4269 - {0x0B,0x08,0x01,0x04,0x20}, 4270 - {0x0A,0x08,0x01,0x02,0x10}, 4271 - {0x09,0x08,0x01,0x01,0x00} 4272 - }; 4273 4234 4274 - for(k = 0; k <= 16; k++) { 4235 + for(k = 0; k < ARRAY_SIZE(SiS_DRAMType); k++) { 4275 4236 4276 4237 RankCapacity = buswidth * SiS_DRAMType[k][3]; 4277 4238
+1 -1
drivers/video/skeletonfb.c
··· 1036 1036 */ 1037 1037 1038 1038 module_init(xxxfb_init); 1039 - module_exit(xxxfb_remove); 1039 + module_exit(xxxfb_exit); 1040 1040 1041 1041 MODULE_LICENSE("GPL");
+2 -2
drivers/video/smscufx.c
··· 846 846 } 847 847 } 848 848 849 - int ufx_handle_damage(struct ufx_data *dev, int x, int y, 849 + static int ufx_handle_damage(struct ufx_data *dev, int x, int y, 850 850 int width, int height) 851 851 { 852 852 size_t packed_line_len = ALIGN((width * 2), 4); ··· 1083 1083 1084 1084 struct fb_deferred_io *fbdefio; 1085 1085 1086 - fbdefio = kmalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); 1086 + fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); 1087 1087 1088 1088 if (fbdefio) { 1089 1089 fbdefio->delay = UFX_DEFIO_WRITE_DELAY;
+1 -1
drivers/video/udlfb.c
··· 893 893 894 894 struct fb_deferred_io *fbdefio; 895 895 896 - fbdefio = kmalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); 896 + fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); 897 897 898 898 if (fbdefio) { 899 899 fbdefio->delay = DL_DEFIO_WRITE_DELAY;
+12 -22
drivers/video/via/viafbdev.c
··· 1276 1276 static ssize_t viafb_dfph_proc_write(struct file *file, 1277 1277 const char __user *buffer, size_t count, loff_t *pos) 1278 1278 { 1279 - char buf[20]; 1280 - u8 reg_val = 0; 1281 - unsigned long length; 1282 - if (count < 1) 1283 - return -EINVAL; 1284 - length = count > 20 ? 20 : count; 1285 - if (copy_from_user(&buf[0], buffer, length)) 1286 - return -EFAULT; 1287 - buf[length - 1] = '\0'; /*Ensure end string */ 1288 - if (kstrtou8(buf, 0, &reg_val) < 0) 1289 - return -EINVAL; 1279 + int err; 1280 + u8 reg_val; 1281 + err = kstrtou8_from_user(buffer, count, 0, &reg_val); 1282 + if (err) 1283 + return err; 1284 + 1290 1285 viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f); 1291 1286 return count; 1292 1287 } ··· 1311 1316 static ssize_t viafb_dfpl_proc_write(struct file *file, 1312 1317 const char __user *buffer, size_t count, loff_t *pos) 1313 1318 { 1314 - char buf[20]; 1315 - u8 reg_val = 0; 1316 - unsigned long length; 1317 - if (count < 1) 1318 - return -EINVAL; 1319 - length = count > 20 ? 20 : count; 1320 - if (copy_from_user(&buf[0], buffer, length)) 1321 - return -EFAULT; 1322 - buf[length - 1] = '\0'; /*Ensure end string */ 1323 - if (kstrtou8(buf, 0, &reg_val) < 0) 1324 - return -EINVAL; 1319 + int err; 1320 + u8 reg_val; 1321 + err = kstrtou8_from_user(buffer, count, 0, &reg_val); 1322 + if (err) 1323 + return err; 1324 + 1325 1325 viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f); 1326 1326 return count; 1327 1327 }
+1
include/linux/fb.h
··· 611 611 struct mutex lock; /* mutex that protects the page list */ 612 612 struct list_head pagelist; /* list of touched pages */ 613 613 /* callback */ 614 + void (*first_io)(struct fb_info *info); 614 615 void (*deferred_io)(struct fb_info *info, struct list_head *pagelist); 615 616 }; 616 617 #endif
+106
include/video/auo_k190xfb.h
··· 1 + /* 2 + * Definitions for AUO-K190X framebuffer drivers 3 + * 4 + * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #ifndef _LINUX_VIDEO_AUO_K190XFB_H_ 12 + #define _LINUX_VIDEO_AUO_K190XFB_H_ 13 + 14 + /* Controller standby command needs a param */ 15 + #define AUOK190X_QUIRK_STANDBYPARAM (1 << 0) 16 + 17 + /* Controller standby is completely broken */ 18 + #define AUOK190X_QUIRK_STANDBYBROKEN (1 << 1) 19 + 20 + /* 21 + * Resolutions for the displays 22 + */ 23 + #define AUOK190X_RESOLUTION_800_600 0 24 + #define AUOK190X_RESOLUTION_1024_768 1 25 + 26 + /* 27 + * struct used by auok190x. board specific stuff comes from *board 28 + */ 29 + struct auok190xfb_par { 30 + struct fb_info *info; 31 + struct auok190x_board *board; 32 + 33 + struct regulator *regulator; 34 + 35 + struct mutex io_lock; 36 + struct delayed_work work; 37 + wait_queue_head_t waitq; 38 + int resolution; 39 + int rotation; 40 + int consecutive_threshold; 41 + int update_cnt; 42 + 43 + /* panel and controller informations */ 44 + int epd_type; 45 + int panel_size_int; 46 + int panel_size_float; 47 + int panel_model; 48 + int tcon_version; 49 + int lut_version; 50 + 51 + /* individual controller callbacks */ 52 + void (*update_partial)(struct auok190xfb_par *par, u16 y1, u16 y2); 53 + void (*update_all)(struct auok190xfb_par *par); 54 + bool (*need_refresh)(struct auok190xfb_par *par); 55 + void (*init)(struct auok190xfb_par *par); 56 + void (*recover)(struct auok190xfb_par *par); 57 + 58 + int update_mode; /* mode to use for updates */ 59 + int last_mode; /* update mode last used */ 60 + int flash; 61 + 62 + /* power management */ 63 + int autosuspend_delay; 64 + bool standby; 65 + bool manual_standby; 66 + }; 67 + 68 + /** 69 + * Board specific platform-data 70 + * @init: initialize the controller interface 71 + * @cleanup: cleanup the controller interface 72 + * @wait_for_rdy: wait until the controller is not busy anymore 73 + * @set_ctl: change an interface control 74 + * @set_hdb: write a value to the data register 75 + * @get_hdb: read a value from the data register 76 + * @setup_irq: method to setup the irq handling on the busy gpio 77 + * @gpio_nsleep: sleep gpio 78 + * @gpio_nrst: reset gpio 79 + * @gpio_nbusy: busy gpio 80 + * @resolution: one of the AUOK190X_RESOLUTION constants 81 + * @rotation: rotation of the framebuffer 82 + * @quirks: controller quirks to honor 83 + * @fps: frames per second for defio 84 + */ 85 + struct auok190x_board { 86 + int (*init)(struct auok190xfb_par *); 87 + void (*cleanup)(struct auok190xfb_par *); 88 + int (*wait_for_rdy)(struct auok190xfb_par *); 89 + 90 + void (*set_ctl)(struct auok190xfb_par *, unsigned char, u8); 91 + void (*set_hdb)(struct auok190xfb_par *, u16); 92 + u16 (*get_hdb)(struct auok190xfb_par *); 93 + 94 + int (*setup_irq)(struct fb_info *); 95 + 96 + int gpio_nsleep; 97 + int gpio_nrst; 98 + int gpio_nbusy; 99 + 100 + int resolution; 101 + int rotation; 102 + int quirks; 103 + int fps; 104 + }; 105 + 106 + #endif
+1 -1
include/video/exynos_dp.h
··· 14 14 15 15 #define DP_TIMEOUT_LOOP_COUNT 100 16 16 #define MAX_CR_LOOP 5 17 - #define MAX_EQ_LOOP 4 17 + #define MAX_EQ_LOOP 5 18 18 19 19 enum link_rate_type { 20 20 LINK_RATE_1_62GBPS = 0x06,
+1
include/video/exynos_mipi_dsim.h
··· 315 315 int id; 316 316 int bus_id; 317 317 int irq; 318 + int panel_reverse; 318 319 319 320 struct mipi_dsim_device *master; 320 321 void *platform_data;
+40 -7
include/video/omapdss.h
··· 51 51 52 52 struct omap_dss_device; 53 53 struct omap_overlay_manager; 54 + struct snd_aes_iec958; 55 + struct snd_cea_861_aud_if; 54 56 55 57 enum omap_display_type { 56 58 OMAP_DISPLAY_TYPE_NONE = 0, ··· 160 158 OMAP_DSS_DISPLAY_SUSPENDED, 161 159 }; 162 160 161 + enum omap_dss_audio_state { 162 + OMAP_DSS_AUDIO_DISABLED = 0, 163 + OMAP_DSS_AUDIO_ENABLED, 164 + OMAP_DSS_AUDIO_CONFIGURED, 165 + OMAP_DSS_AUDIO_PLAYING, 166 + }; 167 + 163 168 /* XXX perhaps this should be removed */ 164 169 enum omap_dss_overlay_managers { 165 170 OMAP_DSS_OVL_MGR_LCD, ··· 175 166 }; 176 167 177 168 enum omap_dss_rotation_type { 178 - OMAP_DSS_ROT_DMA = 0, 179 - OMAP_DSS_ROT_VRFB = 1, 169 + OMAP_DSS_ROT_DMA = 1 << 0, 170 + OMAP_DSS_ROT_VRFB = 1 << 1, 171 + OMAP_DSS_ROT_TILER = 1 << 2, 180 172 }; 181 173 182 174 /* clockwise rotation angle */ ··· 319 309 struct omap_dss_device *default_device; 320 310 int (*dsi_enable_pads)(int dsi_id, unsigned lane_mask); 321 311 void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask); 312 + int (*set_min_bus_tput)(struct device *dev, unsigned long r); 322 313 }; 323 314 324 315 /* Init with the board info */ 325 316 extern int omap_display_init(struct omap_dss_board_info *board_data); 326 317 /* HDMI mux init*/ 327 318 extern int omap_hdmi_init(enum omap_hdmi_flags flags); 328 - 329 - struct omap_display_platform_data { 330 - struct omap_dss_board_info *board_data; 331 - /* TODO: Additional members to be added when PM is considered */ 332 - }; 333 319 334 320 struct omap_video_timings { 335 321 /* Unit: pixels */ ··· 593 587 594 588 enum omap_dss_display_state state; 595 589 590 + enum omap_dss_audio_state audio_state; 591 + 596 592 /* platform specific */ 597 593 int (*platform_enable)(struct omap_dss_device *dssdev); 598 594 void (*platform_disable)(struct omap_dss_device *dssdev); ··· 605 597 struct omap_dss_hdmi_data 606 598 { 607 599 int hpd_gpio; 600 + }; 601 + 602 + struct omap_dss_audio { 603 + struct snd_aes_iec958 *iec; 604 + struct snd_cea_861_aud_if *cea; 608 605 }; 609 606 610 607 struct omap_dss_driver { ··· 659 646 660 647 int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len); 661 648 bool (*detect)(struct omap_dss_device *dssdev); 649 + 650 + /* 651 + * For display drivers that support audio. This encompasses 652 + * HDMI and DisplayPort at the moment. 653 + */ 654 + /* 655 + * Note: These functions might sleep. Do not call while 656 + * holding a spinlock/readlock. 657 + */ 658 + int (*audio_enable)(struct omap_dss_device *dssdev); 659 + void (*audio_disable)(struct omap_dss_device *dssdev); 660 + bool (*audio_supported)(struct omap_dss_device *dssdev); 661 + int (*audio_config)(struct omap_dss_device *dssdev, 662 + struct omap_dss_audio *audio); 663 + /* Note: These functions may not sleep */ 664 + int (*audio_start)(struct omap_dss_device *dssdev); 665 + void (*audio_stop)(struct omap_dss_device *dssdev); 666 + 662 667 }; 663 668 664 669 int omap_dss_register_driver(struct omap_dss_driver *); ··· 701 670 void omapdss_default_get_resolution(struct omap_dss_device *dssdev, 702 671 u16 *xres, u16 *yres); 703 672 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev); 673 + void omapdss_default_get_timings(struct omap_dss_device *dssdev, 674 + struct omap_video_timings *timings); 704 675 705 676 typedef void (*omap_dispc_isr_t) (void *arg, u32 mask); 706 677 int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
+11 -1
include/video/sh_mobile_hdmi.h
··· 18 18 /* 19 19 * flags format 20 20 * 21 - * 0x0000000A 21 + * 0x00000CBA 22 22 * 23 23 * A: Audio source select 24 + * B: Int output option 25 + * C: Chip specific option 24 26 */ 25 27 26 28 /* Audio source select */ ··· 31 29 #define HDMI_SND_SRC_SPDIF (1 << 0) 32 30 #define HDMI_SND_SRC_DSD (2 << 0) 33 31 #define HDMI_SND_SRC_HBR (3 << 0) 32 + 33 + /* Int output option */ 34 + #define HDMI_OUTPUT_PUSH_PULL (1 << 4) /* System control : output mode */ 35 + #define HDMI_OUTPUT_POLARITY_HI (1 << 5) /* System control : output polarity */ 36 + 37 + /* Chip specific option */ 38 + #define HDMI_32BIT_REG (1 << 8) 39 + #define HDMI_HAS_HTOP1 (1 << 9) 34 40 35 41 struct sh_mobile_hdmi_info { 36 42 unsigned int flags;