mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 22:02:28 +00:00
drm/i915: Pixel Clock changes for DSI dual link
For dual link MIPI Panels, each port needs half of pixel clock. Pixel overlap can be enabled if needed by panel, then in that case, pixel clock will be increased for extra pixels. v2 : Address review comments by Jani - Removed the bit mask used for ->dual_link - Used DSI instead of MIPI for #define variables v3: Added the VLV_DISPLAY_BASE to VLV_CHICKEN_3 register Signed-off-by: Gaurav K Singh <gaurav.k.singh@intel.com> Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
369602d370
commit
a9da9bce88
@ -6030,6 +6030,10 @@ enum punit_power_well {
|
|||||||
#define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31)
|
#define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31)
|
||||||
#define VLV_PWRDWNUPCTL 0xA294
|
#define VLV_PWRDWNUPCTL 0xA294
|
||||||
|
|
||||||
|
#define VLV_CHICKEN_3 (VLV_DISPLAY_BASE + 0x7040C)
|
||||||
|
#define PIXEL_OVERLAP_CNT_MASK (3 << 30)
|
||||||
|
#define PIXEL_OVERLAP_CNT_SHIFT 30
|
||||||
|
|
||||||
#define GEN6_PMISR 0x44020
|
#define GEN6_PMISR 0x44020
|
||||||
#define GEN6_PMIMR 0x44024 /* rps_lock */
|
#define GEN6_PMIMR 0x44024 /* rps_lock */
|
||||||
#define GEN6_PMIIR 0x44028
|
#define GEN6_PMIIR 0x44028
|
||||||
|
@ -818,7 +818,8 @@ struct mipi_config {
|
|||||||
#define DUAL_LINK_PIXEL_ALT 2
|
#define DUAL_LINK_PIXEL_ALT 2
|
||||||
u16 dual_link:2;
|
u16 dual_link:2;
|
||||||
u16 lane_cnt:2;
|
u16 lane_cnt:2;
|
||||||
u16 rsvd3:12;
|
u16 pixel_overlap:3;
|
||||||
|
u16 rsvd3:9;
|
||||||
|
|
||||||
u16 rsvd4;
|
u16 rsvd4;
|
||||||
|
|
||||||
|
@ -111,6 +111,14 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder)
|
|||||||
enum port port;
|
enum port port;
|
||||||
u32 temp;
|
u32 temp;
|
||||||
|
|
||||||
|
if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
|
||||||
|
temp = I915_READ(VLV_CHICKEN_3);
|
||||||
|
temp &= ~PIXEL_OVERLAP_CNT_MASK |
|
||||||
|
intel_dsi->pixel_overlap <<
|
||||||
|
PIXEL_OVERLAP_CNT_SHIFT;
|
||||||
|
I915_WRITE(VLV_CHICKEN_3, temp);
|
||||||
|
}
|
||||||
|
|
||||||
for_each_dsi_port(port, intel_dsi->ports) {
|
for_each_dsi_port(port, intel_dsi->ports) {
|
||||||
temp = I915_READ(MIPI_PORT_CTRL(port));
|
temp = I915_READ(MIPI_PORT_CTRL(port));
|
||||||
temp &= ~LANE_CONFIGURATION_MASK;
|
temp &= ~LANE_CONFIGURATION_MASK;
|
||||||
|
@ -28,6 +28,11 @@
|
|||||||
#include <drm/drm_crtc.h>
|
#include <drm/drm_crtc.h>
|
||||||
#include "intel_drv.h"
|
#include "intel_drv.h"
|
||||||
|
|
||||||
|
/* Dual Link support */
|
||||||
|
#define DSI_DUAL_LINK_NONE 0
|
||||||
|
#define DSI_DUAL_LINK_FRONT_BACK 1
|
||||||
|
#define DSI_DUAL_LINK_PIXEL_ALT 2
|
||||||
|
|
||||||
struct intel_dsi_device {
|
struct intel_dsi_device {
|
||||||
unsigned int panel_id;
|
unsigned int panel_id;
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -105,6 +110,7 @@ struct intel_dsi {
|
|||||||
|
|
||||||
u8 escape_clk_div;
|
u8 escape_clk_div;
|
||||||
u8 dual_link;
|
u8 dual_link;
|
||||||
|
u8 pixel_overlap;
|
||||||
u32 port_bits;
|
u32 port_bits;
|
||||||
u32 bw_timer;
|
u32 bw_timer;
|
||||||
u32 dphy_reg;
|
u32 dphy_reg;
|
||||||
|
@ -288,6 +288,7 @@ static bool generic_init(struct intel_dsi_device *dsi)
|
|||||||
intel_dsi->lane_count = mipi_config->lane_cnt + 1;
|
intel_dsi->lane_count = mipi_config->lane_cnt + 1;
|
||||||
intel_dsi->pixel_format = mipi_config->videomode_color_format << 7;
|
intel_dsi->pixel_format = mipi_config->videomode_color_format << 7;
|
||||||
intel_dsi->dual_link = mipi_config->dual_link;
|
intel_dsi->dual_link = mipi_config->dual_link;
|
||||||
|
intel_dsi->pixel_overlap = mipi_config->pixel_overlap;
|
||||||
|
|
||||||
if (intel_dsi->dual_link)
|
if (intel_dsi->dual_link)
|
||||||
intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C));
|
intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C));
|
||||||
@ -310,6 +311,20 @@ static bool generic_init(struct intel_dsi_device *dsi)
|
|||||||
|
|
||||||
pclk = mode->clock;
|
pclk = mode->clock;
|
||||||
|
|
||||||
|
/* In dual link mode each port needs half of pixel clock */
|
||||||
|
if (intel_dsi->dual_link) {
|
||||||
|
pclk = pclk / 2;
|
||||||
|
|
||||||
|
/* we can enable pixel_overlap if needed by panel. In this
|
||||||
|
* case we need to increase the pixelclock for extra pixels
|
||||||
|
*/
|
||||||
|
if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
|
||||||
|
pclk += DIV_ROUND_UP(mode->vtotal *
|
||||||
|
intel_dsi->pixel_overlap *
|
||||||
|
60, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Burst Mode Ratio
|
/* Burst Mode Ratio
|
||||||
* Target ddr frequency from VBT / non burst ddr freq
|
* Target ddr frequency from VBT / non burst ddr freq
|
||||||
* multiply by 100 to preserve remainder
|
* multiply by 100 to preserve remainder
|
||||||
@ -504,6 +519,12 @@ static bool generic_init(struct intel_dsi_device *dsi)
|
|||||||
DRM_DEBUG_KMS("Clockstop %s\n", intel_dsi->clock_stop ?
|
DRM_DEBUG_KMS("Clockstop %s\n", intel_dsi->clock_stop ?
|
||||||
"disabled" : "enabled");
|
"disabled" : "enabled");
|
||||||
DRM_DEBUG_KMS("Mode %s\n", intel_dsi->operation_mode ? "command" : "video");
|
DRM_DEBUG_KMS("Mode %s\n", intel_dsi->operation_mode ? "command" : "video");
|
||||||
|
if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
|
||||||
|
DRM_DEBUG_KMS("Dual link: DSI_DUAL_LINK_FRONT_BACK\n");
|
||||||
|
else if (intel_dsi->dual_link == DSI_DUAL_LINK_PIXEL_ALT)
|
||||||
|
DRM_DEBUG_KMS("Dual link: DSI_DUAL_LINK_PIXEL_ALT\n");
|
||||||
|
else
|
||||||
|
DRM_DEBUG_KMS("Dual link: NONE\n");
|
||||||
DRM_DEBUG_KMS("Pixel Format %d\n", intel_dsi->pixel_format);
|
DRM_DEBUG_KMS("Pixel Format %d\n", intel_dsi->pixel_format);
|
||||||
DRM_DEBUG_KMS("TLPX %d\n", intel_dsi->escape_clk_div);
|
DRM_DEBUG_KMS("TLPX %d\n", intel_dsi->escape_clk_div);
|
||||||
DRM_DEBUG_KMS("LP RX Timeout 0x%x\n", intel_dsi->lp_rx_timeout);
|
DRM_DEBUG_KMS("LP RX Timeout 0x%x\n", intel_dsi->lp_rx_timeout);
|
||||||
|
Loading…
Reference in New Issue
Block a user