.. | .. |
---|
185 | 185 | |
---|
186 | 186 | regmap_write(lt9611->regmap, 0x8319, (u8)(hfront_porch % 256)); |
---|
187 | 187 | |
---|
188 | | - regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256)); |
---|
| 188 | + regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256) | |
---|
| 189 | + ((hfront_porch / 256) << 4)); |
---|
189 | 190 | regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256)); |
---|
190 | 191 | } |
---|
191 | 192 | |
---|
192 | | -static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode) |
---|
| 193 | +static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int postdiv) |
---|
193 | 194 | { |
---|
| 195 | + unsigned int pcr_m = mode->clock * 5 * postdiv / 27000; |
---|
194 | 196 | const struct reg_sequence reg_cfg[] = { |
---|
195 | 197 | { 0x830b, 0x01 }, |
---|
196 | 198 | { 0x830c, 0x10 }, |
---|
.. | .. |
---|
205 | 207 | |
---|
206 | 208 | /* stage 2 */ |
---|
207 | 209 | { 0x834a, 0x40 }, |
---|
208 | | - { 0x831d, 0x10 }, |
---|
209 | 210 | |
---|
210 | 211 | /* MK limit */ |
---|
211 | 212 | { 0x832d, 0x38 }, |
---|
.. | .. |
---|
220 | 221 | { 0x8325, 0x00 }, |
---|
221 | 222 | { 0x832a, 0x01 }, |
---|
222 | 223 | { 0x834a, 0x10 }, |
---|
223 | | - { 0x831d, 0x10 }, |
---|
224 | | - { 0x8326, 0x37 }, |
---|
225 | 224 | }; |
---|
| 225 | + u8 pol = 0x10; |
---|
226 | 226 | |
---|
227 | | - regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg)); |
---|
| 227 | + if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
---|
| 228 | + pol |= 0x2; |
---|
| 229 | + if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
---|
| 230 | + pol |= 0x1; |
---|
| 231 | + regmap_write(lt9611->regmap, 0x831d, pol); |
---|
228 | 232 | |
---|
229 | | - switch (mode->hdisplay) { |
---|
230 | | - case 640: |
---|
231 | | - regmap_write(lt9611->regmap, 0x8326, 0x14); |
---|
232 | | - break; |
---|
233 | | - case 1920: |
---|
234 | | - regmap_write(lt9611->regmap, 0x8326, 0x37); |
---|
235 | | - break; |
---|
236 | | - case 3840: |
---|
| 233 | + if (mode->hdisplay == 3840) |
---|
237 | 234 | regmap_multi_reg_write(lt9611->regmap, reg_cfg2, ARRAY_SIZE(reg_cfg2)); |
---|
238 | | - break; |
---|
239 | | - } |
---|
| 235 | + else |
---|
| 236 | + regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg)); |
---|
| 237 | + |
---|
| 238 | + regmap_write(lt9611->regmap, 0x8326, pcr_m); |
---|
240 | 239 | |
---|
241 | 240 | /* pcr rst */ |
---|
242 | 241 | regmap_write(lt9611->regmap, 0x8011, 0x5a); |
---|
243 | 242 | regmap_write(lt9611->regmap, 0x8011, 0xfa); |
---|
244 | 243 | } |
---|
245 | 244 | |
---|
246 | | -static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode) |
---|
| 245 | +static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int *postdiv) |
---|
247 | 246 | { |
---|
248 | 247 | unsigned int pclk = mode->clock; |
---|
249 | 248 | const struct reg_sequence reg_cfg[] = { |
---|
.. | .. |
---|
257 | 256 | { 0x8126, 0x55 }, |
---|
258 | 257 | { 0x8127, 0x66 }, |
---|
259 | 258 | { 0x8128, 0x88 }, |
---|
| 259 | + { 0x812a, 0x20 }, |
---|
260 | 260 | }; |
---|
261 | 261 | |
---|
262 | 262 | regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg)); |
---|
263 | 263 | |
---|
264 | | - if (pclk > 150000) |
---|
| 264 | + if (pclk > 150000) { |
---|
265 | 265 | regmap_write(lt9611->regmap, 0x812d, 0x88); |
---|
266 | | - else if (pclk > 70000) |
---|
| 266 | + *postdiv = 1; |
---|
| 267 | + } else if (pclk > 70000) { |
---|
267 | 268 | regmap_write(lt9611->regmap, 0x812d, 0x99); |
---|
268 | | - else |
---|
| 269 | + *postdiv = 2; |
---|
| 270 | + } else { |
---|
269 | 271 | regmap_write(lt9611->regmap, 0x812d, 0xaa); |
---|
| 272 | + *postdiv = 4; |
---|
| 273 | + } |
---|
270 | 274 | |
---|
271 | 275 | /* |
---|
272 | 276 | * first divide pclk by 2 first |
---|
.. | .. |
---|
446 | 450 | { 0x8023, 0x01 }, |
---|
447 | 451 | { 0x8157, 0x03 }, /* set addr pin as output */ |
---|
448 | 452 | { 0x8149, 0x0b }, |
---|
449 | | - { 0x8151, 0x30 }, /* disable IRQ */ |
---|
| 453 | + |
---|
450 | 454 | { 0x8102, 0x48 }, /* MIPI Rx power down */ |
---|
451 | 455 | { 0x8123, 0x80 }, |
---|
452 | 456 | { 0x8130, 0x00 }, |
---|
453 | | - { 0x8100, 0x01 }, /* bandgap power down */ |
---|
454 | | - { 0x8101, 0x00 }, /* system clk power down */ |
---|
| 457 | + { 0x8011, 0x0a }, |
---|
455 | 458 | }; |
---|
456 | 459 | |
---|
457 | 460 | regmap_multi_reg_write(lt9611->regmap, |
---|
.. | .. |
---|
757 | 760 | static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611, |
---|
758 | 761 | struct device_node *dsi_node) |
---|
759 | 762 | { |
---|
760 | | - const struct mipi_dsi_device_info info = { "lt9611", 0, NULL }; |
---|
| 763 | + const struct mipi_dsi_device_info info = { "lt9611", 0, lt9611->dev->of_node}; |
---|
761 | 764 | struct mipi_dsi_device *dsi; |
---|
762 | 765 | struct mipi_dsi_host *host; |
---|
763 | 766 | int ret; |
---|
.. | .. |
---|
881 | 884 | static void lt9611_bridge_pre_enable(struct drm_bridge *bridge) |
---|
882 | 885 | { |
---|
883 | 886 | struct lt9611 *lt9611 = bridge_to_lt9611(bridge); |
---|
| 887 | + static const struct reg_sequence reg_cfg[] = { |
---|
| 888 | + { 0x8102, 0x12 }, |
---|
| 889 | + { 0x8123, 0x40 }, |
---|
| 890 | + { 0x8130, 0xea }, |
---|
| 891 | + { 0x8011, 0xfa }, |
---|
| 892 | + }; |
---|
884 | 893 | |
---|
885 | 894 | if (!lt9611->sleep) |
---|
886 | 895 | return; |
---|
887 | 896 | |
---|
888 | | - lt9611_reset(lt9611); |
---|
889 | | - regmap_write(lt9611->regmap, 0x80ee, 0x01); |
---|
| 897 | + regmap_multi_reg_write(lt9611->regmap, |
---|
| 898 | + reg_cfg, ARRAY_SIZE(reg_cfg)); |
---|
890 | 899 | |
---|
891 | 900 | lt9611->sleep = false; |
---|
892 | 901 | } |
---|
.. | .. |
---|
904 | 913 | { |
---|
905 | 914 | struct lt9611 *lt9611 = bridge_to_lt9611(bridge); |
---|
906 | 915 | struct hdmi_avi_infoframe avi_frame; |
---|
| 916 | + unsigned int postdiv; |
---|
907 | 917 | int ret; |
---|
908 | 918 | |
---|
909 | 919 | lt9611_bridge_pre_enable(bridge); |
---|
910 | 920 | |
---|
911 | 921 | lt9611_mipi_input_digital(lt9611, mode); |
---|
912 | | - lt9611_pll_setup(lt9611, mode); |
---|
| 922 | + lt9611_pll_setup(lt9611, mode, &postdiv); |
---|
913 | 923 | lt9611_mipi_video_setup(lt9611, mode); |
---|
914 | | - lt9611_pcr_setup(lt9611, mode); |
---|
| 924 | + lt9611_pcr_setup(lt9611, mode, postdiv); |
---|
915 | 925 | |
---|
916 | 926 | ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, |
---|
917 | 927 | <9611->connector, |
---|