mirror of https://gitee.com/openkylin/linux.git
drm fixes for 5.10-rc2
docs: - kernel doc fixes core: - fix shmem helpers dma-buf mmap bug amdgpu: - Add new navi1x PCI ID - GPUVM reserved area fixes - Misc display fixes - Fix bad interactions between display code and CONFIG_KGDB - Fixes for SMU manual fan control and i2c nouveau: - endian regression fix for old gpus - buffer object refcount fix - uapi start/end alignment fix - display notifier fix - display clock checking fixes i915: - Fix max memory region size calculation - Restore ILK-M RPS support, restoring performance - Reject 90/270 degreerotated initial fbs panel: - mantix reset fixes sun4i: - scalar fix vc4: - hdmi audio fixes v3d: - fix double free -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJfm3NLAAoJEAx081l5xIa+9nAP/Rf+N8BXp/xzL2DaxqZmgcMs NokAFcphG8rh+ub04g3QPCgEQlWLydD8vS7WGAmIGPn3eCcio6Lv7TiWDQbFq3f+ 504RlpoIiHp6dC4pZi1LXeXSSi/JfbnHsysXEe89kJ0tjPrj7zg16EDOyW5VCEA9 OnUIM75d0a26xLXOpJQtKWwls/6zMvdNB67yyiT+SNCyAYq3F/j2vTZRTUaA8Dxc XpcZajPdi4kQATqrTM35ja7pA15meJSwC6c/3QBWVtOaFMFO2mj6FYrs5Zp7H7/y guBEEs8Ga5FIe/Hj05s+KgSSXcqiZXrcBopUwYgjDOpBkY9E1eOLAZalBEcU5kRx gt7emX3BIDC7MZ0vNTHULHI5t22KqqXqSk/kPvK3da6h6h7ZQjSERfjthiThmUFH 9cS6dCdzfatoU+dpaHvkU82J326geh5UdvspNYjkZjJVYK28zCH2S/jx01yP9vgX eKS3PZ44NOGHtB9H2UXeTRL44RmFp7D+fn38499f+nyy1WaJt7dEG4s3toBGnB8N egWnBsbYU+sISNtdSrlZqABA/+Ds5IEXZ2gO8F/dzw3BckGJX6Hrfmnfa2m2y4Wo 1aJa8DG0NinbBkGIEJEPvb1KXf5VdGhpXoD9t8xyA0NmKmaHwi6S16gy8rEsw/5E IAp6QFxfTHunAOs3PM+O =/nSY -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2020-10-30-1' of git://anongit.freedesktop.org/drm/drm Pull drm fixes from Dave Airlie: "A busier rc2 than normal, have larger sets of fixes for amdgpu + nouveau, along with some i915, docs, core, panel, sun4i, v3d, vc4 fixes. Nothing spooky though or pumpkin related. docs: - kernel doc fixes core: - fix shmem helpers dma-buf mmap bug amdgpu: - Add new navi1x PCI ID - GPUVM reserved area fixes - Misc display fixes - Fix bad interactions between display code and CONFIG_KGDB - Fixes for SMU manual fan control and i2c nouveau: - endian regression fix for old gpus - buffer object refcount fix - uapi start/end alignment fix - display notifier fix - display clock checking fixes i915: - Fix max memory region size calculation - Restore ILK-M RPS support, restoring performance - Reject 90/270 degreerotated initial fbs panel: - mantix reset fixes sun4i: - scalar fix vc4: - hdmi audio fixes v3d: - fix double free" * tag 'drm-fixes-2020-10-30-1' of git://anongit.freedesktop.org/drm/drm: (42 commits) drm/nouveau/kms/nv50-: Fix clock checking algorithm in nv50_dp_mode_valid() drm/nouveau/kms/nv50-: Get rid of bogus nouveau_conn_mode_valid() drm/nouveau/device: fix changing endianess code to work on older GPUs drm/nouveau/gem: fix "refcount_t: underflow; use-after-free" drm/nouveau/kms/nv50-: Program notifier offset before requesting disp caps drm/nouveau/nouveau: fix the start/end range for migration drm/i915: Reject 90/270 degree rotated initial fbs drm/i915: Restore ILK-M RPS support drm/i915/region: fix max size calculation drm/vc4: Rework the structure conversion functions drm/vc4: hdmi: Add a name to the codec DAI component drm/shme-helpers: Fix dma_buf_mmap forwarding bug drm/vc4: hdmi: Avoid sleeping in atomic context drm/amdgpu/pm: fix the fan speed in fan1_input in manual mode for navi1x drm/amd/pm: fix the wrong fan speed in fan1_input drm/amdgpu/swsmu: drop smu i2c bus on navi1x drm/vc4: drv: Add error handding for bind drm: drm_print.h: fix kernel-doc markups drm: kernel-doc: drm_dp_helper.h: fix a typo drm: kernel-doc: add description for a new function parameter ...
This commit is contained in:
commit
7ba4d86750
|
@ -37,6 +37,9 @@ properties:
|
|||
|
||||
reset-gpios: true
|
||||
|
||||
'mantix,tp-rstn-gpios':
|
||||
description: second reset line that triggers DSI config load
|
||||
|
||||
backlight: true
|
||||
|
||||
required:
|
||||
|
@ -63,6 +66,7 @@ examples:
|
|||
avee-supply = <®_avee>;
|
||||
vddi-supply = <®_1v8_p>;
|
||||
reset-gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
|
||||
mantix,tp-rstn-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
|
||||
backlight = <&backlight>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1066,6 +1066,7 @@ static const struct pci_device_id pciidlist[] = {
|
|||
{0x1002, 0x7319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
{0x1002, 0x731A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
{0x1002, 0x731B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
{0x1002, 0x731E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
{0x1002, 0x731F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
/* Navi14 */
|
||||
{0x1002, 0x7340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14},
|
||||
|
|
|
@ -596,6 +596,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
|||
struct ww_acquire_ctx ticket;
|
||||
struct list_head list, duplicates;
|
||||
uint64_t va_flags;
|
||||
uint64_t vm_size;
|
||||
int r = 0;
|
||||
|
||||
if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {
|
||||
|
@ -616,6 +617,15 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
args->va_address &= AMDGPU_GMC_HOLE_MASK;
|
||||
|
||||
vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
|
||||
vm_size -= AMDGPU_VA_RESERVED_SIZE;
|
||||
if (args->va_address + args->map_size > vm_size) {
|
||||
dev_dbg(&dev->pdev->dev,
|
||||
"va_address 0x%llx is in top reserved area 0x%llx\n",
|
||||
args->va_address + args->map_size, vm_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) {
|
||||
dev_dbg(&dev->pdev->dev, "invalid flags combination 0x%08X\n",
|
||||
args->flags);
|
||||
|
|
|
@ -112,8 +112,8 @@ struct amdgpu_bo_list_entry;
|
|||
#define AMDGPU_MMHUB_0 1
|
||||
#define AMDGPU_MMHUB_1 2
|
||||
|
||||
/* hardcode that limit for now */
|
||||
#define AMDGPU_VA_RESERVED_SIZE (1ULL << 20)
|
||||
/* Reserve 2MB at top/bottom of address space for kernel use */
|
||||
#define AMDGPU_VA_RESERVED_SIZE (2ULL << 20)
|
||||
|
||||
/* max vmids dedicated for process */
|
||||
#define AMDGPU_VM_MAX_RESERVED_VMID 1
|
||||
|
|
|
@ -455,6 +455,14 @@ void nv_set_virt_ops(struct amdgpu_device *adev)
|
|||
adev->virt.ops = &xgpu_nv_virt_ops;
|
||||
}
|
||||
|
||||
static bool nv_is_blockchain_sku(struct pci_dev *pdev)
|
||||
{
|
||||
if (pdev->device == 0x731E &&
|
||||
(pdev->revision == 0xC6 || pdev->revision == 0xC7))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int nv_set_ip_blocks(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
@ -483,7 +491,8 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
else if (amdgpu_device_has_dc_support(adev) &&
|
||||
!nv_is_blockchain_sku(adev->pdev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
|
@ -491,7 +500,8 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
|
||||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
if (!nv_is_blockchain_sku(adev->pdev))
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block);
|
||||
if (adev->enable_mes)
|
||||
amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block);
|
||||
|
|
|
@ -42,6 +42,7 @@ config DRM_AMD_DC_SI
|
|||
config DEBUG_KERNEL_DC
|
||||
bool "Enable kgdb break in DC"
|
||||
depends on DRM_AMD_DC
|
||||
depends on KGDB
|
||||
help
|
||||
Choose this option if you want to hit kdgb_break in assert.
|
||||
|
||||
|
|
|
@ -1571,8 +1571,8 @@ static void init_state(struct dc *dc, struct dc_state *context)
|
|||
|
||||
struct dc_state *dc_create_state(struct dc *dc)
|
||||
{
|
||||
struct dc_state *context = kzalloc(sizeof(struct dc_state),
|
||||
GFP_KERNEL);
|
||||
struct dc_state *context = kvzalloc(sizeof(struct dc_state),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!context)
|
||||
return NULL;
|
||||
|
|
|
@ -1149,7 +1149,8 @@ static uint32_t dcn3_get_pix_clk_dividers(
|
|||
static const struct clock_source_funcs dcn3_clk_src_funcs = {
|
||||
.cs_power_down = dce110_clock_source_power_down,
|
||||
.program_pix_clk = dcn3_program_pix_clk,
|
||||
.get_pix_clk_dividers = dcn3_get_pix_clk_dividers
|
||||
.get_pix_clk_dividers = dcn3_get_pix_clk_dividers,
|
||||
.get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz
|
||||
};
|
||||
#endif
|
||||
/*****************************************/
|
||||
|
|
|
@ -2105,12 +2105,12 @@ static bool dcn30_internal_validate_bw(
|
|||
|
||||
if (split[i]) {
|
||||
if (odm) {
|
||||
if (split[i] == 4 && old_pipe->next_odm_pipe->next_odm_pipe)
|
||||
if (split[i] == 4 && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe)
|
||||
old_index = old_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
|
||||
else if (old_pipe->next_odm_pipe)
|
||||
old_index = old_pipe->next_odm_pipe->pipe_idx;
|
||||
} else {
|
||||
if (split[i] == 4 && old_pipe->bottom_pipe->bottom_pipe &&
|
||||
if (split[i] == 4 && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe &&
|
||||
old_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
|
||||
old_index = old_pipe->bottom_pipe->bottom_pipe->pipe_idx;
|
||||
else if (old_pipe->bottom_pipe &&
|
||||
|
@ -2150,10 +2150,12 @@ static bool dcn30_internal_validate_bw(
|
|||
goto validate_fail;
|
||||
newly_split[pipe_4to1->pipe_idx] = true;
|
||||
|
||||
if (odm && old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe)
|
||||
if (odm && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe
|
||||
&& old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe)
|
||||
old_index = old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
|
||||
else if (!odm && old_pipe->bottom_pipe->bottom_pipe->bottom_pipe &&
|
||||
old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
|
||||
else if (!odm && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe &&
|
||||
old_pipe->bottom_pipe->bottom_pipe->bottom_pipe &&
|
||||
old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
|
||||
old_index = old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->pipe_idx;
|
||||
else
|
||||
old_index = -1;
|
||||
|
|
|
@ -117,6 +117,12 @@ static const struct ddc_registers ddc_data_regs_dcn[] = {
|
|||
ddc_data_regs_dcn2(4),
|
||||
ddc_data_regs_dcn2(5),
|
||||
ddc_data_regs_dcn2(6),
|
||||
{
|
||||
DDC_GPIO_VGA_REG_LIST(DATA),
|
||||
.ddc_setup = 0,
|
||||
.phy_aux_cntl = 0,
|
||||
.dc_gpio_aux_ctrl_5 = 0
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ddc_registers ddc_clk_regs_dcn[] = {
|
||||
|
@ -126,6 +132,12 @@ static const struct ddc_registers ddc_clk_regs_dcn[] = {
|
|||
ddc_clk_regs_dcn2(4),
|
||||
ddc_clk_regs_dcn2(5),
|
||||
ddc_clk_regs_dcn2(6),
|
||||
{
|
||||
DDC_GPIO_VGA_REG_LIST(CLK),
|
||||
.ddc_setup = 0,
|
||||
.phy_aux_cntl = 0,
|
||||
.dc_gpio_aux_ctrl_5 = 0
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ddc_sh_mask ddc_shift[] = {
|
||||
|
|
|
@ -63,13 +63,13 @@ enum gpio_result dal_gpio_open_ex(
|
|||
enum gpio_mode mode)
|
||||
{
|
||||
if (gpio->pin) {
|
||||
ASSERT_CRITICAL(false);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return GPIO_RESULT_ALREADY_OPENED;
|
||||
}
|
||||
|
||||
// No action if allocation failed during gpio construct
|
||||
if (!gpio->hw_container.ddc) {
|
||||
ASSERT_CRITICAL(false);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return GPIO_RESULT_NON_SPECIFIC_ERROR;
|
||||
}
|
||||
gpio->mode = mode;
|
||||
|
|
|
@ -94,36 +94,27 @@
|
|||
* general debug capabilities
|
||||
*
|
||||
*/
|
||||
#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
|
||||
#define ASSERT_CRITICAL(expr) do { \
|
||||
if (WARN_ON(!(expr))) { \
|
||||
kgdb_breakpoint(); \
|
||||
} \
|
||||
} while (0)
|
||||
#ifdef CONFIG_DEBUG_KERNEL_DC
|
||||
#define dc_breakpoint() kgdb_breakpoint()
|
||||
#else
|
||||
#define ASSERT_CRITICAL(expr) do { \
|
||||
if (WARN_ON(!(expr))) { \
|
||||
; \
|
||||
} \
|
||||
} while (0)
|
||||
#define dc_breakpoint() do {} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DEBUG_KERNEL_DC)
|
||||
#define ASSERT(expr) ASSERT_CRITICAL(expr)
|
||||
#define ASSERT_CRITICAL(expr) do { \
|
||||
if (WARN_ON(!(expr))) \
|
||||
dc_breakpoint(); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define ASSERT(expr) WARN_ON_ONCE(!(expr))
|
||||
#endif
|
||||
#define ASSERT(expr) do { \
|
||||
if (WARN_ON_ONCE(!(expr))) \
|
||||
dc_breakpoint(); \
|
||||
} while (0)
|
||||
|
||||
#if defined(CONFIG_DEBUG_KERNEL_DC) && (defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB))
|
||||
#define BREAK_TO_DEBUGGER() \
|
||||
do { \
|
||||
DRM_DEBUG_DRIVER("%s():%d\n", __func__, __LINE__); \
|
||||
kgdb_breakpoint(); \
|
||||
dc_breakpoint(); \
|
||||
} while (0)
|
||||
#else
|
||||
#define BREAK_TO_DEBUGGER() DRM_DEBUG_DRIVER("%s():%d\n", __func__, __LINE__)
|
||||
#endif
|
||||
|
||||
#define DC_ERR(...) do { \
|
||||
dm_error(__VA_ARGS__); \
|
||||
|
|
|
@ -1361,14 +1361,9 @@ static int navi10_get_fan_speed_rpm(struct smu_context *smu,
|
|||
if (!speed)
|
||||
return -EINVAL;
|
||||
|
||||
switch (smu_v11_0_get_fan_control_mode(smu)) {
|
||||
case AMD_FAN_CTRL_AUTO:
|
||||
return navi10_get_smu_metrics_data(smu,
|
||||
METRICS_CURR_FANSPEED,
|
||||
speed);
|
||||
default:
|
||||
return smu_v11_0_get_fan_speed_rpm(smu, speed);
|
||||
}
|
||||
return navi10_get_smu_metrics_data(smu,
|
||||
METRICS_CURR_FANSPEED,
|
||||
speed);
|
||||
}
|
||||
|
||||
static int navi10_get_fan_parameters(struct smu_context *smu)
|
||||
|
@ -2534,29 +2529,6 @@ static const struct i2c_algorithm navi10_i2c_algo = {
|
|||
.functionality = navi10_i2c_func,
|
||||
};
|
||||
|
||||
static int navi10_i2c_control_init(struct smu_context *smu, struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
int res;
|
||||
|
||||
control->owner = THIS_MODULE;
|
||||
control->class = I2C_CLASS_SPD;
|
||||
control->dev.parent = &adev->pdev->dev;
|
||||
control->algo = &navi10_i2c_algo;
|
||||
snprintf(control->name, sizeof(control->name), "AMDGPU SMU");
|
||||
|
||||
res = i2c_add_adapter(control);
|
||||
if (res)
|
||||
DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void navi10_i2c_control_fini(struct smu_context *smu, struct i2c_adapter *control)
|
||||
{
|
||||
i2c_del_adapter(control);
|
||||
}
|
||||
|
||||
static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
|
||||
void **table)
|
||||
{
|
||||
|
@ -2687,8 +2659,6 @@ static const struct pptable_funcs navi10_ppt_funcs = {
|
|||
.set_default_dpm_table = navi10_set_default_dpm_table,
|
||||
.dpm_set_vcn_enable = navi10_dpm_set_vcn_enable,
|
||||
.dpm_set_jpeg_enable = navi10_dpm_set_jpeg_enable,
|
||||
.i2c_init = navi10_i2c_control_init,
|
||||
.i2c_fini = navi10_i2c_control_fini,
|
||||
.print_clk_levels = navi10_print_clk_levels,
|
||||
.force_clk_levels = navi10_force_clk_levels,
|
||||
.populate_umd_state_clk = navi10_populate_umd_state_clk,
|
||||
|
|
|
@ -1177,14 +1177,9 @@ static int sienna_cichlid_get_fan_speed_rpm(struct smu_context *smu,
|
|||
if (!speed)
|
||||
return -EINVAL;
|
||||
|
||||
switch (smu_v11_0_get_fan_control_mode(smu)) {
|
||||
case AMD_FAN_CTRL_AUTO:
|
||||
return sienna_cichlid_get_smu_metrics_data(smu,
|
||||
METRICS_CURR_FANSPEED,
|
||||
speed);
|
||||
default:
|
||||
return smu_v11_0_get_fan_speed_rpm(smu, speed);
|
||||
}
|
||||
return sienna_cichlid_get_smu_metrics_data(smu,
|
||||
METRICS_CURR_FANSPEED,
|
||||
speed);
|
||||
}
|
||||
|
||||
static int sienna_cichlid_get_fan_parameters(struct smu_context *smu)
|
||||
|
|
|
@ -374,6 +374,10 @@ static bool is_edid_digital_input_dp(const struct edid *edid)
|
|||
* drm_dp_downstream_is_type() - is the downstream facing port of certain type?
|
||||
* @dpcd: DisplayPort configuration data
|
||||
* @port_cap: port capabilities
|
||||
* @type: port type to be checked. Can be:
|
||||
* %DP_DS_PORT_TYPE_DP, %DP_DS_PORT_TYPE_VGA, %DP_DS_PORT_TYPE_DVI,
|
||||
* %DP_DS_PORT_TYPE_HDMI, %DP_DS_PORT_TYPE_NON_EDID,
|
||||
* %DP_DS_PORT_TYPE_DP_DUALMODE or %DP_DS_PORT_TYPE_WIRELESS.
|
||||
*
|
||||
* Caveat: Only works with DPCD 1.1+ port caps.
|
||||
*
|
||||
|
@ -870,6 +874,7 @@ EXPORT_SYMBOL(drm_dp_downstream_444_to_420_conversion);
|
|||
|
||||
/**
|
||||
* drm_dp_downstream_mode() - return a mode for downstream facing port
|
||||
* @dev: DRM device
|
||||
* @dpcd: DisplayPort configuration data
|
||||
* @port_cap: port capabilities
|
||||
*
|
||||
|
@ -1028,7 +1033,8 @@ EXPORT_SYMBOL(drm_dp_downstream_debug);
|
|||
|
||||
/**
|
||||
* drm_dp_subconnector_type() - get DP branch device type
|
||||
*
|
||||
* @dpcd: DisplayPort configuration data
|
||||
* @port_cap: port capabilities
|
||||
*/
|
||||
enum drm_mode_subconnector
|
||||
drm_dp_subconnector_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
|
||||
|
@ -1079,6 +1085,10 @@ EXPORT_SYMBOL(drm_dp_subconnector_type);
|
|||
|
||||
/**
|
||||
* drm_mode_set_dp_subconnector_property - set subconnector for DP connector
|
||||
* @connector: connector to set property on
|
||||
* @status: connector status
|
||||
* @dpcd: DisplayPort configuration data
|
||||
* @port_cap: port capabilities
|
||||
*
|
||||
* Called by a driver on every detect event.
|
||||
*/
|
||||
|
|
|
@ -3741,7 +3741,7 @@ drm_add_cmdb_modes(struct drm_connector *connector, u8 svd)
|
|||
/**
|
||||
* drm_display_mode_from_cea_vic() - return a mode for CEA VIC
|
||||
* @dev: DRM device
|
||||
* @vic: CEA VIC of the mode
|
||||
* @video_code: CEA VIC of the mode
|
||||
*
|
||||
* Creates a new mode matching the specified CEA VIC.
|
||||
*
|
||||
|
|
|
@ -1085,6 +1085,8 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
|
|||
*/
|
||||
drm_gem_object_get(obj);
|
||||
|
||||
vma->vm_private_data = obj;
|
||||
|
||||
if (obj->funcs && obj->funcs->mmap) {
|
||||
ret = obj->funcs->mmap(obj, vma);
|
||||
if (ret) {
|
||||
|
@ -1107,8 +1109,6 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
|
|||
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
vma->vm_private_data = obj;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_mmap_obj);
|
||||
|
|
|
@ -593,8 +593,13 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
|
|||
/* Remove the fake offset */
|
||||
vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
|
||||
|
||||
if (obj->import_attach)
|
||||
if (obj->import_attach) {
|
||||
/* Drop the reference drm_gem_mmap_obj() acquired.*/
|
||||
drm_gem_object_put(obj);
|
||||
vma->vm_private_data = NULL;
|
||||
|
||||
return dma_buf_mmap(obj->dma_buf, vma, 0);
|
||||
}
|
||||
|
||||
shmem = to_drm_gem_shmem_obj(obj);
|
||||
|
||||
|
|
|
@ -794,6 +794,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
|
|||
|
||||
/**
|
||||
* drm_prime_pages_to_sg - converts a page array into an sg list
|
||||
* @dev: DRM device
|
||||
* @pages: pointer to the array of page pointers to convert
|
||||
* @nr_pages: length of the page vector
|
||||
*
|
||||
|
|
|
@ -10636,6 +10636,10 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
|
|||
val & PLANE_CTL_FLIP_HORIZONTAL)
|
||||
plane_config->rotation |= DRM_MODE_REFLECT_X;
|
||||
|
||||
/* 90/270 degree rotation would require extra work */
|
||||
if (drm_rotation_90_or_270(plane_config->rotation))
|
||||
goto error;
|
||||
|
||||
base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000;
|
||||
plane_config->base = base;
|
||||
|
||||
|
|
|
@ -389,6 +389,7 @@ static const struct intel_device_info ilk_m_info = {
|
|||
GEN5_FEATURES,
|
||||
PLATFORM(INTEL_IRONLAKE),
|
||||
.is_mobile = 1,
|
||||
.has_rps = true,
|
||||
.display.has_fbc = 1,
|
||||
};
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem,
|
|||
min_order = ilog2(size) - ilog2(mem->mm.chunk_size);
|
||||
}
|
||||
|
||||
if (size > BIT(mem->mm.max_order) * mem->mm.chunk_size)
|
||||
if (size > mem->mm.size)
|
||||
return -E2BIG;
|
||||
|
||||
n_pages = size >> ilog2(mem->mm.chunk_size);
|
||||
|
|
|
@ -261,6 +261,82 @@ static int igt_mock_contiguous(void *arg)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int igt_mock_splintered_region(void *arg)
|
||||
{
|
||||
struct intel_memory_region *mem = arg;
|
||||
struct drm_i915_private *i915 = mem->i915;
|
||||
struct drm_i915_gem_object *obj;
|
||||
unsigned int expected_order;
|
||||
LIST_HEAD(objects);
|
||||
u64 size;
|
||||
int err = 0;
|
||||
|
||||
/*
|
||||
* Sanity check we can still allocate everything even if the
|
||||
* mm.max_order != mm.size. i.e our starting address space size is not a
|
||||
* power-of-two.
|
||||
*/
|
||||
|
||||
size = (SZ_4G - 1) & PAGE_MASK;
|
||||
mem = mock_region_create(i915, 0, size, PAGE_SIZE, 0);
|
||||
if (IS_ERR(mem))
|
||||
return PTR_ERR(mem);
|
||||
|
||||
if (mem->mm.size != size) {
|
||||
pr_err("%s size mismatch(%llu != %llu)\n",
|
||||
__func__, mem->mm.size, size);
|
||||
err = -EINVAL;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
expected_order = get_order(rounddown_pow_of_two(size));
|
||||
if (mem->mm.max_order != expected_order) {
|
||||
pr_err("%s order mismatch(%u != %u)\n",
|
||||
__func__, mem->mm.max_order, expected_order);
|
||||
err = -EINVAL;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
obj = igt_object_create(mem, &objects, size, 0);
|
||||
if (IS_ERR(obj)) {
|
||||
err = PTR_ERR(obj);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
close_objects(mem, &objects);
|
||||
|
||||
/*
|
||||
* While we should be able allocate everything without any flag
|
||||
* restrictions, if we consider I915_BO_ALLOC_CONTIGUOUS then we are
|
||||
* actually limited to the largest power-of-two for the region size i.e
|
||||
* max_order, due to the inner workings of the buddy allocator. So make
|
||||
* sure that does indeed hold true.
|
||||
*/
|
||||
|
||||
obj = igt_object_create(mem, &objects, size, I915_BO_ALLOC_CONTIGUOUS);
|
||||
if (!IS_ERR(obj)) {
|
||||
pr_err("%s too large contiguous allocation was not rejected\n",
|
||||
__func__);
|
||||
err = -EINVAL;
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
obj = igt_object_create(mem, &objects, rounddown_pow_of_two(size),
|
||||
I915_BO_ALLOC_CONTIGUOUS);
|
||||
if (IS_ERR(obj)) {
|
||||
pr_err("%s largest possible contiguous allocation failed\n",
|
||||
__func__);
|
||||
err = PTR_ERR(obj);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
out_close:
|
||||
close_objects(mem, &objects);
|
||||
out_put:
|
||||
intel_memory_region_put(mem);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int igt_gpu_write_dw(struct intel_context *ce,
|
||||
struct i915_vma *vma,
|
||||
u32 dword,
|
||||
|
@ -771,6 +847,7 @@ int intel_memory_region_mock_selftests(void)
|
|||
static const struct i915_subtest tests[] = {
|
||||
SUBTEST(igt_mock_fill),
|
||||
SUBTEST(igt_mock_contiguous),
|
||||
SUBTEST(igt_mock_splintered_region),
|
||||
};
|
||||
struct intel_memory_region *mem;
|
||||
struct drm_i915_private *i915;
|
||||
|
|
|
@ -24,7 +24,7 @@ mock_object_create(struct intel_memory_region *mem,
|
|||
struct drm_i915_private *i915 = mem->i915;
|
||||
struct drm_i915_gem_object *obj;
|
||||
|
||||
if (size > BIT(mem->mm.max_order) * mem->mm.chunk_size)
|
||||
if (size > mem->mm.size)
|
||||
return ERR_PTR(-E2BIG);
|
||||
|
||||
obj = i915_gem_object_alloc();
|
||||
|
|
|
@ -44,6 +44,7 @@ int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32,
|
|||
struct nv50_core **);
|
||||
int core507d_init(struct nv50_core *);
|
||||
void core507d_ntfy_init(struct nouveau_bo *, u32);
|
||||
int core507d_read_caps(struct nv50_disp *disp);
|
||||
int core507d_caps_init(struct nouveau_drm *, struct nv50_disp *);
|
||||
int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
|
||||
int core507d_update(struct nv50_core *, u32 *, bool);
|
||||
|
@ -55,6 +56,7 @@ extern const struct nv50_outp_func pior507d;
|
|||
int core827d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||
|
||||
int core907d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||
int core907d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp);
|
||||
extern const struct nv50_outp_func dac907d;
|
||||
extern const struct nv50_outp_func sor907d;
|
||||
|
||||
|
|
|
@ -78,18 +78,55 @@ core507d_ntfy_init(struct nouveau_bo *bo, u32 offset)
|
|||
}
|
||||
|
||||
int
|
||||
core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp)
|
||||
core507d_read_caps(struct nv50_disp *disp)
|
||||
{
|
||||
struct nvif_push *push = disp->core->chan.push;
|
||||
int ret;
|
||||
|
||||
if ((ret = PUSH_WAIT(push, 2)))
|
||||
ret = PUSH_WAIT(push, 6);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
PUSH_MTHD(push, NV507D, SET_NOTIFIER_CONTROL,
|
||||
NVDEF(NV507D, SET_NOTIFIER_CONTROL, MODE, WRITE) |
|
||||
NVVAL(NV507D, SET_NOTIFIER_CONTROL, OFFSET, NV50_DISP_CORE_NTFY >> 2) |
|
||||
NVDEF(NV507D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE));
|
||||
|
||||
PUSH_MTHD(push, NV507D, GET_CAPABILITIES, 0x00000000);
|
||||
|
||||
PUSH_MTHD(push, NV507D, SET_NOTIFIER_CONTROL,
|
||||
NVDEF(NV507D, SET_NOTIFIER_CONTROL, NOTIFY, DISABLE));
|
||||
|
||||
return PUSH_KICK(push);
|
||||
}
|
||||
|
||||
int
|
||||
core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp)
|
||||
{
|
||||
struct nv50_core *core = disp->core;
|
||||
struct nouveau_bo *bo = disp->sync;
|
||||
s64 time;
|
||||
int ret;
|
||||
|
||||
NVBO_WR32(bo, NV50_DISP_CORE_NTFY, NV_DISP_CORE_NOTIFIER_1, CAPABILITIES_1,
|
||||
NVDEF(NV_DISP_CORE_NOTIFIER_1, CAPABILITIES_1, DONE, FALSE));
|
||||
|
||||
ret = core507d_read_caps(disp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
time = nvif_msec(core->chan.base.device, 2000ULL,
|
||||
if (NVBO_TD32(bo, NV50_DISP_CORE_NTFY,
|
||||
NV_DISP_CORE_NOTIFIER_1, CAPABILITIES_1, DONE, ==, TRUE))
|
||||
break;
|
||||
usleep_range(1, 2);
|
||||
);
|
||||
if (time < 0)
|
||||
NV_ERROR(drm, "core caps notifier timeout\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
core507d_init(struct nv50_core *core)
|
||||
{
|
||||
|
|
|
@ -22,11 +22,45 @@
|
|||
#include "core.h"
|
||||
#include "head.h"
|
||||
|
||||
#include <nvif/push507c.h>
|
||||
#include <nvif/timer.h>
|
||||
|
||||
#include <nvhw/class/cl907d.h>
|
||||
|
||||
#include "nouveau_bo.h"
|
||||
|
||||
int
|
||||
core907d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp)
|
||||
{
|
||||
struct nv50_core *core = disp->core;
|
||||
struct nouveau_bo *bo = disp->sync;
|
||||
s64 time;
|
||||
int ret;
|
||||
|
||||
NVBO_WR32(bo, NV50_DISP_CORE_NTFY, NV907D_CORE_NOTIFIER_3, CAPABILITIES_4,
|
||||
NVDEF(NV907D_CORE_NOTIFIER_3, CAPABILITIES_4, DONE, FALSE));
|
||||
|
||||
ret = core507d_read_caps(disp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
time = nvif_msec(core->chan.base.device, 2000ULL,
|
||||
if (NVBO_TD32(bo, NV50_DISP_CORE_NTFY,
|
||||
NV907D_CORE_NOTIFIER_3, CAPABILITIES_4, DONE, ==, TRUE))
|
||||
break;
|
||||
usleep_range(1, 2);
|
||||
);
|
||||
if (time < 0)
|
||||
NV_ERROR(drm, "core caps notifier timeout\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct nv50_core_func
|
||||
core907d = {
|
||||
.init = core507d_init,
|
||||
.ntfy_init = core507d_ntfy_init,
|
||||
.caps_init = core507d_caps_init,
|
||||
.caps_init = core907d_caps_init,
|
||||
.ntfy_wait_done = core507d_ntfy_wait_done,
|
||||
.update = core507d_update,
|
||||
.head = &head907d,
|
||||
|
|
|
@ -26,7 +26,7 @@ static const struct nv50_core_func
|
|||
core917d = {
|
||||
.init = core507d_init,
|
||||
.ntfy_init = core507d_ntfy_init,
|
||||
.caps_init = core507d_caps_init,
|
||||
.caps_init = core907d_caps_init,
|
||||
.ntfy_wait_done = core507d_ntfy_wait_done,
|
||||
.update = core507d_update,
|
||||
.head = &head917d,
|
||||
|
|
|
@ -32,7 +32,10 @@
|
|||
#define NV_DISP_CORE_NOTIFIER_1_COMPLETION_0_DONE_TRUE 0x00000001
|
||||
#define NV_DISP_CORE_NOTIFIER_1_COMPLETION_0_R0 15:1
|
||||
#define NV_DISP_CORE_NOTIFIER_1_COMPLETION_0_TIMESTAMP 29:16
|
||||
|
||||
#define NV_DISP_CORE_NOTIFIER_1_CAPABILITIES_1 0x00000001
|
||||
#define NV_DISP_CORE_NOTIFIER_1_CAPABILITIES_1_DONE 0:0
|
||||
#define NV_DISP_CORE_NOTIFIER_1_CAPABILITIES_1_DONE_FALSE 0x00000000
|
||||
#define NV_DISP_CORE_NOTIFIER_1_CAPABILITIES_1_DONE_TRUE 0x00000001
|
||||
|
||||
// class methods
|
||||
#define NV507D_UPDATE (0x00000080)
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#ifndef _cl907d_h_
|
||||
#define _cl907d_h_
|
||||
|
||||
#define NV907D_CORE_NOTIFIER_3_CAPABILITIES_4 0x00000004
|
||||
#define NV907D_CORE_NOTIFIER_3_CAPABILITIES_4_DONE 0:0
|
||||
#define NV907D_CORE_NOTIFIER_3_CAPABILITIES_4_DONE_FALSE 0x00000000
|
||||
#define NV907D_CORE_NOTIFIER_3_CAPABILITIES_4_DONE_TRUE 0x00000001
|
||||
#define NV907D_CORE_NOTIFIER_3_CAPABILITIES_CAP_SOR0_20 0x00000014
|
||||
#define NV907D_CORE_NOTIFIER_3_CAPABILITIES_CAP_SOR0_20_SINGLE_LVDS18 0:0
|
||||
#define NV907D_CORE_NOTIFIER_3_CAPABILITIES_CAP_SOR0_20_SINGLE_LVDS18_FALSE 0x00000000
|
||||
|
|
|
@ -1023,29 +1023,6 @@ get_tmds_link_bandwidth(struct drm_connector *connector)
|
|||
return 112000 * duallink_scale;
|
||||
}
|
||||
|
||||
enum drm_mode_status
|
||||
nouveau_conn_mode_clock_valid(const struct drm_display_mode *mode,
|
||||
const unsigned min_clock,
|
||||
const unsigned max_clock,
|
||||
unsigned int *clock_out)
|
||||
{
|
||||
unsigned int clock = mode->clock;
|
||||
|
||||
if ((mode->flags & DRM_MODE_FLAG_3D_MASK) ==
|
||||
DRM_MODE_FLAG_3D_FRAME_PACKING)
|
||||
clock *= 2;
|
||||
|
||||
if (clock < min_clock)
|
||||
return MODE_CLOCK_LOW;
|
||||
if (clock > max_clock)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
if (clock_out)
|
||||
*clock_out = clock;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
nouveau_connector_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
|
@ -1053,7 +1030,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
|
|||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||
struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
|
||||
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
|
||||
unsigned min_clock = 25000, max_clock = min_clock;
|
||||
unsigned int min_clock = 25000, max_clock = min_clock, clock = mode->clock;
|
||||
|
||||
switch (nv_encoder->dcb->type) {
|
||||
case DCB_OUTPUT_LVDS:
|
||||
|
@ -1082,8 +1059,15 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
|
|||
return MODE_BAD;
|
||||
}
|
||||
|
||||
return nouveau_conn_mode_clock_valid(mode, min_clock, max_clock,
|
||||
NULL);
|
||||
if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
|
||||
clock *= 2;
|
||||
|
||||
if (clock < min_clock)
|
||||
return MODE_CLOCK_LOW;
|
||||
if (clock > max_clock)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static struct drm_encoder *
|
||||
|
|
|
@ -231,23 +231,30 @@ nv50_dp_mode_valid(struct drm_connector *connector,
|
|||
const struct drm_display_mode *mode,
|
||||
unsigned *out_clock)
|
||||
{
|
||||
const unsigned min_clock = 25000;
|
||||
unsigned max_clock, ds_clock, clock;
|
||||
enum drm_mode_status ret;
|
||||
const unsigned int min_clock = 25000;
|
||||
unsigned int max_rate, mode_rate, ds_max_dotclock, clock = mode->clock;
|
||||
const u8 bpp = connector->display_info.bpc * 3;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE && !outp->caps.dp_interlace)
|
||||
return MODE_NO_INTERLACE;
|
||||
|
||||
max_clock = outp->dp.link_nr * outp->dp.link_bw;
|
||||
ds_clock = drm_dp_downstream_max_dotclock(outp->dp.dpcd,
|
||||
outp->dp.downstream_ports);
|
||||
if (ds_clock)
|
||||
max_clock = min(max_clock, ds_clock);
|
||||
if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
|
||||
clock *= 2;
|
||||
|
||||
max_rate = outp->dp.link_nr * outp->dp.link_bw;
|
||||
mode_rate = DIV_ROUND_UP(clock * bpp, 8);
|
||||
if (mode_rate > max_rate)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
ds_max_dotclock = drm_dp_downstream_max_dotclock(outp->dp.dpcd, outp->dp.downstream_ports);
|
||||
if (ds_max_dotclock && clock > ds_max_dotclock)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
if (clock < min_clock)
|
||||
return MODE_CLOCK_LOW;
|
||||
|
||||
clock = mode->clock * (connector->display_info.bpc * 3) / 10;
|
||||
ret = nouveau_conn_mode_clock_valid(mode, min_clock, max_clock,
|
||||
&clock);
|
||||
if (out_clock)
|
||||
*out_clock = clock;
|
||||
return ret;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
|
|
@ -190,7 +190,8 @@ nouveau_gem_new(struct nouveau_cli *cli, u64 size, int align, uint32_t domain,
|
|||
* to the caller, instead of a normal nouveau_bo ttm reference. */
|
||||
ret = drm_gem_object_init(drm->dev, &nvbo->bo.base, size);
|
||||
if (ret) {
|
||||
nouveau_bo_ref(NULL, &nvbo);
|
||||
drm_gem_object_release(&nvbo->bo.base);
|
||||
kfree(nvbo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -105,11 +105,11 @@ nouveau_svmm_bind(struct drm_device *dev, void *data,
|
|||
struct nouveau_cli *cli = nouveau_cli(file_priv);
|
||||
struct drm_nouveau_svm_bind *args = data;
|
||||
unsigned target, cmd, priority;
|
||||
unsigned long addr, end, size;
|
||||
unsigned long addr, end;
|
||||
struct mm_struct *mm;
|
||||
|
||||
args->va_start &= PAGE_MASK;
|
||||
args->va_end &= PAGE_MASK;
|
||||
args->va_end = ALIGN(args->va_end, PAGE_SIZE);
|
||||
|
||||
/* Sanity check arguments */
|
||||
if (args->reserved0 || args->reserved1)
|
||||
|
@ -118,8 +118,6 @@ nouveau_svmm_bind(struct drm_device *dev, void *data,
|
|||
return -EINVAL;
|
||||
if (args->va_start >= args->va_end)
|
||||
return -EINVAL;
|
||||
if (!args->npages)
|
||||
return -EINVAL;
|
||||
|
||||
cmd = args->header >> NOUVEAU_SVM_BIND_COMMAND_SHIFT;
|
||||
cmd &= NOUVEAU_SVM_BIND_COMMAND_MASK;
|
||||
|
@ -151,12 +149,6 @@ nouveau_svmm_bind(struct drm_device *dev, void *data,
|
|||
if (args->stride)
|
||||
return -EINVAL;
|
||||
|
||||
size = ((unsigned long)args->npages) << PAGE_SHIFT;
|
||||
if ((args->va_start + size) <= args->va_start)
|
||||
return -EINVAL;
|
||||
if ((args->va_start + size) > args->va_end)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Ok we are ask to do something sane, for now we only support migrate
|
||||
* commands but we will add things like memory policy (what to do on
|
||||
|
@ -171,7 +163,7 @@ nouveau_svmm_bind(struct drm_device *dev, void *data,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (addr = args->va_start, end = args->va_start + size; addr < end;) {
|
||||
for (addr = args->va_start, end = args->va_end; addr < end;) {
|
||||
struct vm_area_struct *vma;
|
||||
unsigned long next;
|
||||
|
||||
|
|
|
@ -2924,17 +2924,34 @@ nvkm_device_del(struct nvkm_device **pdevice)
|
|||
}
|
||||
}
|
||||
|
||||
/* returns true if the GPU is in the CPU native byte order */
|
||||
static inline bool
|
||||
nvkm_device_endianness(struct nvkm_device *device)
|
||||
{
|
||||
u32 boot1 = nvkm_rd32(device, 0x000004) & 0x01000001;
|
||||
#ifdef __BIG_ENDIAN
|
||||
if (!boot1)
|
||||
return false;
|
||||
const bool big_endian = true;
|
||||
#else
|
||||
if (boot1)
|
||||
return false;
|
||||
const bool big_endian = false;
|
||||
#endif
|
||||
|
||||
/* Read NV_PMC_BOOT_1, and assume non-functional endian switch if it
|
||||
* doesn't contain the expected values.
|
||||
*/
|
||||
u32 pmc_boot_1 = nvkm_rd32(device, 0x000004);
|
||||
if (pmc_boot_1 && pmc_boot_1 != 0x01000001)
|
||||
return !big_endian; /* Assume GPU is LE in this case. */
|
||||
|
||||
/* 0 means LE and 0x01000001 means BE GPU. Condition is true when
|
||||
* GPU/CPU endianness don't match.
|
||||
*/
|
||||
if (big_endian == !pmc_boot_1) {
|
||||
nvkm_wr32(device, 0x000004, 0x01000001);
|
||||
nvkm_rd32(device, 0x000000);
|
||||
if (nvkm_rd32(device, 0x000004) != (big_endian ? 0x01000001 : 0x00000000))
|
||||
return !big_endian; /* Assume GPU is LE on any unexpected read-back. */
|
||||
}
|
||||
|
||||
/* CPU/GPU endianness should (hopefully) match. */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2987,14 +3004,10 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
|
|||
if (detect) {
|
||||
/* switch mmio to cpu's native endianness */
|
||||
if (!nvkm_device_endianness(device)) {
|
||||
nvkm_wr32(device, 0x000004, 0x01000001);
|
||||
nvkm_rd32(device, 0x000000);
|
||||
if (!nvkm_device_endianness(device)) {
|
||||
nvdev_error(device,
|
||||
"GPU not supported on big-endian\n");
|
||||
ret = -ENOSYS;
|
||||
goto done;
|
||||
}
|
||||
nvdev_error(device,
|
||||
"Couldn't switch GPU to CPUs endianess\n");
|
||||
ret = -ENOSYS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
boot0 = nvkm_rd32(device, 0x000000);
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
struct mantix {
|
||||
struct device *dev;
|
||||
struct drm_panel panel;
|
||||
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct gpio_desc *tp_rstn_gpio;
|
||||
|
||||
struct regulator *avdd;
|
||||
struct regulator *avee;
|
||||
|
@ -124,6 +126,10 @@ static int mantix_unprepare(struct drm_panel *panel)
|
|||
{
|
||||
struct mantix *ctx = panel_to_mantix(panel);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 1);
|
||||
usleep_range(5000, 6000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
|
||||
regulator_disable(ctx->avee);
|
||||
regulator_disable(ctx->avdd);
|
||||
/* T11 */
|
||||
|
@ -165,13 +171,10 @@ static int mantix_prepare(struct drm_panel *panel)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* T3+T5 */
|
||||
usleep_range(10000, 12000);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
usleep_range(5150, 7000);
|
||||
|
||||
/* T3 + T4 + time for voltage to become stable: */
|
||||
usleep_range(6000, 7000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 0);
|
||||
|
||||
/* T6 */
|
||||
msleep(50);
|
||||
|
@ -204,7 +207,7 @@ static int mantix_get_modes(struct drm_panel *panel,
|
|||
if (!mode) {
|
||||
dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n",
|
||||
default_mode.hdisplay, default_mode.vdisplay,
|
||||
drm_mode_vrefresh(mode));
|
||||
drm_mode_vrefresh(&default_mode));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -236,12 +239,18 @@ static int mantix_probe(struct mipi_dsi_device *dsi)
|
|||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ctx->reset_gpio)) {
|
||||
dev_err(dev, "cannot get reset gpio\n");
|
||||
return PTR_ERR(ctx->reset_gpio);
|
||||
}
|
||||
|
||||
ctx->tp_rstn_gpio = devm_gpiod_get(dev, "mantix,tp-rstn", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ctx->tp_rstn_gpio)) {
|
||||
dev_err(dev, "cannot get tp-rstn gpio\n");
|
||||
return PTR_ERR(ctx->tp_rstn_gpio);
|
||||
}
|
||||
|
||||
mipi_dsi_set_drvdata(dsi, ctx);
|
||||
ctx->dev = dev;
|
||||
|
||||
|
|
|
@ -407,6 +407,7 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend,
|
|||
struct drm_framebuffer *fb = state->fb;
|
||||
const struct drm_format_info *format = fb->format;
|
||||
uint64_t modifier = fb->modifier;
|
||||
unsigned int ch1_phase_idx;
|
||||
u32 out_fmt_val;
|
||||
u32 in_fmt_val, in_mod_val, in_ps_val;
|
||||
unsigned int i;
|
||||
|
@ -442,18 +443,19 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend,
|
|||
* I have no idea what this does exactly, but it seems to be
|
||||
* related to the scaler FIR filter phase parameters.
|
||||
*/
|
||||
ch1_phase_idx = (format->num_planes > 1) ? 1 : 0;
|
||||
regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZPHASE_REG,
|
||||
frontend->data->ch_phase[0].horzphase);
|
||||
frontend->data->ch_phase[0]);
|
||||
regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZPHASE_REG,
|
||||
frontend->data->ch_phase[1].horzphase);
|
||||
frontend->data->ch_phase[ch1_phase_idx]);
|
||||
regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE0_REG,
|
||||
frontend->data->ch_phase[0].vertphase[0]);
|
||||
frontend->data->ch_phase[0]);
|
||||
regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE0_REG,
|
||||
frontend->data->ch_phase[1].vertphase[0]);
|
||||
frontend->data->ch_phase[ch1_phase_idx]);
|
||||
regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE1_REG,
|
||||
frontend->data->ch_phase[0].vertphase[1]);
|
||||
frontend->data->ch_phase[0]);
|
||||
regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE1_REG,
|
||||
frontend->data->ch_phase[1].vertphase[1]);
|
||||
frontend->data->ch_phase[ch1_phase_idx]);
|
||||
|
||||
/*
|
||||
* Checking the input format is sufficient since we currently only
|
||||
|
@ -687,30 +689,12 @@ static const struct dev_pm_ops sun4i_frontend_pm_ops = {
|
|||
};
|
||||
|
||||
static const struct sun4i_frontend_data sun4i_a10_frontend = {
|
||||
.ch_phase = {
|
||||
{
|
||||
.horzphase = 0,
|
||||
.vertphase = { 0, 0 },
|
||||
},
|
||||
{
|
||||
.horzphase = 0xfc000,
|
||||
.vertphase = { 0xfc000, 0xfc000 },
|
||||
},
|
||||
},
|
||||
.ch_phase = { 0x000, 0xfc000 },
|
||||
.has_coef_rdy = true,
|
||||
};
|
||||
|
||||
static const struct sun4i_frontend_data sun8i_a33_frontend = {
|
||||
.ch_phase = {
|
||||
{
|
||||
.horzphase = 0x400,
|
||||
.vertphase = { 0x400, 0x400 },
|
||||
},
|
||||
{
|
||||
.horzphase = 0x400,
|
||||
.vertphase = { 0x400, 0x400 },
|
||||
},
|
||||
},
|
||||
.ch_phase = { 0x400, 0xfc400 },
|
||||
.has_coef_access_ctrl = true,
|
||||
};
|
||||
|
||||
|
|
|
@ -115,11 +115,7 @@ struct reset_control;
|
|||
struct sun4i_frontend_data {
|
||||
bool has_coef_access_ctrl;
|
||||
bool has_coef_rdy;
|
||||
|
||||
struct {
|
||||
u32 horzphase;
|
||||
u32 vertphase[2];
|
||||
} ch_phase[2];
|
||||
u32 ch_phase[2];
|
||||
};
|
||||
|
||||
struct sun4i_frontend {
|
||||
|
|
|
@ -568,7 +568,6 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
|||
ret = v3d_job_init(v3d, file_priv, &bin->base,
|
||||
v3d_job_free, args->in_sync_bcl);
|
||||
if (ret) {
|
||||
kfree(bin);
|
||||
v3d_job_put(&render->base);
|
||||
kfree(bin);
|
||||
return ret;
|
||||
|
|
|
@ -314,6 +314,7 @@ static int vc4_drm_bind(struct device *dev)
|
|||
component_unbind_all(dev, drm);
|
||||
gem_destroy:
|
||||
vc4_gem_destroy(drm);
|
||||
drm_mode_config_cleanup(drm);
|
||||
vc4_bo_cache_destroy(drm);
|
||||
dev_put:
|
||||
drm_dev_put(drm);
|
||||
|
|
|
@ -287,7 +287,7 @@ struct vc4_bo {
|
|||
static inline struct vc4_bo *
|
||||
to_vc4_bo(struct drm_gem_object *bo)
|
||||
{
|
||||
return (struct vc4_bo *)bo;
|
||||
return container_of(to_drm_gem_cma_obj(bo), struct vc4_bo, base);
|
||||
}
|
||||
|
||||
struct vc4_fence {
|
||||
|
@ -300,7 +300,7 @@ struct vc4_fence {
|
|||
static inline struct vc4_fence *
|
||||
to_vc4_fence(struct dma_fence *fence)
|
||||
{
|
||||
return (struct vc4_fence *)fence;
|
||||
return container_of(fence, struct vc4_fence, base);
|
||||
}
|
||||
|
||||
struct vc4_seqno_cb {
|
||||
|
@ -347,7 +347,7 @@ struct vc4_plane {
|
|||
static inline struct vc4_plane *
|
||||
to_vc4_plane(struct drm_plane *plane)
|
||||
{
|
||||
return (struct vc4_plane *)plane;
|
||||
return container_of(plane, struct vc4_plane, base);
|
||||
}
|
||||
|
||||
enum vc4_scaling_mode {
|
||||
|
@ -423,7 +423,7 @@ struct vc4_plane_state {
|
|||
static inline struct vc4_plane_state *
|
||||
to_vc4_plane_state(struct drm_plane_state *state)
|
||||
{
|
||||
return (struct vc4_plane_state *)state;
|
||||
return container_of(state, struct vc4_plane_state, base);
|
||||
}
|
||||
|
||||
enum vc4_encoder_type {
|
||||
|
@ -499,7 +499,7 @@ struct vc4_crtc {
|
|||
static inline struct vc4_crtc *
|
||||
to_vc4_crtc(struct drm_crtc *crtc)
|
||||
{
|
||||
return (struct vc4_crtc *)crtc;
|
||||
return container_of(crtc, struct vc4_crtc, base);
|
||||
}
|
||||
|
||||
static inline const struct vc4_crtc_data *
|
||||
|
@ -537,7 +537,7 @@ struct vc4_crtc_state {
|
|||
static inline struct vc4_crtc_state *
|
||||
to_vc4_crtc_state(struct drm_crtc_state *crtc_state)
|
||||
{
|
||||
return (struct vc4_crtc_state *)crtc_state;
|
||||
return container_of(crtc_state, struct vc4_crtc_state, base);
|
||||
}
|
||||
|
||||
#define V3D_READ(offset) readl(vc4->v3d->regs + offset)
|
||||
|
|
|
@ -922,6 +922,7 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
|
||||
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
|
||||
struct device *dev = &vc4_hdmi->pdev->dev;
|
||||
u32 audio_packet_config, channel_mask;
|
||||
u32 channel_map;
|
||||
|
@ -981,6 +982,8 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
|
|||
HDMI_WRITE(HDMI_AUDIO_PACKET_CONFIG, audio_packet_config);
|
||||
vc4_hdmi_set_n_cts(vc4_hdmi);
|
||||
|
||||
vc4_hdmi_set_audio_infoframe(encoder);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -988,11 +991,9 @@ static int vc4_hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
|
||||
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
vc4_hdmi_set_audio_infoframe(encoder);
|
||||
vc4_hdmi->audio.streaming = true;
|
||||
|
||||
if (vc4_hdmi->variant->phy_rng_enable)
|
||||
|
@ -1076,6 +1077,7 @@ static const struct snd_soc_dapm_route vc4_hdmi_audio_routes[] = {
|
|||
};
|
||||
|
||||
static const struct snd_soc_component_driver vc4_hdmi_audio_component_drv = {
|
||||
.name = "vc4-hdmi-codec-dai-component",
|
||||
.controls = vc4_hdmi_audio_controls,
|
||||
.num_controls = ARRAY_SIZE(vc4_hdmi_audio_controls),
|
||||
.dapm_widgets = vc4_hdmi_audio_widgets,
|
||||
|
|
|
@ -1836,7 +1836,7 @@ static inline void drm_dp_cec_unset_edid(struct drm_dp_aux *aux)
|
|||
* @link_rate: Requested Link rate from DPCD 0x219
|
||||
* @num_lanes: Number of lanes requested by sing through DPCD 0x220
|
||||
* @phy_pattern: DP Phy test pattern from DPCD 0x248
|
||||
* @hb2_reset: DP HBR2_COMPLIANCE_SCRAMBLER_RESET from DCPD 0x24A and 0x24B
|
||||
* @hbr2_reset: DP HBR2_COMPLIANCE_SCRAMBLER_RESET from DCPD 0x24A and 0x24B
|
||||
* @custom80: DP Test_80BIT_CUSTOM_PATTERN from DPCDs 0x250 through 0x259
|
||||
* @enhanced_frame_cap: flag for enhanced frame capability.
|
||||
*/
|
||||
|
|
|
@ -359,13 +359,6 @@ drm_load_edid_firmware(struct drm_connector *connector)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* drm_edid_are_equal - compare two edid blobs.
|
||||
* @edid1: pointer to first blob
|
||||
* @edid2: pointer to second blob
|
||||
* This helper can be used during probing to determine if
|
||||
* edid had changed.
|
||||
*/
|
||||
bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2);
|
||||
|
||||
int
|
||||
|
|
|
@ -338,7 +338,7 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
|
|||
const char *format, ...);
|
||||
|
||||
/**
|
||||
* Error output.
|
||||
* DRM_DEV_ERROR() - Error output.
|
||||
*
|
||||
* @dev: device pointer
|
||||
* @fmt: printf() like format string.
|
||||
|
@ -347,10 +347,12 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
|
|||
drm_dev_printk(dev, KERN_ERR, "*ERROR* " fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Rate limited error output. Like DRM_ERROR() but won't flood the log.
|
||||
* DRM_DEV_ERROR_RATELIMITED() - Rate limited error output.
|
||||
*
|
||||
* @dev: device pointer
|
||||
* @fmt: printf() like format string.
|
||||
*
|
||||
* Like DRM_ERROR() but won't flood the log.
|
||||
*/
|
||||
#define DRM_DEV_ERROR_RATELIMITED(dev, fmt, ...) \
|
||||
({ \
|
||||
|
@ -375,15 +377,27 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
|
|||
})
|
||||
|
||||
/**
|
||||
* Debug output.
|
||||
* DRM_DEV_DEBUG() - Debug output for generic drm code
|
||||
*
|
||||
* @dev: device pointer
|
||||
* @fmt: printf() like format string.
|
||||
*/
|
||||
#define DRM_DEV_DEBUG(dev, fmt, ...) \
|
||||
drm_dev_dbg(dev, DRM_UT_CORE, fmt, ##__VA_ARGS__)
|
||||
/**
|
||||
* DRM_DEV_DEBUG_DRIVER() - Debug output for vendor specific part of the driver
|
||||
*
|
||||
* @dev: device pointer
|
||||
* @fmt: printf() like format string.
|
||||
*/
|
||||
#define DRM_DEV_DEBUG_DRIVER(dev, fmt, ...) \
|
||||
drm_dev_dbg(dev, DRM_UT_DRIVER, fmt, ##__VA_ARGS__)
|
||||
/**
|
||||
* DRM_DEV_DEBUG_KMS() - Debug output for modesetting code
|
||||
*
|
||||
* @dev: device pointer
|
||||
* @fmt: printf() like format string.
|
||||
*/
|
||||
#define DRM_DEV_DEBUG_KMS(dev, fmt, ...) \
|
||||
drm_dev_dbg(dev, DRM_UT_KMS, fmt, ##__VA_ARGS__)
|
||||
|
||||
|
|
Loading…
Reference in New Issue